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 <bio.h>
641fe996aSDavid du Colombier #include "tapefs.h"
7bd389b36SDavid du Colombier
8bd389b36SDavid du Colombier Idmap *
getpass(char * file)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'))) {
237dd7cddfSDavid du Colombier int nf;
247dd7cddfSDavid du Colombier cp[Blinelen(bp)-1] = 0;
257dd7cddfSDavid du Colombier nf = getfields(cp, line, 3, 0, ":\n");
267dd7cddfSDavid du Colombier if (nf<3) {
277dd7cddfSDavid du Colombier fprint(2, "bad format in %s\n", file);
287dd7cddfSDavid du Colombier break;
297dd7cddfSDavid 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 *
mapid(Idmap * up,int id)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 *
poppath(Fileinf fi,int new)59bd389b36SDavid du Colombier poppath(Fileinf fi, int new)
60bd389b36SDavid du Colombier {
61*bbd061d4SDavid du Colombier char *suffix, *origname;
62bd389b36SDavid du Colombier Ram *dir, *ent;
637dd7cddfSDavid du Colombier Fileinf f;
647dd7cddfSDavid du Colombier
65bd389b36SDavid du Colombier if (*fi.name=='\0')
66bd389b36SDavid du Colombier return 0;
67*bbd061d4SDavid du Colombier origname = estrdup(fi.name);
68bd389b36SDavid du Colombier if (suffix=strrchr(fi.name, '/')){
69bd389b36SDavid du Colombier *suffix = 0;
70bd389b36SDavid du Colombier suffix++;
71bd389b36SDavid du Colombier if (*suffix=='\0'){
729a747e4fSDavid du Colombier fi.mode |= DMDIR;
73*bbd061d4SDavid du Colombier free(origname);
74bd389b36SDavid du Colombier return poppath(fi, 1);
75bd389b36SDavid du Colombier }
76*bbd061d4SDavid du Colombier /*
77*bbd061d4SDavid du Colombier * create parent directory of suffix;
78*bbd061d4SDavid du Colombier * may recurse, thus shortening fi.name even further.
79*bbd061d4SDavid du Colombier */
80bd389b36SDavid du Colombier f = fi;
81bd389b36SDavid du Colombier f.size = 0;
82bd389b36SDavid du Colombier f.addr = 0;
839a747e4fSDavid du Colombier f.mode = 0555|DMDIR;
84bd389b36SDavid du Colombier dir = poppath(f, 0);
85219b2ee8SDavid du Colombier if (dir==0)
86219b2ee8SDavid du Colombier dir = ram;
87bd389b36SDavid du Colombier } else {
88bd389b36SDavid du Colombier suffix = fi.name;
89bd389b36SDavid du Colombier dir = ram;
90*bbd061d4SDavid du Colombier if (strcmp(suffix, ".")==0) {
91*bbd061d4SDavid du Colombier free(origname);
92bd389b36SDavid du Colombier return dir;
93bd389b36SDavid du Colombier }
94*bbd061d4SDavid du Colombier }
95bd389b36SDavid du Colombier ent = lookup(dir, suffix);
96bd389b36SDavid du Colombier fi.mode |= 0400; /* at least user read */
97bd389b36SDavid du Colombier if (ent){
989a747e4fSDavid du Colombier if (((fi.mode&DMDIR)!=0) != ((ent->qid.type&QTDIR)!=0)){
99*bbd061d4SDavid du Colombier fprint(2,
100*bbd061d4SDavid du Colombier "%s file type changed; probably due to union dir.; ignoring\n",
101*bbd061d4SDavid du Colombier origname);
102*bbd061d4SDavid du Colombier free(origname);
103*bbd061d4SDavid du Colombier return ent;
104bd389b36SDavid du Colombier }
105bd389b36SDavid du Colombier if (new) {
106bd389b36SDavid du Colombier ent->ndata = fi.size;
10741fe996aSDavid du Colombier ent->addr = fi.addr;
10841fe996aSDavid du Colombier ent->data = fi.data;
109bd389b36SDavid du Colombier ent->perm = fi.mode;
110bd389b36SDavid du Colombier ent->mtime = fi.mdate;
111bd389b36SDavid du Colombier ent->user = mapid(uidmap, fi.uid);
112bd389b36SDavid du Colombier ent->group = mapid(gidmap, fi.gid);
113bd389b36SDavid du Colombier }
114bd389b36SDavid du Colombier } else {
1157dd7cddfSDavid du Colombier fi.name = suffix;
116bd389b36SDavid du Colombier ent = popfile(dir, fi);
117bd389b36SDavid du Colombier }
118*bbd061d4SDavid du Colombier free(origname);
119bd389b36SDavid du Colombier return ent;
120bd389b36SDavid du Colombier }
121bd389b36SDavid du Colombier
122bd389b36SDavid du Colombier Ram *
popfile(Ram * dir,Fileinf fi)123bd389b36SDavid du Colombier popfile(Ram *dir, Fileinf fi)
124bd389b36SDavid du Colombier {
125bd389b36SDavid du Colombier Ram *ent = (Ram *)emalloc(sizeof(Ram));
126bd389b36SDavid du Colombier if (*fi.name=='\0')
127bd389b36SDavid du Colombier return 0;
128bd389b36SDavid du Colombier ent->busy = 1;
129bd389b36SDavid du Colombier ent->open = 0;
130bd389b36SDavid du Colombier ent->parent = dir;
131bd389b36SDavid du Colombier ent->next = dir->child;
132bd389b36SDavid du Colombier dir->child = ent;
133bd389b36SDavid du Colombier ent->child = 0;
1349a747e4fSDavid du Colombier ent->qid.path = ++path;
135bd389b36SDavid du Colombier ent->qid.vers = 0;
1369a747e4fSDavid du Colombier if(fi.mode&DMDIR)
1379a747e4fSDavid du Colombier ent->qid.type = QTDIR;
1389a747e4fSDavid du Colombier else
1399a747e4fSDavid du Colombier ent->qid.type = QTFILE;
140bd389b36SDavid du Colombier ent->perm = fi.mode;
1419a747e4fSDavid du Colombier ent->name = estrdup(fi.name);
142bd389b36SDavid du Colombier ent->atime = ent->mtime = fi.mdate;
143bd389b36SDavid du Colombier ent->user = mapid(uidmap, fi.uid);
144bd389b36SDavid du Colombier ent->group = mapid(gidmap, fi.gid);
145bd389b36SDavid du Colombier ent->ndata = fi.size;
14641fe996aSDavid du Colombier ent->data = fi.data;
14741fe996aSDavid du Colombier ent->addr = fi.addr;
148bd389b36SDavid du Colombier ent->replete |= replete;
149bd389b36SDavid du Colombier return ent;
150bd389b36SDavid du Colombier }
151bd389b36SDavid du Colombier
152bd389b36SDavid du Colombier Ram *
lookup(Ram * dir,char * name)153bd389b36SDavid du Colombier lookup(Ram *dir, char *name)
154bd389b36SDavid du Colombier {
155bd389b36SDavid du Colombier Ram *r;
156bd389b36SDavid du Colombier
157219b2ee8SDavid du Colombier if (dir==0)
158219b2ee8SDavid du Colombier return 0;
159bd389b36SDavid du Colombier for (r=dir->child; r; r=r->next){
160bd389b36SDavid du Colombier if (r->busy==0 || strcmp(r->name, name)!=0)
161bd389b36SDavid du Colombier continue;
162bd389b36SDavid du Colombier return r;
163bd389b36SDavid du Colombier }
164bd389b36SDavid du Colombier return 0;
165bd389b36SDavid du Colombier }
166