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