aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Masters <jcm@jonmasters.org>2010-01-15 01:55:02 -0500
committerJon Masters <jcm@jonmasters.org>2010-01-15 01:55:02 -0500
commit70c4f735aa41f2f7db3a4e4488f3a98feaf1c729 (patch)
treef4128f4b8770a2adb7cd7e396104e4001638d724
parent1c6fd378d7712a4f4d7178269c22c49b11a5adfe (diff)
downloadmodule-init-tools-70c4f735aa41f2f7db3a4e4488f3a98feaf1c729.tar.gz
depmod: use real regex matching on depmod "overrides" entries
We implement support for matching "override" entries in depmod config files to determine which module of several alternatives will be used. The existing implementation is a very poor "wildcard" match that does not use real regular expressions. This version uses the standard POSIX extended regular expressions, with backward compatibility to match on a single "*" kernel version as in the original (broken) design. Signed-off-by: Jon Masters <jcm@jonmasters.org>
-rw-r--r--depmod.c4
-rw-r--r--util.c29
-rw-r--r--util.h2
3 files changed, 33 insertions, 2 deletions
diff --git a/depmod.c b/depmod.c
index 5b90b3a..dfd210d 100644
--- a/depmod.c
+++ b/depmod.c
@@ -1,6 +1,7 @@
/* New simplified depmod without backwards compat stuff and not
requiring ksyms.
+ (C) 2010 Jon Masters <jcm@jonmasters.org>, and others.
(C) 2002 Rusty Russell IBM Corporation
*/
#define _GNU_SOURCE /* asprintf */
@@ -1120,8 +1121,7 @@ static int parse_config_file(const char *filename,
version = strsep_skipspace(&ptr, "\t ");
subdir = strsep_skipspace(&ptr, "\t ");
- if (strcmp(version, kernelversion) != 0 &&
- strcmp(version, "*") != 0)
+ if (!regex_match(kernelversion, (const char *)version))
continue;
nofail_asprintf(&pathname, "%s%s%s/%s/%s.ko", basedir,
diff --git a/util.c b/util.c
index 4df11e0..59db9cb 100644
--- a/util.c
+++ b/util.c
@@ -4,6 +4,8 @@
#include <string.h>
#include <errno.h>
#include <elf.h>
+#include <sys/types.h>
+#include <regex.h>
#include "logging.h"
#include "util.h"
@@ -203,3 +205,30 @@ int __attribute__ ((pure)) native_endianness()
return (char) *((uint32_t*)("\1\0\0\2"));
}
+/*
+ * Compare "string" with extended regex "pattern". Include backward compatible
+ * matching of "*" as a wildcard by replacing it with ".*" automatically.
+ */
+int regex_match(const char *string, const char *pattern)
+{
+ int status;
+ regex_t re;
+ char *fix_pattern;
+
+ /* backward compatibility with old "match" code */
+ if (strncmp("*", pattern, 1) != 0)
+ fix_pattern = (char *)pattern;
+ else
+ fix_pattern = ".*"; /* match everything */
+
+ if (regcomp(&re, fix_pattern, REG_EXTENDED|REG_NOSUB) != 0)
+ return 0; /* alloc failure */
+
+ status = regexec(&re, string, (size_t) 0, NULL, 0);
+ regfree(&re);
+
+ if (status != 0)
+ return 0; /* no match */
+
+ return 1; /* match */
+}
diff --git a/util.h b/util.h
index d512072..2b50ca5 100644
--- a/util.h
+++ b/util.h
@@ -44,4 +44,6 @@ int native_endianness(void);
#define streq(a,b) (strcmp((a),(b)) == 0)
#define strstarts(a,start) (strncmp((a),(start), strlen(start)) == 0)
+int regex_match(const char *string, const char *pattern);
+
#endif