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