Blob
1 #include "sam.h"3 #define NSYSFILE 34 #define NOFILE 1286 void7 checkqid(File *f)8 {9 int i, w;10 File *g;12 w = whichmenu(f);13 for(i=1; i<file.nused; i++){14 g = file.filepptr[i];15 if(w == i)16 continue;17 if(f->dev==g->dev && f->qidpath==g->qidpath)18 warn_SS(Wdupfile, &f->name, &g->name);19 }20 }22 void23 writef(File *f)24 {25 Posn n;26 char *name;27 int i, samename, newfile;28 ulong dev;29 uvlong qid;30 long mtime, appendonly, length;32 newfile = 0;33 samename = Strcmp(&genstr, &f->name) == 0;34 name = Strtoc(&f->name);35 i = statfile(name, &dev, &qid, &mtime, 0, 0);36 if(i == -1)37 newfile++;38 else if(samename &&39 (f->dev!=dev || f->qidpath!=qid || f->mtime<mtime)){40 f->dev = dev;41 f->qidpath = qid;42 f->mtime = mtime;43 warn_S(Wdate, &genstr);44 return;45 }46 if(genc)47 free(genc);48 genc = Strtoc(&genstr);49 if((io=create(genc, 1, 0666L)) < 0)50 error_r(Ecreate, genc);51 dprint("%s: ", genc);52 if(statfd(io, 0, 0, 0, &length, &appendonly) > 0 && appendonly && length>0)53 error(Eappend);54 n = writeio(f);55 if(f->name.s[0]==0 || samename){56 if(addr.r.p1==0 && addr.r.p2==f->b.nc)57 f->cleanseq = f->seq;58 state(f, f->cleanseq==f->seq? Clean : Dirty);59 }60 if(newfile)61 dprint("(new file) ");62 if(addr.r.p2>0 && filereadc(f, addr.r.p2-1)!='\n')63 warn(Wnotnewline);64 closeio(n);65 if(f->name.s[0]==0 || samename){66 if(statfile(name, &dev, &qid, &mtime, 0, 0) > 0){67 f->dev = dev;68 f->qidpath = qid;69 f->mtime = mtime;70 checkqid(f);71 }72 }73 }75 Posn76 readio(File *f, int *nulls, int setdate, int toterm)77 {78 int n, b, w;79 Rune *r;80 Posn nt;81 Posn p = addr.r.p2;82 ulong dev;83 uvlong qid;84 long mtime;85 char buf[BLOCKSIZE+1], *s;87 *nulls = FALSE;88 b = 0;89 if(f->unread){90 nt = bufload(&f->b, 0, io, nulls);91 if(toterm)92 raspload(f);93 }else94 for(nt = 0; (n = read(io, buf+b, BLOCKSIZE-b))>0; nt+=(r-genbuf)){95 n += b;96 b = 0;97 r = genbuf;98 s = buf;99 while(n > 0){100 if((*r = *(uchar*)s) < Runeself){101 if(*r)102 r++;103 else104 *nulls = TRUE;105 --n;106 s++;107 continue;108 }109 if(fullrune(s, n)){110 w = chartorune(r, s);111 if(*r)112 r++;113 else114 *nulls = TRUE;115 n -= w;116 s += w;117 continue;118 }119 b = n;120 memmove(buf, s, b);121 break;122 }123 loginsert(f, p, genbuf, r-genbuf);124 }125 if(b)126 *nulls = TRUE;127 if(*nulls)128 warn(Wnulls);129 if(setdate){130 if(statfd(io, &dev, &qid, &mtime, 0, 0) > 0){131 f->dev = dev;132 f->qidpath = qid;133 f->mtime = mtime;134 checkqid(f);135 }136 }137 return nt;138 }140 Posn141 writeio(File *f)142 {143 int m, n;144 Posn p = addr.r.p1;145 char *c;147 while(p < addr.r.p2){148 if(addr.r.p2-p>BLOCKSIZE)149 n = BLOCKSIZE;150 else151 n = addr.r.p2-p;152 bufread(&f->b, p, genbuf, n);153 c = Strtoc(tmprstr(genbuf, n));154 m = strlen(c);155 if(Write(io, c, m) != m){156 free(c);157 if(p > 0)158 p += n;159 break;160 }161 free(c);162 p += n;163 }164 return p-addr.r.p1;165 }166 void167 closeio(Posn p)168 {169 close(io);170 io = 0;171 if(p >= 0)172 dprint("#%lud\n", p);173 }175 int remotefd0 = 0;176 int remotefd1 = 1;178 void179 bootterm(char *machine, char **argv, char **end)180 {181 int ph2t[2], pt2h[2];183 if(machine){184 dup(remotefd0, 0);185 dup(remotefd1, 1);186 close(remotefd0);187 close(remotefd1);188 argv[0] = "samterm";189 *end = 0;190 execvp(samterm, argv);191 fprint(2, "can't exec %s: %r\n", samterm);192 _exits("damn");193 }194 if(pipe(ph2t)==-1 || pipe(pt2h)==-1)195 panic("pipe");196 switch(fork()){197 case 0:198 dup(ph2t[0], 0);199 dup(pt2h[1], 1);200 close(ph2t[0]);201 close(ph2t[1]);202 close(pt2h[0]);203 close(pt2h[1]);204 argv[0] = "samterm";205 *end = 0;206 execvp(samterm, argv);207 fprint(2, "can't exec: ");208 perror(samterm);209 _exits("damn");210 case -1:211 panic("can't fork samterm");212 }213 dup(pt2h[0], 0);214 dup(ph2t[1], 1);215 close(ph2t[0]);216 close(ph2t[1]);217 close(pt2h[0]);218 close(pt2h[1]);219 }221 void222 connectto(char *machine, char **argv)223 {224 int p1[2], p2[2];225 char **av;226 int ac;228 // count args229 for(av = argv; *av; av++)230 ;231 av = malloc(sizeof(char*)*((av-argv) + 5));232 if(av == nil){233 dprint("out of memory\n");234 exits("fork/exec");235 }236 ac = 0;237 av[ac++] = RX;238 av[ac++] = machine;239 av[ac++] = rsamname;240 av[ac++] = "-R";241 while(*argv)242 av[ac++] = *argv++;243 av[ac] = 0;244 if(pipe(p1)<0 || pipe(p2)<0){245 dprint("can't pipe\n");246 exits("pipe");247 }248 remotefd0 = p1[0];249 remotefd1 = p2[1];250 switch(fork()){251 case 0:252 dup(p2[0], 0);253 dup(p1[1], 1);254 close(p1[0]);255 close(p1[1]);256 close(p2[0]);257 close(p2[1]);258 execvp(RXPATH, av);259 dprint("can't exec %s\n", RXPATH);260 exits("exec");262 case -1:263 dprint("can't fork\n");264 exits("fork");265 }266 free(av);267 close(p1[1]);268 close(p2[0]);269 }271 void272 startup(char *machine, int Rflag, char **argv, char **end, char **files)273 {274 if(machine)275 connectto(machine, files);276 if(!Rflag)277 bootterm(machine, argv, end);278 downloaded = 1;279 outTs(Hversion, VERSION);280 }