xref: /plan9/sys/src/cmd/dossrv/xfssrv.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
3219b2ee8SDavid du Colombier #include <auth.h>
43e12c5d1SDavid du Colombier #include <fcall.h>
53e12c5d1SDavid du Colombier #include "iotrack.h"
63e12c5d1SDavid du Colombier #include "dat.h"
73e12c5d1SDavid du Colombier #include "fns.h"
83e12c5d1SDavid du Colombier 
93e12c5d1SDavid du Colombier #include "errstr.h"
103e12c5d1SDavid du Colombier 
113e12c5d1SDavid du Colombier Fcall	thdr;
123e12c5d1SDavid du Colombier Fcall	rhdr;
133e12c5d1SDavid du Colombier char	data[sizeof(Fcall)+MAXFDATA];
143e12c5d1SDavid du Colombier char	fdata[MAXFDATA];
153e12c5d1SDavid du Colombier int	errno;
163e12c5d1SDavid du Colombier void	rmservice(void);
173e12c5d1SDavid du Colombier char	srvfile[64];
183e12c5d1SDavid du Colombier char	*deffile;
19*7dd7cddfSDavid du Colombier int	doabort;
203e12c5d1SDavid du Colombier 
213e12c5d1SDavid du Colombier void
223e12c5d1SDavid du Colombier usage(void)
233e12c5d1SDavid du Colombier {
243e12c5d1SDavid du Colombier 	fprint(2, "usage: %s [-v] [-s] [-f devicefile] [srvname]\n", argv0);
253e12c5d1SDavid du Colombier 	exits("usage");
263e12c5d1SDavid du Colombier }
273e12c5d1SDavid du Colombier 
283e12c5d1SDavid du Colombier void
293e12c5d1SDavid du Colombier main(int argc, char **argv)
303e12c5d1SDavid du Colombier {
313e12c5d1SDavid du Colombier 	int srvfd, pipefd[2], n;
323e12c5d1SDavid du Colombier 	int stdio;
333e12c5d1SDavid du Colombier 
343e12c5d1SDavid du Colombier 	stdio = 0;
353e12c5d1SDavid du Colombier 	ARGBEGIN{
36*7dd7cddfSDavid du Colombier 	case 'r':
37*7dd7cddfSDavid du Colombier 		readonly = 1;
38*7dd7cddfSDavid du Colombier 		break;
393e12c5d1SDavid du Colombier 	case 'v':
403e12c5d1SDavid du Colombier 		++chatty;
413e12c5d1SDavid du Colombier 		break;
423e12c5d1SDavid du Colombier 	case 'f':
433e12c5d1SDavid du Colombier 		deffile = ARGF();
443e12c5d1SDavid du Colombier 		break;
453e12c5d1SDavid du Colombier 	case 's':
463e12c5d1SDavid du Colombier 		stdio = 1;
473e12c5d1SDavid du Colombier 		break;
48*7dd7cddfSDavid du Colombier 	case 'p':
49*7dd7cddfSDavid du Colombier 		doabort = 1;
50*7dd7cddfSDavid du Colombier 		break;
513e12c5d1SDavid du Colombier 	default:
523e12c5d1SDavid du Colombier 		usage();
533e12c5d1SDavid du Colombier 	}ARGEND
543e12c5d1SDavid du Colombier 
553e12c5d1SDavid du Colombier 	if(argc == 0)
563e12c5d1SDavid du Colombier 		strcpy(srvfile, "#s/dos");
573e12c5d1SDavid du Colombier 	else if(argc == 1)
583e12c5d1SDavid du Colombier 		sprint(srvfile, "#s/%s", argv[0]);
593e12c5d1SDavid du Colombier 	else
603e12c5d1SDavid du Colombier 		usage();
613e12c5d1SDavid du Colombier 
623e12c5d1SDavid du Colombier 	if(stdio){
633e12c5d1SDavid du Colombier 		pipefd[0] = 0;
643e12c5d1SDavid du Colombier 		pipefd[1] = 1;
653e12c5d1SDavid du Colombier 	}else{
663e12c5d1SDavid du Colombier 		close(0);
673e12c5d1SDavid du Colombier 		close(1);
683e12c5d1SDavid du Colombier 		open("/dev/null", OREAD);
693e12c5d1SDavid du Colombier 		open("/dev/null", OWRITE);
703e12c5d1SDavid du Colombier 		if(pipe(pipefd) < 0)
713e12c5d1SDavid du Colombier 			panic("pipe");
723e12c5d1SDavid du Colombier 		srvfd = create(srvfile, OWRITE, 0666);
733e12c5d1SDavid du Colombier 		if(srvfd < 0)
743e12c5d1SDavid du Colombier 			panic(srvfile);
753e12c5d1SDavid du Colombier 		fprint(srvfd, "%d", pipefd[0]);
763e12c5d1SDavid du Colombier 		close(pipefd[0]);
773e12c5d1SDavid du Colombier 		close(srvfd);
783e12c5d1SDavid du Colombier 		atexit(rmservice);
79*7dd7cddfSDavid du Colombier 		fprint(2, "%s: serving %s\n", argv0, srvfile);
803e12c5d1SDavid du Colombier 	}
813e12c5d1SDavid du Colombier 	srvfd = pipefd[1];
823e12c5d1SDavid du Colombier 
83*7dd7cddfSDavid du Colombier 	switch(rfork(RFNOWAIT|RFNOTEG|RFFDG|RFPROC|RFNAMEG)){
843e12c5d1SDavid du Colombier 	case -1:
853e12c5d1SDavid du Colombier 		panic("fork");
863e12c5d1SDavid du Colombier 	default:
873e12c5d1SDavid du Colombier 		_exits(0);
883e12c5d1SDavid du Colombier 	case 0:
893e12c5d1SDavid du Colombier 		break;
903e12c5d1SDavid du Colombier 	}
913e12c5d1SDavid du Colombier 
923e12c5d1SDavid du Colombier 	iotrack_init();
933e12c5d1SDavid du Colombier 
943e12c5d1SDavid du Colombier 	if(!chatty){
953e12c5d1SDavid du Colombier 		close(2);
963e12c5d1SDavid du Colombier 		open("#c/cons", OWRITE);
973e12c5d1SDavid du Colombier 	}
98219b2ee8SDavid du Colombier 	while((n = read9p(srvfd, data, sizeof data)) > 0){
993e12c5d1SDavid du Colombier 		if(convM2S(data, &thdr, n) <= 0)
1003e12c5d1SDavid du Colombier 			panic("convM2S");
1013e12c5d1SDavid du Colombier 		errno = 0;
1023e12c5d1SDavid du Colombier 		switch(thdr.type){
1033e12c5d1SDavid du Colombier 		default:	panic("type");	break;
1043e12c5d1SDavid du Colombier 		case Tnop:	rnop();		break;
1053e12c5d1SDavid du Colombier 		case Tsession:	rsession();	break;
1063e12c5d1SDavid du Colombier 		case Tflush:	rflush();	break;
1073e12c5d1SDavid du Colombier 		case Tattach:	rattach();	break;
1083e12c5d1SDavid du Colombier 		case Tclone:	rclone();	break;
1093e12c5d1SDavid du Colombier 		case Twalk:	rwalk();	break;
1103e12c5d1SDavid du Colombier 		case Topen:	ropen();	break;
1113e12c5d1SDavid du Colombier 		case Tcreate:	rcreate();	break;
1123e12c5d1SDavid du Colombier 		case Tread:	rread();	break;
1133e12c5d1SDavid du Colombier 		case Twrite:	rwrite();	break;
1143e12c5d1SDavid du Colombier 		case Tclunk:	rclunk();	break;
1153e12c5d1SDavid du Colombier 		case Tremove:	rremove();	break;
1163e12c5d1SDavid du Colombier 		case Tstat:	rstat();	break;
1173e12c5d1SDavid du Colombier 		case Twstat:	rwstat();	break;
1183e12c5d1SDavid du Colombier 		}
1193e12c5d1SDavid du Colombier 		if(errno == 0)
1203e12c5d1SDavid du Colombier 			rhdr.type = thdr.type+1;
1213e12c5d1SDavid du Colombier 		else{
1223e12c5d1SDavid du Colombier 			rhdr.type = Rerror;
1233e12c5d1SDavid du Colombier 			strncpy(rhdr.ename, xerrstr(errno), ERRLEN);
1243e12c5d1SDavid du Colombier 		}
1253e12c5d1SDavid du Colombier 		rhdr.fid = thdr.fid;
1263e12c5d1SDavid du Colombier 		rhdr.tag = thdr.tag;
1273e12c5d1SDavid du Colombier 		chat((errno==0 ? "OK\n" : "%s (%d)\n"),
1283e12c5d1SDavid du Colombier 			xerrstr(errno), errno);
1293e12c5d1SDavid du Colombier 		if((n = convS2M(&rhdr, data)) <= 0)
1303e12c5d1SDavid du Colombier 			panic("convS2M");
131219b2ee8SDavid du Colombier 		if(write9p(srvfd, data, n) != n)
1323e12c5d1SDavid du Colombier 			panic("write");
1333e12c5d1SDavid du Colombier 	}
134219b2ee8SDavid du Colombier 	chat((n<0) ? "server read error: %r\n" : "server EOF\n");
1353e12c5d1SDavid du Colombier 	exits(0);
1363e12c5d1SDavid du Colombier }
1373e12c5d1SDavid du Colombier 
1383e12c5d1SDavid du Colombier void
1393e12c5d1SDavid du Colombier rmservice(void)
1403e12c5d1SDavid du Colombier {
1413e12c5d1SDavid du Colombier 	remove(srvfile);
1423e12c5d1SDavid du Colombier }
1433e12c5d1SDavid du Colombier 
1443e12c5d1SDavid du Colombier char *
1453e12c5d1SDavid du Colombier xerrstr(int e)
1463e12c5d1SDavid du Colombier {
1473e12c5d1SDavid du Colombier 	if (e < 0 || e >= sizeof errmsg/sizeof errmsg[0])
1483e12c5d1SDavid du Colombier 		return "no such error";
1493e12c5d1SDavid du Colombier 	else
1503e12c5d1SDavid du Colombier 		return errmsg[e];
1513e12c5d1SDavid du Colombier }
152