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