diff options
author | Jon Masters <jcm@jonmasters.org> | 2010-01-15 01:55:02 -0500 |
---|---|---|
committer | Jon Masters <jcm@jonmasters.org> | 2010-01-15 01:55:02 -0500 |
commit | 70c4f735aa41f2f7db3a4e4488f3a98feaf1c729 (patch) | |
tree | f4128f4b8770a2adb7cd7e396104e4001638d724 | |
parent | 1c6fd378d7712a4f4d7178269c22c49b11a5adfe (diff) | |
download | module-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.c | 4 | ||||
-rw-r--r-- | util.c | 29 | ||||
-rw-r--r-- | util.h | 2 |
3 files changed, 33 insertions, 2 deletions
@@ -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, @@ -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 */ +} @@ -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 |