diff options
author | Mike Frysinger <vapier@gentoo.org> | 2008-02-01 06:53:50 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2008-02-01 06:53:50 +0000 |
commit | f0044c480c4da9c5818fe7a0973cd5529314d14b (patch) | |
tree | 8a1cf64b29dd2cae330a908c7881ed90f06cf545 | |
parent | c348e0bc7bb104c9e2385a0d1c29099a7033adf8 (diff) | |
download | busybox-w32-f0044c480c4da9c5818fe7a0973cd5529314d14b.tar.gz busybox-w32-f0044c480c4da9c5818fe7a0973cd5529314d14b.tar.bz2 busybox-w32-f0044c480c4da9c5818fe7a0973cd5529314d14b.zip |
add support for renaming/relocating device nodes
-rw-r--r-- | docs/mdev.txt | 9 | ||||
-rw-r--r-- | util-linux/Config.in | 9 | ||||
-rw-r--r-- | util-linux/mdev.c | 48 |
3 files changed, 61 insertions, 5 deletions
diff --git a/docs/mdev.txt b/docs/mdev.txt index 4a4451b4d..38f1da964 100644 --- a/docs/mdev.txt +++ b/docs/mdev.txt | |||
@@ -53,6 +53,15 @@ matched, then the default of 0:0 660 is used. To set your own default, simply | |||
53 | create your own total match like so: | 53 | create your own total match like so: |
54 | .* 1:1 777 | 54 | .* 1:1 777 |
55 | 55 | ||
56 | You can rename/relocate device nodes by using the next optional field. | ||
57 | <device regex> <uid>:<gid> <octal permissions> [>path] | ||
58 | So if you want to place the device node into a subdirectory, make sure the path | ||
59 | has a trailing /. If you want to rename the device node, just place the name. | ||
60 | hda 0:3 660 >drives/ | ||
61 | This will relocate "hda" into the drives/ subdirectory. | ||
62 | hdb 0:3 660 >cdrom | ||
63 | This will rename "hdb" to "cdrom". | ||
64 | |||
56 | If you also enable support for executing your own commands, then the file has | 65 | If you also enable support for executing your own commands, then the file has |
57 | the format: | 66 | the format: |
58 | <device regex> <uid>:<gid> <octal permissions> [<@|$|*> <command>] | 67 | <device regex> <uid>:<gid> <octal permissions> [<@|$|*> <command>] |
diff --git a/util-linux/Config.in b/util-linux/Config.in index 8ec466bb8..d236b77b6 100644 --- a/util-linux/Config.in +++ b/util-linux/Config.in | |||
@@ -301,6 +301,15 @@ config FEATURE_MDEV_CONF | |||
301 | 301 | ||
302 | For more information, please see docs/mdev.txt | 302 | For more information, please see docs/mdev.txt |
303 | 303 | ||
304 | config FEATURE_MDEV_RENAME | ||
305 | bool "Support subdirs/symlinks" | ||
306 | default n | ||
307 | depends on FEATURE_MDEV_CONF | ||
308 | help | ||
309 | Add support for renaming devices and creating symlinks. | ||
310 | |||
311 | For more information, please see docs/mdev.txt | ||
312 | |||
304 | config FEATURE_MDEV_EXEC | 313 | config FEATURE_MDEV_EXEC |
305 | bool "Support command execution at device addition/removal" | 314 | bool "Support command execution at device addition/removal" |
306 | default n | 315 | default n |
diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 65b4da4f4..a18fc0916 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c | |||
@@ -31,6 +31,10 @@ static void make_device(char *path, int delete) | |||
31 | gid_t gid = 0; | 31 | gid_t gid = 0; |
32 | char *temp = path + strlen(path); | 32 | char *temp = path + strlen(path); |
33 | char *command = NULL; | 33 | char *command = NULL; |
34 | char *alias = NULL; | ||
35 | |||
36 | /* Force the configuration file settings exactly. */ | ||
37 | umask(0); | ||
34 | 38 | ||
35 | /* Try to read major/minor string. Note that the kernel puts \n after | 39 | /* Try to read major/minor string. Note that the kernel puts \n after |
36 | * the data, so we don't need to worry about null terminating the string | 40 | * the data, so we don't need to worry about null terminating the string |
@@ -70,7 +74,7 @@ static void make_device(char *path, int delete) | |||
70 | ++lineno; | 74 | ++lineno; |
71 | 75 | ||
72 | /* Three fields: regex, uid:gid, mode */ | 76 | /* Three fields: regex, uid:gid, mode */ |
73 | for (field = 0; field < (3 + ENABLE_FEATURE_MDEV_EXEC); ++field) { | 77 | for (field = 0; field < (3 + ENABLE_FEATURE_MDEV_RENAME + ENABLE_FEATURE_MDEV_EXEC); ++field) { |
74 | 78 | ||
75 | /* Find a non-empty field */ | 79 | /* Find a non-empty field */ |
76 | char *val; | 80 | char *val; |
@@ -131,7 +135,16 @@ static void make_device(char *path, int delete) | |||
131 | /* Mode device permissions */ | 135 | /* Mode device permissions */ |
132 | mode = strtoul(val, NULL, 8); | 136 | mode = strtoul(val, NULL, 8); |
133 | 137 | ||
134 | } else if (ENABLE_FEATURE_MDEV_EXEC && field == 3) { | 138 | } else if (ENABLE_FEATURE_MDEV_RENAME && field == 3) { |
139 | |||
140 | if (*val != '>') | ||
141 | ++field; | ||
142 | else | ||
143 | alias = xstrdup(val + 1); | ||
144 | |||
145 | } | ||
146 | |||
147 | if (ENABLE_FEATURE_MDEV_EXEC && field == 3 + ENABLE_FEATURE_MDEV_RENAME) { | ||
135 | 148 | ||
136 | /* Optional command to run */ | 149 | /* Optional command to run */ |
137 | const char *s = "@$*"; | 150 | const char *s = "@$*"; |
@@ -167,20 +180,45 @@ static void make_device(char *path, int delete) | |||
167 | end_parse: /* nothing */ ; | 180 | end_parse: /* nothing */ ; |
168 | } | 181 | } |
169 | 182 | ||
170 | umask(0); | ||
171 | if (!delete) { | 183 | if (!delete) { |
172 | if (sscanf(temp, "%d:%d", &major, &minor) != 2) | 184 | if (sscanf(temp, "%d:%d", &major, &minor) != 2) |
173 | return; | 185 | return; |
186 | |||
187 | if (ENABLE_FEATURE_MDEV_RENAME) | ||
188 | unlink(device_name); | ||
189 | |||
174 | if (mknod(device_name, mode | type, makedev(major, minor)) && errno != EEXIST) | 190 | if (mknod(device_name, mode | type, makedev(major, minor)) && errno != EEXIST) |
175 | bb_perror_msg_and_die("mknod %s", device_name); | 191 | bb_perror_msg_and_die("mknod %s", device_name); |
176 | 192 | ||
177 | if (major == root_major && minor == root_minor) | 193 | if (major == root_major && minor == root_minor) |
178 | symlink(device_name, "root"); | 194 | symlink(device_name, "root"); |
179 | 195 | ||
180 | if (ENABLE_FEATURE_MDEV_CONF) | 196 | if (ENABLE_FEATURE_MDEV_CONF) { |
181 | chown(device_name, uid, gid); | 197 | chown(device_name, uid, gid); |
198 | |||
199 | if (ENABLE_FEATURE_MDEV_RENAME && alias) { | ||
200 | char *dest; | ||
201 | |||
202 | temp = strrchr(alias, '/'); | ||
203 | if (temp) { | ||
204 | if (temp[1] != '\0') | ||
205 | /* given a file name, so rename it */ | ||
206 | *temp = '\0'; | ||
207 | bb_make_directory(alias, 0755, FILEUTILS_RECUR); | ||
208 | dest = concat_path_file(alias, device_name); | ||
209 | } else | ||
210 | dest = alias; | ||
211 | |||
212 | rename(device_name, dest); | ||
213 | symlink(dest, device_name); | ||
214 | |||
215 | if (alias != dest) | ||
216 | free(alias); | ||
217 | free(dest); | ||
218 | } | ||
219 | } | ||
182 | } | 220 | } |
183 | if (command) { | 221 | if (ENABLE_FEATURE_MDEV_EXEC && command) { |
184 | /* setenv will leak memory, so use putenv */ | 222 | /* setenv will leak memory, so use putenv */ |
185 | char *s = xasprintf("MDEV=%s", device_name); | 223 | char *s = xasprintf("MDEV=%s", device_name); |
186 | putenv(s); | 224 | putenv(s); |