11 Maxiosize = IOHDRSZ+Maxfdata,
30 static int openflags(int);
31 static void rmservice(void);
32 static void usage(void);
34 #define Reqsize (sizeof(Fcall)+Maxfdata)
39 uchar mdata[Maxiosize];
41 uchar statbuf[STATMAX];
44 static char srvfile[64];
46 extern Xfsub *xsublist[];
58 void (*fcalls[])(void) = {
75 main(int argc, char **argv)
77 int srvfd, pipefd[2], stdio;
86 nclust = atoi(EARGF(usage()));
88 sysfatal("nclust %d non-positive", nclust);
91 deffile = EARGF(usage());
120 for(xs=xsublist; *xs; xs++)
129 open("/dev/null", OREAD);
130 open("/dev/null", OWRITE);
133 sprint(srvfile, "/srv/%s", srvname);
134 srvfd = create(srvfile, OWRITE|ORCLOSE, 0600);
137 fprint(srvfd, "%d", pipefd[0]);
139 fprint(2, "%s %d: serving %s\n", argv0, getpid(), srvfile);
143 switch(rfork(RFNOWAIT|RFNOTEG|RFFDG|RFPROC|RFNAMEG)){
165 fmtinstall('F', fcallfmt);
167 while((n = read9pmsg(srvfd, mdata, sizeof mdata)) != 0){
169 panic(1, "mount read");
170 if(convM2S(mdata, n, req) != n)
171 panic(1, "convM2S format error");
174 fprint(2, "9660srv %d:<-%F\n", pid, req);
179 if(req->type >= nelem(fcalls) || !fcalls[req->type])
180 error("bad fcall type");
181 (*fcalls[req->type])();
187 rep->ename = err_msg;
189 rep->type = req->type + 1;
195 fprint(2, "9660srv %d:->%F\n", pid, rep);
196 n = convS2M(rep, mdata, sizeof mdata);
198 panic(1, "convS2M error on write");
199 if(write(srvfd, mdata, n) != n)
200 panic(1, "mount write");
202 panic(0, "err stack %d: %lux %lux %lux %lux %lux %lux", nerr_lab,
203 err_lab[0][JMPBUFPC], err_lab[1][JMPBUFPC],
204 err_lab[2][JMPBUFPC], err_lab[3][JMPBUFPC],
205 err_lab[4][JMPBUFPC], err_lab[5][JMPBUFPC]);
207 chat("server shut down");
213 fprint(2, "usage: %s [-v] [-9Jr] [-s] [-f devicefile] [srvname]\n", argv0);
220 strecpy(err_msg, err_msg+sizeof err_msg, p);
227 longjmp(err_lab[--nerr_lab], 1);
238 setmalloctag(p, getcallerpc(&n));
243 setnames(Dir *d, char *n)
247 d->gid = n+Maxname*2;
248 d->muid = n+Maxname*3;
259 if(req->msize > Maxiosize)
260 rep->msize = Maxiosize;
262 rep->msize = req->msize;
263 rep->version = "9P2000";
269 error("9660srv: authentication not required");
284 chat("attach(fid=%d,uname=\"%s\",aname=\"%s\")...",
285 req->fid, req->uname, req->aname);
288 xfile(req->fid, Clunk);
291 root = xfile(req->fid, Clean);
292 root->qid = (Qid){0, 0, QTDIR};
293 root->xf = xf = ealloc(sizeof(Xfs));
294 memset(xf, 0, sizeof(Xfs));
296 xf->d = getxdata(req->aname);
298 for(xs=xsublist; *xs; xs++)
299 if((*(*xs)->attach)(root) >= 0){
302 xf->rootqid = root->qid;
303 rep->qid = root->qid;
306 error("unknown format");
310 doclone(Xfile *of, int newfid)
314 nf = xfile(newfid, Clean);
316 xfile(newfid, Clunk);
325 nf->ptr = ealloc(nf->len);
326 memmove(nf->ptr, of->ptr, nf->len);
329 (*of->xf->s->clone)(of, nf);
344 f = xfile(req->fid, Asis);
345 if(req->fid != req->newfid)
346 f = nf = doclone(f, req->newfid);
348 /* save old state in case of error */
353 oldptr = ealloc(oldlen);
354 memmove(oldptr, f->ptr, oldlen);
358 if(rep->nwqid == req->nwname){
362 /* restore previous state */
370 xfile(req->newfid, Clunk);
371 if(rep->nwqid==req->nwname || rep->nwqid > 0){
378 for(rep->nwqid=0; rep->nwqid < req->nwname && rep->nwqid < MAXWELEM; rep->nwqid++){
379 chat("\twalking %s\n", req->wname[rep->nwqid]);
380 if(!(f->qid.type & QTDIR)){
381 chat("\tnot dir: type=%#x\n", f->qid.type);
382 error("walk in non-directory");
385 if(strcmp(req->wname[rep->nwqid], "..")==0){
386 if(f->qid.path != f->xf->rootqid.path)
387 (*f->xf->s->walkup)(f);
389 (*f->xf->s->walk)(f, req->wname[rep->nwqid]);
390 rep->wqid[rep->nwqid] = f->qid;
402 f = xfile(req->fid, Asis);
404 error("open on open file");
405 if(req->mode&ORCLOSE)
407 (*f->xf->s->open)(f, req->mode);
408 f->flags = openflags(req->mode);
420 if(strcmp(req->name, ".") == 0 || strcmp(req->name, "..") == 0)
421 error("create . or ..");
422 f = xfile(req->fid, Asis);
424 error("create on open file");
425 if(!(f->qid.path&CHDIR))
426 error("create in non-directory");
427 (*f->xf->s->create)(f, req->name, req->perm, req->mode);
428 chat("f->qid=0x%8.8lux...", f->qid.path);
429 f->flags = openflags(req->mode);
439 f=xfile(req->fid, Asis);
440 if (!(f->flags&Oread))
441 error("file not opened for reading");
442 if(f->qid.type & QTDIR)
443 rep->count = (*f->xf->s->readdir)(f, (uchar*)fdata, req->offset, req->count);
445 rep->count = (*f->xf->s->read)(f, fdata, req->offset, req->count);
454 f=xfile(req->fid, Asis);
455 if(!(f->flags&Owrite))
456 error("file not opened for writing");
457 rep->count = (*f->xf->s->write)(f, req->data, req->offset, req->count);
466 f = xfile(req->fid, Asis);
467 (*f->xf->s->clunk)(f);
470 xfile(req->fid, Clunk);
485 chat("stat(fid=%d)...", req->fid);
486 f=xfile(req->fid, Asis);
487 setnames(&dir, fdata);
488 (*f->xf->s->stat)(f, &dir);
491 rep->nstat = convD2M(&dir, statbuf, sizeof statbuf);
506 switch(mode & ~(OTRUNC|OCEXEC|ORCLOSE)){
509 flags = Oread; break;
511 flags = Owrite; break;
513 flags = Oread|Owrite; break;
521 showdir(int fd, Dir *s)
523 char a_time[32], m_time[32];
526 strcpy(a_time, ctime(s->atime));
527 if(p=strchr(a_time, '\n')) /* assign = */
529 strcpy(m_time, ctime(s->mtime));
530 if(p=strchr(m_time, '\n')) /* assign = */
532 fprint(fd, "name=\"%s\" qid=(0x%llux,%lud) type=%d dev=%d \
533 mode=0x%8.8lux=0%luo atime=%s mtime=%s length=%lld uid=\"%s\" gid=\"%s\"...",
534 s->name, s->qid.path, s->qid.vers, s->type, s->dev,
536 a_time, m_time, s->length, s->uid, s->gid);
548 vfprint(2, fmt, arg);
554 panic(int rflag, char *fmt, ...)
557 char buf[SIZE]; int n;
559 n = sprint(buf, "%s %d: ", argv0, getpid());
561 vseprint(buf+n, buf+SIZE, fmt, arg);
563 fprint(2, (rflag ? "%s: %r\n" : "%s\n"), buf);
565 fprint(2, "abort\n");