xref: /plan9/sys/src/cmd/tapefs/util.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1bd389b36SDavid du Colombier #include <u.h>
2bd389b36SDavid du Colombier #include <libc.h>
3219b2ee8SDavid du Colombier #include <auth.h>
4bd389b36SDavid du Colombier #include <fcall.h>
5bd389b36SDavid du Colombier #include <tapefs.h>
6bd389b36SDavid du Colombier #include <bio.h>
7bd389b36SDavid du Colombier 
8bd389b36SDavid du Colombier Idmap *
9bd389b36SDavid du Colombier getpass(char *file)
10bd389b36SDavid du Colombier {
11bd389b36SDavid du Colombier 	Biobuf *bp;
12bd389b36SDavid du Colombier 	char *cp;
13bd389b36SDavid du Colombier 	Idmap *up;
14bd389b36SDavid du Colombier 	int nid, maxid;
15bd389b36SDavid du Colombier 	char *line[4];
16bd389b36SDavid du Colombier 
17bd389b36SDavid du Colombier 	if ((bp = Bopen(file, OREAD)) == 0)
18bd389b36SDavid du Colombier 		error("Can't open passwd/group");
19bd389b36SDavid du Colombier 	up = emalloc(1*sizeof(Idmap));
20bd389b36SDavid du Colombier 	maxid = 1;
21bd389b36SDavid du Colombier 	nid = 0;
22bd389b36SDavid du Colombier 	while ((cp = Brdline(bp, '\n'))) {
23*7dd7cddfSDavid du Colombier 		int nf;
24*7dd7cddfSDavid du Colombier 		cp[Blinelen(bp)-1] = 0;
25*7dd7cddfSDavid du Colombier 		nf = getfields(cp, line, 3, 0, ":\n");
26*7dd7cddfSDavid du Colombier 		if (nf<3) {
27*7dd7cddfSDavid du Colombier 			fprint(2, "bad format in %s\n", file);
28*7dd7cddfSDavid du Colombier 			break;
29*7dd7cddfSDavid du Colombier 		}
30bd389b36SDavid du Colombier 		if (nid>=maxid) {
31bd389b36SDavid du Colombier 			maxid *= 2;
32bd389b36SDavid du Colombier 			up = (Idmap *)erealloc(up, maxid*sizeof(Idmap));
33bd389b36SDavid du Colombier 		}
34bd389b36SDavid du Colombier 		up[nid].id = atoi(line[2]);
35bd389b36SDavid du Colombier 		up[nid].name = strdup(line[0]);
36bd389b36SDavid du Colombier 		nid++;
37bd389b36SDavid du Colombier 	}
38219b2ee8SDavid du Colombier 	Bterm(bp);
39bd389b36SDavid du Colombier 	up[nid].name = 0;
40bd389b36SDavid du Colombier 	return up;
41bd389b36SDavid du Colombier }
42bd389b36SDavid du Colombier 
43bd389b36SDavid du Colombier char *
44bd389b36SDavid du Colombier mapid(Idmap *up, int id)
45bd389b36SDavid du Colombier {
46bd389b36SDavid du Colombier 	char buf[16];
47bd389b36SDavid du Colombier 
48bd389b36SDavid du Colombier 	if (up)
49bd389b36SDavid du Colombier 		while (up->name){
50bd389b36SDavid du Colombier 			if (up->id==id)
51bd389b36SDavid du Colombier 				return strdup(up->name);
52bd389b36SDavid du Colombier 			up++;
53bd389b36SDavid du Colombier 		}
54bd389b36SDavid du Colombier 	sprint(buf, "%d", id);
55bd389b36SDavid du Colombier 	return strdup(buf);
56bd389b36SDavid du Colombier }
57bd389b36SDavid du Colombier 
58bd389b36SDavid du Colombier Ram *
59bd389b36SDavid du Colombier poppath(Fileinf fi, int new)
60bd389b36SDavid du Colombier {
61bd389b36SDavid du Colombier 	char *suffix;
62bd389b36SDavid du Colombier 	Ram *dir, *ent;
63*7dd7cddfSDavid du Colombier 	Fileinf f;
64*7dd7cddfSDavid du Colombier 
65bd389b36SDavid du Colombier 	if (*fi.name=='\0')
66bd389b36SDavid du Colombier 		return 0;
67bd389b36SDavid du Colombier 	if (suffix=strrchr(fi.name, '/')){
68bd389b36SDavid du Colombier 		*suffix = 0;
69bd389b36SDavid du Colombier 		suffix++;
70bd389b36SDavid du Colombier 		if (*suffix=='\0'){
71bd389b36SDavid du Colombier 			fi.mode |= CHDIR;
72bd389b36SDavid du Colombier 			return poppath(fi, 1);
73bd389b36SDavid du Colombier 		}
74bd389b36SDavid du Colombier 		f = fi;
75bd389b36SDavid du Colombier 		f.size = 0;
76bd389b36SDavid du Colombier 		f.addr = 0;
77bd389b36SDavid du Colombier 		f.mode = 0555|CHDIR;
78bd389b36SDavid du Colombier 		dir = poppath(f, 0);
79219b2ee8SDavid du Colombier 		if (dir==0)
80219b2ee8SDavid du Colombier 			dir = ram;
81bd389b36SDavid du Colombier 	} else {
82bd389b36SDavid du Colombier 		suffix = fi.name;
83bd389b36SDavid du Colombier 		dir = ram;
84bd389b36SDavid du Colombier 		if (strcmp(suffix, ".")==0)
85bd389b36SDavid du Colombier 			return dir;
86bd389b36SDavid du Colombier 	}
87bd389b36SDavid du Colombier 	ent = lookup(dir, suffix);
88bd389b36SDavid du Colombier 	fi.mode |= 0400;			/* at least user read */
89bd389b36SDavid du Colombier 	if (ent){
90bd389b36SDavid du Colombier 		if ((fi.mode&CHDIR) != (ent->qid.path&CHDIR)){
91bd389b36SDavid du Colombier 			fprint(2, "%s/%s directory botch\n", fi.name, suffix);
92bd389b36SDavid du Colombier 			exits("");
93bd389b36SDavid du Colombier 		}
94bd389b36SDavid du Colombier 		if (new)  {
95bd389b36SDavid du Colombier 			ent->ndata = fi.size;
96bd389b36SDavid du Colombier 			ent->data = fi.addr;
97bd389b36SDavid du Colombier 			ent->perm = fi.mode;
98bd389b36SDavid du Colombier 			ent->mtime = fi.mdate;
99bd389b36SDavid du Colombier 			ent->user = mapid(uidmap, fi.uid);
100bd389b36SDavid du Colombier 			ent->group = mapid(gidmap, fi.gid);
101bd389b36SDavid du Colombier 		}
102bd389b36SDavid du Colombier 	} else {
103*7dd7cddfSDavid du Colombier 		fi.name = suffix;
104bd389b36SDavid du Colombier 		ent = popfile(dir, fi);
105bd389b36SDavid du Colombier 	}
106bd389b36SDavid du Colombier 	return ent;
107bd389b36SDavid du Colombier }
108bd389b36SDavid du Colombier 
109bd389b36SDavid du Colombier Ram *
110bd389b36SDavid du Colombier popfile(Ram *dir, Fileinf fi)
111bd389b36SDavid du Colombier {
112bd389b36SDavid du Colombier 	Ram *ent = (Ram *)emalloc(sizeof(Ram));
113bd389b36SDavid du Colombier 	if (*fi.name=='\0')
114bd389b36SDavid du Colombier 		return 0;
115bd389b36SDavid du Colombier 	ent->busy = 1;
116bd389b36SDavid du Colombier 	ent->open = 0;
117bd389b36SDavid du Colombier 	ent->parent = dir;
118bd389b36SDavid du Colombier 	ent->next = dir->child;
119bd389b36SDavid du Colombier 	dir->child = ent;
120bd389b36SDavid du Colombier 	ent->child = 0;
121bd389b36SDavid du Colombier 	ent->qid.path = ++path | fi.mode&CHDIR;
122bd389b36SDavid du Colombier 	ent->qid.vers = 0;
123bd389b36SDavid du Colombier 	ent->perm = fi.mode;
124bd389b36SDavid du Colombier 	strncpy(ent->name, fi.name, NAMELEN);
125bd389b36SDavid du Colombier 	ent->atime = ent->mtime = fi.mdate;
126bd389b36SDavid du Colombier 	ent->user = mapid(uidmap, fi.uid);
127bd389b36SDavid du Colombier 	ent->group = mapid(gidmap, fi.gid);
128bd389b36SDavid du Colombier 	ent->ndata = fi.size;
129bd389b36SDavid du Colombier 	ent->data = fi.addr;
130bd389b36SDavid du Colombier 	ent->replete |= replete;
131bd389b36SDavid du Colombier 	return ent;
132bd389b36SDavid du Colombier }
133bd389b36SDavid du Colombier 
134bd389b36SDavid du Colombier Ram *
135bd389b36SDavid du Colombier lookup(Ram *dir, char *name)
136bd389b36SDavid du Colombier {
137bd389b36SDavid du Colombier 	Ram *r;
138bd389b36SDavid du Colombier 
139219b2ee8SDavid du Colombier 	if (dir==0)
140219b2ee8SDavid du Colombier 		return 0;
141bd389b36SDavid du Colombier 	for (r=dir->child; r; r=r->next){
142bd389b36SDavid du Colombier 		if (r->busy==0 || strcmp(r->name, name)!=0)
143bd389b36SDavid du Colombier 			continue;
144bd389b36SDavid du Colombier 		return r;
145bd389b36SDavid du Colombier 	}
146bd389b36SDavid du Colombier 	return 0;
147bd389b36SDavid du Colombier }
148