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