11 Maxiosize = IOHDRSZ+Maxfdata,
30 static int openflags(int);
31 static void usage(void);
33 #define Reqsize (sizeof(Fcall)+Maxfdata)
38 uchar mdata[Maxiosize];
40 uchar statbuf[STATMAX];
43 static char srvfile[64];
45 extern Xfsub *xsublist[];
57 void (*fcalls[])(void) = {
74 main(int argc, char **argv)
76 int srvfd, pipefd[2], stdio;
85 nclust = atoi(EARGF(usage()));
87 sysfatal("nclust %d non-positive", nclust);
90 deffile = EARGF(usage());
119 for(xs=xsublist; *xs; xs++)
128 open("/dev/null", OREAD);
129 open("/dev/null", OWRITE);
132 sprint(srvfile, "/srv/%s", srvname);
133 srvfd = create(srvfile, OWRITE|ORCLOSE, 0600);
136 fprint(srvfd, "%d", pipefd[0]);
138 fprint(2, "%s %d: serving %s\n", argv0, getpid(), srvfile);
142 switch(rfork(RFNOWAIT|RFNOTEG|RFFDG|RFPROC|RFNAMEG)){
164 fmtinstall('F', fcallfmt);
166 while((n = read9pmsg(srvfd, mdata, sizeof mdata)) != 0){
168 panic(1, "mount read");
169 if(convM2S(mdata, n, req) != n)
170 panic(1, "convM2S format error");
173 fprint(2, "9660srv %d:<-%F\n", pid, req);
178 if(req->type >= nelem(fcalls) || !fcalls[req->type])
179 error("bad fcall type");
180 (*fcalls[req->type])();
186 rep->ename = err_msg;
188 rep->type = req->type + 1;
194 fprint(2, "9660srv %d:->%F\n", pid, rep);
195 n = convS2M(rep, mdata, sizeof mdata);
197 panic(1, "convS2M error on write");
198 if(write(srvfd, mdata, n) != n)
199 panic(1, "mount write");
201 panic(0, "err stack %d: %lux %lux %lux %lux %lux %lux", nerr_lab,
202 err_lab[0][JMPBUFPC], err_lab[1][JMPBUFPC],
203 err_lab[2][JMPBUFPC], err_lab[3][JMPBUFPC],
204 err_lab[4][JMPBUFPC], err_lab[5][JMPBUFPC]);
206 chat("server shut down");
212 fprint(2, "usage: %s [-v] [-9Jr] [-s] [-f devicefile] [srvname]\n", argv0);
219 strecpy(err_msg, err_msg+sizeof err_msg, p);
226 longjmp(err_lab[--nerr_lab], 1);
237 setmalloctag(p, getcallerpc(&n));
242 setnames(Dir *d, char *n)
246 d->gid = n+Maxname*2;
247 d->muid = n+Maxname*3;
258 if(req->msize > Maxiosize)
259 rep->msize = Maxiosize;
261 rep->msize = req->msize;
262 rep->version = "9P2000";
268 error("9660srv: authentication not required");
283 chat("attach(fid=%d,uname=\"%s\",aname=\"%s\")...",
284 req->fid, req->uname, req->aname);
287 xfile(req->fid, Clunk);
290 root = xfile(req->fid, Clean);
291 root->qid = (Qid){0, 0, QTDIR};
292 root->xf = xf = ealloc(sizeof(Xfs));
293 memset(xf, 0, sizeof(Xfs));
295 xf->d = getxdata(req->aname);
297 for(xs=xsublist; *xs; xs++)
298 if((*(*xs)->attach)(root) >= 0){
301 xf->rootqid = root->qid;
302 rep->qid = root->qid;
305 error("unknown format");
309 doclone(Xfile *of, int newfid)
313 nf = xfile(newfid, Clean);
315 xfile(newfid, Clunk);
324 nf->ptr = ealloc(nf->len);
325 memmove(nf->ptr, of->ptr, nf->len);
328 (*of->xf->s->clone)(of, nf);
343 f = xfile(req->fid, Asis);
344 if(req->fid != req->newfid)
345 f = nf = doclone(f, req->newfid);
347 /* save old state in case of error */
352 oldptr = ealloc(oldlen);
353 memmove(oldptr, f->ptr, oldlen);
357 if(rep->nwqid == req->nwname){
361 /* restore previous state */
369 xfile(req->newfid, Clunk);
370 if(rep->nwqid==req->nwname || rep->nwqid > 0){
377 for(rep->nwqid=0; rep->nwqid < req->nwname && rep->nwqid < MAXWELEM; rep->nwqid++){
378 chat("\twalking %s\n", req->wname[rep->nwqid]);
379 if(!(f->qid.type & QTDIR)){
380 chat("\tnot dir: type=%#x\n", f->qid.type);
381 error("walk in non-directory");
384 if(strcmp(req->wname[rep->nwqid], "..")==0){
385 if(f->qid.path != f->xf->rootqid.path)
386 (*f->xf->s->walkup)(f);
388 (*f->xf->s->walk)(f, req->wname[rep->nwqid]);
389 rep->wqid[rep->nwqid] = f->qid;
401 f = xfile(req->fid, Asis);
403 error("open on open file");
404 if(req->mode&ORCLOSE)
406 (*f->xf->s->open)(f, req->mode);
407 f->flags = openflags(req->mode);
419 if(strcmp(req->name, ".") == 0 || strcmp(req->name, "..") == 0)
420 error("create . or ..");
421 f = xfile(req->fid, Asis);
423 error("create on open file");
424 if(!(f->qid.path&CHDIR))
425 error("create in non-directory");
426 (*f->xf->s->create)(f, req->name, req->perm, req->mode);
427 chat("f->qid=0x%8.8lux...", f->qid.path);
428 f->flags = openflags(req->mode);
438 f=xfile(req->fid, Asis);
439 if (!(f->flags&Oread))
440 error("file not opened for reading");
441 if(f->qid.type & QTDIR)
442 rep->count = (*f->xf->s->readdir)(f, (uchar*)fdata, req->offset, req->count);
444 rep->count = (*f->xf->s->read)(f, fdata, req->offset, req->count);
453 f=xfile(req->fid, Asis);
454 if(!(f->flags&Owrite))
455 error("file not opened for writing");
456 rep->count = (*f->xf->s->write)(f, req->data, req->offset, req->count);
465 f = xfile(req->fid, Asis);
466 (*f->xf->s->clunk)(f);
469 xfile(req->fid, Clunk);
484 chat("stat(fid=%d)...", req->fid);
485 f=xfile(req->fid, Asis);
486 setnames(&dir, fdata);
487 (*f->xf->s->stat)(f, &dir);
490 rep->nstat = convD2M(&dir, statbuf, sizeof statbuf);
505 switch(mode & ~(OTRUNC|OCEXEC|ORCLOSE)){
508 flags = Oread; break;
510 flags = Owrite; break;
512 flags = Oread|Owrite; break;
520 showdir(int fd, Dir *s)
522 char a_time[32], m_time[32];
525 strcpy(a_time, ctime(s->atime));
526 if(p=strchr(a_time, '\n')) /* assign = */
528 strcpy(m_time, ctime(s->mtime));
529 if(p=strchr(m_time, '\n')) /* assign = */
531 fprint(fd, "name=\"%s\" qid=(0x%llux,%lud) type=%d dev=%d \
532 mode=0x%8.8lux=0%luo atime=%s mtime=%s length=%lld uid=\"%s\" gid=\"%s\"...",
533 s->name, s->qid.path, s->qid.vers, s->type, s->dev,
535 a_time, m_time, s->length, s->uid, s->gid);
547 vfprint(2, fmt, arg);
553 panic(int rflag, char *fmt, ...)
556 char buf[SIZE]; int n;
558 n = sprint(buf, "%s %d: ", argv0, getpid());
560 vseprint(buf+n, buf+SIZE, fmt, arg);
562 fprint(2, (rflag ? "%s: %r\n" : "%s\n"), buf);
564 fprint(2, "abort\n");