## diffname gnot/devsrv.c 1990/03091 ## diff -e /dev/null /n/bootesdump/1990/03091/sys/src/9/68020/devsrv.c 0a #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "errno.h" #include "devtab.h" typedef struct Srv Srv; struct Srv{ Lock; char *name; Chan **chan; }srv; int srvgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) { if(s >= conf.nsrv) return -1; if(srv.chan[s] == 0) return 0; devdir(c, s, &srv.name[s*NAMELEN], 0, 0666, dp); return 1; } void srvinit(void) { } void srvreset(void) { srv.chan = ialloc(conf.nsrv*sizeof(Chan*), 0); srv.name = ialloc(conf.nsrv*NAMELEN, 0); } Chan * srvattach(char *spec) { return devattach('s', spec); } Chan * srvclone(Chan *c, Chan *nc) { return devclone(c, nc); } int srvwalk(Chan *c, char *name) { return devwalk(c, name, (Dirtab *)0, 0, srvgen); } void srvstat(Chan *c, char *db) { devstat(c, db, (Dirtab *)0, 0L, srvgen); } Chan * srvopen(Chan *c, int omode) { Chan *f; if(c->qid == CHDIR){ if(omode != OREAD) error(0, Eisdir); c->mode = omode; c->flag |= COPEN; c->offset = 0; return c; } lock(&srv); if(waserror()){ unlock(&srv); nexterror(); } f = srv.chan[c->qid]; if(f == 0) error(0, Eshutdown); if(omode&OTRUNC) error(0, Eperm); if(omode!=f->mode && f->mode!=ORDWR) error(0, Eperm); close(c); incref(f); unlock(&srv); poperror(); return f; } void srvcreate(Chan *c, char *name, int omode, ulong perm) { int j, i; if(omode != OWRITE) error(0, Eperm); lock(&srv); if(waserror()){ unlock(&srv); nexterror(); } j = -1; for(i=0; iqid = j; c->flag |= COPEN; c->mode = OWRITE; } void srvremove(Chan *c) { Chan *f; if(c->qid == CHDIR) error(0, Eperm); lock(&srv); if(waserror()){ unlock(&srv); nexterror(); } f = srv.chan[c->qid]; if(f == 0) error(0, Eshutdown); if(strcmp(&srv.name[c->qid*NAMELEN], "boot") == 0) error(0, Eperm); srv.chan[c->qid] = 0; unlock(&srv); poperror(); close(f); } void srvwstat(Chan *c, char *dp) { error(0, Egreg); } void srvclose(Chan *c) { } long srvread(Chan *c, void *va, long n) { char *a = va; if(c->qid != CHDIR) panic("srvread"); return devdirread(c, a, n, (Dirtab *)0, 0L, srvgen); } long srvwrite(Chan *c, void *va, long n) { int i, fd; char buf[32]; i = c->qid; if(srv.chan[i] != c) /* already been written to */ error(0, Egreg); if(n >= sizeof buf) error(0, Egreg); memcpy(buf, va, n); /* so we can NUL-terminate */ buf[n] = 0; fd = strtoul(buf, 0, 0); fdtochan(fd, -1); /* error check only */ srv.chan[i] = u->fd[fd]; incref(u->fd[fd]); return n; } void srverrstr(Error *e, char *buf) { rooterrstr(e, buf); } void srvuserstr(Error *e, char *buf) { consuserstr(e, buf); } . ## diffname gnot/devsrv.c 1990/1002 ## diff -e /n/bootesdump/1990/03091/sys/src/9/68020/devsrv.c /n/bootesdump/1990/1002/sys/src/9/68020/devsrv.c 188,189c e->chan = u->fd[fd]; incref(e->chan); unlock(e); poperror(); . 182c if (n >= sizeof buf) . 179,180c if (e->dir.mode & CHDIR) panic("write to directory"); lock(e); if (waserror()) { unlock(e); nexterror(); } if (e->chan != 0) . 175a struct entry *e = c->aux; . 168,170c isdir(c); if (n <= 0) return 0; if ((offset % DIRLEN) != 0 || (n % DIRLEN) != 0) error(0, Egreg); lock(dir); for (e = dir->entries; e != 0; e = e->next) if (offset <= 0) { n = srv_direntry(e, va, n); unlock(dir); c->offset += n; return n; } else offset -= DIRLEN; unlock(dir); return 0; . 166c struct entry *dir = c->aux, *e; int offset = c->offset; . 162a /* A directory is being read. The entries must be synthesized. e points * to a list of entries in this directory. Count is the size to be * read. */ int srv_direntry(struct entry *e, char *a, long count){ Dir dir; int n = 0; while (n != count && e != 0) { n += convD2M(&e->dir, a + n); e = e->next; } return n; } . 149c free(e); . 141,147c if (e->dir.mode & CHDIR) { if (e->entries != 0) error(0, Eperm); } else { if (e->chan == 0) error(0, Eshutdown); close(e->chan); } if ((*e->back = e->next) != 0) e->next->back = e->back; unlock(e->parent); . 136,138c lock(e->parent); if (waserror()) { unlock(e->parent); . 134c if (e->parent == 0) . 132c struct entry *e = c->aux; . 126c c->mode = omode; . 117,124c e = srv_alloc(perm & CHDIR); e->parent = parent; strcpy(e->dir.name, name); e->dir.mode = perm & parent->dir.mode; e->dir.gid = parent->dir.gid; if ((e->next = parent->entries) != 0) e->next->back = &e->next; *(e->back = &parent->entries) = e; parent->dir.mtime = e->dir.mtime; unlock(parent); poperror(); c->qid = e->dir.gid; c->aux = e; . 109,115c for (e = parent->entries; e != 0; e = e->next) if (strcmp(name, e->dir.name) == 0) . 102,106c isdir(c); lock(parent); if (waserror()) { unlock(parent); . 100c struct entry *parent = c->aux, *e; . 92,93d 88c if (omode != f->mode && f->mode != ORDWR) . 86c if (omode & OTRUNC) . 78,84c if ((e = c->aux) == 0) panic("bad aux pointer in srvopen"); if ((f = e->chan) == 0) . 70,71c if (c->qid & CHDIR) { if (omode != OREAD) . 67a struct entry *e; . 62c struct entry *e = c->aux; convD2M(&e->dir, db); . 56c struct entry *dir, *e; isdir(c); if (strcmp(name, ".") == 0) return 1; if ((dir = c->aux) == 0) panic("bad aux pointer in srvwalk"); if (strcmp(name, "..") == 0) e = dir->parent; else { lock(dir); for (e = dir->entries; e != 0; e = e->next) if (strcmp(name, e->dir.name) == 0) break; unlock(dir); } if (e == 0) { u->error.code = Enonexist; u->error.type = 0; u->error.dev = 0; return 0; } c->qid = e->dir.qid; c->aux = e; return 1; . 50c nc = devclone(c, nc); nc->aux = c->aux; return nc; . 44c Chan *c; static Lock rootlock; static struct entry *root; lock(&rootlock); if (root == 0) { root = srv_alloc(CHDIR); root->dir.mode = CHDIR | 0777; } unlock(&rootlock); c = devattach('s', spec); c->qid = root->dir.qid; c->aux = root; return c; . 40a struct entry *srv_alloc(int mode){ struct entry *e = calloc(1, sizeof(*e)); static Lock qidlock; static nextqid; e->dir.atime = e->dir.mtime = seconds(); lock(&qidlock); /* for qid allocation */ e->dir.qid = mode | nextqid++; unlock(&qidlock); return e; } . 37,38d 17,28d 13,15c struct entry *next; /* next entry */ struct entry **back; /* entry pointer */ struct entry *parent; /* parent directory */ Dir dir; /* dir structure */ union { Chan *chan; /* if not a subdirectory */ struct entry *entries; /* directory entries */ }; }; . 10,11c void *calloc(unsigned int, unsigned int); void free(void *); /* This structure holds the contents of a directory entry. Entries are kept * in a linked list. */ struct entry { . 8a #include "fcall.h" . 7d ## diffname gnot/devsrv.c 1990/1110 ## diff -e /n/bootesdump/1990/1002/sys/src/9/68020/devsrv.c /n/bootesdump/1990/1110/sys/src/9/68020/devsrv.c 268c if(n >= sizeof buf) . 266c if(e->chan) . 262c if(waserror()){ . 259c e = c->aux; if(e->dir.mode & CHDIR) . 255c Entry *e; . 245,246c }else . 239,241c for(e=dir->entries; e; e=e->next) if(offset <= 0){ n = srvdirentry(e, va, n); . 236,237c if(offset%DIRLEN || n%DIRLEN) error(0, Ebaddirread); . 234c if(n <= 0) . 232a dir = c->aux; offset = c->offset; . 230,231c Entry *dir, *e; int offset; . 220c n = 0; while(n!=count && e!=0){ . 218c int n; . 216c int srvdirentry(Entry *e, char *a, long count){ . 194c if(*e->back = e->next) /* assign = */ . 188,190c }else{ if(e->chan == 0) . 185c if(e->dir.mode & CHDIR){ . 181c if(waserror()){ . 178c e = c->aux; if(e->parent == 0) . 176c Entry *e; . 163c e->back = &parent->entries; *e->back = e; . 161c if(e->next = parent->entries) /* assign = */ . 156c e = srvalloc(perm & CHDIR); . 153,154c for(e=parent->entries; e; e=e->next) if(strcmp(name, e->dir.name) == 0) . 149c if (waserror()){ . 146a parent = c->aux; . 145c Entry *parent, *e; . 135c if(omode!=f->mode && f->mode!=ORDWR) . 133c if(omode & OTRUNC) . 129,131c if((e=c->aux) == 0) error(0, Egreg); if((f=e->chan) == 0) . 121,122c if(c->qid & CHDIR){ if(omode != OREAD) . 118c Entry *e; . 111a e = c->aux; . 110c Entry *e; . 96c if(e==0){ . 91c for(e=dir->entries; e; e=e->next) . 89c else{ . 87c if(strcmp(name, "..") == 0) . 85c if((dir=c->aux) == 0) . 83c if(strcmp(name, ".") == 0) . 80c Entry *dir, *e; . 58,59c if(root==0){ root = srvalloc(CHDIR); . 55c static Entry *root; . 42a e = calloc(1, sizeof(Entry)); . 38,39c Entry * srvalloc(int mode){ Entry *e; . 22,24c union{ Chan *chan; /* if not a subdirectory */ Entry *entries; /* directory entries */ . 18,20c Entry *next; /* next entry */ Entry **back; /* entry pointer */ Entry *parent; /* parent directory */ . 16c typedef struct Entry Entry; struct Entry { . 10c void *calloc(unsigned, unsigned); . ## diffname gnot/devsrv.c 1990/1121 ## diff -e /n/bootesdump/1990/1110/sys/src/9/68020/devsrv.c /n/bootesdump/1990/1121/sys/src/9/68020/devsrv.c 173c c->qid = e->dir.qid; . ## diffname gnot/devsrv.c 1990/11211 ## diff -e /n/bootesdump/1990/1121/sys/src/9/68020/devsrv.c /n/bootesdump/1990/11211/sys/src/9/68020/devsrv.c 289,300d 279c error(Egreg); . 277c error(Egreg); . 247c error(Ebaddirread); . 210c error(Egreg); . 197c error(Eshutdown); . 194c error(Eperm); . 186c error(Eperm); . 165c strcpy(e->dir.gid, parent->dir.gid); . 160c error(Einuse); . 140c error(Eperm); . 138c error(Eperm); . 136c error(Eshutdown); . 134c error(Egreg); . 127c error(Eisdir); . 125c if(c->qid.path & CHDIR){ . 100,102c strncpy(u->error, errstrtab[Enonexist], NAMELEN); . 48c e->dir.qid = (Qid){mode|nextqid++, 0}; . ## diffname gnot/devsrv.c 1990/1210 # deleted ## diff -e /n/bootesdump/1990/11211/sys/src/9/68020/devsrv.c /n/bootesdump/1990/1210/sys/src/9/68020/devsrv.c 1,287d