xref: /plan9/sys/src/cmd/dossrv/xfssrv.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
3*219b2ee8SDavid 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;
193e12c5d1SDavid du Colombier 
203e12c5d1SDavid du Colombier void
213e12c5d1SDavid du Colombier usage(void)
223e12c5d1SDavid du Colombier {
233e12c5d1SDavid du Colombier 	fprint(2, "usage: %s [-v] [-s] [-f devicefile] [srvname]\n", argv0);
243e12c5d1SDavid du Colombier 	exits("usage");
253e12c5d1SDavid du Colombier }
263e12c5d1SDavid du Colombier 
273e12c5d1SDavid du Colombier void
283e12c5d1SDavid du Colombier main(int argc, char **argv)
293e12c5d1SDavid du Colombier {
303e12c5d1SDavid du Colombier 	int srvfd, pipefd[2], n;
313e12c5d1SDavid du Colombier 	int stdio;
323e12c5d1SDavid du Colombier 
333e12c5d1SDavid du Colombier 	stdio = 0;
343e12c5d1SDavid du Colombier 	ARGBEGIN{
353e12c5d1SDavid du Colombier 	case 'v':
363e12c5d1SDavid du Colombier 		++chatty;
373e12c5d1SDavid du Colombier 		break;
383e12c5d1SDavid du Colombier 	case 'f':
393e12c5d1SDavid du Colombier 		deffile = ARGF();
403e12c5d1SDavid du Colombier 		break;
413e12c5d1SDavid du Colombier 	case 's':
423e12c5d1SDavid du Colombier 		stdio = 1;
433e12c5d1SDavid du Colombier 		break;
443e12c5d1SDavid du Colombier 	default:
453e12c5d1SDavid du Colombier 		usage();
463e12c5d1SDavid du Colombier 	}ARGEND
473e12c5d1SDavid du Colombier 
483e12c5d1SDavid du Colombier 	if(argc == 0)
493e12c5d1SDavid du Colombier 		strcpy(srvfile, "#s/dos");
503e12c5d1SDavid du Colombier 	else if(argc == 1)
513e12c5d1SDavid du Colombier 		sprint(srvfile, "#s/%s", argv[0]);
523e12c5d1SDavid du Colombier 	else
533e12c5d1SDavid du Colombier 		usage();
543e12c5d1SDavid du Colombier 
553e12c5d1SDavid du Colombier 	if(stdio){
563e12c5d1SDavid du Colombier 		pipefd[0] = 0;
573e12c5d1SDavid du Colombier 		pipefd[1] = 1;
583e12c5d1SDavid du Colombier 	}else{
593e12c5d1SDavid du Colombier 		close(0);
603e12c5d1SDavid du Colombier 		close(1);
613e12c5d1SDavid du Colombier 		open("/dev/null", OREAD);
623e12c5d1SDavid du Colombier 		open("/dev/null", OWRITE);
633e12c5d1SDavid du Colombier 		if(pipe(pipefd) < 0)
643e12c5d1SDavid du Colombier 			panic("pipe");
653e12c5d1SDavid du Colombier 		srvfd = create(srvfile, OWRITE, 0666);
663e12c5d1SDavid du Colombier 		if(srvfd < 0)
673e12c5d1SDavid du Colombier 			panic(srvfile);
683e12c5d1SDavid du Colombier 		fprint(srvfd, "%d", pipefd[0]);
693e12c5d1SDavid du Colombier 		close(pipefd[0]);
703e12c5d1SDavid du Colombier 		close(srvfd);
713e12c5d1SDavid du Colombier 		atexit(rmservice);
723e12c5d1SDavid du Colombier 		fprint(2, "%s %d: serving %s\n", argv0, getpid(), srvfile);
733e12c5d1SDavid du Colombier 	}
743e12c5d1SDavid du Colombier 	srvfd = pipefd[1];
753e12c5d1SDavid du Colombier 
763e12c5d1SDavid du Colombier 	switch(rfork(RFNOWAIT|RFNOTEG|RFFDG|RFPROC)){
773e12c5d1SDavid du Colombier 	case -1:
783e12c5d1SDavid du Colombier 		panic("fork");
793e12c5d1SDavid du Colombier 	default:
803e12c5d1SDavid du Colombier 		_exits(0);
813e12c5d1SDavid du Colombier 	case 0:
823e12c5d1SDavid du Colombier 		break;
833e12c5d1SDavid du Colombier 	}
843e12c5d1SDavid du Colombier 
853e12c5d1SDavid du Colombier 	iotrack_init();
863e12c5d1SDavid du Colombier 
873e12c5d1SDavid du Colombier 	if(!chatty){
883e12c5d1SDavid du Colombier 		close(2);
893e12c5d1SDavid du Colombier 		open("#c/cons", OWRITE);
903e12c5d1SDavid du Colombier 	}
91*219b2ee8SDavid du Colombier 	while((n = read9p(srvfd, data, sizeof data)) > 0){
923e12c5d1SDavid du Colombier 		if(convM2S(data, &thdr, n) <= 0)
933e12c5d1SDavid du Colombier 			panic("convM2S");
943e12c5d1SDavid du Colombier 		errno = 0;
953e12c5d1SDavid du Colombier 		switch(thdr.type){
963e12c5d1SDavid du Colombier 		default:	panic("type");	break;
973e12c5d1SDavid du Colombier 		case Tnop:	rnop();		break;
983e12c5d1SDavid du Colombier 		case Tsession:	rsession();	break;
993e12c5d1SDavid du Colombier 		case Tflush:	rflush();	break;
1003e12c5d1SDavid du Colombier 		case Tattach:	rattach();	break;
1013e12c5d1SDavid du Colombier 		case Tclone:	rclone();	break;
1023e12c5d1SDavid du Colombier 		case Twalk:	rwalk();	break;
1033e12c5d1SDavid du Colombier 		case Topen:	ropen();	break;
1043e12c5d1SDavid du Colombier 		case Tcreate:	rcreate();	break;
1053e12c5d1SDavid du Colombier 		case Tread:	rread();	break;
1063e12c5d1SDavid du Colombier 		case Twrite:	rwrite();	break;
1073e12c5d1SDavid du Colombier 		case Tclunk:	rclunk();	break;
1083e12c5d1SDavid du Colombier 		case Tremove:	rremove();	break;
1093e12c5d1SDavid du Colombier 		case Tstat:	rstat();	break;
1103e12c5d1SDavid du Colombier 		case Twstat:	rwstat();	break;
1113e12c5d1SDavid du Colombier 		}
1123e12c5d1SDavid du Colombier 		if(errno == 0)
1133e12c5d1SDavid du Colombier 			rhdr.type = thdr.type+1;
1143e12c5d1SDavid du Colombier 		else{
1153e12c5d1SDavid du Colombier 			rhdr.type = Rerror;
1163e12c5d1SDavid du Colombier 			strncpy(rhdr.ename, xerrstr(errno), ERRLEN);
1173e12c5d1SDavid du Colombier 		}
1183e12c5d1SDavid du Colombier 		rhdr.fid = thdr.fid;
1193e12c5d1SDavid du Colombier 		rhdr.tag = thdr.tag;
1203e12c5d1SDavid du Colombier 		chat((errno==0 ? "OK\n" : "%s (%d)\n"),
1213e12c5d1SDavid du Colombier 			xerrstr(errno), errno);
1223e12c5d1SDavid du Colombier 		if((n = convS2M(&rhdr, data)) <= 0)
1233e12c5d1SDavid du Colombier 			panic("convS2M");
124*219b2ee8SDavid du Colombier 		if(write9p(srvfd, data, n) != n)
1253e12c5d1SDavid du Colombier 			panic("write");
1263e12c5d1SDavid du Colombier 	}
127*219b2ee8SDavid du Colombier 	chat((n<0) ? "server read error: %r\n" : "server EOF\n");
1283e12c5d1SDavid du Colombier 	exits(0);
1293e12c5d1SDavid du Colombier }
1303e12c5d1SDavid du Colombier 
1313e12c5d1SDavid du Colombier void
1323e12c5d1SDavid du Colombier rmservice(void)
1333e12c5d1SDavid du Colombier {
1343e12c5d1SDavid du Colombier 	remove(srvfile);
1353e12c5d1SDavid du Colombier }
1363e12c5d1SDavid du Colombier 
1373e12c5d1SDavid du Colombier char *
1383e12c5d1SDavid du Colombier xerrstr(int e)
1393e12c5d1SDavid du Colombier {
1403e12c5d1SDavid du Colombier 	if (e < 0 || e >= sizeof errmsg/sizeof errmsg[0])
1413e12c5d1SDavid du Colombier 		return "no such error";
1423e12c5d1SDavid du Colombier 	else
1433e12c5d1SDavid du Colombier 		return errmsg[e];
1443e12c5d1SDavid du Colombier }
145