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