1 #include "sam.h" 2 3 #define NSYSFILE 3 4 #define NOFILE 128 5 6 void 7 checkqid(File *f) 8 { 9 int i, w; 10 File *g; 11 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 } 21 22 void 23 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; 31 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->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 } 74 75 Posn 76 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; 86 87 *nulls = FALSE; 88 b = 0; 89 if(f->unread){ 90 nt = bufload(f, 0, io, nulls); 91 if(toterm) 92 raspload(f); 93 }else 94 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 else 104 *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 else 114 *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 } 139 140 Posn 141 writeio(File *f) 142 { 143 int m, n; 144 Posn p = addr.r.p1; 145 char *c; 146 147 while(p < addr.r.p2){ 148 if(addr.r.p2-p>BLOCKSIZE) 149 n = BLOCKSIZE; 150 else 151 n = addr.r.p2-p; 152 bufread(f, 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 void 167 closeio(Posn p) 168 { 169 close(io); 170 io = 0; 171 if(p >= 0) 172 dprint("#%lud\n", p); 173 } 174 175 int remotefd0 = 0; 176 int remotefd1 = 1; 177 178 void 179 bootterm(char *machine, char **argv, char **end) 180 { 181 int ph2t[2], pt2h[2]; 182 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 exec(samterm, argv); 191 fprint(2, "can't exec: "); 192 perror(samterm); 193 _exits("damn"); 194 } 195 if(pipe(ph2t)==-1 || pipe(pt2h)==-1) 196 panic("pipe"); 197 switch(fork()){ 198 case 0: 199 dup(ph2t[0], 0); 200 dup(pt2h[1], 1); 201 close(ph2t[0]); 202 close(ph2t[1]); 203 close(pt2h[0]); 204 close(pt2h[1]); 205 argv[0] = "samterm"; 206 *end = 0; 207 exec(samterm, argv); 208 fprint(2, "can't exec: "); 209 perror(samterm); 210 _exits("damn"); 211 case -1: 212 panic("can't fork samterm"); 213 } 214 dup(pt2h[0], 0); 215 dup(ph2t[1], 1); 216 close(ph2t[0]); 217 close(ph2t[1]); 218 close(pt2h[0]); 219 close(pt2h[1]); 220 } 221 222 void 223 connectto(char *machine) 224 { 225 int p1[2], p2[2]; 226 227 if(pipe(p1)<0 || pipe(p2)<0){ 228 dprint("can't pipe\n"); 229 exits("pipe"); 230 } 231 remotefd0 = p1[0]; 232 remotefd1 = p2[1]; 233 switch(fork()){ 234 case 0: 235 dup(p2[0], 0); 236 dup(p1[1], 1); 237 close(p1[0]); 238 close(p1[1]); 239 close(p2[0]); 240 close(p2[1]); 241 execl(RXPATH, RX, machine, rsamname, "-R", (char*)0); 242 dprint("can't exec %s\n", RXPATH); 243 exits("exec"); 244 245 case -1: 246 dprint("can't fork\n"); 247 exits("fork"); 248 } 249 close(p1[1]); 250 close(p2[0]); 251 } 252 253 void 254 startup(char *machine, int Rflag, char **argv, char **end) 255 { 256 if(machine) 257 connectto(machine); 258 if(!Rflag) 259 bootterm(machine, argv, end); 260 downloaded = 1; 261 outTs(Hversion, VERSION); 262 } 263