--- squashfs-tools/mksquashfs.c 2007-01-16 09:24:40.000000000 +0100 +++ squashfs-tools-vito/mksquashfs.c 2007-01-17 08:34:17.000000000 +0100 @@ -44,6 +44,7 @@ #include #include #include +#include #ifndef linux #define __BYTE_ORDER BYTE_ORDER @@ -162,15 +163,19 @@ struct file_info *dupl[65536]; int dup_files = 0; -/* list of exclude dirs/files */ -struct exclude_info { +/* list of include/exclude files/regexes */ +struct filter_info { dev_t st_dev; ino_t st_ino; + regex_t *preg; + int action; }; -#define EXCLUDE_SIZE 8192 -int exclude = 0; -struct exclude_info *exclude_paths = NULL; +#define EXCLUDE 0 +#define INCLUDE 1 +#define FILTER_SIZE 8192 +int filter_count = 0; +struct filter_info *filters = NULL; int excluded(char *filename, struct stat *buf); /* fragment block data structures */ @@ -2606,20 +2611,32 @@ { int i; - for(i = 0; i < exclude; i++) - if((exclude_paths[i].st_dev == buf->st_dev) && (exclude_paths[i].st_ino == buf->st_ino)) - return TRUE; + for(i = 0; i < filter_count; i++) { + struct filter_info f = filters[i]; + + if(f.preg == NULL) { + if((f.st_dev == buf->st_dev) && (f.st_ino == buf->st_ino)) + return TRUE; + } else if(regexec(f.preg, filename, (size_t)0, NULL, 0) == 0) + if(f.action == EXCLUDE) + return TRUE; + else + return FALSE; + } + return FALSE; } -#define ADD_ENTRY(buf) \ - if(exclude % EXCLUDE_SIZE == 0) {\ - if((exclude_paths = (struct exclude_info *) realloc(exclude_paths, (exclude + EXCLUDE_SIZE) * sizeof(struct exclude_info))) == NULL)\ - BAD_ERROR("Out of memory in exclude dir/file table\n");\ +#define ADD_ENTRY(b, a, p) \ + if(filter_count % FILTER_SIZE == 0) {\ + if((filters = (struct filter_info *) realloc(filters, (filter_count + FILTER_SIZE) * sizeof(struct filter_info))) == NULL)\ + BAD_ERROR("Out of memory in the include/exclude file/regex table\n");\ }\ - exclude_paths[exclude].st_dev = buf.st_dev;\ - exclude_paths[exclude++].st_ino = buf.st_ino; + filters[filter_count].action = a;\ + filters[filter_count].preg = p;\ + filters[filter_count].st_dev = b.st_dev;\ + filters[filter_count++].st_ino = b.st_ino; int add_exclude(char *path) { int i; @@ -2632,7 +2649,7 @@ perror(buffer); return TRUE; } - ADD_ENTRY(buf); + ADD_ENTRY(buf, EXCLUDE, NULL); return TRUE; } @@ -2645,11 +2662,47 @@ } continue; } - ADD_ENTRY(buf); + ADD_ENTRY(buf, EXCLUDE, NULL); } return TRUE; } +void add_pattern(char *pattern) +{ + struct stat dummy; + int action = -1; + + if(pattern[0] == '#') + return; + + if(strlen(pattern) < 3) + goto bad_pattern; + + if(strncmp(pattern, "+ ", 2) == 0) + action = INCLUDE; + + if(strncmp(pattern, "- ", 2) == 0) + action = EXCLUDE; + + if(action != -1) { + regex_t *preg = (regex_t*)malloc(sizeof(regex_t)); + char message[1024]; + int error = regcomp(preg, pattern+2, REG_EXTENDED|REG_NOSUB); + regerror(error, preg, message, 1024); + + if(error) { + fprintf(stderr, "Ignoring invalid regex \"%s\" (%s)\n", pattern+2, message); + return; + } + + ADD_ENTRY(dummy, action, preg); + return; + } + +bad_pattern: + fprintf(stderr, "Ignoring wrong filter pattern \"%s\"\n", pattern); +} + void add_old_root_entry(char *name, squashfs_inode inode, int inode_number, int type) { @@ -2849,6 +2902,11 @@ ERROR("%s: -ef missing filename\n", argv[0]); exit(1); } + } else if(strcmp(argv[i], "-ff") == 0) { + if(++i == argc) { + ERROR("%s: -ff missing filename\n", argv[0]); + exit(1); + } } else if(strcmp(argv[i], "-no-duplicates") == 0) duplicate_checking = FALSE; @@ -2991,6 +3049,10 @@ ERROR("\t\t\tfile or dir with priority per line. Priority -32768 to\n"); ERROR("\t\t\t32767, default priority 0\n"); ERROR("-ef \tlist of exclude dirs/files. One per line\n"); + ERROR("-ff \tlist of include/exclude patterns. One per line.\n"); + ERROR("\t\t\tThe first pattern that matches a dir/file is applied.\n"); + ERROR("\t\t\tExclude patterns are written '+ regex', include patterns\n"); + ERROR("\t\t\tare written '- regex'. Comments start with #\n"); exit(1); } } @@ -3048,7 +3110,7 @@ signal(SIGINT, sighandler2); } - /* process the exclude files - must be done afer destination file has been possibly created */ + /* process the include/exclude files/patterns - must be done afer destination file has been possibly created */ for(i = source + 2; i < argc; i++) if(strcmp(argv[i], "-ef") == 0) { FILE *fd; @@ -3060,6 +3122,16 @@ while(fscanf(fd, "%16384[^\n]\n", filename) != EOF) add_exclude(filename); fclose(fd); + } else if(strcmp(argv[i], "-ff") == 0) { + FILE *fd; + char pattern[16385]; + if((fd = fopen(argv[++i], "r")) == NULL) { + perror("Could not open filter file..."); + EXIT_MKSQUASHFS(); + } + while(fscanf(fd, "%16384[^\n]\n", pattern) != EOF) + add_pattern(pattern); + fclose(fd); } else if(strcmp(argv[i], "-e") == 0) break; else if(strcmp(argv[i], "-b") == 0 || strcmp(argv[i], "-root-becomes") == 0 || strcmp(argv[i], "-sort") == 0) @@ -3073,14 +3145,14 @@ while(i < argc && add_exclude(argv[i++])); } - /* process the sort files - must be done afer the exclude files */ + /* process the sort files - must be done afer processing the include/exclude files/patterns */ for(i = source + 2; i < argc; i++) if(strcmp(argv[i], "-sort") == 0) { read_sort_file(argv[++i], source, source_path); sorted ++; } else if(strcmp(argv[i], "-e") == 0) break; - else if(strcmp(argv[i], "-b") == 0 || strcmp(argv[i], "-root-becomes") == 0 || strcmp(argv[i], "-ef") == 0) + else if(strcmp(argv[i], "-b") == 0 || strcmp(argv[i], "-root-becomes") == 0 || strcmp(argv[i], "-ef") == 0 || strcmp(argv[i], "-ff") == 0) i++; initialise_threads();