]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/tapefs/util.c
cc: use 7 octal digits for 21 bit runes
[plan9front.git] / sys / src / cmd / tapefs / util.c
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 *
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, *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 *
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 *
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 }