From f2f3868e0d69c586d395dc9187e0ca99d5e47880 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Sat, 29 Mar 2008 17:26:10 +0000 Subject: mdev: optional support for regex pattern group substitution. +142 bytes. --- testsuite/mdev.tests | 17 +++++++++++++++++ util-linux/Config.in | 7 +++++++ util-linux/mdev.c | 44 +++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/testsuite/mdev.tests b/testsuite/mdev.tests index 777c5c540..81c440d1f 100755 --- a/testsuite/mdev.tests +++ b/testsuite/mdev.tests @@ -76,6 +76,23 @@ br--r--r-- 1 0 0 sda " \ "" "" +# continuing to use directory structure from prev test +rm -rf mdev.testdir/dev/* +# here we complicate things by having non-matching group 1 and using %0 +echo "s([0-9])*d([a-z]+) 0:0 644 >sd/%2_%0" >mdev.testdir/etc/mdev.conf +testing "mdev regexp substring match + replace" \ + "env - ACTION=add DEVPATH=/block/sda chroot mdev.testdir /mdev 2>&1; + ls -lnR mdev.testdir/dev | $FILTER_LS2" \ +"\ +mdev.testdir/dev: +drwxr-xr-x 2 0 0 sd +lrwxrwxrwx 1 0 0 sda -> sd/a_sda + +mdev.testdir/dev/sd: +brw-r--r-- 1 0 0 a_sda +" \ + "" "" + # clean up rm -rf mdev.testdir diff --git a/util-linux/Config.in b/util-linux/Config.in index 1f4322bec..869ec61d5 100644 --- a/util-linux/Config.in +++ b/util-linux/Config.in @@ -321,6 +321,13 @@ config FEATURE_MDEV_RENAME For more information, please see docs/mdev.txt +config FEATURE_MDEV_RENAME_REGEXP + bool "Support regular expressions substitutions when renaming device" + default n + depends on FEATURE_MDEV_RENAME + help + Add support for regular expressions substitutions when renaming device. + config FEATURE_MDEV_EXEC bool "Support command execution at device addition/removal" default n diff --git a/util-linux/mdev.c b/util-linux/mdev.c index c8d603bcf..9d77f6a1f 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c @@ -84,6 +84,8 @@ static void make_device(char *path, int delete) goto end_parse; while ((line = xmalloc_fgetline(fp)) != NULL) { + regmatch_t off[1+9*ENABLE_FEATURE_MDEV_RENAME_REGEXP]; + ++lineno; trim(line); if (!line[0]) @@ -95,16 +97,24 @@ static void make_device(char *path, int delete) next = next_field(line); { regex_t match; - regmatch_t off; int result; /* Is this it? */ xregcomp(&match, line, REG_EXTENDED); - result = regexec(&match, device_name, 1, &off, 0); + result = regexec(&match, device_name, ARRAY_SIZE(off), off, 0); regfree(&match); + //bb_error_msg("matches:"); + //for (int i = 0; i < ARRAY_SIZE(off); i++) { + // if (off[i].rm_so < 0) continue; + // bb_error_msg("match %d: '%.*s'\n", i, + // (int)(off[i].rm_eo - off[i].rm_so), + // device_name + off[i].rm_so); + //} + /* If not this device, skip rest of line */ - if (result || off.rm_so || off.rm_eo != strlen(device_name)) + /* (regexec returns whole pattern as "range" 0) */ + if (result || off[0].rm_so || off[0].rm_eo != strlen(device_name)) goto next_line; } @@ -152,7 +162,35 @@ static void make_device(char *path, int delete) val = next; next = next_field(val); if (*val == '>') { +#if ENABLE_FEATURE_MDEV_RENAME_REGEXP + /* substitute %1..9 with off[1..9], if any */ + char *s, *p; + unsigned i, n; + + n = 0; + s = val; + while (*s && *s++ == '%') + n++; + + p = alias = xzalloc(strlen(val) + n * strlen(device_name)); + s = val + 1; + while (*s) { + *p = *s; + if ('%' == *s) { + i = (s[1] - '0'); + if (i <= 9 && off[i].rm_so >= 0) { + n = off[i].rm_eo - off[i].rm_so; + strncpy(p, device_name + off[i].rm_so, n); + p += n - 1; + s++; + } + } + p++; + s++; + } +#else alias = xstrdup(val + 1); +#endif } } -- cgit v1.2.3