diff -r 5b18d18ae709 sys/src/libdisk/proto.c --- a/sys/src/libdisk/proto.c Sat Oct 13 00:07:46 2018 +0200 +++ b/sys/src/libdisk/proto.c Sat Oct 13 04:33:31 2018 +0200 @@ -64,6 +64,8 @@ static int copyfile(Mkaux*, File*, Dir*, int); static void freefile(File*); +static void freeoptptr(Opt*, void*); +static char* getline(Mkaux*); static File* getfile(Mkaux*, File*); static char* getmode(Mkaux*, char*, ulong*); static char* getname(Mkaux*, char*, char**); @@ -72,16 +74,11 @@ static char* mkpath(Mkaux*, char*, char*); static void mktree(Mkaux*, File*, int); static void setname(Mkaux*, Name*, File*); +static void setopt(Mkaux*, char*, char*); static void skipdir(Mkaux*); static void warn(Mkaux*, char *, ...); static void popopt(Mkaux *mkaux); -//static void -//mprint(char *new, char *old, Dir *d, void*) -//{ -// print("%s %s %D\n", new, old, d); -//} - int rdproto(char *proto, char *root, Mkfsenum *mkenum, Mkfserr *mkerr, void *a) { @@ -151,7 +148,7 @@ int rec; child = getfile(mkaux, me); - if(!child) + if(child == nil) return; if((child->elem[0] == '+' || child->elem[0] == '*') && child->elem[1] == '\0'){ rec = child->elem[0] == '+'; @@ -162,13 +159,13 @@ freefile(child); child = getfile(mkaux, me); } - while(child && mkaux->indent > level){ + while(child != nil && mkaux->indent > level){ if(mkfile(mkaux, child)) domkfs(mkaux, child, mkaux->indent); freefile(child); child = getfile(mkaux, me); } - if(child){ + if(child != nil){ freefile(child); Bseek(mkaux->b, -Blinelen(mkaux->b), 1); mkaux->lineno--; @@ -198,15 +195,14 @@ continue; } child.new = mkpath(mkaux, me->new, d[i].name); - if(me->old) + if(me->old != nil) child.old = mkpath(mkaux, me->old, d[i].name); child.elem = d[i].name; setname(mkaux, &mkaux->oldfile, &child); if((!(d[i].mode&DMDIR) || rec) && copyfile(mkaux, &child, &d[i], 1) && rec) mktree(mkaux, &child, rec); free(child.new); - if(child.old) - free(child.old); + free(child.old); } free(d); } @@ -281,11 +277,11 @@ o = mkaux->opt; if(strcmp(f->uid, "-") != 0) d->uid = f->uid; - else if(o && o->uid) + else if(o != nil && o->uid != nil) d->uid = o->uid; if(strcmp(f->gid, "-") != 0) d->gid = f->gid; - else if(o && o->gid) + else if(o != nil && o->gid != nil) d->gid = o->gid; if(f->mode != ~0){ if(permonly) @@ -294,10 +290,10 @@ warn(mkaux, "inconsistent mode for %s", f->new); else d->mode = f->mode; - } else if(o && o->mask) + } else if(o != nil && o->mask) d->mode = (d->mode & ~o->mask) | (o->mode & o->mask); - if(p = strrchr(f->new, '/')) + if((p = strrchr(f->new, '/')) != nil) d->name = p+1; else d->name = f->new; @@ -415,28 +411,22 @@ o = mkaux->opt; if(o == nil || mkaux->indent > o->level){ o = emalloc(mkaux, sizeof(*o)); - if(o == nil) - longjmp(mkaux->jmp, 1); - if(mkaux->opt){ + if(mkaux->opt != nil) *o = *mkaux->opt; - if(o->uid) - o->uid = estrdup(mkaux, o->uid); - if(o->gid) - o->gid = estrdup(mkaux, o->gid); - }else - memset(o, 0, sizeof(*o)); o->level = mkaux->indent; o->prev = mkaux->opt; mkaux->opt = o; } else if(mkaux->indent < o->level) return; if(strcmp(key, "skip") == 0){ - o->skip = regcomp(val); + freeoptptr(o, &o->skip); + if((o->skip = regcomp(val)) == nil) + warn(mkaux, "bad regular expression %s", val); } else if(strcmp(key, "uid") == 0){ - free(o->uid); + freeoptptr(o, &o->uid); o->uid = *val ? estrdup(mkaux, val) : nil; } else if(strcmp(key, "gid") == 0){ - free(o->gid); + freeoptptr(o, &o->gid); o->gid = *val ? estrdup(mkaux, val) : nil; } else if(strcmp(key, "mode") == 0){ if(!parsemode(val, &o->mask, &o->mode)) @@ -451,23 +441,37 @@ { Opt *o; - while(o = mkaux->opt){ + while((o = mkaux->opt) != nil){ if(o->level <= mkaux->indent) break; mkaux->opt = o->prev; - free(o->uid); - free(o->gid); + freeoptptr(o, &o->skip); + freeoptptr(o, &o->uid); + freeoptptr(o, &o->gid); free(o); } } static void +freeoptptr(Opt *o, void *p) +{ + int x = (void**)p - (void**)o; + void *v = ((void**)o)[x]; + if(v == nil) + return; + ((void**)o)[x] = nil; + if((o = o->prev) != nil) + if(((void**)o)[x] == v) + return; + free(v); +} + + +static void freefile(File *f) { - if(f->old) - free(f->old); - if(f->new) - free(f->new); + free(f->old); + free(f->new); free(f); } @@ -478,27 +482,10 @@ static void skipdir(Mkaux *mkaux) { - char *p, c; int level; - if(mkaux->indent < 0) - return; level = mkaux->indent; - for(;;){ - mkaux->indent = 0; - p = Brdline(mkaux->b, '\n'); - mkaux->lineno++; - if(!p){ - mkaux->indent = -1; - return; - } - while((c = *p++) != '\n') - if(c == ' ') - mkaux->indent++; - else if(c == '\t') - mkaux->indent += 8; - else - break; + while(getline(mkaux) != nil){ if(mkaux->indent <= level){ popopt(mkaux); Bseek(mkaux->b, -Blinelen(mkaux->b), 1); @@ -508,23 +495,26 @@ } } -static File* -getfile(Mkaux *mkaux, File *old) +static char* +getline(Mkaux *mkaux) { - File *f; - char *elem; - char *p, *s; + char *p; int c; if(mkaux->indent < 0) - return 0; + return nil; loop: mkaux->indent = 0; p = Brdline(mkaux->b, '\n'); mkaux->lineno++; - if(!p){ + if(p == nil){ mkaux->indent = -1; - return 0; + return nil; + } + if(memchr(p, 0, Blinelen(mkaux->b)) != nil){ + warn(mkaux, "null bytes in proto"); + longjmp(mkaux->jmp, 1); + return nil; } while((c = *p++) != '\n') if(c == ' ') @@ -535,41 +525,62 @@ break; if(c == '\n' || c == '#') goto loop; - p--; + return --p; +} + +static File* +getfile(Mkaux *mkaux, File *old) +{ + File *f; + char *elem; + char *p, *s; + +loop: + if((p = getline(mkaux)) == nil) + return nil; popopt(mkaux); + *strchr(p, '\n') = 0; - if(s = strchr(p, '=')){ + if((s = strchr(p, '=')) != nil){ *s++ = 0; setopt(mkaux, p, s); goto loop; }else p[strlen(p)] = '\n'; - f = emalloc(mkaux, sizeof *f); - p = getname(mkaux, p, &elem); - if(p == nil) + + if((p = getname(mkaux, p, &elem)) == nil) return nil; + f = emalloc(mkaux, sizeof *f); f->new = mkpath(mkaux, old->new, elem); free(elem); f->elem = utfrrune(f->new, L'/') + 1; - p = getmode(mkaux, p, &f->mode); - p = getname(mkaux, p, &f->uid); /* LEAK */ - if(p == nil) + + if((p = getmode(mkaux, p, &f->mode)) == nil){ + freefile(f); return nil; + } - if(!*f->uid) + if((p = getname(mkaux, p, &f->uid)) == nil){ + freefile(f); + return nil; + } + if(*f->uid == 0) strcpy(f->uid, "-"); - p = getname(mkaux, p, &f->gid); /* LEAK */ - if(p == nil) + + if((p = getname(mkaux, p, &f->gid)) == nil){ + freefile(f); return nil; + } + if(*f->gid == 0) + strcpy(f->gid, "-"); - if(!*f->gid) - strcpy(f->gid, "-"); f->old = getpath(mkaux, p); - if(f->old && strcmp(f->old, "-") == 0){ + if(f->old != nil && strcmp(f->old, "-") == 0){ free(f->old); - f->old = 0; + f->old = nil; } + setname(mkaux, &mkaux->oldfile, f); return f; @@ -587,7 +598,7 @@ while((c = *q) != '\n' && c != ' ' && c != '\t') q++; if(q == p) - return 0; + return nil; n = q - p; new = emalloc(mkaux, n + 1); memcpy(new, p, n); @@ -613,14 +624,14 @@ return nil; memmove(*buf, start, p-start); - (*buf)[p-start] = '\0'; + (*buf)[p-start] = 0; if(**buf == '$'){ s = getenv(*buf+1); - if(s == 0){ + if(s == nil){ warn(mkaux, "can't read environment variable %s", *buf+1); + free(*buf); skipdir(mkaux); - free(*buf); return nil; } free(*buf); @@ -636,12 +647,11 @@ ulong m; *xmode = ~0; - p = getname(mkaux, p, &buf); - if(p == nil) + if((p = getname(mkaux, p, &buf)) == nil) return nil; s = buf; - if(!*s || strcmp(s, "-") == 0) + if(*s == 0 || strcmp(s, "-") == 0) return p; m = 0; if(*s == 'd'){ @@ -679,7 +689,7 @@ vseprint(buf, buf+sizeof(buf), fmt, va); va_end(va); - if(mkaux->warn) + if(mkaux->warn != nil) mkaux->warn(buf, mkaux->a); else fprint(2, "warning: %s\n", buf);