summaryrefslogtreecommitdiff
path: root/sys/src/libdisk
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@centraldogma>2011-06-08 00:49:45 +0000
committercinap_lenrek <cinap_lenrek@centraldogma>2011-06-08 00:49:45 +0000
commit4626ebdbd8e58938e0d82b3f1d4560c84c19324f (patch)
treee5489bc9c65855983dcbe1c84e87fb85f4c1ded4 /sys/src/libdisk
parent6feb86937194c4becd1135ee9532e0b8f509195b (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.c102
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);
}
}