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) 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 exec(samterm, argv); 190 fprint(2, "can't exec: "); 191 perror(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 exec(samterm, argv); 206 fprint(2, "can't exec: "); 207 perror(samterm); 208 _exits("damn"); 209 case -1: 210 panic("can't fork samterm"); 211 } 212 dup(pt2h[0], 0); 213 dup(ph2t[1], 1); 214 close(ph2t[0]); 215 close(ph2t[1]); 216 close(pt2h[0]); 217 close(pt2h[1]); 218 } 219 220 void 221 connectto(char *machine, char **argv) 222 { 223 int p1[2], p2[2]; 224 char **av; 225 int ac; 226 227 // count args 228 for(av = argv; *av; av++) 229 ; 230 av = malloc(sizeof(char*)*((av-argv) + 5)); 231 if(av == nil){ 232 dprint("out of memory\n"); 233 exits("fork/exec"); 234 } 235 ac = 0; 236 av[ac++] = RX; 237 av[ac++] = machine; 238 av[ac++] = rsamname; 239 av[ac++] = "-R"; 240 while(*argv) 241 av[ac++] = *argv++; 242 av[ac] = 0; 243 if(pipe(p1)<0 || pipe(p2)<0){ 244 dprint("can't pipe\n"); 245 exits("pipe"); 246 } 247 remotefd0 = p1[0]; 248 remotefd1 = p2[1]; 249 switch(fork()){ 250 case 0: 251 dup(p2[0], 0); 252 dup(p1[1], 1); 253 close(p1[0]); 254 close(p1[1]); 255 close(p2[0]); 256 close(p2[1]); 257 exec(RXPATH, av); 258 dprint("can't exec %s\n", RXPATH); 259 exits("exec"); 260 261 case -1: 262 dprint("can't fork\n"); 263 exits("fork"); 264 } 265 free(av); 266 close(p1[1]); 267 close(p2[0]); 268 } 269 270 void 271 startup(char *machine, int Rflag, char **argv, char **files) 272 { 273 if(machine) 274 connectto(machine, files); 275 if(!Rflag) 276 bootterm(machine, argv); 277 downloaded = 1; 278 outTs(Hversion, VERSION); 279 } 280