summaryrefslogblamecommitdiffstats
path: root/src/tools/mksquashfs-filter-patch
blob: 5cb4ba24c4e2f0ec5769bbb4b7e3f128afd7fbbb (plain) (tree)








































































































































































































                                                                                                                                                          
--- 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 <sys/mman.h>
 #include <pthread.h>
 #include <math.h>
+#include <regex.h>
 
 #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 <exclude_file>\tlist of exclude dirs/files.  One per line\n");
+			ERROR("-ff <filter_file>\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();