diff options
author | cinap_lenrek <cinap_lenrek@centraldogma> | 2011-06-08 00:49:45 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@centraldogma> | 2011-06-08 00:49:45 +0000 |
commit | 4626ebdbd8e58938e0d82b3f1d4560c84c19324f (patch) | |
tree | e5489bc9c65855983dcbe1c84e87fb85f4c1ded4 /sys/src/libdisk | |
parent | 6feb86937194c4becd1135ee9532e0b8f509195b (diff) |
add support for mode override in libdisk/proto, fix some perms and add logfiles to cdproto
Diffstat (limited to 'sys/src/libdisk')
-rw-r--r-- | sys/src/libdisk/proto.c | 102 |
1 files changed, 95 insertions, 7 deletions
diff --git a/sys/src/libdisk/proto.c b/sys/src/libdisk/proto.c index c209ace8d..192efc0d8 100644 --- a/sys/src/libdisk/proto.c +++ b/sys/src/libdisk/proto.c @@ -33,6 +33,8 @@ struct Name { typedef struct Opt Opt; struct Opt { int level; + long mode; + long mask; Reprog *skip; char *uid; char *gid; @@ -275,12 +277,6 @@ copyfile(Mkaux *mkaux, File *f, Dir *d, int permonly) d = nd; d->name = f->elem; - if(d->type != 'M'){ - d->uid = "sys"; - d->gid = "sys"; - xmode = (d->mode >> 6) & 7; - d->mode |= xmode | (xmode << 3); - } o = mkaux->opt; if(strcmp(f->uid, "-") != 0) d->uid = f->uid; @@ -297,7 +293,8 @@ copyfile(Mkaux *mkaux, File *f, Dir *d, int permonly) warn(mkaux, "inconsistent mode for %s", f->new); else d->mode = f->mode; - } + } else if(o && o->mask) + d->mode = (d->mode & ~o->mask) | (o->mode & o->mask); if(p = strrchr(f->new, '/')) d->name = p+1; @@ -323,6 +320,92 @@ mkpath(Mkaux *mkaux, char *prefix, char *elem) return p; } +static int +parsemode(char *spec, long *pmask, long *pmode) +{ + char op, set, *s; + long mode; + long mask; + + s = spec; + op = set = 0; + mode = 0; + mask = DMAPPEND | DMEXCL | DMTMP; + + if(*s >= '0' && *s <= '7'){ + mask = 0666; + mode = strtoul(s, 0, 8); + op = '='; + s = "!"; + } + + for(; *s && op == 0; s++){ + switch(*s){ + case 'a': + mask |= 0666; + break; + case 'u': + mask |= 0600; + break; + case 'g': + mask |= 060; + break; + case 'o': + mask |= 06; + break; + case '-': + case '+': + case '=': + op = *s; + break; + default: + return 0; + } + } + if(s == spec) + mask |= 0666; + + for(; *s; s++){ + switch(*s){ + case 'r': + mode |= 0444; + break; + case 'w': + mode |= 0222; + break; + case 'x': + mode |= 0111; + break; + case 'a': + mode |= DMAPPEND; + break; + case 'l': + mode |= DMEXCL; + break; + case 't': + mode |= DMTMP; + break; + case '!': + set = 1; + break; + default: + return 0; + } + } + + if(op == '+' || op == '-') + mask &= mode; + if(op == '-') + mode = ~mode; + if(set) + *pmask = 0; + + *pmask |= mask; + *pmode = (*pmode & ~mask) | (mode & mask); + + return 1; +} + static void setopt(Mkaux *mkaux, char *key, char *val) { @@ -354,6 +437,11 @@ setopt(Mkaux *mkaux, char *key, char *val) } else if(strcmp(key, "gid") == 0){ free(o->gid); o->gid = *val ? estrdup(mkaux, val) : nil; + } else if(strcmp(key, "mode") == 0){ + if(!parsemode(val, &o->mask, &o->mode)) + warn(mkaux, "bad mode specification %s", val); + } else { + warn(mkaux, "bad option %s=%s", key, val); } } |