plan 9 kernel history: overview | file list | diff list

1992/1217/port/dev.c (diff list | history)

port/dev.c on 1990/0227
1990/0227    
#include	"u.h" 
1992/0321    
#include	"../port/lib.h" 
1990/0227    
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
1992/0111    
#include	"../port/error.h" 
1990/0227    
#define	DEVTAB 
#include	"devtab.h" 
 
1991/1220    
extern ulong	kerndate; 
 
1990/0227    
int 
devno(int c, int user) 
{ 
1992/1217    
	Rune *s; 
	int i; 
1990/0227    
 
1992/1217    
	s = devchar; 
	i = 0; 
	while(*s){ 
		if(c == *s) 
			return i; 
		i++; 
		s++; 
1990/0227    
	} 
1992/1217    
 
	if(user) 
		return -1; 
	panic("devno %C 0x%ux", c, c); 
	return 0; 
1990/0227    
} 
 
void 
1991/1109    
devdir(Chan *c, Qid qid, char *n, long length, char *user, long perm, Dir *db) 
1990/0227    
{ 
	strcpy(db->name, n); 
	db->qid = qid; 
	db->type = devchar[c->type]; 
	db->dev = c->dev; 
1990/11211    
	if(qid.path & CHDIR) 
1990/0227    
		db->mode = CHDIR|perm; 
	else 
		db->mode = perm; 
	db->atime = seconds(); 
1991/1220    
	db->mtime = kerndate; 
1990/0227    
	db->hlength = 0; 
	db->length = length; 
1991/1112    
	strncpy(db->uid, user, NAMELEN); 
	strncpy(db->gid, eve, NAMELEN); 
1990/0227    
} 
 
int 
devgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) 
{ 
	if(tab==0 || i>=ntab) 
		return -1; 
	tab += i; 
1991/1109    
	devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp); 
1990/0227    
	return 1; 
} 
 
Chan * 
devattach(int tc, char *spec) 
{ 
	Chan *c; 
 
1992/0711    
	USED(spec); 
1990/0227    
	c = newchan(); 
1990/11211    
	c->qid = (Qid){CHDIR, 0}; 
1990/0227    
	c->type = devno(tc, 0); 
	return c; 
} 
 
Chan * 
devclone(Chan *c, Chan *nc) 
{ 
1990/0329    
	if(c->flag & COPEN) 
1992/1217    
		panic("clone of open file type %C\n", devchar[c->type]); 
1990/0227    
	if(nc == 0) 
		nc = newchan(); 
	nc->type = c->type; 
1991/0421    
	nc->dev = c->dev; 
1990/0227    
	nc->mode = c->mode; 
	nc->qid = c->qid; 
	nc->offset = c->offset; 
	nc->flag = c->flag; 
	nc->mnt = c->mnt; 
1991/0427    
	nc->mountid = c->mountid; 
1991/0421    
	nc->aux = c->aux; 
1990/0303    
	nc->mchan = c->mchan; 
	nc->mqid = c->mqid; 
1990/0227    
	return nc; 
} 
 
int 
devwalk(Chan *c, char *name, Dirtab *tab, int ntab, Devgen *gen) 
{ 
	long i; 
	Dir dir; 
 
	isdir(c); 
	if(name[0]=='.' && name[1]==0) 
		return 1; 
	for(i=0;; i++) 
		switch((*gen)(c, tab, ntab, i, &dir)){ 
		case -1: 
1992/0111    
			strncpy(u->error, Enonexist, NAMELEN); 
1990/0227    
			return 0; 
		case 0: 
			continue; 
		case 1: 
			if(strcmp(name, dir.name) == 0){ 
				c->qid = dir.qid; 
				return 1; 
			} 
			continue; 
		} 
1992/0520    
	return 1;	/* not reached */ 
1991/0411    
} 
 
1990/0227    
void 
devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen) 
{ 
	int i; 
	Dir dir; 
 
	for(i=0;; i++) 
		switch((*gen)(c, tab, ntab, i, &dir)){ 
		case -1: 
			/* 
1991/1206    
			 *  given a channel, we cannot derive the directory name 
			 *  that the channel was generated from since it was lost 
			 *  by namec. 
1990/0227    
			 */ 
1990/11211    
			if(c->qid.path & CHDIR){ 
1991/1109    
				devdir(c, c->qid, ".", 0L, eve, CHDIR|0700, &dir); 
1990/0227    
				convD2M(&dir, db); 
				return; 
			} 
1992/1217    
			print("%s %s: devstat %C %lux\n", u->p->text, u->p->user, 
1991/1120    
							devchar[c->type], c->qid.path); 
1991/0626    
			error(Enonexist); 
1990/0227    
		case 0: 
			break; 
		case 1: 
1990/11211    
			if(eqqid(c->qid, dir.qid)){ 
1990/0227    
				convD2M(&dir, db); 
				return; 
			} 
			break; 
		} 
} 
 
long 
devdirread(Chan *c, char *d, long n, Dirtab *tab, int ntab, Devgen *gen) 
{ 
1990/0821    
	long k, m; 
1990/0227    
	Dir dir; 
 
	k = c->offset/DIRLEN; 
1990/0821    
	for(m=0; m<n; k++) 
1990/0227    
		switch((*gen)(c, tab, ntab, k, &dir)){ 
		case -1: 
1990/0821    
			return m; 
1990/0227    
 
		case 0: 
			c->offset += DIRLEN; 
			break; 
 
		case 1: 
			convD2M(&dir, d); 
1990/0821    
			m += DIRLEN; 
1990/0227    
			d += DIRLEN; 
			break; 
		} 
1990/0821    
	return m; 
1990/0227    
} 
 
Chan * 
devopen(Chan *c, int omode, Dirtab *tab, int ntab, Devgen *gen) 
{ 
	int i; 
	Dir dir; 
1991/1112    
	ulong t, mode; 
1990/0227    
	static int access[] = { 0400, 0200, 0600, 0100 }; 
 
	for(i=0;; i++) 
		switch((*gen)(c, tab, ntab, i, &dir)){ 
		case -1: 
			goto Return; 
		case 0: 
			break; 
		case 1: 
1991/1112    
			if(eqqid(c->qid, dir.qid)) { 
				if(strcmp(u->p->user, dir.uid) == 0)	/* User */ 
					mode = dir.mode; 
1991/1206    
				else if(strcmp(u->p->user, eve) == 0)	/* eve is group */ 
1991/1112    
					mode = dir.mode<<3; 
				else 
					mode = dir.mode<<6;		/* Other */ 
 
				t = access[omode&3]; 
				if((t & mode) == t) 
1990/0227    
					goto Return; 
1990/11211    
				error(Eperm); 
1990/0227    
			} 
			break; 
		} 
    Return: 
	c->offset = 0; 
1990/11211    
	if((c->qid.path&CHDIR) && omode!=OREAD) 
		error(Eperm); 
1990/0227    
	c->mode = openmode(omode); 
	c->flag |= COPEN; 
	return c; 
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)