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
checkqid(File * f)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;
177dd7cddfSDavid du Colombier if(f->dev==g->dev && f->qidpath==g->qidpath)
18bd389b36SDavid du Colombier warn_SS(Wdupfile, &f->name, &g->name);
19bd389b36SDavid du Colombier }
20bd389b36SDavid du Colombier }
21bd389b36SDavid du Colombier
22bd389b36SDavid du Colombier void
writef(File * f)233e12c5d1SDavid du Colombier writef(File *f)
243e12c5d1SDavid du Colombier {
253e12c5d1SDavid du Colombier Posn n;
263e12c5d1SDavid du Colombier char *name;
273e12c5d1SDavid du Colombier int i, samename, newfile;
289a747e4fSDavid du Colombier ulong dev;
299a747e4fSDavid du Colombier uvlong qid;
30219b2ee8SDavid 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);
35219b2ee8SDavid 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 &&
397dd7cddfSDavid du Colombier (f->dev!=dev || f->qidpath!=qid || f->mtime<mtime)){
40bd389b36SDavid du Colombier f->dev = dev;
417dd7cddfSDavid du Colombier f->qidpath = qid;
427dd7cddfSDavid du Colombier f->mtime = 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)
509a747e4fSDavid du Colombier error_r(Ecreate, genc);
513e12c5d1SDavid du Colombier dprint("%s: ", genc);
52219b2ee8SDavid du Colombier if(statfd(io, 0, 0, 0, &length, &appendonly) > 0 && appendonly && length>0)
53219b2ee8SDavid du Colombier error(Eappend);
543e12c5d1SDavid du Colombier n = writeio(f);
557dd7cddfSDavid du Colombier if(f->name.s[0]==0 || samename){
567dd7cddfSDavid du Colombier if(addr.r.p1==0 && addr.r.p2==f->nc)
577dd7cddfSDavid du Colombier f->cleanseq = f->seq;
587dd7cddfSDavid du Colombier state(f, f->cleanseq==f->seq? Clean : Dirty);
597dd7cddfSDavid du Colombier }
603e12c5d1SDavid du Colombier if(newfile)
613e12c5d1SDavid du Colombier dprint("(new file) ");
627dd7cddfSDavid du Colombier if(addr.r.p2>0 && filereadc(f, addr.r.p2-1)!='\n')
633e12c5d1SDavid du Colombier warn(Wnotnewline);
647dd7cddfSDavid du Colombier closeio(n);
653e12c5d1SDavid du Colombier if(f->name.s[0]==0 || samename){
667dd7cddfSDavid du Colombier if(statfile(name, &dev, &qid, &mtime, 0, 0) > 0){
67bd389b36SDavid du Colombier f->dev = dev;
687dd7cddfSDavid du Colombier f->qidpath = qid;
697dd7cddfSDavid du Colombier f->mtime = mtime;
70bd389b36SDavid du Colombier checkqid(f);
713e12c5d1SDavid du Colombier }
723e12c5d1SDavid du Colombier }
733e12c5d1SDavid du Colombier }
743e12c5d1SDavid du Colombier
753e12c5d1SDavid du Colombier Posn
readio(File * f,int * nulls,int setdate,int toterm)767dd7cddfSDavid du Colombier readio(File *f, int *nulls, int setdate, int toterm)
773e12c5d1SDavid du Colombier {
783e12c5d1SDavid du Colombier int n, b, w;
793e12c5d1SDavid du Colombier Rune *r;
803e12c5d1SDavid du Colombier Posn nt;
813e12c5d1SDavid du Colombier Posn p = addr.r.p2;
829a747e4fSDavid du Colombier ulong dev;
839a747e4fSDavid du Colombier uvlong qid;
843e12c5d1SDavid du Colombier long mtime;
853e12c5d1SDavid du Colombier char buf[BLOCKSIZE+1], *s;
863e12c5d1SDavid du Colombier
873e12c5d1SDavid du Colombier *nulls = FALSE;
883e12c5d1SDavid du Colombier b = 0;
897dd7cddfSDavid du Colombier if(f->unread){
907dd7cddfSDavid du Colombier nt = bufload(f, 0, io, nulls);
917dd7cddfSDavid du Colombier if(toterm)
927dd7cddfSDavid du Colombier raspload(f);
937dd7cddfSDavid du Colombier }else
943e12c5d1SDavid du Colombier for(nt = 0; (n = read(io, buf+b, BLOCKSIZE-b))>0; nt+=(r-genbuf)){
953e12c5d1SDavid du Colombier n += b;
963e12c5d1SDavid du Colombier b = 0;
973e12c5d1SDavid du Colombier r = genbuf;
983e12c5d1SDavid du Colombier s = buf;
993e12c5d1SDavid du Colombier while(n > 0){
1003e12c5d1SDavid du Colombier if((*r = *(uchar*)s) < Runeself){
1013e12c5d1SDavid du Colombier if(*r)
1023e12c5d1SDavid du Colombier r++;
1033e12c5d1SDavid du Colombier else
1043e12c5d1SDavid du Colombier *nulls = TRUE;
1053e12c5d1SDavid du Colombier --n;
1063e12c5d1SDavid du Colombier s++;
1073e12c5d1SDavid du Colombier continue;
1083e12c5d1SDavid du Colombier }
1093e12c5d1SDavid du Colombier if(fullrune(s, n)){
1103e12c5d1SDavid du Colombier w = chartorune(r, s);
1113e12c5d1SDavid du Colombier if(*r)
1123e12c5d1SDavid du Colombier r++;
1133e12c5d1SDavid du Colombier else
1143e12c5d1SDavid du Colombier *nulls = TRUE;
1153e12c5d1SDavid du Colombier n -= w;
1163e12c5d1SDavid du Colombier s += w;
1173e12c5d1SDavid du Colombier continue;
1183e12c5d1SDavid du Colombier }
1193e12c5d1SDavid du Colombier b = n;
1203e12c5d1SDavid du Colombier memmove(buf, s, b);
1213e12c5d1SDavid du Colombier break;
1223e12c5d1SDavid du Colombier }
1237dd7cddfSDavid du Colombier loginsert(f, p, genbuf, r-genbuf);
1243e12c5d1SDavid du Colombier }
1253e12c5d1SDavid du Colombier if(b)
1263e12c5d1SDavid du Colombier *nulls = TRUE;
1273e12c5d1SDavid du Colombier if(*nulls)
1283e12c5d1SDavid du Colombier warn(Wnulls);
1293e12c5d1SDavid du Colombier if(setdate){
130219b2ee8SDavid du Colombier if(statfd(io, &dev, &qid, &mtime, 0, 0) > 0){
131bd389b36SDavid du Colombier f->dev = dev;
1327dd7cddfSDavid du Colombier f->qidpath = qid;
1337dd7cddfSDavid du Colombier f->mtime = mtime;
134bd389b36SDavid du Colombier checkqid(f);
1353e12c5d1SDavid du Colombier }
1363e12c5d1SDavid du Colombier }
1373e12c5d1SDavid du Colombier return nt;
1383e12c5d1SDavid du Colombier }
1393e12c5d1SDavid du Colombier
1403e12c5d1SDavid du Colombier Posn
writeio(File * f)1413e12c5d1SDavid du Colombier writeio(File *f)
1423e12c5d1SDavid du Colombier {
1433e12c5d1SDavid du Colombier int m, n;
1443e12c5d1SDavid du Colombier Posn p = addr.r.p1;
1453e12c5d1SDavid du Colombier char *c;
1463e12c5d1SDavid du Colombier
1473e12c5d1SDavid du Colombier while(p < addr.r.p2){
1483e12c5d1SDavid du Colombier if(addr.r.p2-p>BLOCKSIZE)
1493e12c5d1SDavid du Colombier n = BLOCKSIZE;
1503e12c5d1SDavid du Colombier else
1513e12c5d1SDavid du Colombier n = addr.r.p2-p;
1527dd7cddfSDavid du Colombier bufread(f, p, genbuf, n);
1533e12c5d1SDavid du Colombier c = Strtoc(tmprstr(genbuf, n));
1543e12c5d1SDavid du Colombier m = strlen(c);
1553e12c5d1SDavid du Colombier if(Write(io, c, m) != m){
1563e12c5d1SDavid du Colombier free(c);
1573e12c5d1SDavid du Colombier if(p > 0)
1583e12c5d1SDavid du Colombier p += n;
1593e12c5d1SDavid du Colombier break;
1603e12c5d1SDavid du Colombier }
1613e12c5d1SDavid du Colombier free(c);
1623e12c5d1SDavid du Colombier p += n;
1633e12c5d1SDavid du Colombier }
1643e12c5d1SDavid du Colombier return p-addr.r.p1;
1653e12c5d1SDavid du Colombier }
1663e12c5d1SDavid du Colombier void
closeio(Posn p)1673e12c5d1SDavid du Colombier closeio(Posn p)
1683e12c5d1SDavid du Colombier {
1693e12c5d1SDavid du Colombier close(io);
1703e12c5d1SDavid du Colombier io = 0;
1713e12c5d1SDavid du Colombier if(p >= 0)
1723e12c5d1SDavid du Colombier dprint("#%lud\n", p);
1733e12c5d1SDavid du Colombier }
1743e12c5d1SDavid du Colombier
1753e12c5d1SDavid du Colombier int remotefd0 = 0;
1763e12c5d1SDavid du Colombier int remotefd1 = 1;
1773e12c5d1SDavid du Colombier
1783e12c5d1SDavid du Colombier void
bootterm(char * machine,char ** argv)179*e7d29567SDavid du Colombier bootterm(char *machine, char **argv)
1803e12c5d1SDavid du Colombier {
1813e12c5d1SDavid du Colombier int ph2t[2], pt2h[2];
1823e12c5d1SDavid du Colombier
1833e12c5d1SDavid du Colombier if(machine){
1843e12c5d1SDavid du Colombier dup(remotefd0, 0);
1853e12c5d1SDavid du Colombier dup(remotefd1, 1);
1863e12c5d1SDavid du Colombier close(remotefd0);
1873e12c5d1SDavid du Colombier close(remotefd1);
1883e12c5d1SDavid du Colombier argv[0] = "samterm";
1893e12c5d1SDavid du Colombier exec(samterm, argv);
1903e12c5d1SDavid du Colombier fprint(2, "can't exec: ");
1913e12c5d1SDavid du Colombier perror(samterm);
1923e12c5d1SDavid du Colombier _exits("damn");
1933e12c5d1SDavid du Colombier }
1943e12c5d1SDavid du Colombier if(pipe(ph2t)==-1 || pipe(pt2h)==-1)
1953e12c5d1SDavid du Colombier panic("pipe");
1963e12c5d1SDavid du Colombier switch(fork()){
1973e12c5d1SDavid du Colombier case 0:
1983e12c5d1SDavid du Colombier dup(ph2t[0], 0);
1993e12c5d1SDavid du Colombier dup(pt2h[1], 1);
2003e12c5d1SDavid du Colombier close(ph2t[0]);
2013e12c5d1SDavid du Colombier close(ph2t[1]);
2023e12c5d1SDavid du Colombier close(pt2h[0]);
2033e12c5d1SDavid du Colombier close(pt2h[1]);
2043e12c5d1SDavid du Colombier argv[0] = "samterm";
2053e12c5d1SDavid du Colombier exec(samterm, argv);
2063e12c5d1SDavid du Colombier fprint(2, "can't exec: ");
2073e12c5d1SDavid du Colombier perror(samterm);
2083e12c5d1SDavid du Colombier _exits("damn");
2093e12c5d1SDavid du Colombier case -1:
2103e12c5d1SDavid du Colombier panic("can't fork samterm");
2113e12c5d1SDavid du Colombier }
2123e12c5d1SDavid du Colombier dup(pt2h[0], 0);
2133e12c5d1SDavid du Colombier dup(ph2t[1], 1);
2143e12c5d1SDavid du Colombier close(ph2t[0]);
2153e12c5d1SDavid du Colombier close(ph2t[1]);
2163e12c5d1SDavid du Colombier close(pt2h[0]);
2173e12c5d1SDavid du Colombier close(pt2h[1]);
2183e12c5d1SDavid du Colombier }
2193e12c5d1SDavid du Colombier
2203e12c5d1SDavid du Colombier void
connectto(char * machine,char ** argv)221*e7d29567SDavid du Colombier connectto(char *machine, char **argv)
2223e12c5d1SDavid du Colombier {
2233e12c5d1SDavid du Colombier int p1[2], p2[2];
224*e7d29567SDavid du Colombier char **av;
225*e7d29567SDavid du Colombier int ac;
2263e12c5d1SDavid du Colombier
227*e7d29567SDavid du Colombier // count args
228*e7d29567SDavid du Colombier for(av = argv; *av; av++)
229*e7d29567SDavid du Colombier ;
230*e7d29567SDavid du Colombier av = malloc(sizeof(char*)*((av-argv) + 5));
231*e7d29567SDavid du Colombier if(av == nil){
232*e7d29567SDavid du Colombier dprint("out of memory\n");
233*e7d29567SDavid du Colombier exits("fork/exec");
234*e7d29567SDavid du Colombier }
235*e7d29567SDavid du Colombier ac = 0;
236*e7d29567SDavid du Colombier av[ac++] = RX;
237*e7d29567SDavid du Colombier av[ac++] = machine;
238*e7d29567SDavid du Colombier av[ac++] = rsamname;
239*e7d29567SDavid du Colombier av[ac++] = "-R";
240*e7d29567SDavid du Colombier while(*argv)
241*e7d29567SDavid du Colombier av[ac++] = *argv++;
242*e7d29567SDavid du Colombier av[ac] = 0;
2433e12c5d1SDavid du Colombier if(pipe(p1)<0 || pipe(p2)<0){
2443e12c5d1SDavid du Colombier dprint("can't pipe\n");
2453e12c5d1SDavid du Colombier exits("pipe");
2463e12c5d1SDavid du Colombier }
2473e12c5d1SDavid du Colombier remotefd0 = p1[0];
2483e12c5d1SDavid du Colombier remotefd1 = p2[1];
2493e12c5d1SDavid du Colombier switch(fork()){
2503e12c5d1SDavid du Colombier case 0:
2513e12c5d1SDavid du Colombier dup(p2[0], 0);
2523e12c5d1SDavid du Colombier dup(p1[1], 1);
2533e12c5d1SDavid du Colombier close(p1[0]);
2543e12c5d1SDavid du Colombier close(p1[1]);
2553e12c5d1SDavid du Colombier close(p2[0]);
2563e12c5d1SDavid du Colombier close(p2[1]);
257*e7d29567SDavid du Colombier exec(RXPATH, av);
2583e12c5d1SDavid du Colombier dprint("can't exec %s\n", RXPATH);
2593e12c5d1SDavid du Colombier exits("exec");
2603e12c5d1SDavid du Colombier
2613e12c5d1SDavid du Colombier case -1:
2623e12c5d1SDavid du Colombier dprint("can't fork\n");
2633e12c5d1SDavid du Colombier exits("fork");
2643e12c5d1SDavid du Colombier }
265*e7d29567SDavid du Colombier free(av);
2663e12c5d1SDavid du Colombier close(p1[1]);
2673e12c5d1SDavid du Colombier close(p2[0]);
2683e12c5d1SDavid du Colombier }
2693e12c5d1SDavid du Colombier
2703e12c5d1SDavid du Colombier void
startup(char * machine,int Rflag,char ** argv,char ** files)271*e7d29567SDavid du Colombier startup(char *machine, int Rflag, char **argv, char **files)
2723e12c5d1SDavid du Colombier {
2733e12c5d1SDavid du Colombier if(machine)
274*e7d29567SDavid du Colombier connectto(machine, files);
2753e12c5d1SDavid du Colombier if(!Rflag)
276*e7d29567SDavid du Colombier bootterm(machine, argv);
2773e12c5d1SDavid du Colombier downloaded = 1;
2783e12c5d1SDavid du Colombier outTs(Hversion, VERSION);
2793e12c5d1SDavid du Colombier }
280