xref: /plan9/sys/src/cmd/unix/drawterm/kern/unused/syscall.c (revision bd2f137306843ada51788e7326a4138ee3a27647)
1*bd2f1373SDavid du Colombier #include	"u.h"
2*bd2f1373SDavid du Colombier #include	"lib.h"
3*bd2f1373SDavid du Colombier #include	"dat.h"
4*bd2f1373SDavid du Colombier #include	"fns.h"
5*bd2f1373SDavid du Colombier #include	"error.h"
6*bd2f1373SDavid du Colombier 
7*bd2f1373SDavid du Colombier Chan*
fdtochan(int fd,int mode,int chkmnt,int iref)8*bd2f1373SDavid du Colombier fdtochan(int fd, int mode, int chkmnt, int iref)
9*bd2f1373SDavid du Colombier {
10*bd2f1373SDavid du Colombier 	Fgrp *f;
11*bd2f1373SDavid du Colombier 	Chan *c;
12*bd2f1373SDavid du Colombier 
13*bd2f1373SDavid du Colombier 	c = 0;
14*bd2f1373SDavid du Colombier 	f = up->fgrp;
15*bd2f1373SDavid du Colombier 
16*bd2f1373SDavid du Colombier 	lock(&f->ref.lk);
17*bd2f1373SDavid du Colombier 	if(fd<0 || NFD<=fd || (c = f->fd[fd])==0) {
18*bd2f1373SDavid du Colombier 		unlock(&f->ref.lk);
19*bd2f1373SDavid du Colombier 		error(Ebadfd);
20*bd2f1373SDavid du Colombier 	}
21*bd2f1373SDavid du Colombier 	if(iref)
22*bd2f1373SDavid du Colombier 		refinc(&c->ref);
23*bd2f1373SDavid du Colombier 	unlock(&f->ref.lk);
24*bd2f1373SDavid du Colombier 
25*bd2f1373SDavid du Colombier 	if(chkmnt && (c->flag&CMSG))
26*bd2f1373SDavid du Colombier 		goto bad;
27*bd2f1373SDavid du Colombier 	if(mode<0 || c->mode==ORDWR)
28*bd2f1373SDavid du Colombier 		return c;
29*bd2f1373SDavid du Colombier 	if((mode&OTRUNC) && c->mode==OREAD)
30*bd2f1373SDavid du Colombier 		goto bad;
31*bd2f1373SDavid du Colombier 	if((mode&~OTRUNC) != c->mode)
32*bd2f1373SDavid du Colombier 		goto bad;
33*bd2f1373SDavid du Colombier 	return c;
34*bd2f1373SDavid du Colombier bad:
35*bd2f1373SDavid du Colombier 	if(iref)
36*bd2f1373SDavid du Colombier 		cclose(c);
37*bd2f1373SDavid du Colombier 	error(Ebadusefd);
38*bd2f1373SDavid du Colombier 	return nil; /* shut up compiler */
39*bd2f1373SDavid du Colombier }
40*bd2f1373SDavid du Colombier 
41*bd2f1373SDavid du Colombier static void
fdclose(int fd,int flag)42*bd2f1373SDavid du Colombier fdclose(int fd, int flag)
43*bd2f1373SDavid du Colombier {
44*bd2f1373SDavid du Colombier 	int i;
45*bd2f1373SDavid du Colombier 	Chan *c;
46*bd2f1373SDavid du Colombier 	Fgrp *f;
47*bd2f1373SDavid du Colombier 
48*bd2f1373SDavid du Colombier 	f = up->fgrp;
49*bd2f1373SDavid du Colombier 
50*bd2f1373SDavid du Colombier 	lock(&f->ref.lk);
51*bd2f1373SDavid du Colombier 	c = f->fd[fd];
52*bd2f1373SDavid du Colombier 	if(c == 0) {
53*bd2f1373SDavid du Colombier 		unlock(&f->ref.lk);
54*bd2f1373SDavid du Colombier 		return;
55*bd2f1373SDavid du Colombier 	}
56*bd2f1373SDavid du Colombier 	if(flag) {
57*bd2f1373SDavid du Colombier 		if(c==0 || !(c->flag&flag)) {
58*bd2f1373SDavid du Colombier 			unlock(&f->ref.lk);
59*bd2f1373SDavid du Colombier 			return;
60*bd2f1373SDavid du Colombier 		}
61*bd2f1373SDavid du Colombier 	}
62*bd2f1373SDavid du Colombier 	f->fd[fd] = 0;
63*bd2f1373SDavid du Colombier 	if(fd == f->maxfd)
64*bd2f1373SDavid du Colombier 		for(i=fd; --i>=0 && f->fd[i]==0; )
65*bd2f1373SDavid du Colombier 			f->maxfd = i;
66*bd2f1373SDavid du Colombier 
67*bd2f1373SDavid du Colombier 	unlock(&f->ref.lk);
68*bd2f1373SDavid du Colombier 	cclose(c);
69*bd2f1373SDavid du Colombier }
70*bd2f1373SDavid du Colombier 
71*bd2f1373SDavid du Colombier static int
newfd(Chan * c)72*bd2f1373SDavid du Colombier newfd(Chan *c)
73*bd2f1373SDavid du Colombier {
74*bd2f1373SDavid du Colombier 	int i;
75*bd2f1373SDavid du Colombier 	Fgrp *f;
76*bd2f1373SDavid du Colombier 
77*bd2f1373SDavid du Colombier 	f = up->fgrp;
78*bd2f1373SDavid du Colombier 	lock(&f->ref.lk);
79*bd2f1373SDavid du Colombier 	for(i=0; i<NFD; i++)
80*bd2f1373SDavid du Colombier 		if(f->fd[i] == 0){
81*bd2f1373SDavid du Colombier 			if(i > f->maxfd)
82*bd2f1373SDavid du Colombier 				f->maxfd = i;
83*bd2f1373SDavid du Colombier 			f->fd[i] = c;
84*bd2f1373SDavid du Colombier 			unlock(&f->ref.lk);
85*bd2f1373SDavid du Colombier 			return i;
86*bd2f1373SDavid du Colombier 		}
87*bd2f1373SDavid du Colombier 	unlock(&f->ref.lk);
88*bd2f1373SDavid du Colombier 	error("no file descriptors");
89*bd2f1373SDavid du Colombier 	return 0;
90*bd2f1373SDavid du Colombier }
91*bd2f1373SDavid du Colombier 
92*bd2f1373SDavid du Colombier int
sysclose(int fd)93*bd2f1373SDavid du Colombier sysclose(int fd)
94*bd2f1373SDavid du Colombier {
95*bd2f1373SDavid du Colombier 	if(waserror())
96*bd2f1373SDavid du Colombier 		return -1;
97*bd2f1373SDavid du Colombier 
98*bd2f1373SDavid du Colombier 	fdtochan(fd, -1, 0, 0);
99*bd2f1373SDavid du Colombier 	fdclose(fd, 0);
100*bd2f1373SDavid du Colombier 	poperror();
101*bd2f1373SDavid du Colombier 	return 0;
102*bd2f1373SDavid du Colombier }
103*bd2f1373SDavid du Colombier 
104*bd2f1373SDavid du Colombier int
syscreate(char * path,int mode,ulong perm)105*bd2f1373SDavid du Colombier syscreate(char *path, int mode, ulong perm)
106*bd2f1373SDavid du Colombier {
107*bd2f1373SDavid du Colombier 	int fd;
108*bd2f1373SDavid du Colombier 	Chan *c = 0;
109*bd2f1373SDavid du Colombier 
110*bd2f1373SDavid du Colombier 	if(waserror()) {
111*bd2f1373SDavid du Colombier 		cclose(c);
112*bd2f1373SDavid du Colombier 		return -1;
113*bd2f1373SDavid du Colombier 	}
114*bd2f1373SDavid du Colombier 
115*bd2f1373SDavid du Colombier 	openmode(mode);			/* error check only */
116*bd2f1373SDavid du Colombier 	c = namec(path, Acreate, mode, perm);
117*bd2f1373SDavid du Colombier 	fd = newfd((Chan*)c);
118*bd2f1373SDavid du Colombier 	poperror();
119*bd2f1373SDavid du Colombier 	return fd;
120*bd2f1373SDavid du Colombier }
121*bd2f1373SDavid du Colombier 
122*bd2f1373SDavid du Colombier int
sysdup(int old,int new)123*bd2f1373SDavid du Colombier sysdup(int old, int new)
124*bd2f1373SDavid du Colombier {
125*bd2f1373SDavid du Colombier 	Chan *oc;
126*bd2f1373SDavid du Colombier 	Fgrp *f = up->fgrp;
127*bd2f1373SDavid du Colombier 	Chan *c = 0;
128*bd2f1373SDavid du Colombier 
129*bd2f1373SDavid du Colombier 	if(waserror())
130*bd2f1373SDavid du Colombier 		return -1;
131*bd2f1373SDavid du Colombier 
132*bd2f1373SDavid du Colombier 	c = fdtochan(old, -1, 0, 1);
133*bd2f1373SDavid du Colombier 	if(new != -1) {
134*bd2f1373SDavid du Colombier 		if(new < 0 || NFD <= new) {
135*bd2f1373SDavid du Colombier 			cclose(c);
136*bd2f1373SDavid du Colombier 			error(Ebadfd);
137*bd2f1373SDavid du Colombier 		}
138*bd2f1373SDavid du Colombier 		lock(&f->ref.lk);
139*bd2f1373SDavid du Colombier 		if(new > f->maxfd)
140*bd2f1373SDavid du Colombier 			f->maxfd = new;
141*bd2f1373SDavid du Colombier 		oc = f->fd[new];
142*bd2f1373SDavid du Colombier 		f->fd[new] = (Chan*)c;
143*bd2f1373SDavid du Colombier 		unlock(&f->ref.lk);
144*bd2f1373SDavid du Colombier 		if(oc != 0)
145*bd2f1373SDavid du Colombier 			cclose(oc);
146*bd2f1373SDavid du Colombier 	}
147*bd2f1373SDavid du Colombier 	else {
148*bd2f1373SDavid du Colombier 		if(waserror()) {
149*bd2f1373SDavid du Colombier 			cclose(c);
150*bd2f1373SDavid du Colombier 			nexterror();
151*bd2f1373SDavid du Colombier 		}
152*bd2f1373SDavid du Colombier 		new = newfd((Chan*)c);
153*bd2f1373SDavid du Colombier 		poperror();
154*bd2f1373SDavid du Colombier 	}
155*bd2f1373SDavid du Colombier 	poperror();
156*bd2f1373SDavid du Colombier 	return new;
157*bd2f1373SDavid du Colombier }
158*bd2f1373SDavid du Colombier 
159*bd2f1373SDavid du Colombier int
sysfstat(int fd,char * buf)160*bd2f1373SDavid du Colombier sysfstat(int fd, char *buf)
161*bd2f1373SDavid du Colombier {
162*bd2f1373SDavid du Colombier 	Chan *c = 0;
163*bd2f1373SDavid du Colombier 
164*bd2f1373SDavid du Colombier 	if(waserror()) {
165*bd2f1373SDavid du Colombier 		cclose(c);
166*bd2f1373SDavid du Colombier 		return -1;
167*bd2f1373SDavid du Colombier 	}
168*bd2f1373SDavid du Colombier 	c = fdtochan(fd, -1, 0, 1);
169*bd2f1373SDavid du Colombier 	devtab[c->type]->stat((Chan*)c, buf);
170*bd2f1373SDavid du Colombier 	poperror();
171*bd2f1373SDavid du Colombier 	cclose(c);
172*bd2f1373SDavid du Colombier 	return 0;
173*bd2f1373SDavid du Colombier }
174*bd2f1373SDavid du Colombier 
175*bd2f1373SDavid du Colombier int
sysfwstat(int fd,char * buf)176*bd2f1373SDavid du Colombier sysfwstat(int fd, char *buf)
177*bd2f1373SDavid du Colombier {
178*bd2f1373SDavid du Colombier 	Chan *c = 0;
179*bd2f1373SDavid du Colombier 
180*bd2f1373SDavid du Colombier 	if(waserror()) {
181*bd2f1373SDavid du Colombier 		cclose(c);
182*bd2f1373SDavid du Colombier 		return -1;
183*bd2f1373SDavid du Colombier 	}
184*bd2f1373SDavid du Colombier 	nameok(buf);
185*bd2f1373SDavid du Colombier 	c = fdtochan(fd, -1, 1, 1);
186*bd2f1373SDavid du Colombier 	devtab[c->type]->wstat((Chan*)c, buf);
187*bd2f1373SDavid du Colombier 	poperror();
188*bd2f1373SDavid du Colombier 	cclose(c);
189*bd2f1373SDavid du Colombier 	return 0;
190*bd2f1373SDavid du Colombier }
191*bd2f1373SDavid du Colombier 
192*bd2f1373SDavid du Colombier int
syschdir(char * dir)193*bd2f1373SDavid du Colombier syschdir(char *dir)
194*bd2f1373SDavid du Colombier {
195*bd2f1373SDavid du Colombier 	return 0;
196*bd2f1373SDavid du Colombier }
197*bd2f1373SDavid du Colombier 
198*bd2f1373SDavid du Colombier long
bindmount(Chan * c0,char * old,int flag,char * spec)199*bd2f1373SDavid du Colombier bindmount(Chan *c0, char *old, int flag, char *spec)
200*bd2f1373SDavid du Colombier {
201*bd2f1373SDavid du Colombier 	int ret;
202*bd2f1373SDavid du Colombier 	Chan *c1 = 0;
203*bd2f1373SDavid du Colombier 
204*bd2f1373SDavid du Colombier 	if(flag>MMASK || (flag&MORDER) == (MBEFORE|MAFTER))
205*bd2f1373SDavid du Colombier 		error(Ebadarg);
206*bd2f1373SDavid du Colombier 
207*bd2f1373SDavid du Colombier 	c1 = namec(old, Amount, 0, 0);
208*bd2f1373SDavid du Colombier 	if(waserror()){
209*bd2f1373SDavid du Colombier 		cclose(c1);
210*bd2f1373SDavid du Colombier 		nexterror();
211*bd2f1373SDavid du Colombier 	}
212*bd2f1373SDavid du Colombier 
213*bd2f1373SDavid du Colombier 	ret = cmount(c0, c1, flag, spec);
214*bd2f1373SDavid du Colombier 
215*bd2f1373SDavid du Colombier 	poperror();
216*bd2f1373SDavid du Colombier 	cclose(c1);
217*bd2f1373SDavid du Colombier 	return ret;
218*bd2f1373SDavid du Colombier }
219*bd2f1373SDavid du Colombier 
220*bd2f1373SDavid du Colombier int
sysbind(char * new,char * old,int flags)221*bd2f1373SDavid du Colombier sysbind(char *new, char *old, int flags)
222*bd2f1373SDavid du Colombier {
223*bd2f1373SDavid du Colombier 	long r;
224*bd2f1373SDavid du Colombier 	Chan *c0 = 0;
225*bd2f1373SDavid du Colombier 
226*bd2f1373SDavid du Colombier 	if(waserror()) {
227*bd2f1373SDavid du Colombier 		cclose(c0);
228*bd2f1373SDavid du Colombier 		return -1;
229*bd2f1373SDavid du Colombier 	}
230*bd2f1373SDavid du Colombier 	c0 = namec(new, Aaccess, 0, 0);
231*bd2f1373SDavid du Colombier 	r = bindmount(c0, old, flags, "");
232*bd2f1373SDavid du Colombier 	poperror();
233*bd2f1373SDavid du Colombier 	cclose(c0);
234*bd2f1373SDavid du Colombier 	return 0;
235*bd2f1373SDavid du Colombier }
236*bd2f1373SDavid du Colombier 
237*bd2f1373SDavid du Colombier int
sysmount(int fd,char * old,int flags,char * spec)238*bd2f1373SDavid du Colombier sysmount(int fd, char *old, int flags, char *spec)
239*bd2f1373SDavid du Colombier {
240*bd2f1373SDavid du Colombier 	long r;
241*bd2f1373SDavid du Colombier 	Chan *c0 = 0, *bc = 0;
242*bd2f1373SDavid du Colombier 	struct {
243*bd2f1373SDavid du Colombier 		Chan*	chan;
244*bd2f1373SDavid du Colombier 		char*	spec;
245*bd2f1373SDavid du Colombier 		int	flags;
246*bd2f1373SDavid du Colombier 	} mntparam;
247*bd2f1373SDavid du Colombier 
248*bd2f1373SDavid du Colombier 	if(waserror()) {
249*bd2f1373SDavid du Colombier 		cclose(bc);
250*bd2f1373SDavid du Colombier 		cclose(c0);
251*bd2f1373SDavid du Colombier 		return -1;
252*bd2f1373SDavid du Colombier 	}
253*bd2f1373SDavid du Colombier 	bc = fdtochan(fd, ORDWR, 0, 1);
254*bd2f1373SDavid du Colombier 	mntparam.chan = (Chan*)bc;
255*bd2f1373SDavid du Colombier 	mntparam.spec = spec;
256*bd2f1373SDavid du Colombier 	mntparam.flags = flags;
257*bd2f1373SDavid du Colombier 	c0 = (*devtab[devno('M', 0)].attach)(&mntparam);
258*bd2f1373SDavid du Colombier 	cclose(bc);
259*bd2f1373SDavid du Colombier 	r = bindmount(c0, old, flags, spec);
260*bd2f1373SDavid du Colombier 	poperror();
261*bd2f1373SDavid du Colombier 	cclose(c0);
262*bd2f1373SDavid du Colombier 
263*bd2f1373SDavid du Colombier 	return r;
264*bd2f1373SDavid du Colombier }
265*bd2f1373SDavid du Colombier 
266*bd2f1373SDavid du Colombier int
sysunmount(char * old,char * new)267*bd2f1373SDavid du Colombier sysunmount(char *old, char *new)
268*bd2f1373SDavid du Colombier {
269*bd2f1373SDavid du Colombier 	Chan *cmount = 0, *cmounted = 0;
270*bd2f1373SDavid du Colombier 
271*bd2f1373SDavid du Colombier 	if(waserror()) {
272*bd2f1373SDavid du Colombier 		cclose(cmount);
273*bd2f1373SDavid du Colombier 		cclose(cmounted);
274*bd2f1373SDavid du Colombier 		return -1;
275*bd2f1373SDavid du Colombier 	}
276*bd2f1373SDavid du Colombier 
277*bd2f1373SDavid du Colombier 	cmount = namec(new, Amount, OREAD, 0);
278*bd2f1373SDavid du Colombier 	if(old != 0)
279*bd2f1373SDavid du Colombier 		cmounted = namec(old, Aopen, OREAD, 0);
280*bd2f1373SDavid du Colombier 
281*bd2f1373SDavid du Colombier 	cunmount(cmount, cmounted);
282*bd2f1373SDavid du Colombier 	poperror();
283*bd2f1373SDavid du Colombier 	cclose(cmount);
284*bd2f1373SDavid du Colombier 	cclose(cmounted);
285*bd2f1373SDavid du Colombier 	return 0;
286*bd2f1373SDavid du Colombier }
287*bd2f1373SDavid du Colombier 
288*bd2f1373SDavid du Colombier int
sysopen(char * path,int mode)289*bd2f1373SDavid du Colombier sysopen(char *path, int mode)
290*bd2f1373SDavid du Colombier {
291*bd2f1373SDavid du Colombier 	int fd;
292*bd2f1373SDavid du Colombier 	Chan *c = 0;
293*bd2f1373SDavid du Colombier 
294*bd2f1373SDavid du Colombier 	if(waserror()){
295*bd2f1373SDavid du Colombier 		cclose(c);
296*bd2f1373SDavid du Colombier 		return -1;
297*bd2f1373SDavid du Colombier 	}
298*bd2f1373SDavid du Colombier 	openmode(mode);				/* error check only */
299*bd2f1373SDavid du Colombier 	c = namec(path, Aopen, mode, 0);
300*bd2f1373SDavid du Colombier 	fd = newfd((Chan*)c);
301*bd2f1373SDavid du Colombier 	poperror();
302*bd2f1373SDavid du Colombier 	return fd;
303*bd2f1373SDavid du Colombier }
304*bd2f1373SDavid du Colombier 
305*bd2f1373SDavid du Colombier long
unionread(Chan * c,void * va,long n)306*bd2f1373SDavid du Colombier unionread(Chan *c, void *va, long n)
307*bd2f1373SDavid du Colombier {
308*bd2f1373SDavid du Colombier 	long nr;
309*bd2f1373SDavid du Colombier 	Chan *nc = 0;
310*bd2f1373SDavid du Colombier 	Pgrp *pg = 0;
311*bd2f1373SDavid du Colombier 
312*bd2f1373SDavid du Colombier 	pg = up->pgrp;
313*bd2f1373SDavid du Colombier 	rlock(&pg->ns);
314*bd2f1373SDavid du Colombier 
315*bd2f1373SDavid du Colombier 	for(;;) {
316*bd2f1373SDavid du Colombier 		if(waserror()) {
317*bd2f1373SDavid du Colombier 			runlock(&pg->ns);
318*bd2f1373SDavid du Colombier 			nexterror();
319*bd2f1373SDavid du Colombier 		}
320*bd2f1373SDavid du Colombier 		nc = clone(c->mnt->to, 0);
321*bd2f1373SDavid du Colombier 		poperror();
322*bd2f1373SDavid du Colombier 
323*bd2f1373SDavid du Colombier 		if(c->mountid != c->mnt->mountid) {
324*bd2f1373SDavid du Colombier 			runlock(&pg->ns);
325*bd2f1373SDavid du Colombier 			cclose(nc);
326*bd2f1373SDavid du Colombier 			return 0;
327*bd2f1373SDavid du Colombier 		}
328*bd2f1373SDavid du Colombier 
329*bd2f1373SDavid du Colombier 		/* Error causes component of union to be skipped */
330*bd2f1373SDavid du Colombier 		if(waserror()) {
331*bd2f1373SDavid du Colombier 			cclose(nc);
332*bd2f1373SDavid du Colombier 			goto next;
333*bd2f1373SDavid du Colombier 		}
334*bd2f1373SDavid du Colombier 
335*bd2f1373SDavid du Colombier 		nc = (*devtab[nc->type].open)((Chan*)nc, OREAD);
336*bd2f1373SDavid du Colombier 		nc->offset = c->offset;
337*bd2f1373SDavid du Colombier 		nr = (*devtab[nc->type].read)((Chan*)nc, va, n, nc->offset);
338*bd2f1373SDavid du Colombier 		/* devdirread e.g. changes it */
339*bd2f1373SDavid du Colombier 		c->offset = nc->offset;
340*bd2f1373SDavid du Colombier 		poperror();
341*bd2f1373SDavid du Colombier 
342*bd2f1373SDavid du Colombier 		cclose(nc);
343*bd2f1373SDavid du Colombier 		if(nr > 0) {
344*bd2f1373SDavid du Colombier 			runlock(&pg->ns);
345*bd2f1373SDavid du Colombier 			return nr;
346*bd2f1373SDavid du Colombier 		}
347*bd2f1373SDavid du Colombier 		/* Advance to next element */
348*bd2f1373SDavid du Colombier 	next:
349*bd2f1373SDavid du Colombier 		c->mnt = c->mnt->next;
350*bd2f1373SDavid du Colombier 		if(c->mnt == 0)
351*bd2f1373SDavid du Colombier 			break;
352*bd2f1373SDavid du Colombier 		c->mountid = c->mnt->mountid;
353*bd2f1373SDavid du Colombier 		c->offset = 0;
354*bd2f1373SDavid du Colombier 	}
355*bd2f1373SDavid du Colombier 	runlock(&pg->ns);
356*bd2f1373SDavid du Colombier 	return 0;
357*bd2f1373SDavid du Colombier }
358*bd2f1373SDavid du Colombier 
359*bd2f1373SDavid du Colombier long
sysread(int fd,void * va,long n)360*bd2f1373SDavid du Colombier sysread(int fd, void *va, long n)
361*bd2f1373SDavid du Colombier {
362*bd2f1373SDavid du Colombier 	int dir;
363*bd2f1373SDavid du Colombier 	Lock *cl;
364*bd2f1373SDavid du Colombier 	Chan *c = 0;
365*bd2f1373SDavid du Colombier 
366*bd2f1373SDavid du Colombier 	if(waserror()) {
367*bd2f1373SDavid du Colombier 		cclose(c);
368*bd2f1373SDavid du Colombier 		return -1;
369*bd2f1373SDavid du Colombier 	}
370*bd2f1373SDavid du Colombier 	c = fdtochan(fd, OREAD, 1, 1);
371*bd2f1373SDavid du Colombier 
372*bd2f1373SDavid du Colombier 	dir = c->qid.path&CHDIR;
373*bd2f1373SDavid du Colombier 	if(dir) {
374*bd2f1373SDavid du Colombier 		n -= n%DIRLEN;
375*bd2f1373SDavid du Colombier 		if(c->offset%DIRLEN || n==0)
376*bd2f1373SDavid du Colombier 			error(Etoosmall);
377*bd2f1373SDavid du Colombier 	}
378*bd2f1373SDavid du Colombier 
379*bd2f1373SDavid du Colombier 	if(dir && c->mnt)
380*bd2f1373SDavid du Colombier 		n = unionread((Chan*)c, va, n);
381*bd2f1373SDavid du Colombier 	else
382*bd2f1373SDavid du Colombier 		n = (*devtab[c->type].read)((Chan*)c, va, n, c->offset);
383*bd2f1373SDavid du Colombier 
384*bd2f1373SDavid du Colombier 	cl = (Lock*)&c->r.l;
385*bd2f1373SDavid du Colombier 	lock(cl);
386*bd2f1373SDavid du Colombier 	c->offset += n;
387*bd2f1373SDavid du Colombier 	unlock(cl);
388*bd2f1373SDavid du Colombier 
389*bd2f1373SDavid du Colombier 	poperror();
390*bd2f1373SDavid du Colombier 	cclose(c);
391*bd2f1373SDavid du Colombier 
392*bd2f1373SDavid du Colombier 	return n;
393*bd2f1373SDavid du Colombier }
394*bd2f1373SDavid du Colombier 
395*bd2f1373SDavid du Colombier int
sysremove(char * path)396*bd2f1373SDavid du Colombier sysremove(char *path)
397*bd2f1373SDavid du Colombier {
398*bd2f1373SDavid du Colombier 	Chan *c = 0;
399*bd2f1373SDavid du Colombier 
400*bd2f1373SDavid du Colombier 	if(waserror()) {
401*bd2f1373SDavid du Colombier 		if(c != 0)
402*bd2f1373SDavid du Colombier 			c->type = 0;	/* see below */
403*bd2f1373SDavid du Colombier 		cclose(c);
404*bd2f1373SDavid du Colombier 		return -1;
405*bd2f1373SDavid du Colombier 	}
406*bd2f1373SDavid du Colombier 	c = namec(path, Aaccess, 0, 0);
407*bd2f1373SDavid du Colombier 	(*devtab[c->type].remove)((Chan*)c);
408*bd2f1373SDavid du Colombier 	/*
409*bd2f1373SDavid du Colombier 	 * Remove clunks the fid, but we need to recover the Chan
410*bd2f1373SDavid du Colombier 	 * so fake it up.  rootclose() is known to be a nop.
411*bd2f1373SDavid du Colombier 	 */
412*bd2f1373SDavid du Colombier 	c->type = 0;
413*bd2f1373SDavid du Colombier 	poperror();
414*bd2f1373SDavid du Colombier 	cclose(c);
415*bd2f1373SDavid du Colombier 	return 0;
416*bd2f1373SDavid du Colombier }
417*bd2f1373SDavid du Colombier 
418*bd2f1373SDavid du Colombier long
sysseek(int fd,long off,int whence)419*bd2f1373SDavid du Colombier sysseek(int fd, long off, int whence)
420*bd2f1373SDavid du Colombier {
421*bd2f1373SDavid du Colombier 	Dir dir;
422*bd2f1373SDavid du Colombier 	Chan *c;
423*bd2f1373SDavid du Colombier 	char buf[DIRLEN];
424*bd2f1373SDavid du Colombier 
425*bd2f1373SDavid du Colombier 	if(waserror())
426*bd2f1373SDavid du Colombier 		return -1;
427*bd2f1373SDavid du Colombier 
428*bd2f1373SDavid du Colombier 	c = fdtochan(fd, -1, 1, 0);
429*bd2f1373SDavid du Colombier 	if(c->qid.path & CHDIR)
430*bd2f1373SDavid du Colombier 		error(Eisdir);
431*bd2f1373SDavid du Colombier 
432*bd2f1373SDavid du Colombier 	switch(whence) {
433*bd2f1373SDavid du Colombier 	case 0:
434*bd2f1373SDavid du Colombier 		c->offset = off;
435*bd2f1373SDavid du Colombier 		break;
436*bd2f1373SDavid du Colombier 
437*bd2f1373SDavid du Colombier 	case 1:
438*bd2f1373SDavid du Colombier 		lock(&c->r.l);	/* lock for read/write update */
439*bd2f1373SDavid du Colombier 		c->offset += off;
440*bd2f1373SDavid du Colombier 		off = c->offset;
441*bd2f1373SDavid du Colombier 		unlock(&c->r.l);
442*bd2f1373SDavid du Colombier 		break;
443*bd2f1373SDavid du Colombier 
444*bd2f1373SDavid du Colombier 	case 2:
445*bd2f1373SDavid du Colombier 		(*devtab[c->type].stat)(c, buf);
446*bd2f1373SDavid du Colombier 		convM2D(buf, &dir);
447*bd2f1373SDavid du Colombier 		c->offset = dir.length + off;
448*bd2f1373SDavid du Colombier 		off = c->offset;
449*bd2f1373SDavid du Colombier 		break;
450*bd2f1373SDavid du Colombier 	}
451*bd2f1373SDavid du Colombier 	poperror();
452*bd2f1373SDavid du Colombier 	return off;
453*bd2f1373SDavid du Colombier }
454*bd2f1373SDavid du Colombier 
455*bd2f1373SDavid du Colombier int
sysstat(char * path,char * buf)456*bd2f1373SDavid du Colombier sysstat(char *path, char *buf)
457*bd2f1373SDavid du Colombier {
458*bd2f1373SDavid du Colombier 	Chan *c = 0;
459*bd2f1373SDavid du Colombier 
460*bd2f1373SDavid du Colombier 	if(waserror()){
461*bd2f1373SDavid du Colombier 		cclose(c);
462*bd2f1373SDavid du Colombier 		return -1;
463*bd2f1373SDavid du Colombier 	}
464*bd2f1373SDavid du Colombier 	c = namec(path, Aaccess, 0, 0);
465*bd2f1373SDavid du Colombier 	(*devtab[c->type].stat)((Chan*)c, buf);
466*bd2f1373SDavid du Colombier 	poperror();
467*bd2f1373SDavid du Colombier 	cclose(c);
468*bd2f1373SDavid du Colombier 	return 0;
469*bd2f1373SDavid du Colombier }
470*bd2f1373SDavid du Colombier 
471*bd2f1373SDavid du Colombier long
syswrite(int fd,void * va,long n)472*bd2f1373SDavid du Colombier syswrite(int fd, void *va, long n)
473*bd2f1373SDavid du Colombier {
474*bd2f1373SDavid du Colombier 	Lock *cl;
475*bd2f1373SDavid du Colombier 	Chan *c = 0;
476*bd2f1373SDavid du Colombier 
477*bd2f1373SDavid du Colombier 	if(waserror()) {
478*bd2f1373SDavid du Colombier 		cclose(c);
479*bd2f1373SDavid du Colombier 		return -1;
480*bd2f1373SDavid du Colombier 	}
481*bd2f1373SDavid du Colombier 	c = fdtochan(fd, OWRITE, 1, 1);
482*bd2f1373SDavid du Colombier 	if(c->qid.path & CHDIR)
483*bd2f1373SDavid du Colombier 		error(Eisdir);
484*bd2f1373SDavid du Colombier 
485*bd2f1373SDavid du Colombier 	n = (*devtab[c->type].write)((Chan*)c, va, n, c->offset);
486*bd2f1373SDavid du Colombier 
487*bd2f1373SDavid du Colombier 	cl = (Lock*)&c->r.l;
488*bd2f1373SDavid du Colombier 	lock(cl);
489*bd2f1373SDavid du Colombier 	c->offset += n;
490*bd2f1373SDavid du Colombier 	unlock(cl);
491*bd2f1373SDavid du Colombier 
492*bd2f1373SDavid du Colombier 	poperror();
493*bd2f1373SDavid du Colombier 	cclose(c);
494*bd2f1373SDavid du Colombier 
495*bd2f1373SDavid du Colombier 	return n;
496*bd2f1373SDavid du Colombier }
497*bd2f1373SDavid du Colombier 
498*bd2f1373SDavid du Colombier int
syswstat(char * path,char * buf)499*bd2f1373SDavid du Colombier syswstat(char *path, char *buf)
500*bd2f1373SDavid du Colombier {
501*bd2f1373SDavid du Colombier 	Chan *c = 0;
502*bd2f1373SDavid du Colombier 
503*bd2f1373SDavid du Colombier 	if(waserror()) {
504*bd2f1373SDavid du Colombier 		cclose(c);
505*bd2f1373SDavid du Colombier 		return -1;
506*bd2f1373SDavid du Colombier 	}
507*bd2f1373SDavid du Colombier 
508*bd2f1373SDavid du Colombier 	nameok(buf);
509*bd2f1373SDavid du Colombier 	c = namec(path, Aaccess, 0, 0);
510*bd2f1373SDavid du Colombier 	(*devtab[c->type].wstat)((Chan*)c, buf);
511*bd2f1373SDavid du Colombier 	poperror();
512*bd2f1373SDavid du Colombier 	cclose(c);
513*bd2f1373SDavid du Colombier 	return 0;
514*bd2f1373SDavid du Colombier }
515*bd2f1373SDavid du Colombier 
516*bd2f1373SDavid du Colombier int
sysdirstat(char * name,Dir * dir)517*bd2f1373SDavid du Colombier sysdirstat(char *name, Dir *dir)
518*bd2f1373SDavid du Colombier {
519*bd2f1373SDavid du Colombier 	char buf[DIRLEN];
520*bd2f1373SDavid du Colombier 
521*bd2f1373SDavid du Colombier 	if(sysstat(name, buf) == -1)
522*bd2f1373SDavid du Colombier 		return -1;
523*bd2f1373SDavid du Colombier 	convM2D(buf, dir);
524*bd2f1373SDavid du Colombier 	return 0;
525*bd2f1373SDavid du Colombier }
526*bd2f1373SDavid du Colombier 
527*bd2f1373SDavid du Colombier int
sysdirfstat(int fd,Dir * dir)528*bd2f1373SDavid du Colombier sysdirfstat(int fd, Dir *dir)
529*bd2f1373SDavid du Colombier {
530*bd2f1373SDavid du Colombier 	char buf[DIRLEN];
531*bd2f1373SDavid du Colombier 
532*bd2f1373SDavid du Colombier 	if(sysfstat(fd, buf) == -1)
533*bd2f1373SDavid du Colombier 		return -1;
534*bd2f1373SDavid du Colombier 
535*bd2f1373SDavid du Colombier 	convM2D(buf, dir);
536*bd2f1373SDavid du Colombier 	return 0;
537*bd2f1373SDavid du Colombier }
538*bd2f1373SDavid du Colombier 
539*bd2f1373SDavid du Colombier int
sysdirwstat(char * name,Dir * dir)540*bd2f1373SDavid du Colombier sysdirwstat(char *name, Dir *dir)
541*bd2f1373SDavid du Colombier {
542*bd2f1373SDavid du Colombier 	char buf[DIRLEN];
543*bd2f1373SDavid du Colombier 
544*bd2f1373SDavid du Colombier 	convD2M(dir, buf);
545*bd2f1373SDavid du Colombier 	return syswstat(name, buf);
546*bd2f1373SDavid du Colombier }
547*bd2f1373SDavid du Colombier 
548*bd2f1373SDavid du Colombier int
sysdirfwstat(int fd,Dir * dir)549*bd2f1373SDavid du Colombier sysdirfwstat(int fd, Dir *dir)
550*bd2f1373SDavid du Colombier {
551*bd2f1373SDavid du Colombier 	char buf[DIRLEN];
552*bd2f1373SDavid du Colombier 
553*bd2f1373SDavid du Colombier 	convD2M(dir, buf);
554*bd2f1373SDavid du Colombier 	return sysfwstat(fd, buf);
555*bd2f1373SDavid du Colombier }
556*bd2f1373SDavid du Colombier 
557*bd2f1373SDavid du Colombier long
sysdirread(int fd,Dir * dbuf,long count)558*bd2f1373SDavid du Colombier sysdirread(int fd, Dir *dbuf, long count)
559*bd2f1373SDavid du Colombier {
560*bd2f1373SDavid du Colombier 	int c, n, i, r;
561*bd2f1373SDavid du Colombier 	char buf[DIRLEN*50];
562*bd2f1373SDavid du Colombier 
563*bd2f1373SDavid du Colombier 	n = 0;
564*bd2f1373SDavid du Colombier 	count = (count/sizeof(Dir)) * DIRLEN;
565*bd2f1373SDavid du Colombier 	while(n < count) {
566*bd2f1373SDavid du Colombier 		c = count - n;
567*bd2f1373SDavid du Colombier 		if(c > sizeof(buf))
568*bd2f1373SDavid du Colombier 			c = sizeof(buf);
569*bd2f1373SDavid du Colombier 		r = sysread(fd, buf, c);
570*bd2f1373SDavid du Colombier 		if(r == 0)
571*bd2f1373SDavid du Colombier 			break;
572*bd2f1373SDavid du Colombier 		if(r < 0 || r % DIRLEN)
573*bd2f1373SDavid du Colombier 			return -1;
574*bd2f1373SDavid du Colombier 		for(i=0; i<r; i+=DIRLEN) {
575*bd2f1373SDavid du Colombier 			convM2D(buf+i, dbuf);
576*bd2f1373SDavid du Colombier 			dbuf++;
577*bd2f1373SDavid du Colombier 		}
578*bd2f1373SDavid du Colombier 		n += r;
579*bd2f1373SDavid du Colombier 		if(r != c)
580*bd2f1373SDavid du Colombier 			break;
581*bd2f1373SDavid du Colombier 	}
582*bd2f1373SDavid du Colombier 
583*bd2f1373SDavid du Colombier 	return (n/DIRLEN) * sizeof(Dir);
584*bd2f1373SDavid du Colombier }
585*bd2f1373SDavid du Colombier 
586*bd2f1373SDavid du Colombier static int
call(char * clone,char * dest,int * cfdp,char * dir,char * local)587*bd2f1373SDavid du Colombier call(char *clone, char *dest, int *cfdp, char *dir, char *local)
588*bd2f1373SDavid du Colombier {
589*bd2f1373SDavid du Colombier 	int fd, cfd, n;
590*bd2f1373SDavid du Colombier 	char *p, name[3*NAMELEN+5], data[3*NAMELEN+10];
591*bd2f1373SDavid du Colombier 
592*bd2f1373SDavid du Colombier 	cfd = sysopen(clone, ORDWR);
593*bd2f1373SDavid du Colombier 	if(cfd < 0){
594*bd2f1373SDavid du Colombier 		werrstr("%s: %r", clone);
595*bd2f1373SDavid du Colombier 		return -1;
596*bd2f1373SDavid du Colombier 	}
597*bd2f1373SDavid du Colombier 
598*bd2f1373SDavid du Colombier 	/* get directory name */
599*bd2f1373SDavid du Colombier 	n = sysread(cfd, name, sizeof(name)-1);
600*bd2f1373SDavid du Colombier 	if(n < 0) {
601*bd2f1373SDavid du Colombier 		sysclose(cfd);
602*bd2f1373SDavid du Colombier 		return -1;
603*bd2f1373SDavid du Colombier 	}
604*bd2f1373SDavid du Colombier 	name[n] = 0;
605*bd2f1373SDavid du Colombier 	sprint(name, "%d", strtoul(name, 0, 0));
606*bd2f1373SDavid du Colombier 	p = strrchr(clone, '/');
607*bd2f1373SDavid du Colombier 	*p = 0;
608*bd2f1373SDavid du Colombier 	if(dir)
609*bd2f1373SDavid du Colombier 		snprint(dir, 2*NAMELEN, "%s/%s", clone, name);
610*bd2f1373SDavid du Colombier 	snprint(data, sizeof(data), "%s/%s/data", clone, name);
611*bd2f1373SDavid du Colombier 
612*bd2f1373SDavid du Colombier 	/* connect */
613*bd2f1373SDavid du Colombier 	/* set local side (port number, for example) if we need to */
614*bd2f1373SDavid du Colombier 	if(local)
615*bd2f1373SDavid du Colombier 		snprint(name, sizeof(name), "connect %s %s", dest, local);
616*bd2f1373SDavid du Colombier 	else
617*bd2f1373SDavid du Colombier 		snprint(name, sizeof(name), "connect %s", dest);
618*bd2f1373SDavid du Colombier 	if(syswrite(cfd, name, strlen(name)) < 0){
619*bd2f1373SDavid du Colombier 		werrstr("%s failed: %r", name);
620*bd2f1373SDavid du Colombier 		sysclose(cfd);
621*bd2f1373SDavid du Colombier 		return -1;
622*bd2f1373SDavid du Colombier 	}
623*bd2f1373SDavid du Colombier 
624*bd2f1373SDavid du Colombier 	/* open data connection */
625*bd2f1373SDavid du Colombier 	fd = sysopen(data, ORDWR);
626*bd2f1373SDavid du Colombier 	if(fd < 0){
627*bd2f1373SDavid du Colombier 		werrstr("can't open %s: %r", data);
628*bd2f1373SDavid du Colombier 		sysclose(cfd);
629*bd2f1373SDavid du Colombier 		return -1;
630*bd2f1373SDavid du Colombier 	}
631*bd2f1373SDavid du Colombier 	if(cfdp)
632*bd2f1373SDavid du Colombier 		*cfdp = cfd;
633*bd2f1373SDavid du Colombier 	else
634*bd2f1373SDavid du Colombier 		sysclose(cfd);
635*bd2f1373SDavid du Colombier 	return fd;
636*bd2f1373SDavid du Colombier }
637*bd2f1373SDavid du Colombier 
638*bd2f1373SDavid du Colombier int
sysdial(char * dest,char * local,char * dir,int * cfdp)639*bd2f1373SDavid du Colombier sysdial(char *dest, char *local, char *dir, int *cfdp)
640*bd2f1373SDavid du Colombier {
641*bd2f1373SDavid du Colombier 	int n, fd, rv;
642*bd2f1373SDavid du Colombier 	char *p, net[128], clone[NAMELEN+12];
643*bd2f1373SDavid du Colombier 
644*bd2f1373SDavid du Colombier 	/* go for a standard form net!... */
645*bd2f1373SDavid du Colombier 	p = strchr(dest, '!');
646*bd2f1373SDavid du Colombier 	if(p == 0){
647*bd2f1373SDavid du Colombier 		snprint(net, sizeof(net), "net!%s", dest);
648*bd2f1373SDavid du Colombier 	} else {
649*bd2f1373SDavid du Colombier 		strncpy(net, dest, sizeof(net)-1);
650*bd2f1373SDavid du Colombier 		net[sizeof(net)-1] = 0;
651*bd2f1373SDavid du Colombier 	}
652*bd2f1373SDavid du Colombier 
653*bd2f1373SDavid du Colombier 	/* call the connection server */
654*bd2f1373SDavid du Colombier 	fd = sysopen("/net/cs", ORDWR);
655*bd2f1373SDavid du Colombier 	if(fd < 0){
656*bd2f1373SDavid du Colombier 		/* no connection server, don't translate */
657*bd2f1373SDavid du Colombier 		p = strchr(net, '!');
658*bd2f1373SDavid du Colombier 		*p++ = 0;
659*bd2f1373SDavid du Colombier 		snprint(clone, sizeof(clone), "/net/%s/clone", net);
660*bd2f1373SDavid du Colombier 		return call(clone, p, cfdp, dir, local);
661*bd2f1373SDavid du Colombier 	}
662*bd2f1373SDavid du Colombier 
663*bd2f1373SDavid du Colombier 	/*
664*bd2f1373SDavid du Colombier 	 *  send dest to connection to translate
665*bd2f1373SDavid du Colombier 	 */
666*bd2f1373SDavid du Colombier 	if(syswrite(fd, net, strlen(net)) < 0){
667*bd2f1373SDavid du Colombier 		werrstr("%s: %r", net);
668*bd2f1373SDavid du Colombier 		sysclose(fd);
669*bd2f1373SDavid du Colombier 		return -1;
670*bd2f1373SDavid du Colombier 	}
671*bd2f1373SDavid du Colombier 
672*bd2f1373SDavid du Colombier 	/*
673*bd2f1373SDavid du Colombier 	 *  loop through each address from the connection server till
674*bd2f1373SDavid du Colombier 	 *  we get one that works.
675*bd2f1373SDavid du Colombier 	 */
676*bd2f1373SDavid du Colombier 	rv = -1;
677*bd2f1373SDavid du Colombier 	sysseek(fd, 0, 0);
678*bd2f1373SDavid du Colombier 	while((n = sysread(fd, net, sizeof(net) - 1)) > 0){
679*bd2f1373SDavid du Colombier 		net[n] = 0;
680*bd2f1373SDavid du Colombier 		p = strchr(net, ' ');
681*bd2f1373SDavid du Colombier 		if(p == 0)
682*bd2f1373SDavid du Colombier 			continue;
683*bd2f1373SDavid du Colombier 		*p++ = 0;
684*bd2f1373SDavid du Colombier 		rv = call(net, p, cfdp, dir, local);
685*bd2f1373SDavid du Colombier 		if(rv >= 0)
686*bd2f1373SDavid du Colombier 			break;
687*bd2f1373SDavid du Colombier 	}
688*bd2f1373SDavid du Colombier 	sysclose(fd);
689*bd2f1373SDavid du Colombier 	return rv;
690*bd2f1373SDavid du Colombier }
691*bd2f1373SDavid du Colombier 
692*bd2f1373SDavid du Colombier static int
identtrans(char * addr,char * naddr,int na,char * file,int nf)693*bd2f1373SDavid du Colombier identtrans(char *addr, char *naddr, int na, char *file, int nf)
694*bd2f1373SDavid du Colombier {
695*bd2f1373SDavid du Colombier 	char *p;
696*bd2f1373SDavid du Colombier 	char reply[4*NAMELEN];
697*bd2f1373SDavid du Colombier 
698*bd2f1373SDavid du Colombier 	/* parse the network */
699*bd2f1373SDavid du Colombier 	strncpy(reply, addr, sizeof(reply));
700*bd2f1373SDavid du Colombier 	reply[sizeof(reply)-1] = 0;
701*bd2f1373SDavid du Colombier 	p = strchr(reply, '!');
702*bd2f1373SDavid du Colombier 	if(p)
703*bd2f1373SDavid du Colombier 		*p++ = 0;
704*bd2f1373SDavid du Colombier 
705*bd2f1373SDavid du Colombier 	sprint(file, "/net/%.*s/clone", na - sizeof("/net//clone"), reply);
706*bd2f1373SDavid du Colombier 	strncpy(naddr, p, na);
707*bd2f1373SDavid du Colombier 	naddr[na-1] = 0;
708*bd2f1373SDavid du Colombier 	return 1;
709*bd2f1373SDavid du Colombier }
710*bd2f1373SDavid du Colombier 
711*bd2f1373SDavid du Colombier static int
nettrans(char * addr,char * naddr,int na,char * file,int nf)712*bd2f1373SDavid du Colombier nettrans(char *addr, char *naddr, int na, char *file, int nf)
713*bd2f1373SDavid du Colombier {
714*bd2f1373SDavid du Colombier 	long n;
715*bd2f1373SDavid du Colombier 	int fd;
716*bd2f1373SDavid du Colombier 	char *cp;
717*bd2f1373SDavid du Colombier 	char reply[4*NAMELEN];
718*bd2f1373SDavid du Colombier 
719*bd2f1373SDavid du Colombier 	/*
720*bd2f1373SDavid du Colombier 	 *  ask the connection server
721*bd2f1373SDavid du Colombier 	 */
722*bd2f1373SDavid du Colombier 	fd = sysopen("/net/cs", ORDWR);
723*bd2f1373SDavid du Colombier 	if(fd < 0)
724*bd2f1373SDavid du Colombier 		return identtrans(addr, naddr, na, file, nf);
725*bd2f1373SDavid du Colombier 	if(syswrite(fd, addr, strlen(addr)) < 0){
726*bd2f1373SDavid du Colombier 		sysclose(fd);
727*bd2f1373SDavid du Colombier 		return -1;
728*bd2f1373SDavid du Colombier 	}
729*bd2f1373SDavid du Colombier 	sysseek(fd, 0, 0);
730*bd2f1373SDavid du Colombier 	n = sysread(fd, reply, sizeof(reply)-1);
731*bd2f1373SDavid du Colombier 	sysclose(fd);
732*bd2f1373SDavid du Colombier 	if(n <= 0)
733*bd2f1373SDavid du Colombier 		return -1;
734*bd2f1373SDavid du Colombier 	reply[n] = '\0';
735*bd2f1373SDavid du Colombier 
736*bd2f1373SDavid du Colombier 	/*
737*bd2f1373SDavid du Colombier 	 *  parse the reply
738*bd2f1373SDavid du Colombier 	 */
739*bd2f1373SDavid du Colombier 	cp = strchr(reply, ' ');
740*bd2f1373SDavid du Colombier 	if(cp == 0)
741*bd2f1373SDavid du Colombier 		return -1;
742*bd2f1373SDavid du Colombier 	*cp++ = 0;
743*bd2f1373SDavid du Colombier 	strncpy(naddr, cp, na);
744*bd2f1373SDavid du Colombier 	naddr[na-1] = 0;
745*bd2f1373SDavid du Colombier 	strncpy(file, reply, nf);
746*bd2f1373SDavid du Colombier 	file[nf-1] = 0;
747*bd2f1373SDavid du Colombier 	return 0;
748*bd2f1373SDavid du Colombier }
749*bd2f1373SDavid du Colombier 
750*bd2f1373SDavid du Colombier int
sysannounce(char * addr,char * dir)751*bd2f1373SDavid du Colombier sysannounce(char *addr, char *dir)
752*bd2f1373SDavid du Colombier {
753*bd2f1373SDavid du Colombier 	char *cp;
754*bd2f1373SDavid du Colombier 	int ctl, n, m;
755*bd2f1373SDavid du Colombier 	char buf[3*NAMELEN];
756*bd2f1373SDavid du Colombier 	char buf2[3*NAMELEN];
757*bd2f1373SDavid du Colombier 	char netdir[2*NAMELEN];
758*bd2f1373SDavid du Colombier 	char naddr[3*NAMELEN];
759*bd2f1373SDavid du Colombier 
760*bd2f1373SDavid du Colombier 	/*
761*bd2f1373SDavid du Colombier 	 *  translate the address
762*bd2f1373SDavid du Colombier 	 */
763*bd2f1373SDavid du Colombier 	if(nettrans(addr, naddr, sizeof(naddr), netdir, sizeof(netdir)) < 0){
764*bd2f1373SDavid du Colombier 		werrstr("can't translate address");
765*bd2f1373SDavid du Colombier 		return -1;
766*bd2f1373SDavid du Colombier 	}
767*bd2f1373SDavid du Colombier 
768*bd2f1373SDavid du Colombier 	/*
769*bd2f1373SDavid du Colombier 	 * get a control channel
770*bd2f1373SDavid du Colombier 	 */
771*bd2f1373SDavid du Colombier 	ctl = sysopen(netdir, ORDWR);
772*bd2f1373SDavid du Colombier 	if(ctl<0){
773*bd2f1373SDavid du Colombier 		werrstr("can't open control channel");
774*bd2f1373SDavid du Colombier 		return -1;
775*bd2f1373SDavid du Colombier 	}
776*bd2f1373SDavid du Colombier 	cp = strrchr(netdir, '/');
777*bd2f1373SDavid du Colombier 	*cp = 0;
778*bd2f1373SDavid du Colombier 
779*bd2f1373SDavid du Colombier 	/*
780*bd2f1373SDavid du Colombier 	 *  find out which line we have
781*bd2f1373SDavid du Colombier 	 */
782*bd2f1373SDavid du Colombier 	n = sprint(buf, "%.*s/", 2*NAMELEN+1, netdir);
783*bd2f1373SDavid du Colombier 	m = sysread(ctl, &buf[n], sizeof(buf)-n-1);
784*bd2f1373SDavid du Colombier 	if(m <= 0) {
785*bd2f1373SDavid du Colombier 		sysclose(ctl);
786*bd2f1373SDavid du Colombier 		werrstr("can't read control file");
787*bd2f1373SDavid du Colombier 		return -1;
788*bd2f1373SDavid du Colombier 	}
789*bd2f1373SDavid du Colombier 	buf[n+m] = 0;
790*bd2f1373SDavid du Colombier 
791*bd2f1373SDavid du Colombier 	/*
792*bd2f1373SDavid du Colombier 	 *  make the call
793*bd2f1373SDavid du Colombier 	 */
794*bd2f1373SDavid du Colombier 	n = sprint(buf2, "announce %.*s", 2*NAMELEN, naddr);
795*bd2f1373SDavid du Colombier 	if(syswrite(ctl, buf2, n) != n) {
796*bd2f1373SDavid du Colombier 		sysclose(ctl);
797*bd2f1373SDavid du Colombier 		werrstr("announcement fails");
798*bd2f1373SDavid du Colombier 		return -1;
799*bd2f1373SDavid du Colombier 	}
800*bd2f1373SDavid du Colombier 
801*bd2f1373SDavid du Colombier 	strcpy(dir, buf);
802*bd2f1373SDavid du Colombier 
803*bd2f1373SDavid du Colombier 	return ctl;
804*bd2f1373SDavid du Colombier }
805*bd2f1373SDavid du Colombier 
806*bd2f1373SDavid du Colombier int
syslisten(char * dir,char * newdir)807*bd2f1373SDavid du Colombier syslisten(char *dir, char *newdir)
808*bd2f1373SDavid du Colombier {
809*bd2f1373SDavid du Colombier 	char *cp;
810*bd2f1373SDavid du Colombier 	int ctl, n, m;
811*bd2f1373SDavid du Colombier 	char buf[3*NAMELEN];
812*bd2f1373SDavid du Colombier 
813*bd2f1373SDavid du Colombier 	/*
814*bd2f1373SDavid du Colombier 	 *  open listen, wait for a call
815*bd2f1373SDavid du Colombier 	 */
816*bd2f1373SDavid du Colombier 	sprint(buf, "%.*s/listen", 2*NAMELEN+1, dir);
817*bd2f1373SDavid du Colombier 	ctl = sysopen(buf, ORDWR);
818*bd2f1373SDavid du Colombier 	if(ctl < 0)
819*bd2f1373SDavid du Colombier 		return -1;
820*bd2f1373SDavid du Colombier 
821*bd2f1373SDavid du Colombier 	/*
822*bd2f1373SDavid du Colombier 	 *  find out which line we have
823*bd2f1373SDavid du Colombier 	 */
824*bd2f1373SDavid du Colombier 	strcpy(buf, dir);
825*bd2f1373SDavid du Colombier 	cp = strrchr(buf, '/');
826*bd2f1373SDavid du Colombier 	*++cp = 0;
827*bd2f1373SDavid du Colombier 	n = cp-buf;
828*bd2f1373SDavid du Colombier 	m = sysread(ctl, cp, sizeof(buf) - n - 1);
829*bd2f1373SDavid du Colombier 	if(n<=0){
830*bd2f1373SDavid du Colombier 		sysclose(ctl);
831*bd2f1373SDavid du Colombier 		return -1;
832*bd2f1373SDavid du Colombier 	}
833*bd2f1373SDavid du Colombier 	buf[n+m] = 0;
834*bd2f1373SDavid du Colombier 
835*bd2f1373SDavid du Colombier 	strcpy(newdir, buf);
836*bd2f1373SDavid du Colombier 	return ctl;
837*bd2f1373SDavid du Colombier }
838