xref: /plan9/sys/src/cmd/sam/io.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
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