📄 srvold9p.c
字号:
break; } qunlock(&taglock); if(oldt == nil){ /* nothing to flush */ if(debug) fprint(2, "no such tag to flush\n"); return 0; } transact9p1(&t9, &r9, mdata9p1); /* can't error */ qlock(&taglock); if(oldt->received == 0){ /* wake up receiver */ if(debug) fprint(2, "wake up receiver\n"); oldt->received = 1; rendezvous((void*)t->oldtag, 0); } freetag(oldt); qunlock(&taglock); return 0;}char*rversion(Fcall *t, Fcall *r, char*){ Fid *f; /* just ack; this one doesn't go to old service */ if(t->msize > IOHDRSZ+Maxfdata) r->msize = IOHDRSZ+Maxfdata; else r->msize = t->msize; if(strncmp(t->version, "9P2000", 6) != 0) return "unknown 9P version"; r->version = "9P2000"; qlock(&fidlock); for(f = fids; f; f = f->next){ f->busy = 0; f->allocated = 0; } qunlock(&fidlock); return 0;}char*rauth(Fcall *, Fcall *, char *){ return "srvold9p: authentication not supported";}#ifdef asdfvoidmemrandom(void *p, int n){ ulong *lp; uchar *cp; for(lp = p; n >= sizeof(ulong); n -= sizeof(ulong)) *lp++ = fastrand(); for(cp = (uchar*)lp; n > 0; n--) *cp++ = fastrand();}char*rsession(Fcall *t, Fcall *r, char *mdata9p1){ char *err; Fcall9p1 t9, r9; Fid *f; t9.type = Tsession9p1; t9.tag = t->tag; if(doauth) memrandom(t9.chal, sizeof t9.chal); else memset(t9.chal, 0, sizeof t9.chal); err = transact9p1(&t9, &r9, mdata9p1); if(err) return err; qlock(&fidlock); for(f = fids; f; f = f->next){ f->busy = 0; f->allocated = 0; } qunlock(&fidlock); if(doauth){ memmove(ai.authid, r9.authid, sizeof ai.authid); memmove(ai.authdom, r9.authdom, sizeof ai.authid); memmove(ai.rchal, r9.chal, sizeof ai.rchal); memmove(ai.chal, t9.chal, sizeof ai.chal); r->authid = ai.authid; r->authdom = ai.authdom; r->chal = (uchar*)ai.rchal; r->nchal = CHALLEN; } else { r->authid = ""; r->authdom = ""; r->nchal = 0; r->chal = nil; } return 0;}#endifchar*rattach(Fcall *t, Fcall *r, char *mdata9p1){ char *err; Fcall9p1 t9, r9; Fid *f; f = newfid(t->fid); if(f->busy) return "attach: fid in use"; /* no authentication! */ t9.type = Tattach9p1; t9.tag = t->tag; t9.fid = t->fid; strncpy(t9.uname, t->uname, NAMEREC); if(strcmp(user, "none") == 0) strncpy(t9.uname, user, NAMEREC); strncpy(t9.aname, t->aname, NAMEREC); memset(t9.ticket, 0, sizeof t9.ticket); memset(t9.auth, 0, sizeof t9.auth); err = transact9p1(&t9, &r9, mdata9p1); if(err) return err; r->qid.path = r9.qid.path & ~0x80000000; r->qid.vers = r9.qid.version; r->qid.type = QTDIR; f->busy = 1; f->qid = r->qid; return 0;}char*rwalk(Fcall *t, Fcall *r, char *mdata9p1){ char *err; Fcall9p1 t9, r9; int i, fid; Qid *q; Fid *f, *nf; f = newfid(t->fid); if(!f->busy) return "walk: bad fid"; fid = t->fid; nf = nil; if(t->fid != t->newfid){ nf = newfid(t->newfid); if(nf->busy) return "walk: newfid in use"; t9.type = Tclone9p1; t9.tag = t->tag; t9.fid = t->fid; t9.newfid = t->newfid; err = transact9p1(&t9, &r9, mdata9p1); if(err){ nf->busy = 0; nf->allocated = 0; return err; } fid = t->newfid; nf->busy = 1; } err = nil; r->nwqid = 0; for(i=0; i<t->nwname && err==nil; i++){ if(i > MAXWELEM) break; t9.type = Twalk9p1; t9.tag = t->tag; t9.fid = fid; strncpy(t9.name, t->wname[i], NAMEREC); err = transact9p1(&t9, &r9, mdata9p1); if(err == FLUSHED){ i = -1; /* guarantee cleanup */ break; } if(err == nil){ q = &r->wqid[r->nwqid++]; q->type = QTFILE; if(r9.qid.path & 0x80000000) q->type = QTDIR; q->vers = r9.qid.version; q->path = r9.qid.path & ~0x80000000; } } if(nf!=nil && (err!=nil || i<t->nwname)){ /* clunk the new fid */ t9.type = Tclunk9p1; t9.tag = t->tag; t9.fid = t->newfid; transact9p1(&t9, &r9, mdata9p1); /* ignore more errors */ nf->busy = 0; nf->allocated = 0; } if(i>0 && i==t->nwname && err==nil) f->qid = r->wqid[r->nwqid-1]; if(i > 0) return 0; return err;}char*ropen(Fcall *t, Fcall *r, char *mdata9p1){ char *err; Fcall9p1 t9, r9; Fid *f; f = newfid(t->fid); if(!f->busy) return "open: bad fid"; t9.type = Topen9p1; t9.tag = t->tag; t9.fid = t->fid; t9.mode = t->mode; err = transact9p1(&t9, &r9, mdata9p1); if(err) return err; r->qid.path = r9.qid.path & ~0x80000000; r->qid.vers = r9.qid.version; r->qid.type = QTFILE; if(r9.qid.path & 0x80000000) r->qid.type = QTDIR; f->qid = r->qid; f->newoffset = 0; f->oldoffset = 0; r->iounit = 0; return 0;}char*rcreate(Fcall *t, Fcall *r, char *mdata9p1){ char *err; Fcall9p1 t9, r9; Fid *f; f = newfid(t->fid); if(!f->busy) return "create: bad fid"; t9.type = Tcreate9p1; t9.tag = t->tag; t9.fid = t->fid; if(strlen(t->name)+1 >= NAMEREC) return "file name element too long"; strncpy(t9.name, t->name, NAMEREC); t9.perm = t->perm; t9.mode = t->mode; err = transact9p1(&t9, &r9, mdata9p1); if(err) return err; r->qid.path = r9.qid.path & ~0x80000000; r->qid.vers = r9.qid.version; r->qid.type = QTFILE; if(r9.qid.path & 0x80000000) r->qid.type = QTDIR; if(r9.qid.path & 0x40000000) r->qid.type |= QTAPPEND; if(r9.qid.path & 0x20000000) r->qid.type |= QTEXCL; f->qid = r->qid; r->iounit = 0; return 0;}char*dirrread(Fcall *t, Fcall *r, char *mdata9p1){ char *err; Fcall9p1 t9, r9; Fid *f; int i, ndir, n, count; Dir d; uchar buf[Maxfdata]; char *old; f = newfid(t->fid); if(!f->busy) return "dirread: bad fid"; if(f->newoffset != t->offset) return "seek in directory disallowed"; t9.type = Tread9p1; t9.tag = t->tag; t9.fid = t->fid; t9.offset = f->oldoffset; t9.count = t->count; /* new directories tend to be smaller, so this may overshoot */ err = transact9p1(&t9, &r9, mdata9p1); if(err) return err; ndir = r9.count/DIRREC; old = r9.data; count = 0; for(i=0; i<ndir; i++){ if(convM2D9p1(old, &d) != DIRREC) return "bad dir conversion in read"; n = convD2M(&d, buf+count, sizeof buf-count); if(n<=BIT16SZ || count+n>t->count) break; old += DIRREC; f->oldoffset += DIRREC; f->newoffset += n; count += n; } memmove(r9.data, buf, count); /* put it back in stable storage */ r->data = r9.data; r->count = count; return 0;}char*rread(Fcall *t, Fcall *r, char *mdata9p1){ char *err; Fcall9p1 t9, r9; Fid *f; f = newfid(t->fid); if(!f->busy) return "read: bad fid"; if(f->qid.type & QTDIR) return dirrread(t, r, mdata9p1); t9.type = Tread9p1; t9.tag = t->tag; t9.fid = t->fid; t9.offset = t->offset; t9.count = t->count; err = transact9p1(&t9, &r9, mdata9p1); if(err) return err; r->count = r9.count; r->data = r9.data; /* points to stable storage */ return 0;}char*rwrite(Fcall *t, Fcall *r, char *mdata9p1){ char *err; Fcall9p1 t9, r9; Fid *f; f = newfid(t->fid); if(!f->busy) return "write: bad fid"; t9.type = Twrite9p1; t9.tag = t->tag; t9.fid = t->fid; t9.offset = t->offset; t9.count = t->count; t9.data = t->data; err = transact9p1(&t9, &r9, mdata9p1); if(err) return err; r->count = r9.count; return 0;}char*rclunk(Fcall *t, Fcall *, char *mdata9p1){ Fcall9p1 t9, r9; Fid *f; f = newfid(t->fid); if(!f->busy) return "clunk: bad fid"; t9.type = Tclunk9p1; t9.tag = t->tag; t9.fid = t->fid; transact9p1(&t9, &r9, mdata9p1); f->busy = 0; f->allocated = 0; /* disregard error */ return 0;}char*rremove(Fcall *t, Fcall*, char *mdata9p1){ char *err; Fcall9p1 t9, r9; Fid *f; f = newfid(t->fid); if(!f->busy) return "remove: bad fid"; t9.type = Tremove9p1; t9.tag = t->tag; t9.fid = t->fid; err = transact9p1(&t9, &r9, mdata9p1); f->busy = 0; f->allocated = 0; return err;}char*rstat(Fcall *t, Fcall *r, char *mdata9p1){ Fcall9p1 t9, r9; char *err; Fid *f; Dir d; uchar buf[256]; /* big enough; there's no long names */ f = newfid(t->fid); if(!f->busy) return "stat: bad fid"; t9.type = Tstat9p1; t9.tag = t->tag; t9.fid = t->fid; err = transact9p1(&t9, &r9, mdata9p1); if(err) return err; if(convM2D9p1(r9.stat, &d) != DIRREC) return "bad conversion in stat"; r->stat = buf; r->nstat = convD2M(&d, buf, sizeof buf); return 0;}intanydefault(Dir *d){ if(d->name[0] == '\0') return 1; if(d->uid[0] == '\0') return 1; if(d->gid[0] == '\0') return 1; if(d->mode == ~0) return 1; if(d->mtime == ~0) return 1; return 0;}char*rwstat(Fcall *t, Fcall *, char *mdata9p1){ Fcall9p1 t9, r9; char strs[DIRREC]; char *err; Fid *f; Dir d, cd; f = newfid(t->fid); if(!f->busy) return "wstat: bad fid"; convM2D(t->stat, t->nstat, &d, strs); cd = d; if(anydefault(&d)){ /* must first stat file so we can copy current values */ t9.type = Tstat9p1; t9.tag = t->tag; t9.fid = t->fid; err = transact9p1(&t9, &r9, mdata9p1); if(err) return err; if(convM2D9p1(r9.stat, &cd) != DIRREC) return "bad in conversion in wstat"; /* fill in default values */ if(d.name[0] != '\0'){ if(strlen(d.name) >= NAMEREC) return Etoolong; cd.name = d.name; } if(d.uid[0] != '\0'){ if(strlen(d.uid) >= NAMEREC) return Etoolong; cd.uid = d.uid; } if(d.gid[0] != '\0'){ if(strlen(d.gid) >= NAMEREC) return Etoolong; cd.gid = d.gid; } if(d.mode != ~0) cd.mode = d.mode; if(d.mtime != ~0) cd.mtime = d.mtime; if(d.length != ~0LL) cd.length = d.length; } if(convD2M9p1(&cd, t9.stat) != DIRREC) return "bad out conversion in wstat"; t9.type = Twstat9p1; t9.tag = t->tag; t9.fid = t->fid; err = transact9p1(&t9, &r9, mdata9p1); if(err) return err; return 0;}void *emalloc(ulong n){ void *p; p = malloc(n); if(!p) fatal("out of memory: %r"); memset(p, 0, n); return p;}voidfatal(char *fmt, ...){ char buf[1024]; va_list arg; if(fmt){ va_start(arg, fmt); vseprint(buf, buf+sizeof(buf), fmt, arg); va_end(arg); fprint(2, "%s: (pid %d) %s\n", argv0, getpid(), buf); }else buf[0] = '\0'; if(mainpid){ /* two hits are sometimes needed */ postnote(PNGROUP, mainpid, "die1 - from srvold9p"); postnote(PNGROUP, mainpid, "die2 - from srvold9p"); } exits(buf);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -