Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/port/devsrv.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname port/devsrv.c 1990/0227
## diff -e /dev/null /n/bootesdump/1990/0227/sys/src/9/mips/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 port/devsrv.c 1990/0725
## diff -e /n/bootesdump/1990/0227/sys/src/9/mips/devsrv.c /n/bootesdump/1990/0725/sys/src/9/mips/devsrv.c
86c
	if(omode & OTRUNC)
.
## diffname port/devsrv.c 1990/1002
## diff -e /n/bootesdump/1990/0725/sys/src/9/mips/devsrv.c /n/bootesdump/1990/1002/sys/src/9/mips/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 port/devsrv.c 1990/1110
## diff -e /n/bootesdump/1990/1002/sys/src/9/mips/devsrv.c /n/bootesdump/1990/1110/sys/src/9/mips/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 port/devsrv.c 1990/1121
## diff -e /n/bootesdump/1990/1110/sys/src/9/mips/devsrv.c /n/bootesdump/1990/1121/sys/src/9/mips/devsrv.c
173c
	c->qid = e->dir.qid;
.
## diffname port/devsrv.c 1990/11211
## diff -e /n/bootesdump/1990/1121/sys/src/9/mips/devsrv.c /n/bootesdump/1990/11211/sys/src/9/mips/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 port/devsrv.c 1991/0318
## diff -e /n/bootesdump/1990/1210/sys/src/9/mips/devsrv.c /n/bootesdump/1991/0318/sys/src/9/port/devsrv.c
278c
	memmove(buf, va, n);	/* so we can NUL-terminate */
.
## diffname port/devsrv.c 1991/0411
## diff -e /n/bootesdump/1991/0318/sys/src/9/port/devsrv.c /n/bootesdump/1991/0411/sys/src/9/port/devsrv.c
260c
srvwrite(Chan *c, void *va, long n, ulong offset)
.
240d
237d
234c
srvread(Chan *c, void *va, long n, ulong offset)
.
## diffname port/devsrv.c 1991/0419
## diff -e /n/bootesdump/1991/0411/sys/src/9/port/devsrv.c /n/bootesdump/1991/0419/sys/src/9/port/devsrv.c
107a
Chan*
srvclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

.
## diffname port/devsrv.c 1991/0421
## diff -e /n/bootesdump/1991/0419/sys/src/9/port/devsrv.c /n/bootesdump/1991/0421/sys/src/9/port/devsrv.c
76d
## diffname port/devsrv.c 1991/0427
## diff -e /n/bootesdump/1991/0421/sys/src/9/port/devsrv.c /n/bootesdump/1991/0427/sys/src/9/port/devsrv.c
107,112d
## diffname port/devsrv.c 1991/0705
## diff -e /n/bootesdump/1991/0427/sys/src/9/port/devsrv.c /n/bootesdump/1991/0705/sys/src/9/port/devsrv.c
278,279c
	e->chan = fdtochan(fd, -1);
.
## diffname port/devsrv.c 1991/0828
## diff -e /n/bootesdump/1991/0705/sys/src/9/port/devsrv.c /n/bootesdump/1991/0828/sys/src/9/port/devsrv.c
278,281c
	fdtochan(fd, -1);	/* error check only */
	srv.chan[i] = u->p->fgrp->fd[fd];
	incref(u->p->fgrp->fd[fd]);
.
263,271c
	i = c->qid.path;
	if(srv.chan[i] != c)	/* already been written to */
.
259d
239,253c
	return devdirread(c, va, n, 0, 0, srvgen);
.
235,237d
215,231d
201c
	close(f);
.
189,199c
	f = srv.chan[c->qid.path];
	if(f == 0)
		error(Eshutdown);
	if(strcmp(&srv.name[c->qid.path*NAMELEN], "boot") == 0)
		error(Eperm);
	srv.chan[c->qid.path] = 0;
	unlock(&srv);
.
186c
		unlock(&srv);
.
184c
	lock(&srv);
.
181,182c
	if(c->qid.path == CHDIR)
.
179c
	Chan *f;
.
173c
	c->mode = OWRITE;
.
170,171c
	strcpy(&srv.name[j*NAMELEN], name);
	c->qid.path = j;
.
158,168c
	}
	if(j == -1)
		error(Enosrv);
	srv.chan[j] = c;
	unlock(&srv);
.
155,156c
	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)
.
148,152c
	if(omode != OWRITE)
		error(Eperm);
	lock(&srv);
	if(waserror()){
		unlock(&srv);
.
146c
	int j, i;
.
139a
	unlock(&srv);
	poperror();
.
134c
	if(omode&OTRUNC)
.
130,132c
	lock(&srv);
	if(waserror()){
		unlock(&srv);
		nexterror();
	}
	f = srv.chan[c->qid.path];
	if(f == 0)
.
122c
	if(c->qid.path == CHDIR){
.
119d
110,113c
	devstat(c, db, 0, 0, srvgen);
.
82,104c
	return devwalk(c, name, 0, 0, srvgen);
.
75,76c
	return devclone(c, nc);
.
56,69c
	return devattach('s', spec);
.
39,52d
36a
	srv.chan = ialloc(conf.nsrv*sizeof(Chan*), 0);
	srv.name = ialloc(conf.nsrv*NAMELEN, 0);
.
28a
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, (Qid){s, 0}, &srv.name[s*NAMELEN], 0, 0666, dp);
	return 1;
}

.
19,27c
	char	*name;
	Chan	**chan;
}srv;
.
10,17c
typedef struct	Srv Srv;
struct Srv{
.
8d
6a

.
## diffname port/devsrv.c 1991/0921
## diff -e /n/bootesdump/1991/0828/sys/src/9/port/devsrv.c /n/bootesdump/1991/0921/sys/src/9/port/devsrv.c
184c
	incref(srv.chan[i]);
.
## diffname port/devsrv.c 1991/1011
## diff -e /n/bootesdump/1991/0921/sys/src/9/port/devsrv.c /n/bootesdump/1991/1011/sys/src/9/port/devsrv.c
182c
	fdtochan(fd, -1, 0);	/* error check only */
.
## diffname port/devsrv.c 1991/1109
## diff -e /n/bootesdump/1991/1011/sys/src/9/port/devsrv.c /n/bootesdump/1991/1109/sys/src/9/port/devsrv.c
24c
	devdir(c, (Qid){s, 0}, &srv.name[s*NAMELEN], 0, eve, 0666, dp);
.
## diffname port/devsrv.c 1991/1115
## diff -e /n/bootesdump/1991/1109/sys/src/9/port/devsrv.c /n/bootesdump/1991/1115/sys/src/9/port/devsrv.c
158a
	USED(c);
.
152a
	USED(c, dp);
.
## diffname port/devsrv.c 1991/1127
## diff -e /n/bootesdump/1991/1115/sys/src/9/port/devsrv.c /n/bootesdump/1991/1127/sys/src/9/port/devsrv.c
186a
	unlock(f);
.
185c
	srv.chan[i] = f->fd[fd];
.
183a
	f = u->p->fgrp;
	lock(f);
.
172a
	Fgrp *f;
.
## diffname port/devsrv.c 1991/1219
## diff -e /n/bootesdump/1991/1127/sys/src/9/port/devsrv.c /n/bootesdump/1991/1219/sys/src/9/port/devsrv.c
188,189c
	srv[i].chan = f->fd[fd];
	incref(srv[i].chan);
.
178c
	if(srv[i].chan != c)	/* already been written to */
.
144,145c
	srv[c->qid.path].chan = 0;
	unlock(&srvlk);
.
142c
	if(strcmp(srv[c->qid.path].name, "boot") == 0)
.
139c
	f = srv[c->qid.path].chan;
.
136c
		unlock(&srvlk);
.
134c

	lock(&srvlk);
.
121c
	strncpy(sp->name, name, NAMELEN);
	strncpy(sp->owner, u->p->user, NAMELEN);
	sp->perm = perm&0777;

.
118,119c
	sp = &srv[j];
	sp->chan = c;
	unlock(&srvlk);
.
113c
		}
		else if(strcmp(name, srv[i].name) == 0)
.
110c
		if(srv[i].chan == 0){
.
105c
		unlock(&srvlk);
.
103c

	lock(&srvlk);
.
99a
	Srv *sp;
.
91c
	unlock(&srvlk);
.
82c
	f = srv[c->qid.path].chan;
.
79c
		unlock(&srvlk);
.
77c
	lock(&srvlk);
.
36,37c
	srv = ialloc(conf.nsrv*sizeof(Srv), 0);
.
24c
	devdir(c, (Qid){s, 0}, sp->name, 0, sp->owner, sp->perm, dp);
.
22c

	sp = &srv[s];
	if(sp->chan == 0)
.
19a
	Srv *sp;

.
16a
Lock	srvlk;
Srv	*srv;

.
12,15c
	char	name[NAMELEN];
	char	owner[NAMELEN];
	ulong	perm;
	Chan	*chan;
};
.
## diffname port/devsrv.c 1992/0111
## diff -e /n/bootesdump/1991/1219/sys/src/9/port/devsrv.c /n/bootesdump/1992/0111/sys/src/9/port/devsrv.c
6c
#include	"../port/error.h"
.
## diffname port/devsrv.c 1992/0114
## diff -e /n/bootesdump/1992/0111/sys/src/9/port/devsrv.c /n/bootesdump/1992/0114/sys/src/9/port/devsrv.c
127c
		exhausted("server slots");
.
## diffname port/devsrv.c 1992/0226
## diff -e /n/bootesdump/1992/0114/sys/src/9/port/devsrv.c /n/bootesdump/1992/0226/sys/src/9/port/devsrv.c
205a
	poperror();
.
201a
	if(waserror()){
		unlock(f);
		nexterror();
	}
.
## diffname port/devsrv.c 1992/0321
## diff -e /n/bootesdump/1992/0226/sys/src/9/port/devsrv.c /n/bootesdump/1992/0321/sys/src/9/port/devsrv.c
2c
#include	"../port/lib.h"
.
## diffname port/devsrv.c 1992/0520
## diff -e /n/bootesdump/1992/0321/sys/src/9/port/devsrv.c /n/bootesdump/1992/0520/sys/src/9/port/devsrv.c
209a
	poperror();

	lock(&srvlk);
	if (waserror()) {
		unlock(&srvlk);
		close(c1);
		nexterror();
	}
	i = c->qid.path;
	if(srv[i].chan != c)	/* already been written to */
		error(Egreg);
	close(c);
	srv[i].chan = c1;
	unlock(&srvlk);
.
207,208c
	c1 = f->fd[fd];
	incref(c1);
.
200a

.
192,194d
190a
	Chan *c1;
.
129a
	incref(c);
.
## diffname port/devsrv.c 1992/0607
## diff -e /n/bootesdump/1992/0520/sys/src/9/port/devsrv.c /n/bootesdump/1992/0607/sys/src/9/port/devsrv.c
221d
## diffname port/devsrv.c 1992/0620
## diff -e /n/bootesdump/1992/0607/sys/src/9/port/devsrv.c /n/bootesdump/1992/0620/sys/src/9/port/devsrv.c
220a

.
200a
	f = u->p->fgrp;
.
199d
10c
typedef struct Srv Srv;
.
## diffname port/devsrv.c 1992/0622
## diff -e /n/bootesdump/1992/0620/sys/src/9/port/devsrv.c /n/bootesdump/1992/0622/sys/src/9/port/devsrv.c
222,223c
	if(sp == 0)
		error(Enonexist);

	if(sp->chan)
		panic("srvwrite");

	sp->chan = c1;
	qunlock(&srvlk);
.
218,220c
	for(sp = srv; sp; sp = sp->link)
		if(sp->path == c->qid.path)
			break;
.
212,214c
	qlock(&srvlk);
	if(waserror()) {
		qunlock(&srvlk);
.
192d
189a
	Chan *c1;
.
188a
	Srv *sp;
.
163c

	if(sp->chan)
		close(sp->chan);
	free(sp);
.
160,161c

	*l = sp->link;
	qunlock(&srvlk);
.
155,158c
	l = &srv;
	for(sp = *l; sp; sp = sp->link) {
		if(sp->path == c->qid.path)
			break;

		l = &srv->link;
	}
	if(sp == 0)
		error(Enonexist);

	if(strcmp(sp->name, "boot") == 0)
.
152c
		qunlock(&srvlk);
.
150c
	qlock(&srvlk);
.
145a
	Srv *sp, **l;
.
137d
132a

.
117,131c
	sp->path = path++;
	sp->link = srv;
	c->qid.path = sp->path;
	srv = sp;
	qunlock(&srvlk);
.
114c
		qunlock(&srvlk);
.
112c
	sp = malloc(sizeof(Srv));
	if(sp == 0)
		error(Enomem);

	qlock(&srvlk);
.
106d
100c
	return sp->chan;
.
97,98c
	incref(sp->chan);
	qunlock(&srvlk);
.
95a

.
94c
	if(omode!=sp->chan->mode && sp->chan->mode!=ORDWR)
.
91a

.
89,90c

	for(sp = srv; sp; sp = sp->link)
		if(sp->path == c->qid.path)
			break;

	if(sp == 0 || sp->chan == 0)
.
86c
		qunlock(&srvlk);
.
84c
	qlock(&srvlk);
.
74c
	Srv *sp;
.
71c
Chan*
.
53c
Chan*
.
47c
Chan*
.
44d
38a
	path = 1;
.
29,32c
	if(sp == 0) {
		qunlock(&srvlk);
		return -1;
	}
	devdir(c, (Qid){sp->path, 0}, sp->name, 0, sp->owner, sp->perm, dp);
	qunlock(&srvlk);
.
26,27c
	qlock(&srvlk);
	for(sp = srv; sp && s; sp = sp->link)
		s--;
.
18,19c
static QLock	srvlk;
static Srv	*srv;
static int	path;
.
15a
	Srv	*link;
	ulong	path;
.
11c
struct Srv
{
.
## diffname port/devsrv.c 1992/0711
## diff -e /n/bootesdump/1992/0622/sys/src/9/port/devsrv.c /n/bootesdump/1992/0711/sys/src/9/port/devsrv.c
212a
	USED(offset);
.
210c
	int fd;
.
199a
	USED(offset);
.
151d
29a
	USED(tab);
	USED(ntab);
.
## diffname port/devsrv.c 1992/0825
## diff -e /n/bootesdump/1992/0711/sys/src/9/port/devsrv.c /n/bootesdump/1992/0825/sys/src/9/port/devsrv.c
222,232c
	c1 = fdtochan(fd, -1, 0, 1);	/* error check only */
.
210d
## diffname port/devsrv.c 1993/0501
## diff -e /n/bootesdump/1992/0825/sys/src/9/port/devsrv.c /n/fornaxdump/1993/0501/sys/src/brazil/port/devsrv.c
242a
}

void
srvrecover(Chan *old, Chan *new)
{
	Srv *sp;

	qlock(&srvlk);
	for(sp = srv; sp; sp = sp->link) {
		if(sp->chan == old) {
			sp->chan = new;
			incref(new);
			qunlock(&srvlk);
			close(old);
			return;
		}
	}
	qunlock(&srvlk);
.
221c
	c1 = fdtochan(fd, -1, 0, 1);	/* error check and inc ref */
.
143c
	strncpy(sp->owner, up->user, NAMELEN);
.
135c
	sp->path = qidpath++;
.
48c
	qidpath = 1;
.
23c
static int	qidpath;
.
## diffname port/devsrv.c 1993/0701
## diff -e /n/fornaxdump/1993/0501/sys/src/brazil/port/devsrv.c /n/fornaxdump/1993/0701/sys/src/brazil/port/devsrv.c
168c
		l = &sp->link;
.
## diffname port/devsrv.c 1994/1018
## diff -e /n/fornaxdump/1993/0701/sys/src/brazil/port/devsrv.c /n/fornaxdump/1994/1018/sys/src/brazil/port/devsrv.c
188,189c
	Dir d;
	Srv *sp;

	if(!iseve())
		error(Eperm);
	if(CHDIR & c->qid.path)
		error(Eperm);

	qlock(&srvlk);
	if(waserror()){
		qunlock(&srvlk);
		nexterror();
	}

	for(sp = srv; sp; sp = sp->link)
		if(sp->path == c->qid.path)
			break;
	if(sp == 0 || sp->chan == 0)
		error(Eshutdown);
	convM2D(dp, &d);
	d.mode &= 0777;
	sp->perm = d.mode;

	qunlock(&srvlk);
	poperror();
.
## diffname port/devsrv.c 1995/0108
## diff -e /n/fornaxdump/1994/1018/sys/src/brazil/port/devsrv.c /n/fornaxdump/1995/0108/sys/src/brazil/port/devsrv.c
265a
}

long
srvbwrite(Chan *c, Block *bp, ulong offset)
{
	return devbwrite(c, bp, offset);
.
228a
Block*
srvbread(Chan *c, long n, ulong offset)
{
	return devbread(c, n, offset);
}

.
## diffname port/devsrv.c 1995/0804
## diff -e /n/fornaxdump/1995/0108/sys/src/brazil/port/devsrv.c /n/fornaxdump/1995/0804/sys/src/brazil/port/devsrv.c
243d
236c
srvwrite(Chan *c, void *va, long n, ulong)
.
224d
222c
srvread(Chan *c, void *va, long n, ulong)
.
218d
216c
srvclose(Chan*)
.
30,31d
26c
srvgen(Chan *c, Dirtab*, int, int s, Dir *dp)
.
## diffname port/devsrv.c 1996/0223
## diff -e /n/fornaxdump/1995/0804/sys/src/brazil/port/devsrv.c /n/fornaxdump/1996/0223/sys/src/brazil/port/devsrv.c
8d
## diffname port/devsrv.c 1997/0327
## diff -e /n/fornaxdump/1996/0223/sys/src/brazil/port/devsrv.c /n/emeliedump/1997/0327/sys/src/brazil/port/devsrv.c
285c
			cclose(old);
.
268,272c
Dev srvdevtab = {
	devreset,
	srvinit,
	srvattach,
	devclone,
	srvwalk,
	srvstat,
	srvopen,
	srvcreate,
	srvclose,
	srvread,
	devbread,
	srvwrite,
	devbwrite,
	srvremove,
	srvwstat,
};
.
249c
		cclose(c1);
.
224,230c
static long
.
217c
static long
.
212c
static void
.
182c
static void
.
178c
		cclose(sp->chan);
.
147c
static void
.
115c
static void
.
108c
	cclose(c);
.
77c
static Chan*
.
71c
static void
.
59,65c
static int
.
48,53c
static Chan*
.
42c
static void
.
24c
static int
.
## diffname port/devsrv.c 1997/0408
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/port/devsrv.c /n/emeliedump/1997/0408/sys/src/brazil/port/devsrv.c
251a
	's',
	"srv",

.
## diffname port/devsrv.c 1998/0319
## diff -e /n/emeliedump/1997/0408/sys/src/brazil/port/devsrv.c /n/emeliedump/1998/0319/sys/src/brazil/port/devsrv.c
214c
srvwrite(Chan *c, void *va, long n, vlong)
.
207c
srvread(Chan *c, void *va, long n, vlong)
.
## diffname port/devsrv.c 1999/0122
## diff -e /n/emeliedump/1998/0319/sys/src/brazil/port/devsrv.c /n/emeliedump/1999/0122/sys/src/brazil/port/devsrv.c
243c
		error(Ebadusefd);
.
235,238c
	sp = srvlookup(nil, c->qid.path);
.
203a
	/*
	 * errors from srvremove will be caught by cclose and ignored.
	 * in theory we need to override any changes in removability
	 * since open, but since all that's checked is the owner,
	 * which is immutable, all is well.
	 */
	if(c->flag & CRCLOSE)
		srvremove(c);
.
202c
srvclose(Chan *c)
.
188,192c
	sp = srvlookup(nil, c->qid.path);
	if(sp == 0)
		error(Enonexist);

	if(strcmp(sp->owner, up->user) && !iseve())
		error(Eperm);

.
179,180d
177c
	if(c->qid.path & CHDIR)
.
120a
	if(srvlookup(name, -1))
		error(Eexist);

.
111a
	if(omode & OCEXEC)	/* can't happen */
		panic("someone broke namec");

.
109c
	if(openmode(omode) != OWRITE)
.
94c
	if(openmode(omode)!=sp->chan->mode && sp->chan->mode!=ORDWR)
.
85,88c
	sp = srvlookup(nil, c->qid.path);
.
71a
		if(omode & ORCLOSE)
			error(Eperm);
.
65a
static Srv*
srvlookup(char *name, ulong qidpath)
{
	Srv *sp;
	for(sp = srv; sp; sp = sp->link)
		if(sp->path == qidpath || (name && strcmp(sp->name, name) == 0))
			return sp;
	return nil;
}

.
## diffname port/devsrv.c 1999/0629
## diff -e /n/emeliedump/1999/0122/sys/src/brazil/port/devsrv.c /n/emeliedump/1999/0629/sys/src/brazil/port/devsrv.c
75a
char*
srvname(Chan *c)
{
	Srv *sp;
	char *s;

	for(sp = srv; sp; sp = sp->link)
		if(sp->chan == c){
			s = smalloc(3+strlen(sp->name)+1);
			sprint(s, "#s/%s", sp->name);
			return s;
		}
	return nil;
}

.
## diffname port/devsrv.c 1999/0716
## diff -e /n/emeliedump/1999/0629/sys/src/brazil/port/devsrv.c /n/emeliedump/1999/0716/sys/src/brazil/port/devsrv.c
272a
	if(c1->flag & (CCEXEC|CRCLOSE))
		error("posted fd has remove-on-close or close-on-exec");
.
117c
		error("srv file already exists");
.
## diffname port/devsrv.c 1999/1105
## diff -e /n/emeliedump/1999/0716/sys/src/brazil/port/devsrv.c /n/emeliedump/1999/1105/sys/src/9/port/devsrv.c
308,325d
## diffname port/devsrv.c 1999/1230
## diff -e /n/emeliedump/1999/1105/sys/src/9/port/devsrv.c /n/emeliedump/1999/1230/sys/src/9/port/devsrv.c
28a
	if(s == DEVDOTDOT){
		devdir(c, c->qid, "#s", 0, eve, 0555, dp);
		return 1;
	}

.
## diffname port/devsrv.c 2000/0718
## diff -e /n/emeliedump/1999/1230/sys/src/9/port/devsrv.c /n/emeliedump/2000/0718/sys/src/9/port/devsrv.c
124a
	devpermcheck(sp->owner, sp->perm, omode);
.
## diffname port/devsrv.c 2001/0503
## diff -e /n/emeliedump/2000/0718/sys/src/9/port/devsrv.c /n/emeliedump/2001/0503/sys/src/9/port/devsrv.c
247a
		poperror();
	}
.
246c
	if(c->flag & CRCLOSE){
		if(waserror())
			return;
.
241d
## diffname port/devsrv.c 2001/0527
## diff -e /n/emeliedump/2001/0503/sys/src/9/port/devsrv.c /n/emeliedump/2001/0527/sys/src/9/port/devsrv.c
304d
234a
	return n;
.
229,231c
	n = convM2D(dp, n, &d, nil);
	if(n > 0)
		sp->perm = d.mode & 0777;
.
213c
	if(c->qid.type & QTDIR)
.
207,208c
static int
srvwstat(Chan *c, uchar *dp, int n)
.
203a
	if(sp->name){
		free(sp->name);
		sp->name = nil;
	}
.
177c
	if(c->qid.type == QTDIR)
.
164,165c
	sp->name = smalloc(strlen(name)+1);
	strcpy(sp->name, name);
	kstrdup(&sp->owner, up->user);
.
158a
	c->qid.type = QTFILE;
.
150a
		free(sp);
.
101c
	if(c->qid.type == QTDIR){
.
80a
static int
srvstat(Chan *c, uchar *db, int n)
{
	return devstat(c, db, n, 0, 0, srvgen);
}

.
65,70d
62c
	return devwalk(c, nc, name, nname, 0, 0, srvgen);
.
59,60c
static Walkqid*
srvwalk(Chan *c, Chan *nc, char **name, int nname)
.
42c

	mkqid(&q, sp->path, 0, QTFILE);
	/* make sure name string continues to exist after we release lock */
	kstrcpy(up->genbuf, sp->name, sizeof up->genbuf);
	devdir(c, q, up->genbuf, 0, sp->owner, sp->perm, dp);
.
27a
	Qid q;
.
25c
srvgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp)
.
12,13c
	char	*name;
	char	*owner;
.
## diffname port/devsrv.c 2001/0819
## diff -e /n/emeliedump/2001/0527/sys/src/9/port/devsrv.c /n/emeliedump/2001/0819/sys/src/9/port/devsrv.c
296a
	if(c1->qid.type & QTAUTH)
		error("can't post auth file in srv");
.
## diffname port/devsrv.c 2001/1106
## diff -e /n/emeliedump/2001/0819/sys/src/9/port/devsrv.c /n/emeliedump/2001/1106/sys/src/9/port/devsrv.c
242c
	if(n == 0)
		error (Eshortstat);
	if(d.mode != ~0UL)
.
## diffname port/devsrv.c 2002/0109
## diff -e /n/emeliedump/2001/1106/sys/src/9/port/devsrv.c /n/emeliedump/2002/0109/sys/src/9/port/devsrv.c
319c
	srvinit,	
	devshutdown,
.

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].