174 lines · 3.3 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include <u.h>#include <libc.h>#include <auth.h>#include <fcall.h>#include <bio.h>#include "tapefs.h" Idmap *getpass(char *file){	Biobuf *bp;	char *cp;	Idmap *up;	int nid, maxid;	char *line[4]; 	if ((bp = Bopen(file, OREAD)) == 0)		error("Can't open passwd/group");	up = emalloc(1*sizeof(Idmap));	maxid = 1;	nid = 0;	while ((cp = Brdline(bp, '\n'))) {		int nf;		cp[Blinelen(bp)-1] = 0;		nf = getfields(cp, line, 3, 0, ":\n");		if (nf<3) {			fprint(2, "bad format in %s\n", file);			break;		}		if (nid>=maxid) {			maxid *= 2;			up = (Idmap *)erealloc(up, maxid*sizeof(Idmap));		}		up[nid].id = atoi(line[2]);		up[nid].name = strdup(line[0]);		nid++;	}			Bterm(bp);	up[nid].name = 0;	return up;} char *mapid(Idmap *up, int id){	char buf[16]; 	if (up)		while (up->name){			if (up->id==id)				return strdup(up->name);			up++;		}	sprint(buf, "%d", id);	return strdup(buf);} Ram *poppath(Fileinf fi, int new){	char *suffix, *origname;	Ram *dir, *ent;	Fileinf f; 	if (*fi.name=='\0')		return 0;	origname = estrdup(fi.name);	if (suffix=strrchr(fi.name, '/')){		*suffix = 0;		suffix++;		if (*suffix=='\0'){			fi.mode |= DMDIR;			free(origname);			return poppath(fi, 1);		}		/*		 * create parent directory of suffix;		 * may recurse, thus shortening fi.name even further.		 */		f = fi;		f.size = 0;		f.addr = 0;		f.mode = 0555|DMDIR;		dir = poppath(f, 0);		if (dir==0)			dir = ram;	} else {		suffix = fi.name;		dir = ram;		if (strcmp(suffix, ".")==0) {			free(origname);			return dir;		}	}	ent = lookup(dir, suffix);	fi.mode |= 0400;			/* at least user read */	if (ent){		if (((fi.mode&DMDIR)!=0) != ((ent->qid.type&QTDIR)!=0)){			fprint(2,		"%s file type changed; probably due to union dir.; ignoring\n",				origname);			free(origname);			return ent;		}		if (new)  {			ent->ndata = fi.size;			ent->addr = fi.addr;			ent->data = fi.data;			ent->perm = fi.mode;			ent->mtime = fi.mdate;			ent->user = mapid(uidmap, fi.uid);			ent->group = mapid(gidmap, fi.gid);		}	} else {		fi.name = suffix;		ent = popfile(dir, fi);	}	free(origname);	return ent;} Ram *popfile(Ram *dir, Fileinf fi){	Ram *ent = (Ram *)emalloc(sizeof(Ram));	if (*fi.name=='\0')		return 0;	ent->busy = 1;	ent->open = 0;	ent->parent = dir;	ent->next = dir->child;	dir->child = ent;	ent->child = 0;	ent->qid.path = ++path;	ent->qid.vers = 0;	if(fi.mode&DMDIR)		ent->qid.type = QTDIR;	else		ent->qid.type = QTFILE;	ent->perm = fi.mode;	ent->name = estrdup(fi.name);	ent->atime = ent->mtime = fi.mdate;	ent->user = mapid(uidmap, fi.uid);	ent->group = mapid(gidmap, fi.gid);	ent->ndata = fi.size;	ent->data = fi.data;	ent->addr = fi.addr;	ent->replete |= replete;	return ent;} Ram *lookup(Ram *dir, char *name){	Ram *r; 	if (dir==0)		return 0;	for (r=dir->child; r; r=r->next){		if (r->busy==0 || strcmp(r->name, name)!=0)			continue;		return r;	}	return 0;}