- if (ENABLE_FEATURE_MDEV_CONF) {
- FILE *fp;
- char *line, *val, *next;
- unsigned lineno = 0;
-
- /* If we have config file, look up user settings */
- fp = fopen_or_warn("/etc/mdev.conf", "r");
- if (!fp)
- 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])
- goto next_line;
-
- /* Fields: regex uid:gid mode [alias] [cmd] */
-
- /* 1st field: regex to match this device */
- next = next_field(line);
- {
- regex_t match;
- int result;
-
- /* Is this it? */
- xregcomp(&match, line, REG_EXTENDED);
- 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 */
- /* (regexec returns whole pattern as "range" 0) */
- if (result || off[0].rm_so
- || ((int)off[0].rm_eo != (int)strlen(device_name))
- ) {
- goto next_line;
- }
+#if ENABLE_FEATURE_MDEV_CONF
+ parser = config_open2("/etc/mdev.conf", fopen_for_read);
+
+ /* If we have config file, look up user settings */
+ while (config_read(parser, tokens, 4, 3, "# \t", PARSE_NORMAL)) {
+ regmatch_t off[1 + 9*ENABLE_FEATURE_MDEV_RENAME_REGEXP];
+ char *val;
+
+ /* Fields: regex uid:gid mode [alias] [cmd] */
+
+ /* 1st field: @<numeric maj,min>... */
+ if (tokens[0][0] == '@') {
+ /* @major,minor[-last] */
+ /* (useful when name is ambiguous:
+ * "/sys/class/usb/lp0" and
+ * "/sys/class/printer/lp0") */
+ int cmaj, cmin0, cmin1, sc;
+ if (major < 0)
+ continue; /* no dev, no match */
+ sc = sscanf(tokens[0], "@%u,%u-%u", &cmaj, &cmin0, &cmin1);
+ if (sc < 1 || major != cmaj
+ || (sc == 2 && minor != cmin0)
+ || (sc == 3 && (minor < cmin0 || minor > cmin1))
+ ) {
+ continue; /* no match */