xref: /plan9/sys/src/cmd/exportfs/exportsrv.c (revision 7ec5746a5244cc505568e3d45ab9d5421abbdc7d)
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 #define Extern	extern
63e12c5d1SDavid du Colombier #include "exportfs.h"
73e12c5d1SDavid du Colombier 
8*7ec5746aSDavid du Colombier extern char *netdir, *local, *remote;
9*7ec5746aSDavid du Colombier 
109a747e4fSDavid du Colombier char Ebadfid[] = "Bad fid";
119a747e4fSDavid du Colombier char Enotdir[] = "Not a directory";
129a747e4fSDavid du Colombier char Edupfid[] = "Fid already in use";
139a747e4fSDavid du Colombier char Eopen[] = "Fid already opened";
149a747e4fSDavid du Colombier char Exmnt[] = "Cannot .. past mount point";
159a747e4fSDavid du Colombier char Emip[] = "Mount in progress";
169a747e4fSDavid du Colombier char Enopsmt[] = "Out of pseudo mount points";
179a747e4fSDavid du Colombier char Enomem[] = "No memory";
189a747e4fSDavid du Colombier char Eversion[] = "Bad 9P2000 version";
1924b9ac62SDavid du Colombier char Ereadonly[] = "File system read only";
209a747e4fSDavid du Colombier 
219a747e4fSDavid du Colombier ulong messagesize;
2224b9ac62SDavid du Colombier int readonly;
233e12c5d1SDavid du Colombier 
243e12c5d1SDavid du Colombier void
Xversion(Fsrpc * t)259a747e4fSDavid du Colombier Xversion(Fsrpc *t)
263e12c5d1SDavid du Colombier {
279a747e4fSDavid du Colombier 	Fcall rhdr;
283e12c5d1SDavid du Colombier 
299a747e4fSDavid du Colombier 	if(t->work.msize > messagesize)
309a747e4fSDavid du Colombier 		t->work.msize = messagesize;
319a747e4fSDavid du Colombier 	messagesize = t->work.msize;
329a747e4fSDavid du Colombier 	if(strncmp(t->work.version, "9P2000", 6) != 0){
339a747e4fSDavid du Colombier 		reply(&t->work, &rhdr, Eversion);
349a747e4fSDavid du Colombier 		return;
359a747e4fSDavid du Colombier 	}
369a747e4fSDavid du Colombier 	rhdr.version = "9P2000";
379a747e4fSDavid du Colombier 	rhdr.msize = t->work.msize;
389a747e4fSDavid du Colombier 	reply(&t->work, &rhdr, 0);
399a747e4fSDavid du Colombier 	t->busy = 0;
403e12c5d1SDavid du Colombier }
413e12c5d1SDavid du Colombier 
423e12c5d1SDavid du Colombier void
Xauth(Fsrpc * t)439a747e4fSDavid du Colombier Xauth(Fsrpc *t)
443e12c5d1SDavid du Colombier {
459a747e4fSDavid du Colombier 	Fcall rhdr;
463e12c5d1SDavid du Colombier 
473ff48bf5SDavid du Colombier 	reply(&t->work, &rhdr, "exportfs: authentication not required");
489a747e4fSDavid du Colombier 	t->busy = 0;
493e12c5d1SDavid du Colombier }
503e12c5d1SDavid du Colombier 
513e12c5d1SDavid du Colombier void
Xflush(Fsrpc * t)529a747e4fSDavid du Colombier Xflush(Fsrpc *t)
533e12c5d1SDavid du Colombier {
549a747e4fSDavid du Colombier 	Fsrpc *w, *e;
559a747e4fSDavid du Colombier 	Fcall rhdr;
563e12c5d1SDavid du Colombier 
573e12c5d1SDavid du Colombier 	e = &Workq[Nr_workbufs];
583e12c5d1SDavid du Colombier 
599a747e4fSDavid du Colombier 	for(w = Workq; w < e; w++) {
609a747e4fSDavid du Colombier 		if(w->work.tag == t->work.oldtag) {
6174f16c81SDavid du Colombier 			DEBUG(DFD, "\tQ busy %d pid %p can %d\n", w->busy, w->pid, w->canint);
629a747e4fSDavid du Colombier 			if(w->busy && w->pid) {
639a747e4fSDavid du Colombier 				w->flushtag = t->work.tag;
649a747e4fSDavid du Colombier 				DEBUG(DFD, "\tset flushtag %d\n", t->work.tag);
659a747e4fSDavid du Colombier 				if(w->canint)
669a747e4fSDavid du Colombier 					postnote(PNPROC, w->pid, "flush");
679a747e4fSDavid du Colombier 				t->busy = 0;
683e12c5d1SDavid du Colombier 				return;
693e12c5d1SDavid du Colombier 			}
703e12c5d1SDavid du Colombier 		}
713e12c5d1SDavid du Colombier 	}
723e12c5d1SDavid du Colombier 
739a747e4fSDavid du Colombier 	reply(&t->work, &rhdr, 0);
747dd7cddfSDavid du Colombier 	DEBUG(DFD, "\tflush reply\n");
759a747e4fSDavid du Colombier 	t->busy = 0;
763e12c5d1SDavid du Colombier }
773e12c5d1SDavid du Colombier 
783e12c5d1SDavid du Colombier void
Xattach(Fsrpc * t)799a747e4fSDavid du Colombier Xattach(Fsrpc *t)
803e12c5d1SDavid du Colombier {
819a747e4fSDavid du Colombier 	int i, nfd;
829a747e4fSDavid du Colombier 	Fcall rhdr;
833e12c5d1SDavid du Colombier 	Fid *f;
849a747e4fSDavid du Colombier 	char buf[128];
853e12c5d1SDavid du Colombier 
869a747e4fSDavid du Colombier 	f = newfid(t->work.fid);
873e12c5d1SDavid du Colombier 	if(f == 0) {
889a747e4fSDavid du Colombier 		reply(&t->work, &rhdr, Ebadfid);
899a747e4fSDavid du Colombier 		t->busy = 0;
903e12c5d1SDavid du Colombier 		return;
913e12c5d1SDavid du Colombier 	}
923e12c5d1SDavid du Colombier 
939a747e4fSDavid du Colombier 	if(srvfd >= 0){
949a747e4fSDavid du Colombier 		if(psmpt == 0){
959a747e4fSDavid du Colombier 		Nomount:
969a747e4fSDavid du Colombier 			reply(&t->work, &rhdr, Enopsmt);
979a747e4fSDavid du Colombier 			t->busy = 0;
989a747e4fSDavid du Colombier 			freefid(t->work.fid);
999a747e4fSDavid du Colombier 			return;
1009a747e4fSDavid du Colombier 		}
1019a747e4fSDavid du Colombier 		for(i=0; i<Npsmpt; i++)
1029a747e4fSDavid du Colombier 			if(psmap[i] == 0)
1039a747e4fSDavid du Colombier 				break;
1049a747e4fSDavid du Colombier 		if(i >= Npsmpt)
1059a747e4fSDavid du Colombier 			goto Nomount;
1069a747e4fSDavid du Colombier 		sprint(buf, "%d", i);
1079a747e4fSDavid du Colombier 		f->f = file(psmpt, buf);
1089a747e4fSDavid du Colombier 		if(f->f == nil)
1099a747e4fSDavid du Colombier 			goto Nomount;
1109a747e4fSDavid du Colombier 		sprint(buf, "/mnt/exportfs/%d", i);
1119a747e4fSDavid du Colombier 		nfd = dup(srvfd, -1);
1129a747e4fSDavid du Colombier 		if(amount(nfd, buf, MREPL|MCREATE, t->work.aname) < 0){
1139a747e4fSDavid du Colombier 			errstr(buf, sizeof buf);
1149a747e4fSDavid du Colombier 			reply(&t->work, &rhdr, buf);
1159a747e4fSDavid du Colombier 			t->busy = 0;
1169a747e4fSDavid du Colombier 			freefid(t->work.fid);
1179a747e4fSDavid du Colombier 			close(nfd);
1189a747e4fSDavid du Colombier 			return;
1199a747e4fSDavid du Colombier 		}
1209a747e4fSDavid du Colombier 		psmap[i] = 1;
1219a747e4fSDavid du Colombier 		f->mid = i;
1229a747e4fSDavid du Colombier 	}else{
1233e12c5d1SDavid du Colombier 		f->f = root;
1247dd7cddfSDavid du Colombier 		f->f->ref++;
1253e12c5d1SDavid du Colombier 	}
1263e12c5d1SDavid du Colombier 
1279a747e4fSDavid du Colombier 	rhdr.qid = f->f->qid;
1289a747e4fSDavid du Colombier 	reply(&t->work, &rhdr, 0);
1299a747e4fSDavid du Colombier 	t->busy = 0;
1309a747e4fSDavid du Colombier }
1319a747e4fSDavid du Colombier 
1329a747e4fSDavid du Colombier Fid*
clonefid(Fid * f,int new)1339a747e4fSDavid du Colombier clonefid(Fid *f, int new)
1343e12c5d1SDavid du Colombier {
1359a747e4fSDavid du Colombier 	Fid *n;
1363e12c5d1SDavid du Colombier 
1379a747e4fSDavid du Colombier 	n = newfid(new);
1383e12c5d1SDavid du Colombier 	if(n == 0) {
1399a747e4fSDavid du Colombier 		n = getfid(new);
140219b2ee8SDavid du Colombier 		if(n == 0)
141219b2ee8SDavid du Colombier 			fatal("inconsistent fids");
142219b2ee8SDavid du Colombier 		if(n->fid >= 0)
143219b2ee8SDavid du Colombier 			close(n->fid);
1449a747e4fSDavid du Colombier 		freefid(new);
1459a747e4fSDavid du Colombier 		n = newfid(new);
146219b2ee8SDavid du Colombier 		if(n == 0)
147219b2ee8SDavid du Colombier 			fatal("inconsistent fids2");
1483e12c5d1SDavid du Colombier 	}
1493e12c5d1SDavid du Colombier 	n->f = f->f;
1507dd7cddfSDavid du Colombier 	n->f->ref++;
1519a747e4fSDavid du Colombier 	return n;
1523e12c5d1SDavid du Colombier }
1533e12c5d1SDavid du Colombier 
1549a747e4fSDavid du Colombier void
Xwalk(Fsrpc * t)1559a747e4fSDavid du Colombier Xwalk(Fsrpc *t)
1563e12c5d1SDavid du Colombier {
1579a747e4fSDavid du Colombier 	char err[ERRMAX], *e;
1589a747e4fSDavid du Colombier 	Fcall rhdr;
1599a747e4fSDavid du Colombier 	Fid *f, *nf;
1609a747e4fSDavid du Colombier 	File *wf;
1619a747e4fSDavid du Colombier 	int i;
1623e12c5d1SDavid du Colombier 
1639a747e4fSDavid du Colombier 	f = getfid(t->work.fid);
1643e12c5d1SDavid du Colombier 	if(f == 0) {
1659a747e4fSDavid du Colombier 		reply(&t->work, &rhdr, Ebadfid);
1669a747e4fSDavid du Colombier 		t->busy = 0;
1679a747e4fSDavid du Colombier 		return;
1683e12c5d1SDavid du Colombier 	}
1693e12c5d1SDavid du Colombier 
1709a747e4fSDavid du Colombier 	nf = nil;
1719a747e4fSDavid du Colombier 	if(t->work.newfid != t->work.fid){
1729a747e4fSDavid du Colombier 		nf = clonefid(f, t->work.newfid);
1739a747e4fSDavid du Colombier 		f = nf;
1749a747e4fSDavid du Colombier 	}
1759a747e4fSDavid du Colombier 
1769a747e4fSDavid du Colombier 	rhdr.nwqid = 0;
1779a747e4fSDavid du Colombier 	e = nil;
1789a747e4fSDavid du Colombier 	for(i=0; i<t->work.nwname; i++){
1799a747e4fSDavid du Colombier 		if(i == MAXWELEM){
1809a747e4fSDavid du Colombier 			e = "Too many path elements";
1819a747e4fSDavid du Colombier 			break;
1829a747e4fSDavid du Colombier 		}
1839a747e4fSDavid du Colombier 
1849a747e4fSDavid du Colombier 		if(strcmp(t->work.wname[i], "..") == 0) {
1857dd7cddfSDavid du Colombier 			if(f->f->parent == nil) {
1869a747e4fSDavid du Colombier 				e = Exmnt;
1879a747e4fSDavid du Colombier 				break;
1883e12c5d1SDavid du Colombier 			}
1899a747e4fSDavid du Colombier 			wf = f->f->parent;
1909a747e4fSDavid du Colombier 			wf->ref++;
1919a747e4fSDavid du Colombier 			goto Accept;
1923e12c5d1SDavid du Colombier 		}
1933e12c5d1SDavid du Colombier 
1949a747e4fSDavid du Colombier 		wf = file(f->f, t->work.wname[i]);
1959a747e4fSDavid du Colombier 		if(wf == 0){
1969a747e4fSDavid du Colombier 			errstr(err, sizeof err);
1979a747e4fSDavid du Colombier 			e = err;
1989a747e4fSDavid du Colombier 			break;
1999a747e4fSDavid du Colombier 		}
2009a747e4fSDavid du Colombier     Accept:
2019a747e4fSDavid du Colombier 		freefile(f->f);
2029a747e4fSDavid du Colombier 		rhdr.wqid[rhdr.nwqid++] = wf->qid;
2039a747e4fSDavid du Colombier 		f->f = wf;
2049a747e4fSDavid du Colombier 		continue;
2053e12c5d1SDavid du Colombier 	}
2063e12c5d1SDavid du Colombier 
2079a747e4fSDavid du Colombier 	if(nf!=nil && (e!=nil || rhdr.nwqid!=t->work.nwname))
2089a747e4fSDavid du Colombier 		freefid(t->work.newfid);
2099a747e4fSDavid du Colombier 	if(rhdr.nwqid > 0)
2109a747e4fSDavid du Colombier 		e = nil;
2119a747e4fSDavid du Colombier 	reply(&t->work, &rhdr, e);
2129a747e4fSDavid du Colombier 	t->busy = 0;
2137dd7cddfSDavid du Colombier }
2147dd7cddfSDavid du Colombier 
2157dd7cddfSDavid du Colombier void
Xclunk(Fsrpc * t)2169a747e4fSDavid du Colombier Xclunk(Fsrpc *t)
2177dd7cddfSDavid du Colombier {
2189a747e4fSDavid du Colombier 	Fcall rhdr;
2193e12c5d1SDavid du Colombier 	Fid *f;
2203e12c5d1SDavid du Colombier 
2219a747e4fSDavid du Colombier 	f = getfid(t->work.fid);
2223e12c5d1SDavid du Colombier 	if(f == 0) {
2239a747e4fSDavid du Colombier 		reply(&t->work, &rhdr, Ebadfid);
2249a747e4fSDavid du Colombier 		t->busy = 0;
2253e12c5d1SDavid du Colombier 		return;
2263e12c5d1SDavid du Colombier 	}
2273e12c5d1SDavid du Colombier 
2283e12c5d1SDavid du Colombier 	if(f->fid >= 0)
2293e12c5d1SDavid du Colombier 		close(f->fid);
2303e12c5d1SDavid du Colombier 
2319a747e4fSDavid du Colombier 	freefid(t->work.fid);
2329a747e4fSDavid du Colombier 	reply(&t->work, &rhdr, 0);
2339a747e4fSDavid du Colombier 	t->busy = 0;
2343e12c5d1SDavid du Colombier }
2353e12c5d1SDavid du Colombier 
2363e12c5d1SDavid du Colombier void
Xstat(Fsrpc * t)2379a747e4fSDavid du Colombier Xstat(Fsrpc *t)
2383e12c5d1SDavid du Colombier {
2399a747e4fSDavid du Colombier 	char err[ERRMAX], *path;
2409a747e4fSDavid du Colombier 	Fcall rhdr;
2413e12c5d1SDavid du Colombier 	Fid *f;
2429a747e4fSDavid du Colombier 	Dir *d;
2433e12c5d1SDavid du Colombier 	int s;
2449a747e4fSDavid du Colombier 	uchar *statbuf;
2453e12c5d1SDavid du Colombier 
2469a747e4fSDavid du Colombier 	f = getfid(t->work.fid);
2473e12c5d1SDavid du Colombier 	if(f == 0) {
2489a747e4fSDavid du Colombier 		reply(&t->work, &rhdr, Ebadfid);
2499a747e4fSDavid du Colombier 		t->busy = 0;
2503e12c5d1SDavid du Colombier 		return;
2513e12c5d1SDavid du Colombier 	}
2523e12c5d1SDavid du Colombier 	if(f->fid >= 0)
2539a747e4fSDavid du Colombier 		d = dirfstat(f->fid);
2543e12c5d1SDavid du Colombier 	else {
2559a747e4fSDavid du Colombier 		path = makepath(f->f, "");
2569a747e4fSDavid du Colombier 		d = dirstat(path);
2579a747e4fSDavid du Colombier 		free(path);
2583e12c5d1SDavid du Colombier 	}
2593e12c5d1SDavid du Colombier 
2609a747e4fSDavid du Colombier 	if(d == nil) {
2619a747e4fSDavid du Colombier 		errstr(err, sizeof err);
2629a747e4fSDavid du Colombier 		reply(&t->work, &rhdr, err);
2639a747e4fSDavid du Colombier 		t->busy = 0;
2643e12c5d1SDavid du Colombier 		return;
2653e12c5d1SDavid du Colombier 	}
2669a747e4fSDavid du Colombier 
2679a747e4fSDavid du Colombier 	d->qid.path = f->f->qidt->uniqpath;
2689a747e4fSDavid du Colombier 	s = sizeD2M(d);
2699a747e4fSDavid du Colombier 	statbuf = emallocz(s);
2709a747e4fSDavid du Colombier 	s = convD2M(d, statbuf, s);
2719a747e4fSDavid du Colombier 	free(d);
2729a747e4fSDavid du Colombier 	rhdr.nstat = s;
2739a747e4fSDavid du Colombier 	rhdr.stat = statbuf;
2749a747e4fSDavid du Colombier 	reply(&t->work, &rhdr, 0);
2759a747e4fSDavid du Colombier 	free(statbuf);
2769a747e4fSDavid du Colombier 	t->busy = 0;
2779a747e4fSDavid du Colombier }
2789a747e4fSDavid du Colombier 
2799a747e4fSDavid du Colombier static int
getiounit(int fd)2809a747e4fSDavid du Colombier getiounit(int fd)
2819a747e4fSDavid du Colombier {
2829a747e4fSDavid du Colombier 	int n;
2839a747e4fSDavid du Colombier 
2849a747e4fSDavid du Colombier 	n = iounit(fd);
2859a747e4fSDavid du Colombier 	if(n > messagesize-IOHDRSZ)
2869a747e4fSDavid du Colombier 		n = messagesize-IOHDRSZ;
2879a747e4fSDavid du Colombier 	return n;
2883e12c5d1SDavid du Colombier }
2893e12c5d1SDavid du Colombier 
2903e12c5d1SDavid du Colombier void
Xcreate(Fsrpc * t)2919a747e4fSDavid du Colombier Xcreate(Fsrpc *t)
2923e12c5d1SDavid du Colombier {
2939a747e4fSDavid du Colombier 	char err[ERRMAX], *path;
2949a747e4fSDavid du Colombier 	Fcall rhdr;
2953e12c5d1SDavid du Colombier 	Fid *f;
2963e12c5d1SDavid du Colombier 	File *nf;
2973e12c5d1SDavid du Colombier 
29824b9ac62SDavid du Colombier 	if(readonly) {
29924b9ac62SDavid du Colombier 		reply(&t->work, &rhdr, Ereadonly);
30024b9ac62SDavid du Colombier 		t->busy = 0;
30124b9ac62SDavid du Colombier 		return;
30224b9ac62SDavid du Colombier 	}
3039a747e4fSDavid du Colombier 	f = getfid(t->work.fid);
3043e12c5d1SDavid du Colombier 	if(f == 0) {
3059a747e4fSDavid du Colombier 		reply(&t->work, &rhdr, Ebadfid);
3069a747e4fSDavid du Colombier 		t->busy = 0;
3073e12c5d1SDavid du Colombier 		return;
3083e12c5d1SDavid du Colombier 	}
3093e12c5d1SDavid du Colombier 
3103e12c5d1SDavid du Colombier 
3119a747e4fSDavid du Colombier 	path = makepath(f->f, t->work.name);
3129a747e4fSDavid du Colombier 	f->fid = create(path, t->work.mode, t->work.perm);
3139a747e4fSDavid du Colombier 	free(path);
3143e12c5d1SDavid du Colombier 	if(f->fid < 0) {
3159a747e4fSDavid du Colombier 		errstr(err, sizeof err);
3169a747e4fSDavid du Colombier 		reply(&t->work, &rhdr, err);
3179a747e4fSDavid du Colombier 		t->busy = 0;
3183e12c5d1SDavid du Colombier 		return;
3193e12c5d1SDavid du Colombier 	}
3203e12c5d1SDavid du Colombier 
3219a747e4fSDavid du Colombier 	nf = file(f->f, t->work.name);
3223e12c5d1SDavid du Colombier 	if(nf == 0) {
3239a747e4fSDavid du Colombier 		errstr(err, sizeof err);
3249a747e4fSDavid du Colombier 		reply(&t->work, &rhdr, err);
3259a747e4fSDavid du Colombier 		t->busy = 0;
3263e12c5d1SDavid du Colombier 		return;
3273e12c5d1SDavid du Colombier 	}
3283e12c5d1SDavid du Colombier 
3299a747e4fSDavid du Colombier 	f->mode = t->work.mode;
3307dd7cddfSDavid du Colombier 	freefile(f->f);
3313e12c5d1SDavid du Colombier 	f->f = nf;
3329a747e4fSDavid du Colombier 	rhdr.qid = f->f->qid;
3339a747e4fSDavid du Colombier 	rhdr.iounit = getiounit(f->fid);
3349a747e4fSDavid du Colombier 	reply(&t->work, &rhdr, 0);
3359a747e4fSDavid du Colombier 	t->busy = 0;
3363e12c5d1SDavid du Colombier }
3373e12c5d1SDavid du Colombier 
3383e12c5d1SDavid du Colombier void
Xremove(Fsrpc * t)3399a747e4fSDavid du Colombier Xremove(Fsrpc *t)
3403e12c5d1SDavid du Colombier {
3419a747e4fSDavid du Colombier 	char err[ERRMAX], *path;
3429a747e4fSDavid du Colombier 	Fcall rhdr;
3433e12c5d1SDavid du Colombier 	Fid *f;
3443e12c5d1SDavid du Colombier 
34524b9ac62SDavid du Colombier 	if(readonly) {
34624b9ac62SDavid du Colombier 		reply(&t->work, &rhdr, Ereadonly);
34724b9ac62SDavid du Colombier 		t->busy = 0;
34824b9ac62SDavid du Colombier 		return;
34924b9ac62SDavid du Colombier 	}
3509a747e4fSDavid du Colombier 	f = getfid(t->work.fid);
3513e12c5d1SDavid du Colombier 	if(f == 0) {
3529a747e4fSDavid du Colombier 		reply(&t->work, &rhdr, Ebadfid);
3539a747e4fSDavid du Colombier 		t->busy = 0;
3543e12c5d1SDavid du Colombier 		return;
3553e12c5d1SDavid du Colombier 	}
3563e12c5d1SDavid du Colombier 
3579a747e4fSDavid du Colombier 	path = makepath(f->f, "");
3587dd7cddfSDavid du Colombier 	DEBUG(DFD, "\tremove: %s\n", path);
3593e12c5d1SDavid du Colombier 	if(remove(path) < 0) {
3609a747e4fSDavid du Colombier 		free(path);
3619a747e4fSDavid du Colombier 		errstr(err, sizeof err);
3629a747e4fSDavid du Colombier 		reply(&t->work, &rhdr, err);
3639a747e4fSDavid du Colombier 		t->busy = 0;
3643e12c5d1SDavid du Colombier 		return;
3653e12c5d1SDavid du Colombier 	}
3669a747e4fSDavid du Colombier 	free(path);
3673e12c5d1SDavid du Colombier 
3687dd7cddfSDavid du Colombier 	f->f->inval = 1;
3693e12c5d1SDavid du Colombier 	if(f->fid >= 0)
3703e12c5d1SDavid du Colombier 		close(f->fid);
3719a747e4fSDavid du Colombier 	freefid(t->work.fid);
3723e12c5d1SDavid du Colombier 
3739a747e4fSDavid du Colombier 	reply(&t->work, &rhdr, 0);
3749a747e4fSDavid du Colombier 	t->busy = 0;
3753e12c5d1SDavid du Colombier }
3763e12c5d1SDavid du Colombier 
3773e12c5d1SDavid du Colombier void
Xwstat(Fsrpc * t)3789a747e4fSDavid du Colombier Xwstat(Fsrpc *t)
3793e12c5d1SDavid du Colombier {
3809a747e4fSDavid du Colombier 	char err[ERRMAX], *path;
3819a747e4fSDavid du Colombier 	Fcall rhdr;
3823e12c5d1SDavid du Colombier 	Fid *f;
3833e12c5d1SDavid du Colombier 	int s;
3849a747e4fSDavid du Colombier 	char *strings;
3859a747e4fSDavid du Colombier 	Dir d;
3863e12c5d1SDavid du Colombier 
38724b9ac62SDavid du Colombier 	if(readonly) {
38824b9ac62SDavid du Colombier 		reply(&t->work, &rhdr, Ereadonly);
38924b9ac62SDavid du Colombier 		t->busy = 0;
39024b9ac62SDavid du Colombier 		return;
39124b9ac62SDavid du Colombier 	}
3929a747e4fSDavid du Colombier 	f = getfid(t->work.fid);
3933e12c5d1SDavid du Colombier 	if(f == 0) {
3949a747e4fSDavid du Colombier 		reply(&t->work, &rhdr, Ebadfid);
3959a747e4fSDavid du Colombier 		t->busy = 0;
3963e12c5d1SDavid du Colombier 		return;
3973e12c5d1SDavid du Colombier 	}
3989a747e4fSDavid du Colombier 	strings = emallocz(t->work.nstat);	/* ample */
39974f16c81SDavid du Colombier 	if(convM2D(t->work.stat, t->work.nstat, &d, strings) <= BIT16SZ){
4009a747e4fSDavid du Colombier 		rerrstr(err, sizeof err);
4019a747e4fSDavid du Colombier 		reply(&t->work, &rhdr, err);
4029a747e4fSDavid du Colombier 		t->busy = 0;
4039a747e4fSDavid du Colombier 		free(strings);
4049a747e4fSDavid du Colombier 		return;
4059a747e4fSDavid du Colombier 	}
4069a747e4fSDavid du Colombier 
4073e12c5d1SDavid du Colombier 	if(f->fid >= 0)
4089a747e4fSDavid du Colombier 		s = dirfwstat(f->fid, &d);
4093e12c5d1SDavid du Colombier 	else {
4109a747e4fSDavid du Colombier 		path = makepath(f->f, "");
4119a747e4fSDavid du Colombier 		s = dirwstat(path, &d);
4129a747e4fSDavid du Colombier 		free(path);
4133e12c5d1SDavid du Colombier 	}
4143e12c5d1SDavid du Colombier 	if(s < 0) {
4159a747e4fSDavid du Colombier 		rerrstr(err, sizeof err);
4169a747e4fSDavid du Colombier 		reply(&t->work, &rhdr, err);
4173e12c5d1SDavid du Colombier 	}
418219b2ee8SDavid du Colombier 	else {
419219b2ee8SDavid du Colombier 		/* wstat may really be rename */
420d9306527SDavid du Colombier 		if(strcmp(d.name, f->f->name)!=0 && strcmp(d.name, "")!=0){
4219a747e4fSDavid du Colombier 			free(f->f->name);
4229a747e4fSDavid du Colombier 			f->f->name = estrdup(d.name);
423219b2ee8SDavid du Colombier 		}
4249a747e4fSDavid du Colombier 		reply(&t->work, &rhdr, 0);
4253e12c5d1SDavid du Colombier 	}
4269a747e4fSDavid du Colombier 	free(strings);
4279a747e4fSDavid du Colombier 	t->busy = 0;
4283e12c5d1SDavid du Colombier }
4293e12c5d1SDavid du Colombier 
430*7ec5746aSDavid du Colombier /*
431*7ec5746aSDavid du Colombier  * based on libthread's threadsetname, but drags in less library code.
432*7ec5746aSDavid du Colombier  * actually just sets the arguments displayed.
433*7ec5746aSDavid du Colombier  */
434*7ec5746aSDavid du Colombier void
procsetname(char * fmt,...)435*7ec5746aSDavid du Colombier procsetname(char *fmt, ...)
436*7ec5746aSDavid du Colombier {
437*7ec5746aSDavid du Colombier 	int fd;
438*7ec5746aSDavid du Colombier 	char *cmdname;
439*7ec5746aSDavid du Colombier 	char buf[128];
440*7ec5746aSDavid du Colombier 	va_list arg;
441*7ec5746aSDavid du Colombier 
442*7ec5746aSDavid du Colombier 	va_start(arg, fmt);
443*7ec5746aSDavid du Colombier 	cmdname = vsmprint(fmt, arg);
444*7ec5746aSDavid du Colombier 	va_end(arg);
445*7ec5746aSDavid du Colombier 	if (cmdname == nil)
446*7ec5746aSDavid du Colombier 		return;
447*7ec5746aSDavid du Colombier 	snprint(buf, sizeof buf, "#p/%d/args", getpid());
448*7ec5746aSDavid du Colombier 	if((fd = open(buf, OWRITE)) >= 0){
449*7ec5746aSDavid du Colombier 		write(fd, cmdname, strlen(cmdname)+1);
450*7ec5746aSDavid du Colombier 		close(fd);
451*7ec5746aSDavid du Colombier 	}
452*7ec5746aSDavid du Colombier 	free(cmdname);
453*7ec5746aSDavid du Colombier }
454*7ec5746aSDavid du Colombier 
4553e12c5d1SDavid du Colombier void
slave(Fsrpc * f)4563e12c5d1SDavid du Colombier slave(Fsrpc *f)
4573e12c5d1SDavid du Colombier {
4583e12c5d1SDavid du Colombier 	Proc *p;
45974f16c81SDavid du Colombier 	uintptr pid;
46024b9ac62SDavid du Colombier 	Fcall rhdr;
4613e12c5d1SDavid du Colombier 	static int nproc;
4623e12c5d1SDavid du Colombier 
46324b9ac62SDavid du Colombier 	if(readonly){
46424b9ac62SDavid du Colombier 		switch(f->work.type){
46524b9ac62SDavid du Colombier 		case Twrite:
46624b9ac62SDavid du Colombier 			reply(&f->work, &rhdr, Ereadonly);
46724b9ac62SDavid du Colombier 			f->busy = 0;
46824b9ac62SDavid du Colombier 			return;
46924b9ac62SDavid du Colombier 		case Topen:
47024b9ac62SDavid du Colombier 		  	if((f->work.mode&3) == OWRITE || (f->work.mode&OTRUNC)){
47124b9ac62SDavid du Colombier 				reply(&f->work, &rhdr, Ereadonly);
47224b9ac62SDavid du Colombier 				f->busy = 0;
47324b9ac62SDavid du Colombier 				return;
47424b9ac62SDavid du Colombier 			}
47524b9ac62SDavid du Colombier 		}
47624b9ac62SDavid du Colombier 	}
4773e12c5d1SDavid du Colombier 	for(;;) {
4783e12c5d1SDavid du Colombier 		for(p = Proclist; p; p = p->next) {
4793e12c5d1SDavid du Colombier 			if(p->busy == 0) {
4803e12c5d1SDavid du Colombier 				f->pid = p->pid;
4813e12c5d1SDavid du Colombier 				p->busy = 1;
48274f16c81SDavid du Colombier 				pid = (uintptr)rendezvous((void*)p->pid, f);
4833e12c5d1SDavid du Colombier 				if(pid != p->pid)
4843e12c5d1SDavid du Colombier 					fatal("rendezvous sync fail");
4853e12c5d1SDavid du Colombier 				return;
4863e12c5d1SDavid du Colombier 			}
4873e12c5d1SDavid du Colombier 		}
4883e12c5d1SDavid du Colombier 
4893e12c5d1SDavid du Colombier 		if(++nproc > MAXPROC)
4903e12c5d1SDavid du Colombier 			fatal("too many procs");
4913e12c5d1SDavid du Colombier 
4923e12c5d1SDavid du Colombier 		pid = rfork(RFPROC|RFMEM);
4933e12c5d1SDavid du Colombier 		switch(pid) {
4943e12c5d1SDavid du Colombier 		case -1:
4953e12c5d1SDavid du Colombier 			fatal("rfork");
4963e12c5d1SDavid du Colombier 
4973e12c5d1SDavid du Colombier 		case 0:
498*7ec5746aSDavid du Colombier 			if (local[0] != '\0')
499*7ec5746aSDavid du Colombier 				if (netdir[0] != '\0')
500*7ec5746aSDavid du Colombier 					procsetname("%s: %s -> %s", netdir,
501*7ec5746aSDavid du Colombier 						local, remote);
502*7ec5746aSDavid du Colombier 				else
503*7ec5746aSDavid du Colombier 					procsetname("%s -> %s", local, remote);
5043e12c5d1SDavid du Colombier 			blockingslave();
5053e12c5d1SDavid du Colombier 			fatal("slave");
5063e12c5d1SDavid du Colombier 
5073e12c5d1SDavid du Colombier 		default:
5083e12c5d1SDavid du Colombier 			p = malloc(sizeof(Proc));
5093e12c5d1SDavid du Colombier 			if(p == 0)
5103e12c5d1SDavid du Colombier 				fatal("out of memory");
5113e12c5d1SDavid du Colombier 
5123e12c5d1SDavid du Colombier 			p->busy = 0;
5133e12c5d1SDavid du Colombier 			p->pid = pid;
5143e12c5d1SDavid du Colombier 			p->next = Proclist;
5153e12c5d1SDavid du Colombier 			Proclist = p;
5163e12c5d1SDavid du Colombier 
51774f16c81SDavid du Colombier 			rendezvous((void*)pid, p);
5183e12c5d1SDavid du Colombier 		}
5193e12c5d1SDavid du Colombier 	}
5203e12c5d1SDavid du Colombier }
5213e12c5d1SDavid du Colombier 
5223e12c5d1SDavid du Colombier void
blockingslave(void)5233e12c5d1SDavid du Colombier blockingslave(void)
5243e12c5d1SDavid du Colombier {
5253e12c5d1SDavid du Colombier 	Fsrpc *p;
5269a747e4fSDavid du Colombier 	Fcall rhdr;
5273e12c5d1SDavid du Colombier 	Proc *m;
52874f16c81SDavid du Colombier 	uintptr pid;
5293e12c5d1SDavid du Colombier 
5303e12c5d1SDavid du Colombier 	notify(flushaction);
5313e12c5d1SDavid du Colombier 
5323e12c5d1SDavid du Colombier 	pid = getpid();
5333e12c5d1SDavid du Colombier 
53474f16c81SDavid du Colombier 	m = rendezvous((void*)pid, 0);
5353e12c5d1SDavid du Colombier 
5363e12c5d1SDavid du Colombier 	for(;;) {
53774f16c81SDavid du Colombier 		p = rendezvous((void*)pid, (void*)pid);
53874f16c81SDavid du Colombier 		if(p == (void*)~0)			/* Interrupted */
5393e12c5d1SDavid du Colombier 			continue;
5403e12c5d1SDavid du Colombier 
54174f16c81SDavid du Colombier 		DEBUG(DFD, "\tslave: %p %F b %d p %p\n", pid, &p->work, p->busy, p->pid);
5423e12c5d1SDavid du Colombier 		if(p->flushtag != NOTAG)
5433e12c5d1SDavid du Colombier 			goto flushme;
5443e12c5d1SDavid du Colombier 
5453e12c5d1SDavid du Colombier 		switch(p->work.type) {
5463e12c5d1SDavid du Colombier 		case Tread:
5473e12c5d1SDavid du Colombier 			slaveread(p);
5483e12c5d1SDavid du Colombier 			break;
5493e12c5d1SDavid du Colombier 
5503e12c5d1SDavid du Colombier 		case Twrite:
5513e12c5d1SDavid du Colombier 			slavewrite(p);
5523e12c5d1SDavid du Colombier 			break;
5533e12c5d1SDavid du Colombier 
5543e12c5d1SDavid du Colombier 		case Topen:
5553e12c5d1SDavid du Colombier 			slaveopen(p);
5563e12c5d1SDavid du Colombier 			break;
5573e12c5d1SDavid du Colombier 
5583e12c5d1SDavid du Colombier 		default:
5599a747e4fSDavid du Colombier 			reply(&p->work, &rhdr, "exportfs: slave type error");
5603e12c5d1SDavid du Colombier 		}
5613e12c5d1SDavid du Colombier 		if(p->flushtag != NOTAG) {
5623e12c5d1SDavid du Colombier flushme:
5633e12c5d1SDavid du Colombier 			p->work.type = Tflush;
5643e12c5d1SDavid du Colombier 			p->work.tag = p->flushtag;
5659a747e4fSDavid du Colombier 			reply(&p->work, &rhdr, 0);
5663e12c5d1SDavid du Colombier 		}
5673e12c5d1SDavid du Colombier 		p->busy = 0;
5683e12c5d1SDavid du Colombier 		m->busy = 0;
5693e12c5d1SDavid du Colombier 	}
5703e12c5d1SDavid du Colombier }
5713e12c5d1SDavid du Colombier 
5729a747e4fSDavid du Colombier int
openmount(int sfd)5739a747e4fSDavid du Colombier openmount(int sfd)
574219b2ee8SDavid du Colombier {
5759a747e4fSDavid du Colombier 	int p[2];
5769a747e4fSDavid du Colombier 	char *arg[10], fdbuf[20], mbuf[20];
577219b2ee8SDavid du Colombier 
5789a747e4fSDavid du Colombier 	if(pipe(p) < 0)
5799a747e4fSDavid du Colombier 		return -1;
580219b2ee8SDavid du Colombier 
5819a747e4fSDavid du Colombier 	switch(rfork(RFPROC|RFMEM|RFNOWAIT|RFNAMEG|RFFDG)){
5829a747e4fSDavid du Colombier 	case -1:
5839a747e4fSDavid du Colombier 		return -1;
5849a747e4fSDavid du Colombier 
5859a747e4fSDavid du Colombier 	default:
5869a747e4fSDavid du Colombier 		close(sfd);
5879a747e4fSDavid du Colombier 		close(p[0]);
5889a747e4fSDavid du Colombier 		return p[1];
5899a747e4fSDavid du Colombier 
5909a747e4fSDavid du Colombier 	case 0:
591219b2ee8SDavid du Colombier 		break;
592219b2ee8SDavid du Colombier 	}
593219b2ee8SDavid du Colombier 
5949a747e4fSDavid du Colombier 	close(p[1]);
595219b2ee8SDavid du Colombier 
5969a747e4fSDavid du Colombier 	arg[0] = "exportfs";
5979a747e4fSDavid du Colombier 	snprint(fdbuf, sizeof fdbuf, "-S/fd/%d", sfd);
5989a747e4fSDavid du Colombier 	arg[1] = fdbuf;
5999a747e4fSDavid du Colombier 	snprint(mbuf, sizeof mbuf, "-m%lud", messagesize-IOHDRSZ);
6009a747e4fSDavid du Colombier 	arg[2] = mbuf;
6019a747e4fSDavid du Colombier 	arg[3] = nil;
602219b2ee8SDavid du Colombier 
6039a747e4fSDavid du Colombier 	close(0);
6049a747e4fSDavid du Colombier 	close(1);
6059a747e4fSDavid du Colombier 	dup(p[0], 0);
6069a747e4fSDavid du Colombier 	dup(p[0], 1);
6079a747e4fSDavid du Colombier 	exec("/bin/exportfs", arg);
6089a747e4fSDavid du Colombier 	_exits("whoops: exec failed");
6099a747e4fSDavid du Colombier 	return -1;
610219b2ee8SDavid du Colombier }
611219b2ee8SDavid du Colombier 
6123e12c5d1SDavid du Colombier void
slaveopen(Fsrpc * p)6133e12c5d1SDavid du Colombier slaveopen(Fsrpc *p)
6143e12c5d1SDavid du Colombier {
6159a747e4fSDavid du Colombier 	char err[ERRMAX], *path;
6169a747e4fSDavid du Colombier 	Fcall *work, rhdr;
6173e12c5d1SDavid du Colombier 	Fid *f;
6189a747e4fSDavid du Colombier 	Dir *d;
6193e12c5d1SDavid du Colombier 
6203e12c5d1SDavid du Colombier 	work = &p->work;
6213e12c5d1SDavid du Colombier 
6223e12c5d1SDavid du Colombier 	f = getfid(work->fid);
6233e12c5d1SDavid du Colombier 	if(f == 0) {
6249a747e4fSDavid du Colombier 		reply(work, &rhdr, Ebadfid);
6253e12c5d1SDavid du Colombier 		return;
6263e12c5d1SDavid du Colombier 	}
6273e12c5d1SDavid du Colombier 	if(f->fid >= 0) {
6283e12c5d1SDavid du Colombier 		close(f->fid);
6293e12c5d1SDavid du Colombier 		f->fid = -1;
6303e12c5d1SDavid du Colombier 	}
6313e12c5d1SDavid du Colombier 
6329a747e4fSDavid du Colombier 	path = makepath(f->f, "");
6337dd7cddfSDavid du Colombier 	DEBUG(DFD, "\topen: %s %d\n", path, work->mode);
6343e12c5d1SDavid du Colombier 
6353e12c5d1SDavid du Colombier 	p->canint = 1;
6369a747e4fSDavid du Colombier 	if(p->flushtag != NOTAG){
6379a747e4fSDavid du Colombier 		free(path);
6383e12c5d1SDavid du Colombier 		return;
6399a747e4fSDavid du Colombier 	}
6403e12c5d1SDavid du Colombier 	/* There is a race here I ignore because there are no locks */
6413e12c5d1SDavid du Colombier 	f->fid = open(path, work->mode);
6429a747e4fSDavid du Colombier 	free(path);
6433e12c5d1SDavid du Colombier 	p->canint = 0;
6449a747e4fSDavid du Colombier 	if(f->fid < 0 || (d = dirfstat(f->fid)) == nil) {
6459a747e4fSDavid du Colombier 	Error:
6469a747e4fSDavid du Colombier 		errstr(err, sizeof err);
6479a747e4fSDavid du Colombier 		reply(work, &rhdr, err);
6483e12c5d1SDavid du Colombier 		return;
6493e12c5d1SDavid du Colombier 	}
6509a747e4fSDavid du Colombier 	f->f->qid = d->qid;
6519a747e4fSDavid du Colombier 	free(d);
6529a747e4fSDavid du Colombier 	if(f->f->qid.type & QTMOUNT){	/* fork new exportfs for this */
6539a747e4fSDavid du Colombier 		f->fid = openmount(f->fid);
6549a747e4fSDavid du Colombier 		if(f->fid < 0)
6559a747e4fSDavid du Colombier 			goto Error;
6569a747e4fSDavid du Colombier 	}
6573e12c5d1SDavid du Colombier 
6587dd7cddfSDavid du Colombier 	DEBUG(DFD, "\topen: fd %d\n", f->fid);
6593e12c5d1SDavid du Colombier 	f->mode = work->mode;
660a960ed1cSDavid du Colombier 	f->offset = 0;
6619a747e4fSDavid du Colombier 	rhdr.iounit = getiounit(f->fid);
6629a747e4fSDavid du Colombier 	rhdr.qid = f->f->qid;
6639a747e4fSDavid du Colombier 	reply(work, &rhdr, 0);
6643e12c5d1SDavid du Colombier }
6653e12c5d1SDavid du Colombier 
6663e12c5d1SDavid du Colombier void
slaveread(Fsrpc * p)6673e12c5d1SDavid du Colombier slaveread(Fsrpc *p)
6683e12c5d1SDavid du Colombier {
6693e12c5d1SDavid du Colombier 	Fid *f;
6703e12c5d1SDavid du Colombier 	int n, r;
6719a747e4fSDavid du Colombier 	Fcall *work, rhdr;
6729a747e4fSDavid du Colombier 	char *data, err[ERRMAX];
6733e12c5d1SDavid du Colombier 
6743e12c5d1SDavid du Colombier 	work = &p->work;
6753e12c5d1SDavid du Colombier 
6763e12c5d1SDavid du Colombier 	f = getfid(work->fid);
6773e12c5d1SDavid du Colombier 	if(f == 0) {
6789a747e4fSDavid du Colombier 		reply(work, &rhdr, Ebadfid);
6793e12c5d1SDavid du Colombier 		return;
6803e12c5d1SDavid du Colombier 	}
6813e12c5d1SDavid du Colombier 
6829a747e4fSDavid du Colombier 	n = (work->count > messagesize-IOHDRSZ) ? messagesize-IOHDRSZ : work->count;
6833e12c5d1SDavid du Colombier 	p->canint = 1;
6843e12c5d1SDavid du Colombier 	if(p->flushtag != NOTAG)
6853e12c5d1SDavid du Colombier 		return;
6869a747e4fSDavid du Colombier 	data = malloc(n);
6879a747e4fSDavid du Colombier 	if(data == nil)
6889a747e4fSDavid du Colombier 		fatal(Enomem);
6899a747e4fSDavid du Colombier 
6909a747e4fSDavid du Colombier 	/* can't just call pread, since directories must update the offset */
691a960ed1cSDavid du Colombier 	if(patternfile != nil && (f->f->qid.type&QTDIR))
692a960ed1cSDavid du Colombier 		r = preaddir(f, (uchar*)data, n, work->offset);
693a960ed1cSDavid du Colombier 	else
6949a747e4fSDavid du Colombier 		r = pread(f->fid, data, n, work->offset);
6953e12c5d1SDavid du Colombier 	p->canint = 0;
6963e12c5d1SDavid du Colombier 	if(r < 0) {
6979a747e4fSDavid du Colombier 		free(data);
6989a747e4fSDavid du Colombier 		errstr(err, sizeof err);
6999a747e4fSDavid du Colombier 		reply(work, &rhdr, err);
7003e12c5d1SDavid du Colombier 		return;
7013e12c5d1SDavid du Colombier 	}
7023e12c5d1SDavid du Colombier 
7037dd7cddfSDavid du Colombier 	DEBUG(DFD, "\tread: fd=%d %d bytes\n", f->fid, r);
7043e12c5d1SDavid du Colombier 
7059a747e4fSDavid du Colombier 	rhdr.data = data;
7069a747e4fSDavid du Colombier 	rhdr.count = r;
7079a747e4fSDavid du Colombier 	reply(work, &rhdr, 0);
7089a747e4fSDavid du Colombier 	free(data);
7093e12c5d1SDavid du Colombier }
7103e12c5d1SDavid du Colombier 
7113e12c5d1SDavid du Colombier void
slavewrite(Fsrpc * p)7123e12c5d1SDavid du Colombier slavewrite(Fsrpc *p)
7133e12c5d1SDavid du Colombier {
7149a747e4fSDavid du Colombier 	char err[ERRMAX];
7159a747e4fSDavid du Colombier 	Fcall *work, rhdr;
7163e12c5d1SDavid du Colombier 	Fid *f;
7173e12c5d1SDavid du Colombier 	int n;
7183e12c5d1SDavid du Colombier 
7193e12c5d1SDavid du Colombier 	work = &p->work;
7203e12c5d1SDavid du Colombier 
7213e12c5d1SDavid du Colombier 	f = getfid(work->fid);
7223e12c5d1SDavid du Colombier 	if(f == 0) {
7239a747e4fSDavid du Colombier 		reply(work, &rhdr, Ebadfid);
7243e12c5d1SDavid du Colombier 		return;
7253e12c5d1SDavid du Colombier 	}
7263e12c5d1SDavid du Colombier 
7279a747e4fSDavid du Colombier 	n = (work->count > messagesize-IOHDRSZ) ? messagesize-IOHDRSZ : work->count;
7283e12c5d1SDavid du Colombier 	p->canint = 1;
7293e12c5d1SDavid du Colombier 	if(p->flushtag != NOTAG)
7303e12c5d1SDavid du Colombier 		return;
7319a747e4fSDavid du Colombier 	n = pwrite(f->fid, work->data, n, work->offset);
7323e12c5d1SDavid du Colombier 	p->canint = 0;
7333e12c5d1SDavid du Colombier 	if(n < 0) {
7349a747e4fSDavid du Colombier 		errstr(err, sizeof err);
7359a747e4fSDavid du Colombier 		reply(work, &rhdr, err);
7363e12c5d1SDavid du Colombier 		return;
7373e12c5d1SDavid du Colombier 	}
7383e12c5d1SDavid du Colombier 
7397dd7cddfSDavid du Colombier 	DEBUG(DFD, "\twrite: %d bytes fd=%d\n", n, f->fid);
7403e12c5d1SDavid du Colombier 
7419a747e4fSDavid du Colombier 	rhdr.count = n;
7429a747e4fSDavid du Colombier 	reply(work, &rhdr, 0);
7433e12c5d1SDavid du Colombier }
7443e12c5d1SDavid du Colombier 
7453e12c5d1SDavid du Colombier void
reopen(Fid * f)7463e12c5d1SDavid du Colombier reopen(Fid *f)
7473e12c5d1SDavid du Colombier {
7483e12c5d1SDavid du Colombier 	USED(f);
7493e12c5d1SDavid du Colombier 	fatal("reopen");
7503e12c5d1SDavid du Colombier }
7513e12c5d1SDavid du Colombier 
7523e12c5d1SDavid du Colombier void
flushaction(void * a,char * cause)7533e12c5d1SDavid du Colombier flushaction(void *a, char *cause)
7543e12c5d1SDavid du Colombier {
7553e12c5d1SDavid du Colombier 	USED(a);
7563e12c5d1SDavid du Colombier 	if(strncmp(cause, "sys:", 4) == 0 && !strstr(cause, "pipe")) {
7573e12c5d1SDavid du Colombier 		fprint(2, "exportsrv: note: %s\n", cause);
7583e12c5d1SDavid du Colombier 		exits("noted");
7593e12c5d1SDavid du Colombier 	}
7603e12c5d1SDavid du Colombier 	if(strncmp(cause, "kill", 4) == 0)
7613e12c5d1SDavid du Colombier 		noted(NDFLT);
7623e12c5d1SDavid du Colombier 
7633e12c5d1SDavid du Colombier 	noted(NCONT);
7643e12c5d1SDavid du Colombier }
765