#include "sam.h"
#define NSYSFILE 3
#define NOFILE 128
void
checkqid(File *f)
{
int i, w;
File *g;
w = whichmenu(f);
for(i=1; i<file.nused; i++){
g = file.filepptr[i];
if(w == i)
continue;
if(f->dev==g->dev && f->qidpath==g->qidpath)
warn_SS(Wdupfile, &f->name, &g->name);
}
}
void
writef(File *f)
{
Posn n;
char *name;
int i, samename, newfile;
ulong dev;
uvlong qid;
long mtime, appendonly, length;
newfile = 0;
samename = Strcmp(&genstr, &f->name) == 0;
name = Strtoc(&f->name);
i = statfile(name, &dev, &qid, &mtime, 0, 0);
if(i == -1)
newfile++;
else if(samename &&
(f->dev!=dev || f->qidpath!=qid || f->mtime<mtime)){
f->dev = dev;
f->qidpath = qid;
f->mtime = mtime;
warn_S(Wdate, &genstr);
return;
}
if(genc)
free(genc);
genc = Strtoc(&genstr);
if((io=create(genc, 1, 0666L)) < 0)
error_s(Ecreate, genc);
dprint("%s: ", genc);
if(statfd(io, 0, 0, 0, &length, &appendonly) > 0 && appendonly && length>0)
error(Eappend);
n = writeio(f);
if(f->name.s[0]==0 || samename){
if(addr.r.p1==0 && addr.r.p2==f->nc)
f->cleanseq = f->seq;
state(f, f->cleanseq==f->seq? Clean : Dirty);
}
if(newfile)
dprint("(new file) ");
if(addr.r.p2>0 && filereadc(f, addr.r.p2-1)!='\n')
warn(Wnotnewline);
closeio(n);
if(f->name.s[0]==0 || samename){
if(statfile(name, &dev, &qid, &mtime, 0, 0) > 0){
f->dev = dev;
f->qidpath = qid;
f->mtime = mtime;
checkqid(f);
}
}
}
Posn
readio(File *f, int *nulls, int setdate, int toterm)
{
int n, b, w;
Rune *r;
Posn nt;
Posn p = addr.r.p2;
ulong dev;
uvlong qid;
long mtime;
char buf[BLOCKSIZE+1], *s;
*nulls = FALSE;
b = 0;
if(f->unread){
nt = bufload(f, 0, io, nulls);
if(toterm)
raspload(f);
}else
for(nt = 0; (n = read(io, buf+b, BLOCKSIZE-b))>0; nt+=(r-genbuf)){
n += b;
b = 0;
r = genbuf;
s = buf;
while(n > 0){
if((*r = *(uchar*)s) < Runeself){
if(*r)
r++;
else
*nulls = TRUE;
--n;
s++;
continue;
}
if(fullrune(s, n)){
w = chartorune(r, s);
if(*r)
r++;
else
*nulls = TRUE;
n -= w;
s += w;
continue;
}
b = n;
memmove(buf, s, b);
break;
}
loginsert(f, p, genbuf, r-genbuf);
}
if(b)
*nulls = TRUE;
if(*nulls)
warn(Wnulls);
if(setdate){
if(statfd(io, &dev, &qid, &mtime, 0, 0) > 0){
f->dev = dev;
f->qidpath = qid;
f->mtime = mtime;
checkqid(f);
}
}
return nt;
}
Posn
writeio(File *f)
{
int m, n;
Posn p = addr.r.p1;
char *c;
while(p < addr.r.p2){
if(addr.r.p2-p>BLOCKSIZE)
n = BLOCKSIZE;
else
n = addr.r.p2-p;
bufread(f, p, genbuf, n);
c = Strtoc(tmprstr(genbuf, n));
m = strlen(c);
if(Write(io, c, m) != m){
free(c);
if(p > 0)
p += n;
break;
}
free(c);
p += n;
}
return p-addr.r.p1;
}
void
closeio(Posn p)
{
close(io);
io = 0;
if(p >= 0)
dprint("#%lud\n", p);
}
syntax highlighted by Code2HTML, v. 0.9.1