## 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; i<conf.nsrv; i++){
if(srv.chan[i] == 0){
if(j == -1)
j = i;
}else if(strcmp(name, &srv.name[i*NAMELEN]) == 0){
print("reuse of srv name\n");
error(0, Einuse);
}
}
if(j == -1)
error(0, Enosrv);
srv.chan[j] = c;
unlock(&srv);
strcpy(&srv.name[j*NAMELEN], name);
c->qid = 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
|