int32_t netifwstat(Netif *nif, Chan *c, uint8_t *db, int32_t n) { Proc *up = externup(); Dir *dir; Netfile *f; int l; f = nif->f[NETID(c->qid.path)]; if(f == 0) error(Enonexist); if(netown(f, up->user, OWRITE) < 0) error(Eperm); dir = smalloc(sizeof(Dir)+n); l = convM2D(db, n, &dir[0], (char*)&dir[1]); if(l == 0){ free(dir); error(Eshortstat); } if(!emptystr(dir[0].uid)) strncpy(f->owner, dir[0].uid, KNAMELEN); if(dir[0].mode != (uint32_t)~0UL) f->mode = dir[0].mode; free(dir); return l; }
int netifwstat(struct ether *nif, struct chan *c, uint8_t * db, int n) { struct dir *dir; struct netfile *f; int m; f = nif->f[NETID(c->qid.path)]; if (f == 0) { set_errno(ENOENT); error(Enonexist); } if (netown(f, current->user, OWRITE) < 0) error(Eperm); dir = kzmalloc(sizeof(struct dir) + n, 0); m = convM2D(db, n, &dir[0], (char *)&dir[1]); if (m == 0) { kfree(dir); error(Eshortstat); } if (!emptystr(dir[0].uid)) strncpy(f->owner, dir[0].uid, KNAMELEN); if (dir[0].mode != ~0UL) f->mode = dir[0].mode; kfree(dir); return m; }
/* * Increment the reference count of a network device. * If id < 0, return an unused ether device. */ static int openfile(struct ether *nif, int id) { ERRSTACK(1); struct netfile *f, **fp, **efp; if (id >= 0) { f = nif->f[id]; if (f == 0) error(Enodev); qlock(&f->qlock); qreopen(f->in); f->inuse++; qunlock(&f->qlock); return id; } qlock(&nif->qlock); if (waserror()) { qunlock(&nif->qlock); nexterror(); } efp = &nif->f[nif->nfile]; for (fp = nif->f; fp < efp; fp++) { f = *fp; if (f == 0) { f = kzmalloc(sizeof(struct netfile), 0); if (f == 0) exhausted("memory"); /* since we lock before netifinit (if we ever call that...) */ qlock_init(&f->qlock); f->in = qopen(nif->limit, Qmsg, 0, 0); if (f->in == NULL) { kfree(f); exhausted("memory"); } *fp = f; qlock(&f->qlock); } else { qlock(&f->qlock); if (f->inuse) { qunlock(&f->qlock); continue; } } f->inuse = 1; qreopen(f->in); netown(f, current->user, 0); qunlock(&f->qlock); qunlock(&nif->qlock); poperror(); return fp - nif->f; } error(Enodev); return -1; /* not reached */ }
/* * Increment the reference count of a network device. * If id < 0, return an unused ether device. */ static int openfile(Netif *nif, int id) { Proc *up = externup(); Netfile *f, **fp, **efp; if(id >= 0){ f = nif->f[id]; if(f == 0) error(Enodev); qlock(&f->q); qreopen(f->iq); f->inuse++; qunlock(&f->q); return id; } qlock(&nif->q); if(waserror()){ qunlock(&nif->q); nexterror(); } efp = &nif->f[nif->nfile]; for(fp = nif->f; fp < efp; fp++){ f = *fp; if(f == 0){ f = malloc(sizeof(Netfile)); if(f == 0) exhausted("memory"); f->iq = qopen(nif->limit, Qmsg, 0, 0); if(f->iq == nil){ free(f); exhausted("memory"); } *fp = f; qlock(&f->q); } else { qlock(&f->q); if(f->inuse){ qunlock(&f->q); continue; } } f->inuse = 1; qreopen(f->iq); netown(f, up->user, 0); qunlock(&f->q); qunlock(&nif->q); poperror(); return fp - nif->f; } error(Enodev); return -1; /* not reached */ }
Chan* netifopen(Netif *nif, Chan *c, int omode) { Proc *up = externup(); int id; Netfile *f; id = 0; if(c->qid.type & QTDIR){ if(omode != OREAD) error(Eperm); } else { switch(NETTYPE(c->qid.path)){ case Ndataqid: case Nctlqid: id = NETID(c->qid.path); openfile(nif, id); break; case Ncloneqid: id = openfile(nif, -1); c->qid.path = NETQID(id, Nctlqid); break; default: if(omode != OREAD) error(Ebadarg); } switch(NETTYPE(c->qid.path)){ case Ndataqid: case Nctlqid: f = nif->f[id]; if(netown(f, up->user, omode&7) < 0){ netifclose(nif, c); error(Eperm); } break; } } c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; c->iounit = qiomaxatomic; return c; }
struct chan *netifopen(struct ether *nif, struct chan *c, int omode) { int id; struct netfile *f; id = 0; if (c->qid.type & QTDIR) { if (!IS_RDONLY(omode)) error(Eperm); } else { switch (NETTYPE(c->qid.path)) { case Ndataqid: case Nctlqid: id = NETID(c->qid.path); openfile(nif, id); break; case Ncloneqid: id = openfile(nif, -1); c->qid.path = NETQID(id, Nctlqid); break; default: if (!IS_RDONLY(omode)) error(Ebadarg); } switch (NETTYPE(c->qid.path)) { case Ndataqid: case Nctlqid: f = nif->f[id]; if (netown(f, current->user, omode & 7) < 0) error(Eperm); break; } } c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; c->iounit = qiomaxatomic; return c; }