13e12c5d1SDavid du Colombier #include "sam.h" 23e12c5d1SDavid du Colombier 33e12c5d1SDavid du Colombier #define NSYSFILE 3 43e12c5d1SDavid du Colombier #define NOFILE 128 53e12c5d1SDavid du Colombier 63e12c5d1SDavid du Colombier void 7bd389b36SDavid du Colombier checkqid(File *f) 8bd389b36SDavid du Colombier { 9bd389b36SDavid du Colombier int i, w; 10bd389b36SDavid du Colombier File *g; 11bd389b36SDavid du Colombier 12bd389b36SDavid du Colombier w = whichmenu(f); 13bd389b36SDavid du Colombier for(i=1; i<file.nused; i++){ 14bd389b36SDavid du Colombier g = file.filepptr[i]; 15bd389b36SDavid du Colombier if(w == i) 16bd389b36SDavid du Colombier continue; 17bd389b36SDavid du Colombier if(f->dev==g->dev && f->qid==g->qid) 18bd389b36SDavid du Colombier warn_SS(Wdupfile, &f->name, &g->name); 19bd389b36SDavid du Colombier } 20bd389b36SDavid du Colombier } 21bd389b36SDavid du Colombier 22bd389b36SDavid du Colombier void 233e12c5d1SDavid du Colombier writef(File *f) 243e12c5d1SDavid du Colombier { 253e12c5d1SDavid du Colombier Rune c; 263e12c5d1SDavid du Colombier Posn n; 273e12c5d1SDavid du Colombier char *name; 283e12c5d1SDavid du Colombier int i, samename, newfile; 29bd389b36SDavid du Colombier ulong dev, qid; 30*219b2ee8SDavid du Colombier long mtime, appendonly, length; 313e12c5d1SDavid du Colombier 323e12c5d1SDavid du Colombier newfile = 0; 333e12c5d1SDavid du Colombier samename = Strcmp(&genstr, &f->name) == 0; 343e12c5d1SDavid du Colombier name = Strtoc(&f->name); 35*219b2ee8SDavid du Colombier i = statfile(name, &dev, &qid, &mtime, 0, 0); 363e12c5d1SDavid du Colombier if(i == -1) 373e12c5d1SDavid du Colombier newfile++; 383e12c5d1SDavid du Colombier else if(samename && 39bd389b36SDavid du Colombier (f->dev!=dev || f->qid!=qid || f->date<mtime)){ 40bd389b36SDavid du Colombier f->dev = dev; 41bd389b36SDavid du Colombier f->qid = qid; 423e12c5d1SDavid du Colombier f->date = mtime; 433e12c5d1SDavid du Colombier warn_S(Wdate, &genstr); 443e12c5d1SDavid du Colombier return; 453e12c5d1SDavid du Colombier } 463e12c5d1SDavid du Colombier if(genc) 473e12c5d1SDavid du Colombier free(genc); 483e12c5d1SDavid du Colombier genc = Strtoc(&genstr); 493e12c5d1SDavid du Colombier if((io=create(genc, 1, 0666L)) < 0) 503e12c5d1SDavid du Colombier error_s(Ecreate, genc); 513e12c5d1SDavid du Colombier dprint("%s: ", genc); 52*219b2ee8SDavid du Colombier if(statfd(io, 0, 0, 0, &length, &appendonly) > 0 && appendonly && length>0) 53*219b2ee8SDavid du Colombier error(Eappend); 543e12c5d1SDavid du Colombier n = writeio(f); 553e12c5d1SDavid du Colombier if(f->name.s[0]==0 || samename) 563e12c5d1SDavid du Colombier state(f, addr.r.p1==0 && addr.r.p2==f->nrunes? Clean : Dirty); 573e12c5d1SDavid du Colombier if(newfile) 583e12c5d1SDavid du Colombier dprint("(new file) "); 593e12c5d1SDavid du Colombier if(addr.r.p2>0 && Fchars(f, &c, addr.r.p2-1, addr.r.p2) && c!='\n') 603e12c5d1SDavid du Colombier warn(Wnotnewline); 613e12c5d1SDavid du Colombier if(f->name.s[0]==0 || samename){ 62*219b2ee8SDavid du Colombier if(statfd(io, &dev, &qid, &mtime, 0, 0) > 0){ 63bd389b36SDavid du Colombier f->dev = dev; 64bd389b36SDavid du Colombier f->qid = qid; 653e12c5d1SDavid du Colombier f->date = mtime; 66bd389b36SDavid du Colombier checkqid(f); 673e12c5d1SDavid du Colombier } 683e12c5d1SDavid du Colombier } 693e12c5d1SDavid du Colombier closeio(n); 703e12c5d1SDavid du Colombier } 713e12c5d1SDavid du Colombier 723e12c5d1SDavid du Colombier Posn 733e12c5d1SDavid du Colombier readio(File *f, int *nulls, int setdate) 743e12c5d1SDavid du Colombier { 753e12c5d1SDavid du Colombier int n, b, w; 763e12c5d1SDavid du Colombier Rune *r; 773e12c5d1SDavid du Colombier Posn nt; 783e12c5d1SDavid du Colombier Posn p = addr.r.p2; 79bd389b36SDavid du Colombier ulong dev, qid; 803e12c5d1SDavid du Colombier long mtime; 813e12c5d1SDavid du Colombier char buf[BLOCKSIZE+1], *s; 823e12c5d1SDavid du Colombier 833e12c5d1SDavid du Colombier *nulls = FALSE; 843e12c5d1SDavid du Colombier b = 0; 853e12c5d1SDavid du Colombier for(nt = 0; (n = read(io, buf+b, BLOCKSIZE-b))>0; nt+=(r-genbuf)){ 863e12c5d1SDavid du Colombier n += b; 873e12c5d1SDavid du Colombier b = 0; 883e12c5d1SDavid du Colombier r = genbuf; 893e12c5d1SDavid du Colombier s = buf; 903e12c5d1SDavid du Colombier while(n > 0){ 913e12c5d1SDavid du Colombier if((*r = *(uchar*)s) < Runeself){ 923e12c5d1SDavid du Colombier if(*r) 933e12c5d1SDavid du Colombier r++; 943e12c5d1SDavid du Colombier else 953e12c5d1SDavid du Colombier *nulls = TRUE; 963e12c5d1SDavid du Colombier --n; 973e12c5d1SDavid du Colombier s++; 983e12c5d1SDavid du Colombier continue; 993e12c5d1SDavid du Colombier } 1003e12c5d1SDavid du Colombier if(fullrune(s, n)){ 1013e12c5d1SDavid du Colombier w = chartorune(r, s); 1023e12c5d1SDavid du Colombier if(*r) 1033e12c5d1SDavid du Colombier r++; 1043e12c5d1SDavid du Colombier else 1053e12c5d1SDavid du Colombier *nulls = TRUE; 1063e12c5d1SDavid du Colombier n -= w; 1073e12c5d1SDavid du Colombier s += w; 1083e12c5d1SDavid du Colombier continue; 1093e12c5d1SDavid du Colombier } 1103e12c5d1SDavid du Colombier b = n; 1113e12c5d1SDavid du Colombier memmove(buf, s, b); 1123e12c5d1SDavid du Colombier break; 1133e12c5d1SDavid du Colombier } 1143e12c5d1SDavid du Colombier Finsert(f, tmprstr(genbuf, r-genbuf), p); 1153e12c5d1SDavid du Colombier } 1163e12c5d1SDavid du Colombier if(b) 1173e12c5d1SDavid du Colombier *nulls = TRUE; 1183e12c5d1SDavid du Colombier if(*nulls) 1193e12c5d1SDavid du Colombier warn(Wnulls); 1203e12c5d1SDavid du Colombier if(setdate){ 121*219b2ee8SDavid du Colombier if(statfd(io, &dev, &qid, &mtime, 0, 0) > 0){ 122bd389b36SDavid du Colombier f->dev = dev; 123bd389b36SDavid du Colombier f->qid = qid; 1243e12c5d1SDavid du Colombier f->date = mtime; 125bd389b36SDavid du Colombier checkqid(f); 1263e12c5d1SDavid du Colombier } 1273e12c5d1SDavid du Colombier } 1283e12c5d1SDavid du Colombier return nt; 1293e12c5d1SDavid du Colombier } 1303e12c5d1SDavid du Colombier 1313e12c5d1SDavid du Colombier Posn 1323e12c5d1SDavid du Colombier writeio(File *f) 1333e12c5d1SDavid du Colombier { 1343e12c5d1SDavid du Colombier int m, n; 1353e12c5d1SDavid du Colombier Posn p = addr.r.p1; 1363e12c5d1SDavid du Colombier char *c; 1373e12c5d1SDavid du Colombier 1383e12c5d1SDavid du Colombier while(p < addr.r.p2){ 1393e12c5d1SDavid du Colombier if(addr.r.p2-p>BLOCKSIZE) 1403e12c5d1SDavid du Colombier n = BLOCKSIZE; 1413e12c5d1SDavid du Colombier else 1423e12c5d1SDavid du Colombier n = addr.r.p2-p; 1433e12c5d1SDavid du Colombier if(Fchars(f, genbuf, p, p+n)!=n) 1443e12c5d1SDavid du Colombier panic("writef read"); 1453e12c5d1SDavid du Colombier c = Strtoc(tmprstr(genbuf, n)); 1463e12c5d1SDavid du Colombier m = strlen(c); 1473e12c5d1SDavid du Colombier if(Write(io, c, m) != m){ 1483e12c5d1SDavid du Colombier free(c); 1493e12c5d1SDavid du Colombier if(p > 0) 1503e12c5d1SDavid du Colombier p += n; 1513e12c5d1SDavid du Colombier break; 1523e12c5d1SDavid du Colombier } 1533e12c5d1SDavid du Colombier free(c); 1543e12c5d1SDavid du Colombier p += n; 1553e12c5d1SDavid du Colombier } 1563e12c5d1SDavid du Colombier return p-addr.r.p1; 1573e12c5d1SDavid du Colombier } 1583e12c5d1SDavid du Colombier void 1593e12c5d1SDavid du Colombier closeio(Posn p) 1603e12c5d1SDavid du Colombier { 1613e12c5d1SDavid du Colombier close(io); 1623e12c5d1SDavid du Colombier io = 0; 1633e12c5d1SDavid du Colombier if(p >= 0) 1643e12c5d1SDavid du Colombier dprint("#%lud\n", p); 1653e12c5d1SDavid du Colombier } 1663e12c5d1SDavid du Colombier 1673e12c5d1SDavid du Colombier int remotefd0 = 0; 1683e12c5d1SDavid du Colombier int remotefd1 = 1; 1693e12c5d1SDavid du Colombier 1703e12c5d1SDavid du Colombier void 1713e12c5d1SDavid du Colombier bootterm(char *machine, char **argv, char **end) 1723e12c5d1SDavid du Colombier { 1733e12c5d1SDavid du Colombier int ph2t[2], pt2h[2]; 1743e12c5d1SDavid du Colombier 1753e12c5d1SDavid du Colombier if(machine){ 1763e12c5d1SDavid du Colombier dup(remotefd0, 0); 1773e12c5d1SDavid du Colombier dup(remotefd1, 1); 1783e12c5d1SDavid du Colombier close(remotefd0); 1793e12c5d1SDavid du Colombier close(remotefd1); 1803e12c5d1SDavid du Colombier argv[0] = "samterm"; 1813e12c5d1SDavid du Colombier *end = 0; 1823e12c5d1SDavid du Colombier exec(samterm, argv); 1833e12c5d1SDavid du Colombier fprint(2, "can't exec: "); 1843e12c5d1SDavid du Colombier perror(samterm); 1853e12c5d1SDavid du Colombier _exits("damn"); 1863e12c5d1SDavid du Colombier } 1873e12c5d1SDavid du Colombier if(pipe(ph2t)==-1 || pipe(pt2h)==-1) 1883e12c5d1SDavid du Colombier panic("pipe"); 1893e12c5d1SDavid du Colombier switch(fork()){ 1903e12c5d1SDavid du Colombier case 0: 1913e12c5d1SDavid du Colombier dup(ph2t[0], 0); 1923e12c5d1SDavid du Colombier dup(pt2h[1], 1); 1933e12c5d1SDavid du Colombier close(ph2t[0]); 1943e12c5d1SDavid du Colombier close(ph2t[1]); 1953e12c5d1SDavid du Colombier close(pt2h[0]); 1963e12c5d1SDavid du Colombier close(pt2h[1]); 1973e12c5d1SDavid du Colombier argv[0] = "samterm"; 1983e12c5d1SDavid du Colombier *end = 0; 1993e12c5d1SDavid du Colombier exec(samterm, argv); 2003e12c5d1SDavid du Colombier fprint(2, "can't exec: "); 2013e12c5d1SDavid du Colombier perror(samterm); 2023e12c5d1SDavid du Colombier _exits("damn"); 2033e12c5d1SDavid du Colombier case -1: 2043e12c5d1SDavid du Colombier panic("can't fork samterm"); 2053e12c5d1SDavid du Colombier } 2063e12c5d1SDavid du Colombier dup(pt2h[0], 0); 2073e12c5d1SDavid du Colombier dup(ph2t[1], 1); 2083e12c5d1SDavid du Colombier close(ph2t[0]); 2093e12c5d1SDavid du Colombier close(ph2t[1]); 2103e12c5d1SDavid du Colombier close(pt2h[0]); 2113e12c5d1SDavid du Colombier close(pt2h[1]); 2123e12c5d1SDavid du Colombier } 2133e12c5d1SDavid du Colombier 2143e12c5d1SDavid du Colombier void 2153e12c5d1SDavid du Colombier connectto(char *machine) 2163e12c5d1SDavid du Colombier { 2173e12c5d1SDavid du Colombier int p1[2], p2[2]; 2183e12c5d1SDavid du Colombier 2193e12c5d1SDavid du Colombier if(pipe(p1)<0 || pipe(p2)<0){ 2203e12c5d1SDavid du Colombier dprint("can't pipe\n"); 2213e12c5d1SDavid du Colombier exits("pipe"); 2223e12c5d1SDavid du Colombier } 2233e12c5d1SDavid du Colombier remotefd0 = p1[0]; 2243e12c5d1SDavid du Colombier remotefd1 = p2[1]; 2253e12c5d1SDavid du Colombier switch(fork()){ 2263e12c5d1SDavid du Colombier case 0: 2273e12c5d1SDavid du Colombier dup(p2[0], 0); 2283e12c5d1SDavid du Colombier dup(p1[1], 1); 2293e12c5d1SDavid du Colombier close(p1[0]); 2303e12c5d1SDavid du Colombier close(p1[1]); 2313e12c5d1SDavid du Colombier close(p2[0]); 2323e12c5d1SDavid du Colombier close(p2[1]); 2333e12c5d1SDavid du Colombier execl(RXPATH, RX, machine, rsamname, "-R", (char*)0); 2343e12c5d1SDavid du Colombier dprint("can't exec %s\n", RXPATH); 2353e12c5d1SDavid du Colombier exits("exec"); 2363e12c5d1SDavid du Colombier 2373e12c5d1SDavid du Colombier case -1: 2383e12c5d1SDavid du Colombier dprint("can't fork\n"); 2393e12c5d1SDavid du Colombier exits("fork"); 2403e12c5d1SDavid du Colombier } 2413e12c5d1SDavid du Colombier close(p1[1]); 2423e12c5d1SDavid du Colombier close(p2[0]); 2433e12c5d1SDavid du Colombier } 2443e12c5d1SDavid du Colombier 2453e12c5d1SDavid du Colombier void 2463e12c5d1SDavid du Colombier startup(char *machine, int Rflag, char **argv, char **end) 2473e12c5d1SDavid du Colombier { 2483e12c5d1SDavid du Colombier if(machine) 2493e12c5d1SDavid du Colombier connectto(machine); 2503e12c5d1SDavid du Colombier if(!Rflag) 2513e12c5d1SDavid du Colombier bootterm(machine, argv, end); 2523e12c5d1SDavid du Colombier downloaded = 1; 2533e12c5d1SDavid du Colombier outTs(Hversion, VERSION); 2543e12c5d1SDavid du Colombier } 255