diff -ur genromfs-0.3.uclinux/genromfs.c genromfs-0.3/genromfs.c --- genromfs-0.3.uclinux/genromfs.c Sat Apr 1 18:04:47 2000 +++ genromfs-0.3/genromfs.c Sun Apr 2 12:53:43 2000 @@ -99,6 +99,7 @@ struct filenode; struct filehdr { + struct filenode *owner; struct filenode *head; struct filenode *tail; struct filenode *tailpred; @@ -107,6 +108,7 @@ struct filenode { struct filenode *next; struct filenode *prev; + struct filenode *parent; struct filehdr dirlist; struct filenode *orig_link; char *name; @@ -126,8 +128,14 @@ char pattern[0]; }; -void initlist(struct filehdr *fh) +struct excludes { + struct excludes *next; + char pattern[0]; +}; + +void initlist(struct filehdr *fh, struct filenode *owner) { + fh->owner = owner; fh->head = (struct filenode *)&fh->tail; fh->tail = NULL; fh->tailpred = (struct filenode *)&fh->head; @@ -144,6 +152,7 @@ n->next = tail; n->prev = tail->prev; tail->prev = n; n->prev->next =n; + n->parent = fh->owner; } void shownode(int level, struct filenode *node, FILE *f) @@ -168,6 +177,7 @@ static int atoffs = 0; static int align = 16; struct aligns *alignlist = NULL; +struct excludes *excludelist = NULL; int realbase; int findalign(struct filenode *node) @@ -445,7 +455,8 @@ node->realname = str; node->next = node->prev = NULL; - initlist(&node->dirlist); + initlist(&node->dirlist, node); + node->parent = NULL; node->ondev = -1; node->onino = -1; @@ -503,6 +514,7 @@ DIR *dirfd; struct dirent *dp; struct filenode *n, *link; + struct excludes *pe; if (level <= 1) { /* Ok, to make sure . and .. are handled correctly @@ -513,6 +525,7 @@ if (!lstat(link->realname, sb)) { setnode(link, sb->st_dev, sb->st_ino, sb->st_mode); append(&dir->dirlist, link); + dir->dirlist.owner = link; /* special case for root node - '..'s in subdirs should link to '.' of root node, not root node itself. */ curroffset = alignnode(link, curroffset, 0) + spaceneeded(link); n = newnode(base, "..", curroffset); if (!lstat(n->realname, sb)) { @@ -532,6 +545,22 @@ || strcmp(dp->d_name, "..") == 0)) continue; n = newnode(base, dp->d_name, curroffset); + + /* Process exclude list. */ + for (pe = excludelist; pe; pe = pe->next) { + if (pe->pattern[0] == '/') { + if (!fnmatch(pe->pattern, n->realname + realbase, FNM_PATHNAME|FNM_PERIOD)) { + freenode(n); break; + } + } else { + if (!fnmatch(pe->pattern, n->name, FNM_PATHNAME|FNM_PERIOD)) { + freenode(n); break; + } + } + } + if (pe) + continue; + if (lstat(n->realname, sb)) { fprintf(stderr, "ignoring '%s' (lstat failed)\n", n->realname); freenode(n); continue; @@ -555,8 +584,16 @@ freenode(n); continue; } /* Look up old links */ - link = findnode(root, n->ondev, n->onino); - append(&dir->dirlist, n); + if (strcmp(n->name, ".") == 0) { + append(&dir->dirlist, n); + link = n->parent; + } else if (strcmp(n->name, "..") == 0) { + append(&dir->dirlist, n); + link = n->parent->parent; + } else { + link = findnode(root, n->ondev, n->onino); + append(&dir->dirlist, n); + } if (link) { n->orig_link = link; curroffset = alignnode(n, curroffset, 0) + spaceneeded(n); @@ -597,6 +634,7 @@ printf(" -V VOLUME Use the specified volume name\n"); printf(" -a ALIGN Align regular file data to ALIGN bytes\n"); printf(" -A ALIGN,PATTERN Align all objects matching pattern to at least ALIGN bytes\n"); + printf(" -x PATTERN Exclude all objects matching pattern\n"); printf(" -h Show this help\n"); printf("\n"); printf("Report bugs to chexum@shadow.banki.hu\n"); @@ -616,9 +654,10 @@ int i; char *p; struct aligns *pa, *pa2; + struct excludes *pe, *pe2; FILE *f; - while ((c = getopt(argc, argv, "V:vd:f:ha:A:")) != EOF) { + while ((c = getopt(argc, argv, "V:vd:f:ha:A:x:")) != EOF) { switch(c) { case 'd': dir = optarg; @@ -663,6 +702,17 @@ pa2->next = pa; } break; + case 'x': + pe = (struct excludes *)malloc(sizeof(*pe) + strlen(optarg) + 1); + pe->next = NULL; + strcpy(pe->pattern, optarg); + if (!excludelist) + excludelist = pe; + else { + for (pe2 = excludelist; pe2->next; pe2 = pe2->next); + pe2->next = pe; + } + break; default: exit(1); } @@ -689,6 +739,7 @@ realbase = strlen(dir); root = newnode(dir, volname, 0); + root->parent = root; lastoff = processdir (1, dir, dir, &sb, root, root, spaceneeded(root)); if (verbose) shownode(0, root, stderr);