1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4 #include <fcall.h>
5 #include <bio.h>
6 #include "tapefs.h"
7
8 Idmap *
getpass(char * file)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 *
mapid(Idmap * up,int id)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 *
poppath(Fileinf fi,int new)59 poppath(Fileinf fi, int new)
60 {
61 char *suffix, *origname;
62 Ram *dir, *ent;
63 Fileinf f;
64
65 if (*fi.name=='\0')
66 return 0;
67 origname = estrdup(fi.name);
68 if (suffix=strrchr(fi.name, '/')){
69 *suffix = 0;
70 suffix++;
71 if (*suffix=='\0'){
72 fi.mode |= DMDIR;
73 free(origname);
74 return poppath(fi, 1);
75 }
76 /*
77 * create parent directory of suffix;
78 * may recurse, thus shortening fi.name even further.
79 */
80 f = fi;
81 f.size = 0;
82 f.addr = 0;
83 f.mode = 0555|DMDIR;
84 dir = poppath(f, 0);
85 if (dir==0)
86 dir = ram;
87 } else {
88 suffix = fi.name;
89 dir = ram;
90 if (strcmp(suffix, ".")==0) {
91 free(origname);
92 return dir;
93 }
94 }
95 ent = lookup(dir, suffix);
96 fi.mode |= 0400; /* at least user read */
97 if (ent){
98 if (((fi.mode&DMDIR)!=0) != ((ent->qid.type&QTDIR)!=0)){
99 fprint(2,
100 "%s file type changed; probably due to union dir.; ignoring\n",
101 origname);
102 free(origname);
103 return ent;
104 }
105 if (new) {
106 ent->ndata = fi.size;
107 ent->addr = fi.addr;
108 ent->data = fi.data;
109 ent->perm = fi.mode;
110 ent->mtime = fi.mdate;
111 ent->user = mapid(uidmap, fi.uid);
112 ent->group = mapid(gidmap, fi.gid);
113 }
114 } else {
115 fi.name = suffix;
116 ent = popfile(dir, fi);
117 }
118 free(origname);
119 return ent;
120 }
121
122 Ram *
popfile(Ram * dir,Fileinf fi)123 popfile(Ram *dir, Fileinf fi)
124 {
125 Ram *ent = (Ram *)emalloc(sizeof(Ram));
126 if (*fi.name=='\0')
127 return 0;
128 ent->busy = 1;
129 ent->open = 0;
130 ent->parent = dir;
131 ent->next = dir->child;
132 dir->child = ent;
133 ent->child = 0;
134 ent->qid.path = ++path;
135 ent->qid.vers = 0;
136 if(fi.mode&DMDIR)
137 ent->qid.type = QTDIR;
138 else
139 ent->qid.type = QTFILE;
140 ent->perm = fi.mode;
141 ent->name = estrdup(fi.name);
142 ent->atime = ent->mtime = fi.mdate;
143 ent->user = mapid(uidmap, fi.uid);
144 ent->group = mapid(gidmap, fi.gid);
145 ent->ndata = fi.size;
146 ent->data = fi.data;
147 ent->addr = fi.addr;
148 ent->replete |= replete;
149 return ent;
150 }
151
152 Ram *
lookup(Ram * dir,char * name)153 lookup(Ram *dir, char *name)
154 {
155 Ram *r;
156
157 if (dir==0)
158 return 0;
159 for (r=dir->child; r; r=r->next){
160 if (r->busy==0 || strcmp(r->name, name)!=0)
161 continue;
162 return r;
163 }
164 return 0;
165 }
166