+ device_name = (char*) bb_basename(path);
+ /* http://kernel.org/doc/pending/hotplug.txt says that only
+ * "/sys/block/..." is for block devices. "/sys/bus" etc is not.
+ * But since 2.6.25 block devices are also in /sys/class/block.
+ * We use strstr("/block/") to forestall future surprises. */
+ type = S_IFCHR;
+ if (strstr(path, "/block/") || strncmp(G.subsystem, "block", 5) == 0)
+ type = S_IFBLK;
+
+ /* Make path point to "subsystem/device_name" */
+ subsystem_slash_devname = NULL;
+ /* Check for coldplug invocations first */
+ if (strncmp(path, "/sys/block/", 11) == 0) /* legacy case */
+ path += sizeof("/sys/") - 1;
+ else if (strncmp(path, "/sys/class/", 11) == 0)
+ path += sizeof("/sys/class/") - 1;
+ else {
+ /* Example of a hotplug invocation:
+ * SUBSYSTEM="block"
+ * DEVPATH="/sys" + "/devices/virtual/mtd/mtd3/mtdblock3"
+ * ("/sys" is added by mdev_main)
+ * - path does not contain subsystem
+ */
+ subsystem_slash_devname = concat_path_file(G.subsystem, device_name);
+ path = subsystem_slash_devname;
+ }
+
+ /* If we have config file, look up user settings */
+ if (ENABLE_FEATURE_MDEV_CONF)
+ parser = config_open2("/etc/mdev.conf", fopen_for_read);
+
+ do {
+ int keep_matching;
+ struct bb_uidgid_t ugid;
+ char *tokens[4];
+ char *command = NULL;
+ char *alias = NULL;
+ char aliaslink = aliaslink; /* for compiler */
+
+ /* Defaults in case we won't match any line */
+ ugid.uid = ugid.gid = 0;
+ keep_matching = 0;
+ mode = 0660;
+
+ if (ENABLE_FEATURE_MDEV_CONF
+ && config_read(parser, tokens, 4, 3, "# \t", PARSE_NORMAL)
+ ) {
+ char *val;
+ char *str_to_match;
+ regmatch_t off[1 + 9 * ENABLE_FEATURE_MDEV_RENAME_REGEXP];
+
+ val = tokens[0];
+ keep_matching = ('-' == val[0]);
+ val += keep_matching; /* swallow leading dash */
+
+ /* Match against either "subsystem/device_name"
+ * or "device_name" alone */
+ str_to_match = strchr(val, '/') ? path : device_name;
+
+ /* Fields: regex uid:gid mode [alias] [cmd] */
+
+ if (val[0] == '@') {
+ /* @major,minor[-minor2] */
+ /* (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(val, "@%u,%u-%u", &cmaj, &cmin0, &cmin1);
+ if (sc < 1 || major != cmaj
+ || (sc == 2 && minor != cmin0)
+ || (sc == 3 && (minor < cmin0 || minor > cmin1))
+ ) {
+ continue; /* this line doesn't match */
+ }
+ goto line_matches;
+ }
+ if (val[0] == '$') {
+ /* regex to match an environment variable */
+ char *eq = strchr(++val, '=');
+ if (!eq)
+ continue;
+ *eq = '\0';
+ str_to_match = getenv(val);
+ if (!str_to_match)
+ continue;
+ str_to_match -= strlen(val) + 1;
+ *eq = '=';
+ }
+ /* else: regex to match [subsystem/]device_name */