~kris/9p

9hist

5defe39b3175e78780c3e9ee830840861cd9619e — David du Colombier 23 years ago df1702e
Plan 9 from Bell Labs 2003-03-03
2 files changed, 47 insertions(+), 19 deletions(-)

M port/chan.c
M port/devroot.c
M port/chan.c => port/chan.c +35 -15
@@ 81,6 81,7 @@ struct Elemlist
	int	nelems;
	char	**elems;
	int	*off;
	int	mustbedir;
};

#define SEP(c) ((c) == 0 || (c) == '/')


@@ 974,6 975,10 @@ growparse(Elemlist *e)
 * The name is known to be valid.
 * Copy the name so slashes can be overwritten.
 * An empty string will set nelem=0.
 * A path ending in / or /. or /.//./ etc. will have
 * e.mustbedir = 1, so that we correctly
 * reject, e.g., "/adm/users/." when /adm/users is a file
 * rather than a directory.
 */
static void
parsename(char *name, Elemlist *e)


@@ 985,17 990,19 @@ parsename(char *name, Elemlist *e)
	e->nelems = 0;
	e->elems = nil;
	e->off = smalloc(sizeof(int));
	e->off[0] = 0;
	e->off[0] = skipslash(name) - name;
	for(;;){
		name = skipslash(name);
		if(*name=='\0')
		if(*name=='\0'){
			e->mustbedir = 1;
			break;
		}
		growparse(e);
		
		e->elems[e->nelems++] = name;
		slash = utfrune(name, '/');
		if(slash == nil){
			e->off[e->nelems] = name+strlen(name) - e->name;
			e->mustbedir = 0;
			break;
		}
		e->off[e->nelems] = slash - e->name;


@@ 1059,7 1066,6 @@ namec(char *aname, int amode, int omode, ulong perm)
	case '/':
		c = up->slash;
		incref(c);
		name = skipslash(name);
		break;
	
	case '#':


@@ 1099,7 1105,6 @@ namec(char *aname, int amode, int omode, ulong perm)
	default:
		c = up->dot;
		incref(c);
		name = skipslash(name);
		break;
	}
	prefix = name - aname;


@@ 1123,11 1128,19 @@ namec(char *aname, int amode, int omode, ulong perm)
	parsename(name, &e);

	/*
	 * On create, don't try to walk the last path element just yet.
	 * On create, ....
	 */
	if(amode == Acreate){
		/* perm must have DMDIR if last element is / or /. */
		if(e.mustbedir && !(perm&DMDIR)){
			npath = e.nelems;
			strcpy(tmperrbuf, "create without DMDIR");
			goto NameError;
		}

		/* don't try to walk the last path element just yet. */
		if(e.nelems == 0)
			error(Eisdir);
			error(Eexist);
		e.nelems--;
	}



@@ 1136,8 1149,9 @@ namec(char *aname, int amode, int omode, ulong perm)
			print("namec %s walk error npath=%d\n", aname, npath);
			nexterror();
		}
		len = prefix+e.off[npath];
		strcpy(tmperrbuf, up->errstr);
	NameError:
		len = prefix+e.off[npath];
		if(len < ERRMAX/3 || (name=memrchr(aname, '/', len))==nil || name==aname)
			snprint(up->genbuf, sizeof up->genbuf, "%.*s", len, aname);
		else


@@ 1146,6 1160,17 @@ namec(char *aname, int amode, int omode, ulong perm)
		nexterror();
	}

	if(e.mustbedir && !(c->qid.type&QTDIR)){
		npath = e.nelems;
		strcpy(tmperrbuf, "not a directory");
		goto NameError;
	}

	if(amode == Aopen && (omode&3) == OEXEC && (c->qid.type&QTDIR)){
		npath = e.nelems;
		error("cannot exec directory");
	}

	switch(amode){
	case Aaccess:
		if(!nomount)


@@ 1356,18 1381,13 @@ if(c->umh != nil){
}

/*
 * name is valid. skip leading / and ./ and trailing .
 * name is valid. skip leading / and ./ as much as possible
 */
char*
skipslash(char *name)
{
    Again:
	while(*name == '/')
		name++;
	if(*name=='.' && (name[1]=='\0' || name[1]=='/')){
	while(name[0]=='/' || (name[0]=='.' && (name[1]==0 || name[1]=='/')))
		name++;
		goto Again;
	}
	return name;
}


M port/devroot.c => port/devroot.c +12 -4
@@ 121,6 121,10 @@ rootgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp)

	switch((int)c->qid.path){
	case Qdir:
		if(s == DEVDOTDOT){
			devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp);
			return 1;
		}
		return devgen(c, name, rootlist.dir, rootlist.ndir, s, dp);
	case Qboot:
		if(s == DEVDOTDOT){


@@ 129,6 133,8 @@ rootgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp)
		}
		return devgen(c, name, bootlist.dir, bootlist.ndir, s, dp);
	default:
		if(s != 0)
			return -1;
		if((int)c->qid.path < Qboot){
			t = c->qid.path-1;
			l = &rootlist;


@@ 138,8 144,6 @@ rootgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp)
		}
		if(t >= l->ndir)
			return -1;
		if(s != 0)
			return -1;
		d = &l->dir[t];
		devdir(c, d->qid, d->name, d->length, eve, d->perm, dp);
		return 1;


@@ 196,8 200,12 @@ rootread(Chan *c, void *buf, long n, vlong off)
		l = &bootlist;
	}

	d = &l->dir[t-1];
	data = l->data[t-1];
	t--;
	if(t >= l->ndir)
		error(Egreg);

	d = &l->dir[t];
	data = l->data[t];
	if(offset >= d->length)
		return 0;
	if(offset+n > d->length)