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