diff options
Diffstat (limited to 'package/busybox/busybox-1.10.1-mdev.patch')
-rw-r--r-- | package/busybox/busybox-1.10.1-mdev.patch | 512 |
1 files changed, 0 insertions, 512 deletions
diff --git a/package/busybox/busybox-1.10.1-mdev.patch b/package/busybox/busybox-1.10.1-mdev.patch deleted file mode 100644 index 33a9a0d61..000000000 --- a/package/busybox/busybox-1.10.1-mdev.patch +++ /dev/null @@ -1,512 +0,0 @@ ---- busybox-1.10.1/util-linux/mdev.c Sat Apr 19 05:50:39 2008 -+++ busybox-1.10.1-mdev/util-linux/mdev.c Fri May 2 14:48:06 2008 -@@ -12,6 +12,8 @@ - #include "libbb.h" - #include "xregex.h" - -+#define ENABLE_FEATURE_MDEV_RENAME_REGEXP 1 -+ - struct globals { - int root_major, root_minor; - }; -@@ -21,7 +23,21 @@ - - #define MAX_SYSFS_DEPTH 3 /* prevent infinite loops in /sys symlinks */ - -+/* We use additional 64+ bytes in make_device() */ -+#define SCRATCH_SIZE 80 -+ -+static char *next_field(char *s) -+{ -+ char *end = skip_non_whitespace(s); -+ s = skip_whitespace(end); -+ *end = '\0'; -+ if (*s == '\0') -+ s = NULL; -+ return s; -+} -+ - /* mknod in /dev based on a path like "/sys/block/hda/hda1" */ -+/* NB: "mdev -s" may call us many times, do not leak memory/fds! */ - static void make_device(char *path, int delete) - { - const char *device_name; -@@ -29,7 +45,7 @@ - int mode = 0660; - uid_t uid = 0; - gid_t gid = 0; -- char *temp = path + strlen(path); -+ char *dev_maj_min = path + strlen(path); - char *command = NULL; - char *alias = NULL; - -@@ -42,156 +58,178 @@ - * also depend on path having writeable space after it. - */ - if (!delete) { -- strcat(path, "/dev"); -- len = open_read_close(path, temp + 1, 64); -- *temp++ = 0; -+ strcpy(dev_maj_min, "/dev"); -+ len = open_read_close(path, dev_maj_min + 1, 64); -+ *dev_maj_min++ = '\0'; - if (len < 1) { -- if (ENABLE_FEATURE_MDEV_EXEC) -- /* no "dev" file, so just try to run script */ -- *temp = 0; -- else -+ if (!ENABLE_FEATURE_MDEV_EXEC) - return; -+ /* no "dev" file, so just try to run script */ -+ *dev_maj_min = '\0'; - } - } - - /* Determine device name, type, major and minor */ - device_name = bb_basename(path); -- type = (path[5] == 'c' ? S_IFCHR : S_IFBLK); -+ /* http://kernel.org/doc/pending/hotplug.txt says that only -+ * "/sys/block/..." is for block devices. "sys/bus" etc is not! */ -+ type = (strncmp(&path[5], "block/", 6) == 0 ? S_IFBLK : S_IFCHR); - - if (ENABLE_FEATURE_MDEV_CONF) { - FILE *fp; -- char *line, *vline; -+ char *line, *val, *next; - unsigned lineno = 0; - -- /* If we have a config file, look up the user settings */ -+ /* If we have config file, look up user settings */ - fp = fopen_or_warn("/etc/mdev.conf", "r"); - if (!fp) - goto end_parse; - -- while ((vline = line = xmalloc_getline(fp)) != NULL) { -- int field; -+ while ((line = xmalloc_getline(fp)) != NULL) { -+ regmatch_t off[1+9*ENABLE_FEATURE_MDEV_RENAME_REGEXP]; - -- /* A pristine copy for command execution. */ -- char *orig_line; -- if (ENABLE_FEATURE_MDEV_EXEC) -- orig_line = xstrdup(line); -- - ++lineno; -+ trim(line); -+ if (!line[0]) -+ goto next_line; - -- /* Three fields: regex, uid:gid, mode */ -- for (field = 0; field < (3 + ENABLE_FEATURE_MDEV_RENAME + ENABLE_FEATURE_MDEV_EXEC); ++field) { -+ /* Fields: regex uid:gid mode [alias] [cmd] */ - -- /* Find a non-empty field */ -- char *val; -- do { -- val = strtok(vline, " \t"); -- vline = NULL; -- } while (val && !*val); -- if (!val) { -- if (field) -- break; -- else -- goto next_line; -- } -+ /* 1st field: regex to match this device */ -+ next = next_field(line); -+ { -+ regex_t match; -+ int result; - -- if (field == 0) { -+ /* Is this it? */ -+ xregcomp(&match, line, REG_EXTENDED); -+ result = regexec(&match, device_name, ARRAY_SIZE(off), off, 0); -+ regfree(&match); - -- /* Regex to match this device */ -- regex_t match; -- regmatch_t off; -- int result; -+ //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); -+ //} - -- /* Is this it? */ -- xregcomp(&match, val, REG_EXTENDED); -- result = regexec(&match, device_name, 1, &off, 0); -- regfree(&match); -+ /* If not this device, skip rest of line */ -+ /* (regexec returns whole pattern as "range" 0) */ -+ if (result || off[0].rm_so || off[0].rm_eo != strlen(device_name)) -+ goto next_line; -+ } - -- /* If not this device, skip rest of line */ -- if (result || off.rm_so || off.rm_eo != strlen(device_name)) -- goto next_line; -+ /* This line matches: stop parsing the file -+ * after parsing the rest of fields */ - -- } else if (field == 1) { -+ /* 2nd field: uid:gid - device ownership */ -+ if (!next) /* field must exist */ -+ bb_error_msg_and_die("bad line %u", lineno); -+ val = next; -+ next = next_field(val); -+ { -+ struct passwd *pass; -+ struct group *grp; -+ char *str_uid = val; -+ char *str_gid = strchrnul(val, ':'); - -- /* uid:gid device ownership */ -- struct passwd *pass; -- struct group *grp; -+ if (*str_gid) -+ *str_gid++ = '\0'; -+ /* Parse UID */ -+ pass = getpwnam(str_uid); -+ if (pass) -+ uid = pass->pw_uid; -+ else -+ uid = strtoul(str_uid, NULL, 10); -+ /* Parse GID */ -+ grp = getgrnam(str_gid); -+ if (grp) -+ gid = grp->gr_gid; -+ else -+ gid = strtoul(str_gid, NULL, 10); -+ } - -- char *str_uid = val; -- char *str_gid = strchr(val, ':'); -- if (str_gid) -- *str_gid = '\0', ++str_gid; -+ /* 3rd field: mode - device permissions */ -+ if (!next) /* field must exist */ -+ bb_error_msg_and_die("bad line %u", lineno); -+ val = next; -+ next = next_field(val); -+ mode = strtoul(val, NULL, 8); - -- /* Parse UID */ -- pass = getpwnam(str_uid); -- if (pass) -- uid = pass->pw_uid; -- else -- uid = strtoul(str_uid, NULL, 10); -+ /* 4th field (opt): >alias */ -+ if (ENABLE_FEATURE_MDEV_RENAME) { -+ if (!next) -+ break; -+ if (*next == '>') { -+#if ENABLE_FEATURE_MDEV_RENAME_REGEXP -+ char *s, *p; -+ unsigned i, n; -+#endif -+ val = next; -+ next = next_field(val); -+#if ENABLE_FEATURE_MDEV_RENAME_REGEXP -+ /* substitute %1..9 with off[1..9], if any */ -+ n = 0; -+ s = val; -+ while (*s && *s++ == '%') -+ n++; - -- /* parse GID */ -- grp = getgrnam(str_gid); -- if (grp) -- gid = grp->gr_gid; -- else -- gid = strtoul(str_gid, NULL, 10); -- -- } else if (field == 2) { -- -- /* Mode device permissions */ -- mode = strtoul(val, NULL, 8); -- -- } else if (ENABLE_FEATURE_MDEV_RENAME && field == 3) { -- -- if (*val != '>') -- ++field; -- else -- alias = xstrdup(val + 1); -- -+ 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 - } -+ } - -- if (ENABLE_FEATURE_MDEV_EXEC && field == 3 + ENABLE_FEATURE_MDEV_RENAME) { -+ /* The rest (opt): command to run */ -+ if (!next) -+ break; -+ val = next; -+ if (ENABLE_FEATURE_MDEV_EXEC) { -+ const char *s = "@$*"; -+ const char *s2 = strchr(s, *val); - -- /* Optional command to run */ -- const char *s = "@$*"; -- const char *s2 = strchr(s, *val); -+ if (!s2) -+ bb_error_msg_and_die("bad line %u", lineno); - -- if (!s2) { -- /* Force error */ -- field = 1; -- break; -- } -- -- /* Correlate the position in the "@$*" with the delete -- * step so that we get the proper behavior. -- */ -- if ((s2 - s + 1) & (1 << delete)) -- command = xstrdup(orig_line + (val + 1 - line)); -+ /* Correlate the position in the "@$*" with the delete -+ * step so that we get the proper behavior: -+ * @cmd: run on create -+ * $cmd: run on delete -+ * *cmd: run on both -+ */ -+ if ((s2 - s + 1) /*1/2/3*/ & /*1/2*/ (1 + delete)) { -+ command = xstrdup(val + 1); - } - } -- -- /* Did everything parse happily? */ -- if (field <= 2) -- bb_error_msg_and_die("bad line %u", lineno); -- -+ /* end of field parsing */ -+ break; /* we found matching line, stop */ - next_line: - free(line); -- if (ENABLE_FEATURE_MDEV_EXEC) -- free(orig_line); -- } -+ } /* end of "while line is read from /etc/mdev.conf" */ - -- if (ENABLE_FEATURE_CLEAN_UP) -- fclose(fp); -- -- end_parse: /* nothing */ ; -+ free(line); /* in case we used "break" to get here */ -+ fclose(fp); - } -+ end_parse: - -- if (!delete) { -- if (sscanf(temp, "%d:%d", &major, &minor) != 2) { -- if (ENABLE_FEATURE_MDEV_EXEC) -- goto skip_creation; -- else -- return; -- } -+ if (!delete && sscanf(dev_maj_min, "%u:%u", &major, &minor) == 2) { - - if (ENABLE_FEATURE_MDEV_RENAME) - unlink(device_name); -@@ -208,39 +246,44 @@ - if (ENABLE_FEATURE_MDEV_RENAME && alias) { - char *dest; - -- temp = strrchr(alias, '/'); -- if (temp) { -- if (temp[1] != '\0') -- /* given a file name, so rename it */ -- *temp = '\0'; -+ /* ">bar/": rename to bar/device_name */ -+ /* ">bar[/]baz": rename to bar[/]baz */ -+ dest = strrchr(alias, '/'); -+ if (dest) { /* ">bar/[baz]" ? */ -+ *dest = '\0'; /* mkdir bar */ - bb_make_directory(alias, 0755, FILEUTILS_RECUR); -- dest = concat_path_file(alias, device_name); -- } else -- dest = alias; -+ *dest = '/'; -+ if (dest[1] == '\0') { /* ">bar/" => ">bar/device_name" */ -+ dest = alias; -+ alias = concat_path_file(alias, device_name); -+ free(dest); -+ } -+ } - -- rename(device_name, dest); // TODO: xrename? -- symlink(dest, device_name); -+ /* recreate device_name as a symlink to moved device node */ -+ if (rename(device_name, alias) == 0) { -+ symlink(alias, device_name); -+ } - -- if (alias != dest) -- free(alias); -- free(dest); -+ free(alias); - } - } -- skip_creation: /* nothing */ ; - } -+ - if (ENABLE_FEATURE_MDEV_EXEC && command) { -- /* setenv will leak memory, so use putenv */ -+ /* setenv will leak memory, use putenv/unsetenv/free */ - char *s = xasprintf("MDEV=%s", device_name); - putenv(s); - if (system(command) == -1) -- bb_perror_msg_and_die("cannot run %s", command); -+ bb_perror_msg_and_die("can't run '%s'", command); - s[4] = '\0'; - unsetenv(s); - free(s); - free(command); - } -+ - if (delete) -- remove_file(device_name, FILEUTILS_FORCE); -+ unlink(device_name); - } - - /* File callback for /sys/ traversal */ -@@ -249,14 +292,15 @@ - void *userData, - int depth ATTRIBUTE_UNUSED) - { -- size_t len = strlen(fileName) - 4; -+ size_t len = strlen(fileName) - 4; /* can't underflow */ - char *scratch = userData; - -- if (strcmp(fileName + len, "/dev")) -+ /* len check is for paranoid reasons */ -+ if (strcmp(fileName + len, "/dev") || len >= PATH_MAX) - return FALSE; - - strcpy(scratch, fileName); -- scratch[len] = 0; -+ scratch[len] = '\0'; - make_device(scratch, 0); - - return TRUE; -@@ -287,12 +331,6 @@ - int cnt; - int firmware_fd, loading_fd, data_fd; - -- /* check for $FIRMWARE from kernel */ -- /* XXX: dont bother: open(NULL) works same as open("no-such-file") -- * if (!firmware) -- * return; -- */ -- - /* check for /lib/firmware/$FIRMWARE */ - xchdir("/lib/firmware"); - firmware_fd = xopen(firmware, O_RDONLY); -@@ -304,16 +342,15 @@ - xchdir(sysfs_path); - for (cnt = 0; cnt < 30; ++cnt) { - loading_fd = open("loading", O_WRONLY); -- if (loading_fd == -1) -- sleep(1); -- else -- break; -+ if (loading_fd != -1) -+ goto loading; -+ sleep(1); - } -- if (loading_fd == -1) -- goto out; -+ goto out; - -+ loading: - /* tell kernel we're loading by `echo 1 > /sys/$DEVPATH/loading` */ -- if (write(loading_fd, "1", 1) != 1) -+ if (full_write(loading_fd, "1", 1) != 1) - goto out; - - /* load firmware by `cat /lib/firmware/$FIRMWARE > /sys/$DEVPATH/data */ -@@ -324,9 +361,9 @@ - - /* tell kernel result by `echo [0|-1] > /sys/$DEVPATH/loading` */ - if (cnt > 0) -- write(loading_fd, "0", 1); -+ full_write(loading_fd, "0", 1); - else -- write(loading_fd, "-1", 2); -+ full_write(loading_fd, "-1", 2); - - out: - if (ENABLE_FEATURE_CLEAN_UP) { -@@ -341,16 +378,14 @@ - { - char *action; - char *env_path; -- RESERVE_CONFIG_BUFFER(temp,PATH_MAX); -+ RESERVE_CONFIG_BUFFER(temp, PATH_MAX + SCRATCH_SIZE); - - xchdir("/dev"); - -- if (argc == 2 && !strcmp(argv[1],"-s")) { -- -+ if (argc == 2 && !strcmp(argv[1], "-s")) { - /* Scan: - * mdev -s - */ -- - struct stat st; - - xstat("/", &st); -@@ -366,26 +401,27 @@ - fileAction, dirAction, temp, 0); - - } else { -- - /* Hotplug: - * env ACTION=... DEVPATH=... mdev - * ACTION can be "add" or "remove" - * DEVPATH is like "/block/sda" or "/class/input/mice" - */ -- - action = getenv("ACTION"); - env_path = getenv("DEVPATH"); - if (!action || !env_path) - bb_show_usage(); - -- sprintf(temp, "/sys%s", env_path); -+ snprintf(temp, PATH_MAX, "/sys%s", env_path); - if (!strcmp(action, "remove")) - make_device(temp, 1); - else if (!strcmp(action, "add")) { - make_device(temp, 0); - -- if (ENABLE_FEATURE_MDEV_LOAD_FIRMWARE) -- load_firmware(getenv("FIRMWARE"), temp); -+ if (ENABLE_FEATURE_MDEV_LOAD_FIRMWARE) { -+ char *fw = getenv("FIRMWARE"); -+ if (fw) -+ load_firmware(fw, temp); -+ } - } - } - |