Blame


1 e1dddc05 2004-06-17 devnull #include <u.h>
2 e1dddc05 2004-06-17 devnull #include <libc.h>
3 e1dddc05 2004-06-17 devnull #include <bio.h>
4 e1dddc05 2004-06-17 devnull #include <auth.h>
5 e1dddc05 2004-06-17 devnull #include <fcall.h>
6 e1dddc05 2004-06-17 devnull #include <disk.h>
7 e1dddc05 2004-06-17 devnull
8 e1dddc05 2004-06-17 devnull enum {
9 e1dddc05 2004-06-17 devnull LEN = 8*1024,
10 cbeb0b26 2006-04-01 devnull HUNKS = 128
11 e1dddc05 2004-06-17 devnull };
12 e1dddc05 2004-06-17 devnull
13 e1dddc05 2004-06-17 devnull #undef warn
14 e1dddc05 2004-06-17 devnull #define warn protowarn
15 e1dddc05 2004-06-17 devnull
16 fa325e9b 2020-01-10 cross #undef getmode
17 e1dddc05 2004-06-17 devnull #define getmode protogetmode
18 e1dddc05 2004-06-17 devnull
19 e1dddc05 2004-06-17 devnull typedef struct File File;
20 e1dddc05 2004-06-17 devnull struct File{
21 e1dddc05 2004-06-17 devnull char *new;
22 e1dddc05 2004-06-17 devnull char *elem;
23 e1dddc05 2004-06-17 devnull char *old;
24 e1dddc05 2004-06-17 devnull char *uid;
25 e1dddc05 2004-06-17 devnull char *gid;
26 e1dddc05 2004-06-17 devnull ulong mode;
27 e1dddc05 2004-06-17 devnull };
28 e1dddc05 2004-06-17 devnull
29 e1dddc05 2004-06-17 devnull typedef void Mkfserr(char*, void*);
30 e1dddc05 2004-06-17 devnull typedef void Mkfsenum(char*, char*, Dir*, void*);
31 e1dddc05 2004-06-17 devnull
32 e1dddc05 2004-06-17 devnull typedef struct Name Name;
33 e1dddc05 2004-06-17 devnull struct Name {
34 e1dddc05 2004-06-17 devnull int n;
35 e1dddc05 2004-06-17 devnull char *s;
36 e1dddc05 2004-06-17 devnull };
37 e1dddc05 2004-06-17 devnull
38 e1dddc05 2004-06-17 devnull typedef struct Mkaux Mkaux;
39 e1dddc05 2004-06-17 devnull struct Mkaux {
40 e1dddc05 2004-06-17 devnull Mkfserr *warn;
41 e1dddc05 2004-06-17 devnull Mkfsenum *mkenum;
42 e1dddc05 2004-06-17 devnull char *root;
43 e1dddc05 2004-06-17 devnull char *proto;
44 e1dddc05 2004-06-17 devnull jmp_buf jmp;
45 e1dddc05 2004-06-17 devnull Biobuf *b;
46 e1dddc05 2004-06-17 devnull
47 e1dddc05 2004-06-17 devnull Name oldfile;
48 e1dddc05 2004-06-17 devnull Name fullname;
49 e1dddc05 2004-06-17 devnull int lineno;
50 e1dddc05 2004-06-17 devnull int indent;
51 e1dddc05 2004-06-17 devnull
52 e1dddc05 2004-06-17 devnull void *a;
53 e1dddc05 2004-06-17 devnull };
54 e1dddc05 2004-06-17 devnull
55 e1dddc05 2004-06-17 devnull static void domkfs(Mkaux *mkaux, File *me, int level);
56 e1dddc05 2004-06-17 devnull
57 e1dddc05 2004-06-17 devnull static int copyfile(Mkaux*, File*, Dir*, int);
58 e1dddc05 2004-06-17 devnull static void freefile(File*);
59 e1dddc05 2004-06-17 devnull static File* getfile(Mkaux*, File*);
60 e1dddc05 2004-06-17 devnull static char* getmode(Mkaux*, char*, ulong*);
61 e1dddc05 2004-06-17 devnull static char* getname(Mkaux*, char*, char**);
62 e1dddc05 2004-06-17 devnull static char* getpath(Mkaux*, char*);
63 e1dddc05 2004-06-17 devnull static int mkfile(Mkaux*, File*);
64 e1dddc05 2004-06-17 devnull static char* mkpath(Mkaux*, char*, char*);
65 e1dddc05 2004-06-17 devnull static void mktree(Mkaux*, File*, int);
66 e1dddc05 2004-06-17 devnull static void setnames(Mkaux*, File*);
67 e1dddc05 2004-06-17 devnull static void skipdir(Mkaux*);
68 e1dddc05 2004-06-17 devnull static void warn(Mkaux*, char *, ...);
69 e1dddc05 2004-06-17 devnull
70 cbeb0b26 2006-04-01 devnull /*static void */
71 cbeb0b26 2006-04-01 devnull /*mprint(char *new, char *old, Dir *d, void*) */
72 cbeb0b26 2006-04-01 devnull /*{ */
73 cbeb0b26 2006-04-01 devnull /* print("%s %s %D\n", new, old, d); */
74 cbeb0b26 2006-04-01 devnull /*} */
75 e1dddc05 2004-06-17 devnull
76 e1dddc05 2004-06-17 devnull int
77 e1dddc05 2004-06-17 devnull rdproto(char *proto, char *root, Mkfsenum *mkenum, Mkfserr *mkerr, void *a)
78 e1dddc05 2004-06-17 devnull {
79 e1dddc05 2004-06-17 devnull Mkaux mx, *m;
80 e1dddc05 2004-06-17 devnull File file;
81 d9f3e89e 2004-12-26 devnull volatile int rv;
82 e1dddc05 2004-06-17 devnull
83 e1dddc05 2004-06-17 devnull m = &mx;
84 e1dddc05 2004-06-17 devnull memset(&mx, 0, sizeof mx);
85 e1dddc05 2004-06-17 devnull if(root == nil)
86 e1dddc05 2004-06-17 devnull root = "/";
87 e1dddc05 2004-06-17 devnull
88 e1dddc05 2004-06-17 devnull m->root = root;
89 e1dddc05 2004-06-17 devnull m->warn = mkerr;
90 e1dddc05 2004-06-17 devnull m->mkenum = mkenum;
91 e1dddc05 2004-06-17 devnull m->a = a;
92 e1dddc05 2004-06-17 devnull m->proto = proto;
93 e1dddc05 2004-06-17 devnull m->lineno = 0;
94 e1dddc05 2004-06-17 devnull m->indent = 0;
95 e1dddc05 2004-06-17 devnull if((m->b = Bopen(proto, OREAD)) == nil) {
96 e1dddc05 2004-06-17 devnull werrstr("open '%s': %r", proto);
97 e1dddc05 2004-06-17 devnull return -1;
98 e1dddc05 2004-06-17 devnull }
99 e1dddc05 2004-06-17 devnull
100 e1dddc05 2004-06-17 devnull memset(&file, 0, sizeof file);
101 e1dddc05 2004-06-17 devnull file.new = "";
102 e1dddc05 2004-06-17 devnull file.old = nil;
103 e1dddc05 2004-06-17 devnull
104 d9f3e89e 2004-12-26 devnull rv = 0;
105 e1dddc05 2004-06-17 devnull if(setjmp(m->jmp) == 0)
106 e1dddc05 2004-06-17 devnull domkfs(m, &file, -1);
107 e1dddc05 2004-06-17 devnull else
108 e1dddc05 2004-06-17 devnull rv = -1;
109 e1dddc05 2004-06-17 devnull free(m->oldfile.s);
110 e1dddc05 2004-06-17 devnull free(m->fullname.s);
111 e1dddc05 2004-06-17 devnull return rv;
112 e1dddc05 2004-06-17 devnull }
113 e1dddc05 2004-06-17 devnull
114 e1dddc05 2004-06-17 devnull static void*
115 e1dddc05 2004-06-17 devnull emalloc(Mkaux *mkaux, ulong n)
116 e1dddc05 2004-06-17 devnull {
117 e1dddc05 2004-06-17 devnull void *v;
118 e1dddc05 2004-06-17 devnull
119 e1dddc05 2004-06-17 devnull v = malloc(n);
120 e1dddc05 2004-06-17 devnull if(v == nil)
121 e1dddc05 2004-06-17 devnull longjmp(mkaux->jmp, 1); /* memory leak */
122 e1dddc05 2004-06-17 devnull memset(v, 0, n);
123 e1dddc05 2004-06-17 devnull return v;
124 e1dddc05 2004-06-17 devnull }
125 e1dddc05 2004-06-17 devnull
126 e1dddc05 2004-06-17 devnull static char*
127 e1dddc05 2004-06-17 devnull estrdup(Mkaux *mkaux, char *s)
128 e1dddc05 2004-06-17 devnull {
129 e1dddc05 2004-06-17 devnull s = strdup(s);
130 e1dddc05 2004-06-17 devnull if(s == nil)
131 e1dddc05 2004-06-17 devnull longjmp(mkaux->jmp, 1); /* memory leak */
132 e1dddc05 2004-06-17 devnull return s;
133 e1dddc05 2004-06-17 devnull }
134 e1dddc05 2004-06-17 devnull
135 e1dddc05 2004-06-17 devnull static void
136 e1dddc05 2004-06-17 devnull domkfs(Mkaux *mkaux, File *me, int level)
137 e1dddc05 2004-06-17 devnull {
138 e1dddc05 2004-06-17 devnull File *child;
139 e1dddc05 2004-06-17 devnull int rec;
140 e1dddc05 2004-06-17 devnull
141 e1dddc05 2004-06-17 devnull child = getfile(mkaux, me);
142 e1dddc05 2004-06-17 devnull if(!child)
143 e1dddc05 2004-06-17 devnull return;
144 e1dddc05 2004-06-17 devnull if((child->elem[0] == '+' || child->elem[0] == '*') && child->elem[1] == '\0'){
145 e1dddc05 2004-06-17 devnull rec = child->elem[0] == '+';
146 e1dddc05 2004-06-17 devnull free(child->new);
147 e1dddc05 2004-06-17 devnull child->new = estrdup(mkaux, me->new);
148 e1dddc05 2004-06-17 devnull setnames(mkaux, child);
149 e1dddc05 2004-06-17 devnull mktree(mkaux, child, rec);
150 e1dddc05 2004-06-17 devnull freefile(child);
151 e1dddc05 2004-06-17 devnull child = getfile(mkaux, me);
152 e1dddc05 2004-06-17 devnull }
153 e1dddc05 2004-06-17 devnull while(child && mkaux->indent > level){
154 e1dddc05 2004-06-17 devnull if(mkfile(mkaux, child))
155 e1dddc05 2004-06-17 devnull domkfs(mkaux, child, mkaux->indent);
156 e1dddc05 2004-06-17 devnull freefile(child);
157 e1dddc05 2004-06-17 devnull child = getfile(mkaux, me);
158 e1dddc05 2004-06-17 devnull }
159 e1dddc05 2004-06-17 devnull if(child){
160 e1dddc05 2004-06-17 devnull freefile(child);
161 e1dddc05 2004-06-17 devnull Bseek(mkaux->b, -Blinelen(mkaux->b), 1);
162 e1dddc05 2004-06-17 devnull mkaux->lineno--;
163 e1dddc05 2004-06-17 devnull }
164 e1dddc05 2004-06-17 devnull }
165 e1dddc05 2004-06-17 devnull
166 e1dddc05 2004-06-17 devnull static void
167 e1dddc05 2004-06-17 devnull mktree(Mkaux *mkaux, File *me, int rec)
168 e1dddc05 2004-06-17 devnull {
169 e1dddc05 2004-06-17 devnull File child;
170 e1dddc05 2004-06-17 devnull Dir *d;
171 e1dddc05 2004-06-17 devnull int i, n, fd;
172 e1dddc05 2004-06-17 devnull
173 e1dddc05 2004-06-17 devnull fd = open(mkaux->oldfile.s, OREAD);
174 e1dddc05 2004-06-17 devnull if(fd < 0){
175 e1dddc05 2004-06-17 devnull warn(mkaux, "can't open %s: %r", mkaux->oldfile.s);
176 e1dddc05 2004-06-17 devnull return;
177 e1dddc05 2004-06-17 devnull }
178 e1dddc05 2004-06-17 devnull
179 e1dddc05 2004-06-17 devnull child = *me;
180 e1dddc05 2004-06-17 devnull while((n = dirread(fd, &d)) > 0){
181 e1dddc05 2004-06-17 devnull for(i = 0; i < n; i++){
182 e1dddc05 2004-06-17 devnull child.new = mkpath(mkaux, me->new, d[i].name);
183 e1dddc05 2004-06-17 devnull if(me->old)
184 e1dddc05 2004-06-17 devnull child.old = mkpath(mkaux, me->old, d[i].name);
185 e1dddc05 2004-06-17 devnull child.elem = d[i].name;
186 e1dddc05 2004-06-17 devnull setnames(mkaux, &child);
187 e1dddc05 2004-06-17 devnull if((!(d[i].mode&DMDIR) || rec) && copyfile(mkaux, &child, &d[i], 1) && rec)
188 e1dddc05 2004-06-17 devnull mktree(mkaux, &child, rec);
189 e1dddc05 2004-06-17 devnull free(child.new);
190 e1dddc05 2004-06-17 devnull if(child.old)
191 e1dddc05 2004-06-17 devnull free(child.old);
192 e1dddc05 2004-06-17 devnull }
193 e1dddc05 2004-06-17 devnull }
194 e1dddc05 2004-06-17 devnull close(fd);
195 e1dddc05 2004-06-17 devnull }
196 e1dddc05 2004-06-17 devnull
197 e1dddc05 2004-06-17 devnull static int
198 e1dddc05 2004-06-17 devnull mkfile(Mkaux *mkaux, File *f)
199 e1dddc05 2004-06-17 devnull {
200 e1dddc05 2004-06-17 devnull Dir *d;
201 e1dddc05 2004-06-17 devnull
202 e1dddc05 2004-06-17 devnull if((d = dirstat(mkaux->oldfile.s)) == nil){
203 e1dddc05 2004-06-17 devnull warn(mkaux, "can't stat file %s: %r", mkaux->oldfile.s);
204 e1dddc05 2004-06-17 devnull skipdir(mkaux);
205 e1dddc05 2004-06-17 devnull return 0;
206 e1dddc05 2004-06-17 devnull }
207 e1dddc05 2004-06-17 devnull return copyfile(mkaux, f, d, 0);
208 e1dddc05 2004-06-17 devnull }
209 e1dddc05 2004-06-17 devnull
210 e1dddc05 2004-06-17 devnull enum {
211 e1dddc05 2004-06-17 devnull SLOP = 30
212 e1dddc05 2004-06-17 devnull };
213 e1dddc05 2004-06-17 devnull
214 e1dddc05 2004-06-17 devnull static void
215 e1dddc05 2004-06-17 devnull setname(Mkaux *mkaux, Name *name, char *s1, char *s2)
216 e1dddc05 2004-06-17 devnull {
217 e1dddc05 2004-06-17 devnull int l;
218 e1dddc05 2004-06-17 devnull
219 e1dddc05 2004-06-17 devnull l = strlen(s1)+strlen(s2)+1;
220 e1dddc05 2004-06-17 devnull if(name->n < l+SLOP/2) {
221 e1dddc05 2004-06-17 devnull free(name->s);
222 e1dddc05 2004-06-17 devnull name->s = emalloc(mkaux, l+SLOP);
223 e1dddc05 2004-06-17 devnull name->n = l+SLOP;
224 e1dddc05 2004-06-17 devnull }
225 e1dddc05 2004-06-17 devnull snprint(name->s, name->n, "%s%s%s", s1, s1[0]==0 || s1[strlen(s1)-1]!='/' ? "/" : "", s2);
226 e1dddc05 2004-06-17 devnull }
227 e1dddc05 2004-06-17 devnull
228 e1dddc05 2004-06-17 devnull static int
229 e1dddc05 2004-06-17 devnull copyfile(Mkaux *mkaux, File *f, Dir *d, int permonly)
230 e1dddc05 2004-06-17 devnull {
231 e1dddc05 2004-06-17 devnull Dir *nd;
232 e1dddc05 2004-06-17 devnull ulong xmode;
233 e1dddc05 2004-06-17 devnull char *p;
234 e1dddc05 2004-06-17 devnull
235 e1dddc05 2004-06-17 devnull setname(mkaux, &mkaux->fullname, mkaux->root, f->old ? f->old : f->new);
236 e1dddc05 2004-06-17 devnull /*
237 e1dddc05 2004-06-17 devnull * Extra stat here is inefficient but accounts for binds.
238 e1dddc05 2004-06-17 devnull */
239 e1dddc05 2004-06-17 devnull if((nd = dirstat(mkaux->fullname.s)) != nil)
240 e1dddc05 2004-06-17 devnull d = nd;
241 e1dddc05 2004-06-17 devnull
242 e1dddc05 2004-06-17 devnull d->name = f->elem;
243 e1dddc05 2004-06-17 devnull if(d->type != 'M'){
244 e1dddc05 2004-06-17 devnull d->uid = "sys";
245 e1dddc05 2004-06-17 devnull d->gid = "sys";
246 e1dddc05 2004-06-17 devnull xmode = (d->mode >> 6) & 7;
247 e1dddc05 2004-06-17 devnull d->mode |= xmode | (xmode << 3);
248 e1dddc05 2004-06-17 devnull }
249 e1dddc05 2004-06-17 devnull if(strcmp(f->uid, "-") != 0)
250 e1dddc05 2004-06-17 devnull d->uid = f->uid;
251 e1dddc05 2004-06-17 devnull if(strcmp(f->gid, "-") != 0)
252 e1dddc05 2004-06-17 devnull d->gid = f->gid;
253 e1dddc05 2004-06-17 devnull if(f->mode != ~0){
254 e1dddc05 2004-06-17 devnull if(permonly)
255 e1dddc05 2004-06-17 devnull d->mode = (d->mode & ~0666) | (f->mode & 0666);
256 e1dddc05 2004-06-17 devnull else if((d->mode&DMDIR) != (f->mode&DMDIR))
257 e1dddc05 2004-06-17 devnull warn(mkaux, "inconsistent mode for %s", f->new);
258 e1dddc05 2004-06-17 devnull else
259 e1dddc05 2004-06-17 devnull d->mode = f->mode;
260 e1dddc05 2004-06-17 devnull }
261 e1dddc05 2004-06-17 devnull
262 e1dddc05 2004-06-17 devnull if(p = strrchr(f->new, '/'))
263 e1dddc05 2004-06-17 devnull d->name = p+1;
264 e1dddc05 2004-06-17 devnull else
265 e1dddc05 2004-06-17 devnull d->name = f->new;
266 e1dddc05 2004-06-17 devnull
267 e1dddc05 2004-06-17 devnull mkaux->mkenum(f->new, mkaux->fullname.s, d, mkaux->a);
268 e1dddc05 2004-06-17 devnull xmode = d->mode;
269 e1dddc05 2004-06-17 devnull free(nd);
270 e1dddc05 2004-06-17 devnull return (xmode&DMDIR) != 0;
271 e1dddc05 2004-06-17 devnull }
272 e1dddc05 2004-06-17 devnull
273 e1dddc05 2004-06-17 devnull static char *
274 e1dddc05 2004-06-17 devnull mkpath(Mkaux *mkaux, char *prefix, char *elem)
275 e1dddc05 2004-06-17 devnull {
276 e1dddc05 2004-06-17 devnull char *p;
277 e1dddc05 2004-06-17 devnull int n;
278 e1dddc05 2004-06-17 devnull
279 e1dddc05 2004-06-17 devnull n = strlen(prefix) + strlen(elem) + 2;
280 e1dddc05 2004-06-17 devnull p = emalloc(mkaux, n);
281 e1dddc05 2004-06-17 devnull strcpy(p, prefix);
282 e1dddc05 2004-06-17 devnull strcat(p, "/");
283 e1dddc05 2004-06-17 devnull strcat(p, elem);
284 e1dddc05 2004-06-17 devnull return p;
285 e1dddc05 2004-06-17 devnull }
286 e1dddc05 2004-06-17 devnull
287 e1dddc05 2004-06-17 devnull static void
288 e1dddc05 2004-06-17 devnull setnames(Mkaux *mkaux, File *f)
289 e1dddc05 2004-06-17 devnull {
290 fa325e9b 2020-01-10 cross
291 e1dddc05 2004-06-17 devnull if(f->old){
292 e1dddc05 2004-06-17 devnull if(f->old[0] == '/')
293 e1dddc05 2004-06-17 devnull setname(mkaux, &mkaux->oldfile, f->old, "");
294 e1dddc05 2004-06-17 devnull else
295 e1dddc05 2004-06-17 devnull setname(mkaux, &mkaux->oldfile, mkaux->root, f->old);
296 e1dddc05 2004-06-17 devnull } else
297 e1dddc05 2004-06-17 devnull setname(mkaux, &mkaux->oldfile, mkaux->root, f->new);
298 e1dddc05 2004-06-17 devnull }
299 e1dddc05 2004-06-17 devnull
300 e1dddc05 2004-06-17 devnull static void
301 e1dddc05 2004-06-17 devnull freefile(File *f)
302 e1dddc05 2004-06-17 devnull {
303 e1dddc05 2004-06-17 devnull if(f->old)
304 e1dddc05 2004-06-17 devnull free(f->old);
305 e1dddc05 2004-06-17 devnull if(f->new)
306 e1dddc05 2004-06-17 devnull free(f->new);
307 e1dddc05 2004-06-17 devnull free(f);
308 e1dddc05 2004-06-17 devnull }
309 e1dddc05 2004-06-17 devnull
310 e1dddc05 2004-06-17 devnull /*
311 e1dddc05 2004-06-17 devnull * skip all files in the proto that
312 e1dddc05 2004-06-17 devnull * could be in the current dir
313 e1dddc05 2004-06-17 devnull */
314 e1dddc05 2004-06-17 devnull static void
315 e1dddc05 2004-06-17 devnull skipdir(Mkaux *mkaux)
316 e1dddc05 2004-06-17 devnull {
317 e1dddc05 2004-06-17 devnull char *p, c;
318 e1dddc05 2004-06-17 devnull int level;
319 e1dddc05 2004-06-17 devnull
320 e1dddc05 2004-06-17 devnull if(mkaux->indent < 0)
321 e1dddc05 2004-06-17 devnull return;
322 e1dddc05 2004-06-17 devnull level = mkaux->indent;
323 e1dddc05 2004-06-17 devnull for(;;){
324 e1dddc05 2004-06-17 devnull mkaux->indent = 0;
325 e1dddc05 2004-06-17 devnull p = Brdline(mkaux->b, '\n');
326 e1dddc05 2004-06-17 devnull mkaux->lineno++;
327 e1dddc05 2004-06-17 devnull if(!p){
328 e1dddc05 2004-06-17 devnull mkaux->indent = -1;
329 e1dddc05 2004-06-17 devnull return;
330 e1dddc05 2004-06-17 devnull }
331 e1dddc05 2004-06-17 devnull while((c = *p++) != '\n')
332 e1dddc05 2004-06-17 devnull if(c == ' ')
333 e1dddc05 2004-06-17 devnull mkaux->indent++;
334 e1dddc05 2004-06-17 devnull else if(c == '\t')
335 e1dddc05 2004-06-17 devnull mkaux->indent += 8;
336 e1dddc05 2004-06-17 devnull else
337 e1dddc05 2004-06-17 devnull break;
338 e1dddc05 2004-06-17 devnull if(mkaux->indent <= level){
339 e1dddc05 2004-06-17 devnull Bseek(mkaux->b, -Blinelen(mkaux->b), 1);
340 e1dddc05 2004-06-17 devnull mkaux->lineno--;
341 e1dddc05 2004-06-17 devnull return;
342 e1dddc05 2004-06-17 devnull }
343 e1dddc05 2004-06-17 devnull }
344 e1dddc05 2004-06-17 devnull }
345 e1dddc05 2004-06-17 devnull
346 e1dddc05 2004-06-17 devnull static File*
347 e1dddc05 2004-06-17 devnull getfile(Mkaux *mkaux, File *old)
348 e1dddc05 2004-06-17 devnull {
349 e1dddc05 2004-06-17 devnull File *f;
350 e1dddc05 2004-06-17 devnull char *elem;
351 e1dddc05 2004-06-17 devnull char *p;
352 e1dddc05 2004-06-17 devnull int c;
353 e1dddc05 2004-06-17 devnull
354 e1dddc05 2004-06-17 devnull if(mkaux->indent < 0)
355 e1dddc05 2004-06-17 devnull return 0;
356 e1dddc05 2004-06-17 devnull loop:
357 e1dddc05 2004-06-17 devnull mkaux->indent = 0;
358 e1dddc05 2004-06-17 devnull p = Brdline(mkaux->b, '\n');
359 e1dddc05 2004-06-17 devnull mkaux->lineno++;
360 e1dddc05 2004-06-17 devnull if(!p){
361 e1dddc05 2004-06-17 devnull mkaux->indent = -1;
362 e1dddc05 2004-06-17 devnull return 0;
363 e1dddc05 2004-06-17 devnull }
364 e1dddc05 2004-06-17 devnull while((c = *p++) != '\n')
365 e1dddc05 2004-06-17 devnull if(c == ' ')
366 e1dddc05 2004-06-17 devnull mkaux->indent++;
367 e1dddc05 2004-06-17 devnull else if(c == '\t')
368 e1dddc05 2004-06-17 devnull mkaux->indent += 8;
369 e1dddc05 2004-06-17 devnull else
370 e1dddc05 2004-06-17 devnull break;
371 e1dddc05 2004-06-17 devnull if(c == '\n' || c == '#')
372 e1dddc05 2004-06-17 devnull goto loop;
373 e1dddc05 2004-06-17 devnull p--;
374 e1dddc05 2004-06-17 devnull f = emalloc(mkaux, sizeof *f);
375 e1dddc05 2004-06-17 devnull p = getname(mkaux, p, &elem);
376 e1dddc05 2004-06-17 devnull if(p == nil)
377 e1dddc05 2004-06-17 devnull return nil;
378 e1dddc05 2004-06-17 devnull
379 e1dddc05 2004-06-17 devnull f->new = mkpath(mkaux, old->new, elem);
380 e1dddc05 2004-06-17 devnull free(elem);
381 bb0266fe 2005-05-07 devnull f->elem = utfrrune(f->new, '/') + 1;
382 e1dddc05 2004-06-17 devnull p = getmode(mkaux, p, &f->mode);
383 e1dddc05 2004-06-17 devnull p = getname(mkaux, p, &f->uid); /* LEAK */
384 e1dddc05 2004-06-17 devnull if(p == nil)
385 e1dddc05 2004-06-17 devnull return nil;
386 e1dddc05 2004-06-17 devnull
387 e1dddc05 2004-06-17 devnull if(!*f->uid)
388 e1dddc05 2004-06-17 devnull strcpy(f->uid, "-");
389 e1dddc05 2004-06-17 devnull p = getname(mkaux, p, &f->gid); /* LEAK */
390 e1dddc05 2004-06-17 devnull if(p == nil)
391 e1dddc05 2004-06-17 devnull return nil;
392 e1dddc05 2004-06-17 devnull
393 e1dddc05 2004-06-17 devnull if(!*f->gid)
394 e1dddc05 2004-06-17 devnull strcpy(f->gid, "-");
395 e1dddc05 2004-06-17 devnull f->old = getpath(mkaux, p);
396 e1dddc05 2004-06-17 devnull if(f->old && strcmp(f->old, "-") == 0){
397 e1dddc05 2004-06-17 devnull free(f->old);
398 e1dddc05 2004-06-17 devnull f->old = 0;
399 e1dddc05 2004-06-17 devnull }
400 e1dddc05 2004-06-17 devnull setnames(mkaux, f);
401 e1dddc05 2004-06-17 devnull
402 e1dddc05 2004-06-17 devnull return f;
403 e1dddc05 2004-06-17 devnull }
404 e1dddc05 2004-06-17 devnull
405 e1dddc05 2004-06-17 devnull static char*
406 e1dddc05 2004-06-17 devnull getpath(Mkaux *mkaux, char *p)
407 e1dddc05 2004-06-17 devnull {
408 e1dddc05 2004-06-17 devnull char *q, *new;
409 e1dddc05 2004-06-17 devnull int c, n;
410 e1dddc05 2004-06-17 devnull
411 e1dddc05 2004-06-17 devnull while((c = *p) == ' ' || c == '\t')
412 e1dddc05 2004-06-17 devnull p++;
413 e1dddc05 2004-06-17 devnull q = p;
414 e1dddc05 2004-06-17 devnull while((c = *q) != '\n' && c != ' ' && c != '\t')
415 e1dddc05 2004-06-17 devnull q++;
416 e1dddc05 2004-06-17 devnull if(q == p)
417 e1dddc05 2004-06-17 devnull return 0;
418 e1dddc05 2004-06-17 devnull n = q - p;
419 e1dddc05 2004-06-17 devnull new = emalloc(mkaux, n + 1);
420 e1dddc05 2004-06-17 devnull memcpy(new, p, n);
421 e1dddc05 2004-06-17 devnull new[n] = 0;
422 e1dddc05 2004-06-17 devnull return new;
423 e1dddc05 2004-06-17 devnull }
424 e1dddc05 2004-06-17 devnull
425 e1dddc05 2004-06-17 devnull static char*
426 e1dddc05 2004-06-17 devnull getname(Mkaux *mkaux, char *p, char **buf)
427 e1dddc05 2004-06-17 devnull {
428 e1dddc05 2004-06-17 devnull char *s, *start;
429 e1dddc05 2004-06-17 devnull int c;
430 e1dddc05 2004-06-17 devnull
431 e1dddc05 2004-06-17 devnull while((c = *p) == ' ' || c == '\t')
432 e1dddc05 2004-06-17 devnull p++;
433 e1dddc05 2004-06-17 devnull
434 e1dddc05 2004-06-17 devnull start = p;
435 e1dddc05 2004-06-17 devnull while((c = *p) != '\n' && c != ' ' && c != '\t')
436 e1dddc05 2004-06-17 devnull p++;
437 e1dddc05 2004-06-17 devnull
438 e1dddc05 2004-06-17 devnull *buf = malloc(p+2-start); /* +2: need at least 2 bytes; might strcpy "-" into buf */
439 e1dddc05 2004-06-17 devnull if(*buf == nil)
440 e1dddc05 2004-06-17 devnull return nil;
441 e1dddc05 2004-06-17 devnull memmove(*buf, start, p-start);
442 e1dddc05 2004-06-17 devnull
443 e1dddc05 2004-06-17 devnull (*buf)[p-start] = '\0';
444 e1dddc05 2004-06-17 devnull
445 e1dddc05 2004-06-17 devnull if(**buf == '$'){
446 e1dddc05 2004-06-17 devnull s = getenv(*buf+1);
447 e1dddc05 2004-06-17 devnull if(s == 0){
448 e1dddc05 2004-06-17 devnull warn(mkaux, "can't read environment variable %s", *buf+1);
449 e1dddc05 2004-06-17 devnull skipdir(mkaux);
450 e1dddc05 2004-06-17 devnull free(*buf);
451 e1dddc05 2004-06-17 devnull return nil;
452 e1dddc05 2004-06-17 devnull }
453 e1dddc05 2004-06-17 devnull free(*buf);
454 e1dddc05 2004-06-17 devnull *buf = s;
455 e1dddc05 2004-06-17 devnull }
456 e1dddc05 2004-06-17 devnull return p;
457 e1dddc05 2004-06-17 devnull }
458 e1dddc05 2004-06-17 devnull
459 e1dddc05 2004-06-17 devnull static char*
460 e1dddc05 2004-06-17 devnull getmode(Mkaux *mkaux, char *p, ulong *xmode)
461 e1dddc05 2004-06-17 devnull {
462 e1dddc05 2004-06-17 devnull char *buf, *s;
463 e1dddc05 2004-06-17 devnull ulong m;
464 e1dddc05 2004-06-17 devnull
465 e1dddc05 2004-06-17 devnull *xmode = ~0;
466 e1dddc05 2004-06-17 devnull p = getname(mkaux, p, &buf);
467 e1dddc05 2004-06-17 devnull if(p == nil)
468 e1dddc05 2004-06-17 devnull return nil;
469 e1dddc05 2004-06-17 devnull
470 e1dddc05 2004-06-17 devnull s = buf;
471 e1dddc05 2004-06-17 devnull if(!*s || strcmp(s, "-") == 0)
472 e1dddc05 2004-06-17 devnull return p;
473 e1dddc05 2004-06-17 devnull m = 0;
474 e1dddc05 2004-06-17 devnull if(*s == 'd'){
475 e1dddc05 2004-06-17 devnull m |= DMDIR;
476 e1dddc05 2004-06-17 devnull s++;
477 e1dddc05 2004-06-17 devnull }
478 e1dddc05 2004-06-17 devnull if(*s == 'a'){
479 e1dddc05 2004-06-17 devnull m |= DMAPPEND;
480 e1dddc05 2004-06-17 devnull s++;
481 e1dddc05 2004-06-17 devnull }
482 e1dddc05 2004-06-17 devnull if(*s == 'l'){
483 e1dddc05 2004-06-17 devnull m |= DMEXCL;
484 e1dddc05 2004-06-17 devnull s++;
485 e1dddc05 2004-06-17 devnull }
486 e1dddc05 2004-06-17 devnull if(s[0] < '0' || s[0] > '7'
487 e1dddc05 2004-06-17 devnull || s[1] < '0' || s[1] > '7'
488 e1dddc05 2004-06-17 devnull || s[2] < '0' || s[2] > '7'
489 e1dddc05 2004-06-17 devnull || s[3]){
490 e1dddc05 2004-06-17 devnull warn(mkaux, "bad mode specification %s", buf);
491 e1dddc05 2004-06-17 devnull free(buf);
492 e1dddc05 2004-06-17 devnull return p;
493 e1dddc05 2004-06-17 devnull }
494 e1dddc05 2004-06-17 devnull *xmode = m | strtoul(s, 0, 8);
495 e1dddc05 2004-06-17 devnull free(buf);
496 e1dddc05 2004-06-17 devnull return p;
497 e1dddc05 2004-06-17 devnull }
498 e1dddc05 2004-06-17 devnull
499 e1dddc05 2004-06-17 devnull static void
500 e1dddc05 2004-06-17 devnull warn(Mkaux *mkaux, char *fmt, ...)
501 e1dddc05 2004-06-17 devnull {
502 e1dddc05 2004-06-17 devnull char buf[256];
503 e1dddc05 2004-06-17 devnull va_list va;
504 e1dddc05 2004-06-17 devnull
505 e1dddc05 2004-06-17 devnull va_start(va, fmt);
506 e1dddc05 2004-06-17 devnull vseprint(buf, buf+sizeof(buf), fmt, va);
507 e1dddc05 2004-06-17 devnull va_end(va);
508 e1dddc05 2004-06-17 devnull
509 e1dddc05 2004-06-17 devnull if(mkaux->warn)
510 e1dddc05 2004-06-17 devnull mkaux->warn(buf, mkaux->a);
511 e1dddc05 2004-06-17 devnull else
512 e1dddc05 2004-06-17 devnull fprint(2, "warning: %s\n", buf);
513 e1dddc05 2004-06-17 devnull }