1 d2173bb5 2012-07-17 rsc #include <u.h>
2 d2173bb5 2012-07-17 rsc #include <libc.h>
3 d2173bb5 2012-07-17 rsc #include <auth.h>
4 d2173bb5 2012-07-17 rsc #include <bio.h>
6 fee1a463 2012-08-05 rsc #define mkdir plan9mkdir
7 d2173bb5 2012-07-17 rsc #define getmode plan9_getmode
8 d2173bb5 2012-07-17 rsc #define setuid plan9_setuid
11 d2173bb5 2012-07-17 rsc LEN = 8*1024,
15 d2173bb5 2012-07-17 rsc * types of destination file sytems
22 d2173bb5 2012-07-17 rsc typedef struct File File;
33 d2173bb5 2012-07-17 rsc void arch(Dir*);
34 d2173bb5 2012-07-17 rsc void copy(Dir*);
35 d2173bb5 2012-07-17 rsc int copyfile(File*, Dir*, int);
36 d2173bb5 2012-07-17 rsc void* emalloc(ulong);
37 d2173bb5 2012-07-17 rsc void error(char *, ...);
38 d2173bb5 2012-07-17 rsc void freefile(File*);
39 d2173bb5 2012-07-17 rsc File* getfile(File*);
40 d2173bb5 2012-07-17 rsc char* getmode(char*, ulong*);
41 d2173bb5 2012-07-17 rsc char* getname(char*, char**);
42 d2173bb5 2012-07-17 rsc char* getpath(char*);
43 d2173bb5 2012-07-17 rsc void kfscmd(char *);
44 d2173bb5 2012-07-17 rsc void mkdir(Dir*);
45 d2173bb5 2012-07-17 rsc int mkfile(File*);
46 d2173bb5 2012-07-17 rsc void mkfs(File*, int);
47 d2173bb5 2012-07-17 rsc char* mkpath(char*, char*);
48 d2173bb5 2012-07-17 rsc void mktree(File*, int);
49 d2173bb5 2012-07-17 rsc void mountkfs(char*);
50 d2173bb5 2012-07-17 rsc void printfile(File*);
51 d2173bb5 2012-07-17 rsc void setnames(File*);
52 d2173bb5 2012-07-17 rsc void setusers(void);
53 d2173bb5 2012-07-17 rsc void skipdir(void);
54 d2173bb5 2012-07-17 rsc char* strdup(char*);
55 d2173bb5 2012-07-17 rsc int uptodate(Dir*, char*);
56 d2173bb5 2012-07-17 rsc void usage(void);
57 d2173bb5 2012-07-17 rsc void warn(char *, ...);
60 d2173bb5 2012-07-17 rsc Biobuf bout; /* stdout when writing archive */
61 d2173bb5 2012-07-17 rsc uchar boutbuf[2*LEN];
62 d2173bb5 2012-07-17 rsc char newfile[LEN];
63 d2173bb5 2012-07-17 rsc char oldfile[LEN];
65 d2173bb5 2012-07-17 rsc char *cputype;
67 d2173bb5 2012-07-17 rsc char *oldroot;
68 d2173bb5 2012-07-17 rsc char *newroot;
69 d2173bb5 2012-07-17 rsc char *prog = "mkfs";
73 d2173bb5 2012-07-17 rsc int buflen = 1024-8;
81 d2173bb5 2012-07-17 rsc int fskind; /* Kfs, Fs, Archive */
82 d2173bb5 2012-07-17 rsc int setuid; /* on Fs: set uid and gid? */
86 d2173bb5 2012-07-17 rsc main(int argc, char **argv)
92 d2173bb5 2012-07-17 rsc quotefmtinstall();
93 d2173bb5 2012-07-17 rsc user = getuser();
95 d2173bb5 2012-07-17 rsc memset(&file, 0, sizeof file);
96 d2173bb5 2012-07-17 rsc file.new = "";
97 d2173bb5 2012-07-17 rsc file.old = 0;
98 d2173bb5 2012-07-17 rsc oldroot = "";
99 d2173bb5 2012-07-17 rsc newroot = "/n/kfs";
101 d2173bb5 2012-07-17 rsc fskind = Kfs;
104 d2173bb5 2012-07-17 rsc if(fskind != Kfs) {
105 d2173bb5 2012-07-17 rsc fprint(2, "cannot use -a with -d\n");
108 d2173bb5 2012-07-17 rsc fskind = Archive;
109 d2173bb5 2012-07-17 rsc newroot = "";
110 d2173bb5 2012-07-17 rsc Binits(&bout, 1, OWRITE, boutbuf, sizeof boutbuf);
113 d2173bb5 2012-07-17 rsc if(fskind != Kfs) {
114 d2173bb5 2012-07-17 rsc fprint(2, "cannot use -d with -a\n");
117 d2173bb5 2012-07-17 rsc fskind = Fs;
118 d2173bb5 2012-07-17 rsc newroot = ARGF();
124 d2173bb5 2012-07-17 rsc name = EARGF(usage());
133 d2173bb5 2012-07-17 rsc oldroot = ARGF();
136 d2173bb5 2012-07-17 rsc users = ARGF();
148 d2173bb5 2012-07-17 rsc buflen = atoi(ARGF())-8;
157 d2173bb5 2012-07-17 rsc buf = emalloc(buflen);
158 d2173bb5 2012-07-17 rsc zbuf = emalloc(buflen);
159 d2173bb5 2012-07-17 rsc memset(zbuf, 0, buflen);
161 d2173bb5 2012-07-17 rsc mountkfs(name);
162 d2173bb5 2012-07-17 rsc kfscmd("allow");
163 d2173bb5 2012-07-17 rsc proto = "users";
165 d2173bb5 2012-07-17 rsc cputype = getenv("cputype");
166 d2173bb5 2012-07-17 rsc if(cputype == 0)
167 d2173bb5 2012-07-17 rsc cputype = "68020";
170 d2173bb5 2012-07-17 rsc for(i = 0; i < argc; i++){
171 d2173bb5 2012-07-17 rsc proto = argv[i];
172 d2173bb5 2012-07-17 rsc fprint(2, "processing %q\n", proto);
174 d2173bb5 2012-07-17 rsc b = Bopen(proto, OREAD);
176 d2173bb5 2012-07-17 rsc fprint(2, "%q: can't open %q: skipping\n", prog, proto);
183 d2173bb5 2012-07-17 rsc mkfs(&file, -1);
186 d2173bb5 2012-07-17 rsc fprint(2, "file system made\n");
187 d2173bb5 2012-07-17 rsc kfscmd("disallow");
188 d2173bb5 2012-07-17 rsc kfscmd("sync");
190 d2173bb5 2012-07-17 rsc exits("skipped protos");
191 d2173bb5 2012-07-17 rsc if(fskind == Archive){
192 d2173bb5 2012-07-17 rsc Bprint(&bout, "end of archive\n");
193 d2173bb5 2012-07-17 rsc Bterm(&bout);
199 d2173bb5 2012-07-17 rsc mkfs(File *me, int level)
201 d2173bb5 2012-07-17 rsc File *child;
204 d2173bb5 2012-07-17 rsc child = getfile(me);
207 d2173bb5 2012-07-17 rsc if((child->elem[0] == '+' || child->elem[0] == '*') && child->elem[1] == '\0'){
208 d2173bb5 2012-07-17 rsc rec = child->elem[0] == '+';
209 d2173bb5 2012-07-17 rsc free(child->new);
210 d2173bb5 2012-07-17 rsc child->new = strdup(me->new);
211 d2173bb5 2012-07-17 rsc setnames(child);
212 d2173bb5 2012-07-17 rsc mktree(child, rec);
213 d2173bb5 2012-07-17 rsc freefile(child);
214 d2173bb5 2012-07-17 rsc child = getfile(me);
216 d2173bb5 2012-07-17 rsc while(child && indent > level){
217 d2173bb5 2012-07-17 rsc if(mkfile(child))
218 d2173bb5 2012-07-17 rsc mkfs(child, indent);
219 d2173bb5 2012-07-17 rsc freefile(child);
220 d2173bb5 2012-07-17 rsc child = getfile(me);
223 d2173bb5 2012-07-17 rsc freefile(child);
224 d2173bb5 2012-07-17 rsc Bseek(b, -Blinelen(b), 1);
230 d2173bb5 2012-07-17 rsc mktree(File *me, int rec)
234 d2173bb5 2012-07-17 rsc int i, n, fd;
236 d2173bb5 2012-07-17 rsc fd = open(oldfile, OREAD);
238 d2173bb5 2012-07-17 rsc warn("can't open %q: %r", oldfile);
242 d2173bb5 2012-07-17 rsc child = *me;
243 d2173bb5 2012-07-17 rsc while((n = dirread(fd, &d)) > 0){
244 d2173bb5 2012-07-17 rsc for(i = 0; i < n; i++){
245 d2173bb5 2012-07-17 rsc child.new = mkpath(me->new, d[i].name);
247 d2173bb5 2012-07-17 rsc child.old = mkpath(me->old, d[i].name);
248 d2173bb5 2012-07-17 rsc child.elem = d[i].name;
249 d2173bb5 2012-07-17 rsc setnames(&child);
250 d2173bb5 2012-07-17 rsc if(copyfile(&child, &d[i], 1) && rec)
251 d2173bb5 2012-07-17 rsc mktree(&child, rec);
252 d2173bb5 2012-07-17 rsc free(child.new);
253 d2173bb5 2012-07-17 rsc if(child.old)
254 d2173bb5 2012-07-17 rsc free(child.old);
261 d2173bb5 2012-07-17 rsc mkfile(File *f)
265 d2173bb5 2012-07-17 rsc if((dir = dirstat(oldfile)) == nil){
266 d2173bb5 2012-07-17 rsc warn("can't stat file %q: %r", oldfile);
270 d2173bb5 2012-07-17 rsc return copyfile(f, dir, 0);
274 d2173bb5 2012-07-17 rsc copyfile(File *f, Dir *d, int permonly)
280 d2173bb5 2012-07-17 rsc Bprint(&bout, "%q\t%ld\t%lld\n", f->new, d->mtime, d->length);
281 d2173bb5 2012-07-17 rsc return (d->mode & DMDIR) != 0;
283 d2173bb5 2012-07-17 rsc if(verb && (fskind == Archive || ream))
284 d2173bb5 2012-07-17 rsc fprint(2, "%q\n", f->new);
285 d2173bb5 2012-07-17 rsc d->name = f->elem;
286 d2173bb5 2012-07-17 rsc if(d->type != 'M' && d->type != 'Z'){
287 d2173bb5 2012-07-17 rsc d->uid = "sys";
288 d2173bb5 2012-07-17 rsc d->gid = "sys";
289 d2173bb5 2012-07-17 rsc mode = (d->mode >> 6) & 7;
290 d2173bb5 2012-07-17 rsc d->mode |= mode | (mode << 3);
292 d2173bb5 2012-07-17 rsc if(strcmp(f->uid, "-") != 0)
293 d2173bb5 2012-07-17 rsc d->uid = f->uid;
294 d2173bb5 2012-07-17 rsc if(strcmp(f->gid, "-") != 0)
295 d2173bb5 2012-07-17 rsc d->gid = f->gid;
296 d2173bb5 2012-07-17 rsc if(fskind == Fs && !setuid){
297 d2173bb5 2012-07-17 rsc d->uid = "";
298 d2173bb5 2012-07-17 rsc d->gid = "";
300 d2173bb5 2012-07-17 rsc if(f->mode != ~0){
301 d2173bb5 2012-07-17 rsc if(permonly)
302 d2173bb5 2012-07-17 rsc d->mode = (d->mode & ~0666) | (f->mode & 0666);
303 d2173bb5 2012-07-17 rsc else if((d->mode&DMDIR) != (f->mode&DMDIR))
304 d2173bb5 2012-07-17 rsc warn("inconsistent mode for %q", f->new);
306 d2173bb5 2012-07-17 rsc d->mode = f->mode;
308 d2173bb5 2012-07-17 rsc if(!uptodate(d, newfile)){
309 d2173bb5 2012-07-17 rsc if(verb && (fskind != Archive && ream == 0))
310 d2173bb5 2012-07-17 rsc fprint(2, "%q\n", f->new);
311 d2173bb5 2012-07-17 rsc if(d->mode & DMDIR)
315 d2173bb5 2012-07-17 rsc }else if(modes){
316 d2173bb5 2012-07-17 rsc nulldir(&nd);
317 d2173bb5 2012-07-17 rsc nd.mode = d->mode;
318 d2173bb5 2012-07-17 rsc nd.gid = d->gid;
319 d2173bb5 2012-07-17 rsc nd.mtime = d->mtime;
320 d2173bb5 2012-07-17 rsc if(verb && (fskind != Archive && ream == 0))
321 d2173bb5 2012-07-17 rsc fprint(2, "%q\n", f->new);
322 d2173bb5 2012-07-17 rsc if(dirwstat(newfile, &nd) < 0)
323 d2173bb5 2012-07-17 rsc warn("can't set modes for %q: %r", f->new);
324 d2173bb5 2012-07-17 rsc nulldir(&nd);
325 d2173bb5 2012-07-17 rsc nd.uid = d->uid;
326 d2173bb5 2012-07-17 rsc dirwstat(newfile, &nd);
328 d2173bb5 2012-07-17 rsc return (d->mode & DMDIR) != 0;
332 d2173bb5 2012-07-17 rsc * check if file to is up to date with
333 d2173bb5 2012-07-17 rsc * respect to the file represented by df
336 d2173bb5 2012-07-17 rsc uptodate(Dir *df, char *to)
341 d2173bb5 2012-07-17 rsc if(fskind == Archive || ream || (dt = dirstat(to)) == nil)
343 d2173bb5 2012-07-17 rsc ret = dt->mtime >= df->mtime;
349 d2173bb5 2012-07-17 rsc copy(Dir *d)
351 d2173bb5 2012-07-17 rsc char cptmp[LEN], *p;
352 d2173bb5 2012-07-17 rsc int f, t, n, needwrite, nowarnyet = 1;
353 d2173bb5 2012-07-17 rsc vlong tot, len;
356 d2173bb5 2012-07-17 rsc f = open(oldfile, OREAD);
358 d2173bb5 2012-07-17 rsc warn("can't open %q: %r", oldfile);
362 d2173bb5 2012-07-17 rsc if(fskind == Archive)
365 d2173bb5 2012-07-17 rsc strcpy(cptmp, newfile);
366 d2173bb5 2012-07-17 rsc p = utfrrune(cptmp, L'/');
368 d2173bb5 2012-07-17 rsc error("internal temporary file error");
369 d2173bb5 2012-07-17 rsc strcpy(p+1, "__mkfstmp");
370 d2173bb5 2012-07-17 rsc t = create(cptmp, OWRITE, 0666);
372 d2173bb5 2012-07-17 rsc warn("can't create %q: %r", newfile);
378 d2173bb5 2012-07-17 rsc needwrite = 0;
379 d2173bb5 2012-07-17 rsc for(tot = 0; tot < d->length; tot += n){
380 d2173bb5 2012-07-17 rsc len = d->length - tot;
381 d2173bb5 2012-07-17 rsc /* don't read beyond d->length */
382 d2173bb5 2012-07-17 rsc if (len > buflen)
383 d2173bb5 2012-07-17 rsc len = buflen;
384 d2173bb5 2012-07-17 rsc n = read(f, buf, len);
385 d2173bb5 2012-07-17 rsc if(n <= 0) {
386 d2173bb5 2012-07-17 rsc if(n < 0 && nowarnyet) {
387 d2173bb5 2012-07-17 rsc warn("can't read %q: %r", oldfile);
388 d2173bb5 2012-07-17 rsc nowarnyet = 0;
391 d2173bb5 2012-07-17 rsc * don't quit: pad to d->length (in pieces) to agree
392 d2173bb5 2012-07-17 rsc * with the length in the header, already emitted.
394 d2173bb5 2012-07-17 rsc memset(buf, 0, len);
397 d2173bb5 2012-07-17 rsc if(fskind == Archive){
398 d2173bb5 2012-07-17 rsc if(Bwrite(&bout, buf, n) != n)
399 d2173bb5 2012-07-17 rsc error("write error: %r");
400 d2173bb5 2012-07-17 rsc }else if(memcmp(buf, zbuf, n) == 0){
401 d2173bb5 2012-07-17 rsc if(seek(t, n, 1) < 0)
402 d2173bb5 2012-07-17 rsc error("can't write zeros to %q: %r", newfile);
403 d2173bb5 2012-07-17 rsc needwrite = 1;
405 d2173bb5 2012-07-17 rsc if(write(t, buf, n) < n)
406 d2173bb5 2012-07-17 rsc error("can't write %q: %r", newfile);
407 d2173bb5 2012-07-17 rsc needwrite = 0;
411 d2173bb5 2012-07-17 rsc if(needwrite){
412 d2173bb5 2012-07-17 rsc if(seek(t, -1, 1) < 0 || write(t, zbuf, 1) != 1)
413 d2173bb5 2012-07-17 rsc error("can't write zero at end of %q: %r", newfile);
415 d2173bb5 2012-07-17 rsc if(tot != d->length){
416 d2173bb5 2012-07-17 rsc /* this should no longer happen */
417 d2173bb5 2012-07-17 rsc warn("wrong number of bytes written to %q (was %lld should be %lld)\n",
418 d2173bb5 2012-07-17 rsc newfile, tot, d->length);
419 d2173bb5 2012-07-17 rsc if(fskind == Archive){
420 d2173bb5 2012-07-17 rsc warn("seeking to proper position\n");
421 d2173bb5 2012-07-17 rsc /* does no good if stdout is a pipe */
422 d2173bb5 2012-07-17 rsc Bseek(&bout, d->length - tot, 1);
425 d2173bb5 2012-07-17 rsc if(fskind == Archive)
427 d2173bb5 2012-07-17 rsc remove(newfile);
428 d2173bb5 2012-07-17 rsc nulldir(&nd);
429 d2173bb5 2012-07-17 rsc nd.mode = d->mode;
430 d2173bb5 2012-07-17 rsc nd.gid = d->gid;
431 d2173bb5 2012-07-17 rsc nd.mtime = d->mtime;
432 d2173bb5 2012-07-17 rsc nd.name = d->name;
433 d2173bb5 2012-07-17 rsc if(dirfwstat(t, &nd) < 0)
434 d2173bb5 2012-07-17 rsc error("can't move tmp file to %q: %r", newfile);
435 d2173bb5 2012-07-17 rsc nulldir(&nd);
436 d2173bb5 2012-07-17 rsc nd.uid = d->uid;
437 d2173bb5 2012-07-17 rsc dirfwstat(t, &nd);
442 d2173bb5 2012-07-17 rsc mkdir(Dir *d)
448 d2173bb5 2012-07-17 rsc if(fskind == Archive){
452 d2173bb5 2012-07-17 rsc fd = create(newfile, OREAD, d->mode);
453 d2173bb5 2012-07-17 rsc nulldir(&nd);
454 d2173bb5 2012-07-17 rsc nd.mode = d->mode;
455 d2173bb5 2012-07-17 rsc nd.gid = d->gid;
456 d2173bb5 2012-07-17 rsc nd.mtime = d->mtime;
458 d2173bb5 2012-07-17 rsc if((d1 = dirstat(newfile)) == nil || !(d1->mode & DMDIR)){
460 d2173bb5 2012-07-17 rsc error("can't create %q", newfile);
463 d2173bb5 2012-07-17 rsc if(dirwstat(newfile, &nd) < 0)
464 d2173bb5 2012-07-17 rsc warn("can't set modes for %q: %r", newfile);
465 d2173bb5 2012-07-17 rsc nulldir(&nd);
466 d2173bb5 2012-07-17 rsc nd.uid = d->uid;
467 d2173bb5 2012-07-17 rsc dirwstat(newfile, &nd);
470 d2173bb5 2012-07-17 rsc if(dirfwstat(fd, &nd) < 0)
471 d2173bb5 2012-07-17 rsc warn("can't set modes for %q: %r", newfile);
472 d2173bb5 2012-07-17 rsc nulldir(&nd);
473 d2173bb5 2012-07-17 rsc nd.uid = d->uid;
474 d2173bb5 2012-07-17 rsc dirfwstat(fd, &nd);
479 d2173bb5 2012-07-17 rsc arch(Dir *d)
481 d2173bb5 2012-07-17 rsc Bprint(&bout, "%q %luo %q %q %lud %lld\n",
482 d2173bb5 2012-07-17 rsc newfile, d->mode, d->uid, d->gid, d->mtime, d->length);
486 d2173bb5 2012-07-17 rsc mkpath(char *prefix, char *elem)
491 d2173bb5 2012-07-17 rsc n = strlen(prefix) + strlen(elem) + 2;
492 d2173bb5 2012-07-17 rsc p = emalloc(n);
493 d2173bb5 2012-07-17 rsc sprint(p, "%s/%s", prefix, elem);
498 d2173bb5 2012-07-17 rsc strdup(char *s)
502 d2173bb5 2012-07-17 rsc t = emalloc(strlen(s) + 1);
503 d2173bb5 2012-07-17 rsc return strcpy(t, s);
507 d2173bb5 2012-07-17 rsc setnames(File *f)
509 d2173bb5 2012-07-17 rsc sprint(newfile, "%s%s", newroot, f->new);
511 d2173bb5 2012-07-17 rsc if(f->old[0] == '/')
512 d2173bb5 2012-07-17 rsc sprint(oldfile, "%s%s", oldroot, f->old);
514 d2173bb5 2012-07-17 rsc strcpy(oldfile, f->old);
516 d2173bb5 2012-07-17 rsc sprint(oldfile, "%s%s", oldroot, f->new);
517 fa325e9b 2020-01-10 cross if(strlen(newfile) >= sizeof newfile
518 d2173bb5 2012-07-17 rsc || strlen(oldfile) >= sizeof oldfile)
519 d2173bb5 2012-07-17 rsc error("name overfile");
523 d2173bb5 2012-07-17 rsc freefile(File *f)
526 d2173bb5 2012-07-17 rsc free(f->old);
528 d2173bb5 2012-07-17 rsc free(f->new);
533 d2173bb5 2012-07-17 rsc * skip all files in the proto that
534 d2173bb5 2012-07-17 rsc * could be in the current dir
537 d2173bb5 2012-07-17 rsc skipdir(void)
542 d2173bb5 2012-07-17 rsc if(indent < 0 || b == nil) /* b is nil when copying adm/users */
544 d2173bb5 2012-07-17 rsc level = indent;
547 d2173bb5 2012-07-17 rsc p = Brdline(b, '\n');
550 d2173bb5 2012-07-17 rsc indent = -1;
553 d2173bb5 2012-07-17 rsc while((c = *p++) != '\n')
554 d2173bb5 2012-07-17 rsc if(c == ' ')
556 d2173bb5 2012-07-17 rsc else if(c == '\t')
557 d2173bb5 2012-07-17 rsc indent += 8;
560 d2173bb5 2012-07-17 rsc if(indent <= level){
561 d2173bb5 2012-07-17 rsc Bseek(b, -Blinelen(b), 1);
569 d2173bb5 2012-07-17 rsc getfile(File *old)
576 d2173bb5 2012-07-17 rsc if(indent < 0)
580 d2173bb5 2012-07-17 rsc p = Brdline(b, '\n');
583 d2173bb5 2012-07-17 rsc indent = -1;
586 d2173bb5 2012-07-17 rsc while((c = *p++) != '\n')
587 d2173bb5 2012-07-17 rsc if(c == ' ')
589 d2173bb5 2012-07-17 rsc else if(c == '\t')
590 d2173bb5 2012-07-17 rsc indent += 8;
593 d2173bb5 2012-07-17 rsc if(c == '\n' || c == '#')
596 d2173bb5 2012-07-17 rsc f = emalloc(sizeof *f);
597 d2173bb5 2012-07-17 rsc p = getname(p, &elem);
599 d2173bb5 2012-07-17 rsc fprint(2, "getfile: %q root %q\n", elem, old->new);
600 d2173bb5 2012-07-17 rsc f->new = mkpath(old->new, elem);
601 d2173bb5 2012-07-17 rsc f->elem = utfrrune(f->new, L'/') + 1;
602 d2173bb5 2012-07-17 rsc p = getmode(p, &f->mode);
603 d2173bb5 2012-07-17 rsc p = getname(p, &f->uid);
604 d2173bb5 2012-07-17 rsc if(!*f->uid)
605 d2173bb5 2012-07-17 rsc f->uid = "-";
606 d2173bb5 2012-07-17 rsc p = getname(p, &f->gid);
607 d2173bb5 2012-07-17 rsc if(!*f->gid)
608 d2173bb5 2012-07-17 rsc f->gid = "-";
609 d2173bb5 2012-07-17 rsc f->old = getpath(p);
610 d2173bb5 2012-07-17 rsc if(f->old && strcmp(f->old, "-") == 0){
611 d2173bb5 2012-07-17 rsc free(f->old);
614 d2173bb5 2012-07-17 rsc setnames(f);
617 d2173bb5 2012-07-17 rsc printfile(f);
623 d2173bb5 2012-07-17 rsc getpath(char *p)
625 d2173bb5 2012-07-17 rsc char *q, *new;
628 d2173bb5 2012-07-17 rsc while((c = *p) == ' ' || c == '\t')
631 d2173bb5 2012-07-17 rsc while((c = *q) != '\n' && c != ' ' && c != '\t')
636 d2173bb5 2012-07-17 rsc new = emalloc(n + 1);
637 d2173bb5 2012-07-17 rsc memcpy(new, p, n);
643 d2173bb5 2012-07-17 rsc getname(char *p, char **buf)
645 d2173bb5 2012-07-17 rsc char *s, *start;
648 d2173bb5 2012-07-17 rsc while((c = *p) == ' ' || c == '\t')
652 d2173bb5 2012-07-17 rsc while((c = *p) != '\n' && c != ' ' && c != '\t' && c != '\0')
655 d2173bb5 2012-07-17 rsc *buf = malloc(p+1-start);
656 d2173bb5 2012-07-17 rsc if(*buf == nil)
658 d2173bb5 2012-07-17 rsc memmove(*buf, start, p-start);
659 d2173bb5 2012-07-17 rsc (*buf)[p-start] = '\0';
661 d2173bb5 2012-07-17 rsc if(**buf == '$'){
662 d2173bb5 2012-07-17 rsc s = getenv(*buf+1);
664 d2173bb5 2012-07-17 rsc warn("can't read environment variable %q", *buf+1);
676 d2173bb5 2012-07-17 rsc getmode(char *p, ulong *xmode)
678 d2173bb5 2012-07-17 rsc char *buf, *s;
681 d2173bb5 2012-07-17 rsc *xmode = ~0;
682 d2173bb5 2012-07-17 rsc p = getname(p, &buf);
683 d2173bb5 2012-07-17 rsc if(p == nil)
687 d2173bb5 2012-07-17 rsc if(!*s || strcmp(s, "-") == 0)
690 d2173bb5 2012-07-17 rsc if(*s == 'd'){
694 d2173bb5 2012-07-17 rsc if(*s == 'a'){
695 d2173bb5 2012-07-17 rsc m |= DMAPPEND;
698 d2173bb5 2012-07-17 rsc if(*s == 'l'){
699 d2173bb5 2012-07-17 rsc m |= DMEXCL;
702 d2173bb5 2012-07-17 rsc if(s[0] < '0' || s[0] > '7'
703 d2173bb5 2012-07-17 rsc || s[1] < '0' || s[1] > '7'
704 d2173bb5 2012-07-17 rsc || s[2] < '0' || s[2] > '7'
706 d2173bb5 2012-07-17 rsc warn("bad mode specification %q", buf);
710 d2173bb5 2012-07-17 rsc *xmode = m | strtoul(s, 0, 8);
716 d2173bb5 2012-07-17 rsc setusers(void)
721 d2173bb5 2012-07-17 rsc if(fskind != Kfs)
725 d2173bb5 2012-07-17 rsc file.uid = "adm";
726 d2173bb5 2012-07-17 rsc file.gid = "adm";
727 d2173bb5 2012-07-17 rsc file.mode = DMDIR|0775;
728 d2173bb5 2012-07-17 rsc file.new = "/adm";
729 d2173bb5 2012-07-17 rsc file.elem = "adm";
730 d2173bb5 2012-07-17 rsc file.old = 0;
731 d2173bb5 2012-07-17 rsc setnames(&file);
732 d2173bb5 2012-07-17 rsc strcpy(oldfile, file.new); /* Don't use root for /adm */
733 d2173bb5 2012-07-17 rsc mkfile(&file);
734 d2173bb5 2012-07-17 rsc file.new = "/adm/users";
735 d2173bb5 2012-07-17 rsc file.old = users;
736 d2173bb5 2012-07-17 rsc file.elem = "users";
737 d2173bb5 2012-07-17 rsc file.mode = 0664;
738 d2173bb5 2012-07-17 rsc setnames(&file);
739 d2173bb5 2012-07-17 rsc if (file.old)
740 d2173bb5 2012-07-17 rsc strcpy(oldfile, file.old); /* Don't use root for /adm/users */
741 d2173bb5 2012-07-17 rsc mkfile(&file);
742 d2173bb5 2012-07-17 rsc kfscmd("user");
743 d2173bb5 2012-07-17 rsc mkfile(&file);
744 d2173bb5 2012-07-17 rsc file.mode = DMDIR|0775;
745 d2173bb5 2012-07-17 rsc file.new = "/adm";
746 d2173bb5 2012-07-17 rsc file.old = "/adm";
747 d2173bb5 2012-07-17 rsc file.elem = "adm";
748 d2173bb5 2012-07-17 rsc setnames(&file);
749 d2173bb5 2012-07-17 rsc strcpy(oldfile, file.old); /* Don't use root for /adm */
750 d2173bb5 2012-07-17 rsc mkfile(&file);
755 d2173bb5 2012-07-17 rsc mountkfs(char *name)
757 d2173bb5 2012-07-17 rsc if(fskind != Kfs)
759 d2173bb5 2012-07-17 rsc sysfatal("no kfs: use -a or -d");
763 d2173bb5 2012-07-17 rsc kfscmd(char *cmd)
765 d2173bb5 2012-07-17 rsc char buf[4*1024];
768 d2173bb5 2012-07-17 rsc if(fskind != Kfs)
770 d2173bb5 2012-07-17 rsc if(write(sfd, cmd, strlen(cmd)) != strlen(cmd)){
771 d2173bb5 2012-07-17 rsc fprint(2, "%q: error writing %q: %r", prog, cmd);
775 d2173bb5 2012-07-17 rsc n = read(sfd, buf, sizeof buf - 1);
778 d2173bb5 2012-07-17 rsc buf[n] = '\0';
779 d2173bb5 2012-07-17 rsc if(strcmp(buf, "done") == 0 || strcmp(buf, "success") == 0)
781 d2173bb5 2012-07-17 rsc if(strcmp(buf, "unknown command") == 0){
782 d2173bb5 2012-07-17 rsc fprint(2, "%q: command %q not recognized\n", prog, cmd);
789 d2173bb5 2012-07-17 rsc emalloc(ulong n)
793 d2173bb5 2012-07-17 rsc if((p = malloc(n)) == 0)
794 d2173bb5 2012-07-17 rsc error("out of memory");
799 d2173bb5 2012-07-17 rsc error(char *fmt, ...)
801 d2173bb5 2012-07-17 rsc char buf[1024];
802 d2173bb5 2012-07-17 rsc va_list arg;
804 d2173bb5 2012-07-17 rsc sprint(buf, "%q: %q:%d: ", prog, proto, lineno);
805 d2173bb5 2012-07-17 rsc va_start(arg, fmt);
806 d2173bb5 2012-07-17 rsc vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg);
807 d2173bb5 2012-07-17 rsc va_end(arg);
808 d2173bb5 2012-07-17 rsc fprint(2, "%s\n", buf);
809 d2173bb5 2012-07-17 rsc kfscmd("disallow");
810 d2173bb5 2012-07-17 rsc kfscmd("sync");
815 d2173bb5 2012-07-17 rsc warn(char *fmt, ...)
817 d2173bb5 2012-07-17 rsc char buf[1024];
818 d2173bb5 2012-07-17 rsc va_list arg;
820 d2173bb5 2012-07-17 rsc sprint(buf, "%q: %q:%d: ", prog, proto, lineno);
821 d2173bb5 2012-07-17 rsc va_start(arg, fmt);
822 d2173bb5 2012-07-17 rsc vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg);
823 d2173bb5 2012-07-17 rsc va_end(arg);
824 d2173bb5 2012-07-17 rsc fprint(2, "%s\n", buf);
828 d2173bb5 2012-07-17 rsc printfile(File *f)
831 d2173bb5 2012-07-17 rsc fprint(2, "%q from %q %q %q %lo\n", f->new, f->old, f->uid, f->gid, f->mode);
833 d2173bb5 2012-07-17 rsc fprint(2, "%q %q %q %lo\n", f->new, f->uid, f->gid, f->mode);
839 d2173bb5 2012-07-17 rsc fprint(2, "usage: %q [-aprvx] [-d root] [-n name] [-s source] [-u users] [-z n] proto ...\n", prog);
840 d2173bb5 2012-07-17 rsc exits("usage");