Example #1
0
int
connect(char *system, char *tree, int oldserver)
{
	char buf[ERRMAX], dir[128], *na;
	int fd, n;
	char *authp;

	na = netmkaddr(system, 0, "exportfs");
	procsetname("dial %s", na);
	if((fd = dial(na, 0, dir, 0)) < 0)
		sysfatal("can't dial %s: %r", system);

	if(doauth){
		if(oldserver)
			authp = "p9sk2";
		else
			authp = "p9any";

		procsetname("auth_proxy auth_getkey proto=%q role=client %s",
			authp, keyspec);
		ai = auth_proxy(fd, auth_getkey, "proto=%q role=client %s",
			authp, keyspec);
		if(ai == nil)
			sysfatal("%r: %s", system);
	}

	if(!skiptree){
		procsetname("writing tree name %s", tree);
		n = write(fd, tree, strlen(tree));
		if(n < 0)
			sysfatal("can't write tree: %r");

		strcpy(buf, "can't read tree");

		procsetname("awaiting OK for %s", tree);
		n = read(fd, buf, sizeof buf - 1);
		if(n!=2 || buf[0]!='O' || buf[1]!='K'){
			if (timedout)
				sysfatal("timed out connecting to %s", na);
			buf[sizeof buf - 1] = '\0';
			sysfatal("bad remote tree: %s", buf);
		}
	}

	if(oldserver)
		return old9p(fd);
	return fd;
}
Example #2
0
/*
 *  process to notify other servers of changes
 *  (also reads in new databases)
 */
void
notifyproc(void)
{
	Request req;

	switch(rfork(RFPROC|RFNOTEG|RFMEM|RFNOWAIT)){
	case -1:
		return;
	case 0:
		break;
	default:
		return;
	}

	procsetname("notify slaves");
	memset(&req, 0, sizeof req);
	req.isslave = 1;	/* don't fork off subprocesses */

	for(;;){
		getactivity(&req, 0);
		notify_areas(owned, &req);
		putactivity(0);
		sleep(60*1000);
	}
}
Example #3
0
int
passive(void)
{
	int fd;

	/*
	 * Ignore doauth==0 on purpose.  Is it useful here?
	 */

	procsetname("auth_proxy auth_getkey proto=p9any role=server");
	ai = auth_proxy(0, auth_getkey, "proto=p9any role=server");
	if(ai == nil)
		sysfatal("auth_proxy: %r");
	if(auth_chuid(ai, nil) < 0)
		sysfatal("auth_chuid: %r");
	putenv("service", "import");

	fd = dup(0, -1);
	close(0);
	open("/dev/null", ORDWR);
	close(1);
	open("/dev/null", ORDWR);

	return fd;
}
Example #4
0
File: cpu.c Project: 99years/plan9
/*
 *  plan9 authentication followed by rc4 encryption
 */
static int
p9auth(int fd)
{
	uchar key[16];
	uchar digest[SHA1dlen];
	char fromclientsecret[21];
	char fromserversecret[21];
	int i;
	AuthInfo *ai;

	procsetname("%s: auth_proxy proto=%q role=client %s",
		origargs, p9authproto, keyspec);
	ai = auth_proxy(fd, auth_getkey, "proto=%q role=client %s", p9authproto, keyspec);
	if(ai == nil)
		return -1;
	memmove(key+4, ai->secret, ai->nsecret);
	if(ealgs == nil)
		return fd;

	/* exchange random numbers */
	srand(truerand());
	for(i = 0; i < 4; i++)
		key[i] = rand();
	procsetname("writing p9 key");
	if(write(fd, key, 4) != 4)
		return -1;
	procsetname("reading p9 key");
	if(readn(fd, key+12, 4) != 4)
		return -1;

	/* scramble into two secrets */
	sha1(key, sizeof(key), digest, nil);
	mksecret(fromclientsecret, digest);
	mksecret(fromserversecret, digest+10);

	/* set up encryption */
	procsetname("pushssl");
	i = pushssl(fd, ealgs, fromclientsecret, fromserversecret, nil);
	if(i < 0)
		werrstr("can't establish ssl connection: %r");
	return i;
}
Example #5
0
File: pc.c Project: Requaos/harvey
void
newproc(void (*f)(void *), void *arg, char *text)
{
	int kid = rfork(RFPROC|RFMEM|RFNOWAIT);

	if (kid < 0)
		sysfatal("can't fork: %r");
	if (kid == 0) {
		procsetname("%s", text);
		(*f)(arg);
		exits("child returned");
	}
}
Example #6
0
File: cpu.c Project: 99years/plan9
char*
rexcall(int *fd, char *host, char *service)
{
	char *na;
	char dir[MaxStr];
	char err[ERRMAX];
	char msg[MaxStr];
	int n;

	na = netmkaddr(host, 0, service);
	procsetname("dialing %s", na);
	if((*fd = dial(na, 0, dir, 0)) < 0)
		return "can't dial";

	/* negotiate authentication mechanism */
	if(ealgs != nil)
		snprint(msg, sizeof(msg), "%s %s", am->name, ealgs);
	else
		snprint(msg, sizeof(msg), "%s", am->name);
	procsetname("writing %s", msg);
	writestr(*fd, msg, negstr, 0);
	procsetname("awaiting auth method");
	n = readstr(*fd, err, sizeof err);
	if(n < 0)
		return negstr;
	if(*err){
		werrstr(err);
		return negstr;
	}

	/* authenticate */
	procsetname("%s: auth via %s", origargs, am->name);
	*fd = (*am->cf)(*fd);
	if(*fd < 0)
		return "can't authenticate";
	return 0;
}
Example #7
0
void
testrand(void *arg)
{
	Chan *reply;
	size_t i;
	int j;
	ulong r;
	
	procsetname("testrand");
	reply = arg;
	for(i = 0; i < alen(tests); i++){
		procsrand(tests[i].seed);
		for(j = 0; j < Nrand; j++){
			r = procrand();
			if(r != tests[i].expect[j]){
				printf("fail: (seed %lu, j %d) -- expected %lu got %lu\n", tests[i].seed,
					j, tests[i].expect[j], r);
				chansend(reply, &(int){1});
			}
		}
Example #8
0
void
mountinit(char *service, char *mntpt)
{
	int f;
	int p[2];
	char buf[32];

	if(pipe(p) < 0)
		abort(); /* "pipe failed" */;
	switch(rfork(RFFDG|RFPROC)){
	case 0:			/* child: hang around and (re)start main proc */
		close(p[1]);
		procsetname("%s restarter", mntpt);
		mfd[0] = mfd[1] = p[0];
		break;
	case -1:
		abort(); /* "fork failed\n" */;
	default:		/* parent: make /srv/dns, mount it, exit */
		close(p[0]);

		/*
		 *  make a /srv/dns
		 */
		f = create(service, 1, 0666);
		if(f < 0)
			abort(); /* service */;
		snprint(buf, sizeof buf, "%d", p[1]);
		if(write(f, buf, strlen(buf)) != strlen(buf))
			abort(); /* "write %s", service */;
		close(f);

		/*
		 *  put ourselves into the file system
		 *  it's too soon; we need 9p service running.
		 */
//		if(mount(p[1], -1, mntpt, MAFTER, "") < 0)
//			dnslog("dns mount -a on %s failed: %r", mntpt);
		close(p[1]);
		_exits(0);
	}
}
Example #9
0
int
old9p(int fd)
{
	int p[2];

	procsetname("old9p");
	if(pipe(p) < 0)
		sysfatal("pipe: %r");

	switch(rfork(RFPROC|RFMEM|RFFDG|RFNAMEG)) {
	case -1:
		sysfatal("rfork srvold9p: %r");
	case 0:
		if(fd != 1){
			dup(fd, 1);
			close(fd);
		}
		if(p[0] != 0){
			dup(p[0], 0);
			close(p[0]);
		}
		close(p[1]);
		if(0){
			fd = open("/sys/log/cpu", OWRITE);
			if(fd != 2){
				dup(fd, 2);
				close(fd);
			}
			execl("/bin/srvold9p", "srvold9p", "-ds", nil);
		} else
			execl("/bin/srvold9p", "srvold9p", "-s", nil);
		sysfatal("exec srvold9p: %r");
	default:
		close(fd);
		close(p[0]);
	}
	return p[1];
}
Example #10
0
void
main(int argc, char *argv[])
{
	int len, rcode;
	char tname[32];
	char *err, *ext = "";
	unsigned char buf[64*1024], callip[IPaddrlen];
	DNSmsg reqmsg, repmsg;
	Request req;

	alarm(2*60*1000);
	cfg.cachedb = 1;
	ARGBEGIN{
	case 'd':
		debug++;
		break;
	case 'f':
		dbfile = EARGF(usage());
		break;
	case 'r':
		cfg.resolver = 1;
		break;
	case 'R':
		norecursion = 1;
		break;
	case 'x':
		ext = EARGF(usage());
		break;
	default:
		usage();
		break;
	}ARGEND

	if(debug < 2)
		debug = 0;

	if(argc > 0)
		getcaller(argv[0]);

	cfg.inside = 1;
	dninit();

	snprint(mntpt, sizeof mntpt, "/net%s", ext);
	if(myipaddr(ipaddr, mntpt) < 0)
		sysfatal("can't read my ip address");
	dnslog("dnstcp call from %s to %I", caller, ipaddr);
	memset(callip, 0, sizeof callip);
	parseip(callip, caller);

	db2cache(1);

	memset(&req, 0, sizeof req);
	setjmp(req.mret);
	req.isslave = 0;
	procsetname("main loop");

	/* loop on requests */
	for(;; putactivity(0)){
		now = time(nil);
		memset(&repmsg, 0, sizeof repmsg);
		len = readmsg(0, buf, sizeof buf);
		if(len <= 0)
			break;

		getactivity(&req, 0);
		req.aborttime = timems() + S2MS(15*Min);
		rcode = 0;
		memset(&reqmsg, 0, sizeof reqmsg);
		err = convM2DNS(buf, len, &reqmsg, &rcode);
		if(err){
			dnslog("server: input error: %s from %s", err, caller);
			free(err);
			break;
		}
		if (rcode == 0) {
			if(reqmsg.qdcount < 1){
				dnslog("server: no questions from %s", caller);
				break;
			} else if(reqmsg.flags & Fresp){
				dnslog("server: reply not request from %s",
					caller);
				break;
			} else if((reqmsg.flags & Omask) != Oquery){
				dnslog("server: op %d from %s",
					reqmsg.flags & Omask, caller);
				break;
			}
		}
		if(debug)
			dnslog("[%d] %d: serve (%s) %d %s %s",
				getpid(), req.id, caller,
				reqmsg.id, reqmsg.qd->owner->name,
				rrname(reqmsg.qd->type, tname, sizeof tname));

		/* loop through each question */
		while(reqmsg.qd)
			if(reqmsg.qd->type == Taxfr)
				dnzone(&reqmsg, &repmsg, &req);
			else {
				dnserver(&reqmsg, &repmsg, &req, callip, rcode);
				reply(1, &repmsg, &req);
				rrfreelist(repmsg.qd);
				rrfreelist(repmsg.an);
				rrfreelist(repmsg.ns);
				rrfreelist(repmsg.ar);
			}
		rrfreelist(reqmsg.qd);		/* qd will be nil */
		rrfreelist(reqmsg.an);
		rrfreelist(reqmsg.ns);
		rrfreelist(reqmsg.ar);

		if(req.isslave){
			putactivity(0);
			_exits(0);
		}
	}
	refreshmain(mntpt);
}
Example #11
0
void
main(int argc, char **argv)
{
	int i, nets = 0;
	char *ann;

	rfork(RFNOTEG);
	formatinit();
	machinit();
	conf.confdev = "n";		/* Devnone */

	ARGBEGIN{
	case 'a':			/* announce on this net */
		ann = EARGF(usage());
		if (nets >= Maxnets) {
			fprint(2, "%s: too many networks to announce: %s\n",
				argv0, ann);
			exits("too many nets");
		}
		annstrs[nets++] = ann;
		break;
	case 'c':			/* use new, faster cache layout */
		oldcachefmt = 0;
		break;
	case 'f':			/* enter configuration mode first */
		conf.configfirst++;
		break;
	case 'm':			/* name device-map file */
		conf.devmap = EARGF(usage());
		break;
	default:
		usage();
		break;
	}ARGEND

	if (argc != 1)
		usage();
	conf.confdev = argv[0];	/* config string for dev holding full config */

	Binit(&bin, 0, OREAD);
	confinit();

	print("\nPlan 9 %d-bit cached-worm file server with %d-deep indir blks\n",
		sizeof(Off)*8 - 1, NIBLOCK);
	printsizes();

	qlock(&reflock);
	qunlock(&reflock);
	serveq = newqueue(1000, "9P service");	/* tunable */
	raheadq = newqueue(1000, "readahead");	/* tunable */

	mbinit();
	netinit();
	scsiinit();

	files = malloc(conf.nfile * sizeof *files);
	for(i=0; i < conf.nfile; i++) {
		qlock(&files[i]);
		qunlock(&files[i]);
	}

	wpaths = malloc(conf.nwpath * sizeof(*wpaths));
	uid = malloc(conf.nuid * sizeof(*uid));
	gidspace = malloc(conf.gidspace * sizeof(*gidspace));
	authinit();

	print("iobufinit\n");
	iobufinit();

	arginit();
	boottime = time(nil);

	print("sysinit\n");
	sysinit();

	/*
	 * Ethernet i/o processes
	 */
	netstart();

	/*
	 * read ahead processes
	 */
	newproc(rahead, 0, "rah");

	/*
	 * server processes
	 */
	for(i=0; i < conf.nserve; i++)
		newproc(serve, 0, "srv");

	/*
	 * worm "dump" copy process
	 */
	newproc(wormcopy, 0, "wcp");

	/*
	 * processes to read the console
	 */
	consserve();

	/*
	 * "sync" copy process
	 * this doesn't return.
	 */
	procsetname("scp");
	synccopy();
}
Example #12
0
/*
 *  a process to act as a dns server for outside reqeusts
 */
void
dnudpserver(char *mntpt)
{
	volatile int fd, len, op, rcode;
	char *volatile err;
	volatile char tname[32];
	volatile uchar buf[Udphdrsize + Maxudp + 1024];
	volatile DNSmsg reqmsg, repmsg;
	Inprogress *volatile p;
	volatile Request req;
	Udphdr *volatile uh;

	/*
	 * fork sharing text, data, and bss with parent.
	 * stay in the same note group.
	 */
	switch(rfork(RFPROC|RFMEM|RFNOWAIT)){
	case -1:
		break;
	case 0:
		break;
	default:
		return;
	}

	fd = -1;
restart:
	procsetname("udp server announcing");
	if(fd >= 0)
		close(fd);
	while((fd = udpannounce(mntpt)) < 0)
		sleep(5000);

//	procsetname("udp server");
	memset(&req, 0, sizeof req);
	if(setjmp(req.mret))
		putactivity(0);
	req.isslave = 0;
	req.id = 0;
	req.aborttime = 0;

	/* loop on requests */
	for(;; putactivity(0)){
		procsetname("served %d udp; %d alarms",
			stats.qrecvdudp, stats.alarms);
		memset(&repmsg, 0, sizeof repmsg);
		memset(&reqmsg, 0, sizeof reqmsg);

		alarm(60*1000);
		len = read(fd, buf, sizeof buf);
		alarm(0);
		if(len <= Udphdrsize)
			goto restart;

		redistrib(buf, len);

		uh = (Udphdr*)buf;
		len -= Udphdrsize;

		// dnslog("read received UDP from %I to %I",
		//	((Udphdr*)buf)->raddr, ((Udphdr*)buf)->laddr);
		getactivity(&req, 0);
		req.aborttime = timems() + Maxreqtm;
//		req.from = smprint("%I", ((Udphdr*)buf)->raddr);
		req.from = smprint("%I", buf);
		rcode = 0;
		stats.qrecvdudp++;

		err = convM2DNS(&buf[Udphdrsize], len, &reqmsg, &rcode);
		if(err){
			/* first bytes in buf are source IP addr */
			dnslog("server: input error: %s from %I", err, buf);
			free(err);
			goto freereq;
		}
		if (rcode == 0)
			if(reqmsg.qdcount < 1){
				dnslog("server: no questions from %I", buf);
				goto freereq;
			} else if(reqmsg.flags & Fresp){
				dnslog("server: reply not request from %I", buf);
				goto freereq;
			}
		op = reqmsg.flags & Omask;
		if(op != Oquery && op != Onotify){
			dnslog("server: op %d from %I", reqmsg.flags & Omask,
				buf);
			goto freereq;
		}

		if(debug || (trace && subsume(trace, reqmsg.qd->owner->name)))
			dnslog("%d: serve (%I/%d) %d %s %s",
				req.id, buf, uh->rport[0]<<8 | uh->rport[1],
				reqmsg.id, reqmsg.qd->owner->name,
				rrname(reqmsg.qd->type, tname, sizeof tname));

		p = clientrxmit(&reqmsg, buf);
		if(p == nil){
			if(debug)
				dnslog("%d: duplicate", req.id);
			goto freereq;
		}

		if (Logqueries) {
			RR *rr;

			for (rr = reqmsg.qd; rr; rr = rr->next)
				syslog(0, "dnsq", "id %d: (%I/%d) %d %s %s",
					req.id, buf, uh->rport[0]<<8 |
					uh->rport[1], reqmsg.id,
					reqmsg.qd->owner->name,
					rrname(reqmsg.qd->type, tname,
					sizeof tname));
		}
		/* loop through each question */
		while(reqmsg.qd){
			memset(&repmsg, 0, sizeof repmsg);
			switch(op){
			case Oquery:
				dnserver(&reqmsg, &repmsg, &req, buf, rcode);
				break;
			case Onotify:
				dnnotify(&reqmsg, &repmsg, &req);
				break;
			}
			/* send reply on fd to address in buf's udp hdr */
			reply(fd, buf, &repmsg, &req);
			freeanswers(&repmsg);
		}

		p->inuse = 0;
freereq:
		free(req.from);
		req.from = nil;
		freeanswers(&reqmsg);
		if(req.isslave){
			putactivity(0);
			_exits(0);
		}
	}
}
Example #13
0
File: cpu.c Project: 99years/plan9
void
main(int argc, char **argv)
{
	char dat[MaxStr], buf[MaxStr], cmd[MaxStr], *p, *err;
	int ac, fd, ms, data;
	char *av[10];

	quotefmtinstall();
	origargs = procgetname();
	/* see if we should use a larger message size */
	fd = open("/dev/draw", OREAD);
	if(fd > 0){
		ms = iounit(fd);
		if(msgsize < ms+IOHDRSZ)
			msgsize = ms+IOHDRSZ;
		close(fd);
	}

	user = getuser();
	if(user == nil)
		fatal(1, "can't read user name");
	ARGBEGIN{
	case 'a':
		p = EARGF(usage());
		if(setam(p) < 0)
			fatal(0, "unknown auth method %s", p);
		break;
	case 'e':
		ealgs = EARGF(usage());
		if(*ealgs == 0 || strcmp(ealgs, "clear") == 0)
			ealgs = nil;
		break;
	case 'd':
		dbg++;
		break;
	case 'f':
		/* ignored but accepted for compatibility */
		break;
	case 'R':				/* From listen */
		remoteside();
		break;
	case 'h':
		system = EARGF(usage());
		break;
	case 'c':
		cflag++;
		cmd[0] = '!';
		cmd[1] = '\0';
		while(p = ARGF()) {
			strcat(cmd, " ");
			strcat(cmd, p);
		}
		break;
	case 'k':
		keyspec = smprint("%s %s", keyspec, EARGF(usage()));
		break;
	case 'P':
		patternfile = EARGF(usage());
		break;
	case 'u':
		user = EARGF(usage());
		keyspec = smprint("%s user=%s", keyspec, user);
		break;
	default:
		usage();
	}ARGEND;


	if(argc != 0)
		usage();

	if(system == nil) {
		p = getenv("cpu");
		if(p == 0)
			fatal(0, "set $cpu");
		system = p;
	}

	if(err = rexcall(&data, system, srvname))
		fatal(1, "%s: %s", err, system);

	procsetname("%s", origargs);
	/* Tell the remote side the command to execute and where our working directory is */
	if(cflag)
		writestr(data, cmd, "command", 0);
	if(getwd(dat, sizeof(dat)) == 0)
		writestr(data, "NO", "dir", 0);
	else
		writestr(data, dat, "dir", 0);

	/* start up a process to pass along notes */
	lclnoteproc(data);

	/* 
	 *  Wait for the other end to execute and start our file service
	 *  of /mnt/term
	 */
	if(readstr(data, buf, sizeof(buf)) < 0)
		fatal(1, "waiting for FS: %r");
	if(strncmp("FS", buf, 2) != 0) {
		print("remote cpu: %s", buf);
		exits(buf);
	}

	/* Begin serving the gnot namespace */
	close(0);
	dup(data, 0);
	close(data);

	sprint(buf, "%d", msgsize);
	ac = 0;
	av[ac++] = exportfs;
	av[ac++] = "-m";
	av[ac++] = buf;
	if(dbg)
		av[ac++] = "-d";
	if(patternfile != nil){
		av[ac++] = "-P";
		av[ac++] = patternfile;
	}
	av[ac] = nil;
	exec(exportfs, av);
	fatal(1, "starting exportfs");
}
Example #14
0
void
main(int argc, char **argv)
{
	char *mntpt, *srvpost, srvfile[64];
	int backwards = 0, fd, mntflags, oldserver;

	quotefmtinstall();
	srvpost = nil;
	oldserver = 0;
	mntflags = MREPL;
	ARGBEGIN{
	case 'A':
		doauth = 0;
		break;
	case 'a':
		mntflags = MAFTER;
		break;
	case 'b':
		mntflags = MBEFORE;
		break;
	case 'c':
		mntflags |= MCREATE;
		break;
	case 'C':
		mntflags |= MCACHE;
		break;
	case 'd':
		debug++;
		break;
	case 'f':
		/* ignored but allowed for compatibility */
		break;
	case 'O':
	case 'o':
		oldserver = 1;
		break;
	case 'E':
		if ((encproto = lookup(EARGF(usage()), encprotos)) < 0)
			usage();
		break;
	case 'e':
		ealgs = EARGF(usage());
		if(*ealgs == 0 || strcmp(ealgs, "clear") == 0)
			ealgs = nil;
		break;
	case 'k':
		keyspec = EARGF(usage());
		break;
	case 'p':
		filterp = aan;
		break;
	case 'n':
		anstring = EARGF(usage());
		break;
	case 's':
		srvpost = EARGF(usage());
		break;
	case 'B':
		backwards = 1;
		break;
	case 'z':
		skiptree = 1;
		break;
	default:
		usage();
	}ARGEND;

	mntpt = 0;		/* to shut up compiler */
	if(backwards){
		switch(argc) {
		default:
			mntpt = argv[0];
			break;
		case 0:
			usage();
		}
	} else {
		switch(argc) {
		case 2:
			mntpt = argv[1];
			break;
		case 3:
			mntpt = argv[2];
			break;
		default:
			usage();
		}
	}

	if (encproto == Enctls)
		sysfatal("%s: tls has not yet been implemented", argv[0]);

	notify(catcher);
	alarm(60*1000);

	if (backwards)
		fd = passive();
	else
		fd = connect(argv[0], argv[1], oldserver);

	if (!oldserver)
		fprint(fd, "impo %s %s\n", filterp? "aan": "nofilter",
			encprotos[encproto]);

	if (encproto != Encnone && ealgs && ai) {
		uchar key[16], digest[SHA1dlen];
		char fromclientsecret[21];
		char fromserversecret[21];
		int i;

		assert(ai->nsecret <= sizeof(key)-4);
		memmove(key+4, ai->secret, ai->nsecret);

		/* exchange random numbers */
		srand(truerand());
		for(i = 0; i < 4; i++)
			key[i] = rand();
		if(write(fd, key, 4) != 4)
			sysfatal("can't write key part: %r");
		if(readn(fd, key+12, 4) != 4)
			sysfatal("can't read key part: %r");

		/* scramble into two secrets */
		sha1(key, sizeof(key), digest, nil);
		mksecret(fromclientsecret, digest);
		mksecret(fromserversecret, digest+10);

		if (filterp)
			fd = filter(fd, filterp, backwards ? nil : argv[0]);

		/* set up encryption */
		procsetname("pushssl");
		fd = pushssl(fd, ealgs, fromclientsecret, fromserversecret, nil);
		if(fd < 0)
			sysfatal("can't establish ssl connection: %r");
	}
	else if (filterp)
		fd = filter(fd, filterp, backwards ? nil : argv[0]);

	if(ai)
		auth_freeAI(ai);

	if(srvpost){
		snprint(srvfile, sizeof(srvfile), "/srv/%s", srvpost);
		remove(srvfile);
		post(srvfile, srvpost, fd);
	}
	procsetname("mount on %s", mntpt);
	if(mount(fd, -1, mntpt, mntflags, "") < 0)
		sysfatal("can't mount %s: %r", argv[1]);
	alarm(0);

	if(backwards && argc > 1){
		exec(argv[1], &argv[1]);
		sysfatal("exec: %r");
	}
	exits(0);
}
Example #15
0
void
io(void)
{
	volatile long n;
	volatile uchar mdata[IOHDRSZ + Maxfdata];
	Job *volatile job;
	Mfile *volatile mf;
	volatile Request req;

	memset(&req, 0, sizeof req);
	/*
	 *  a slave process is sometimes forked to wait for replies from other
	 *  servers.  The master process returns immediately via a longjmp
	 *  through 'mret'.
	 */
	if(setjmp(req.mret))
		putactivity(0);
	req.isslave = 0;
	stop = 0;
	while(!stop){
		procsetname("%d %s/dns Twrites of %d 9p rpcs read; %d alarms",
			stats.qrecvd9p, mntpt, stats.qrecvd9prpc, stats.alarms);
		n = read9pmsg(mfd[0], mdata, sizeof mdata);
		if(n<=0){
			dnslog("error reading 9P from %s: %r", mntpt);
			sleep(2000);	/* don't thrash after read error */
			return;
		}

		stats.qrecvd9prpc++;
		job = newjob();
		if(convM2S(mdata, n, &job->request) != n){
			freejob(job);
			continue;
		}
		mf = newfid(job->request.fid, 0);
		if(debug)
			dnslog("%F", &job->request);

		getactivity(&req, 0);
		req.aborttime = timems() + Maxreqtm;
		req.from = "9p";

		switch(job->request.type){
		default:
			warning("unknown request type %d", job->request.type);
			break;
		case Tversion:
			rversion(job);
			break;
		case Tauth:
			rauth(job);
			break;
		case Tflush:
			rflush(job);
			break;
		case Tattach:
			rattach(job, mf);
			break;
		case Twalk:
			rwalk(job, mf);
			break;
		case Topen:
			ropen(job, mf);
			break;
		case Tcreate:
			rcreate(job, mf);
			break;
		case Tread:
			rread(job, mf);
			break;
		case Twrite:
			/* &req is handed to dnresolve() */
			rwrite(job, mf, &req);
			break;
		case Tclunk:
			rclunk(job, mf);
			break;
		case Tremove:
			rremove(job, mf);
			break;
		case Tstat:
			rstat(job, mf);
			break;
		case Twstat:
			rwstat(job, mf);
			break;
		}

		freejob(job);

		/*
		 *  slave processes die after replying
		 */
		if(req.isslave){
			putactivity(0);
			_exits(0);
		}

		putactivity(0);
	}
	/* kill any udp server, notifier, etc. processes */
	postnote(PNGROUP, getpid(), "die");
	sleep(1000);
}