diff options
author | Rob Landley <rob@landley.net> | 2005-12-17 10:52:30 +0000 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2005-12-17 10:52:30 +0000 |
commit | b56c285da56b26d9dae57b20477554dbdb33e460 (patch) | |
tree | befeb775e0de7d70c5b638cedbc7276ab59da8eb | |
parent | 1a78103306e149321c6509514ea350c822815f3f (diff) | |
download | busybox-w32-b56c285da56b26d9dae57b20477554dbdb33e460.tar.gz busybox-w32-b56c285da56b26d9dae57b20477554dbdb33e460.tar.bz2 busybox-w32-b56c285da56b26d9dae57b20477554dbdb33e460.zip |
Added /etc/mdev.conf support. Adds about 1.9k to mdev.
-rw-r--r-- | util-linux/Config.in | 2 | ||||
-rw-r--r-- | util-linux/mdev.c | 137 |
2 files changed, 123 insertions, 16 deletions
diff --git a/util-linux/Config.in b/util-linux/Config.in index 5ab54e038..bf3e13b2a 100644 --- a/util-linux/Config.in +++ b/util-linux/Config.in | |||
@@ -254,7 +254,7 @@ config CONFIG_MDEV | |||
254 | have it handle hotplug events afterwards. Device names are taken | 254 | have it handle hotplug events afterwards. Device names are taken |
255 | from sysfs. | 255 | from sysfs. |
256 | 256 | ||
257 | config CONFIG_FEATURE_MDEV_CONFIG | 257 | config CONFIG_FEATURE_MDEV_CONF |
258 | bool " Support /etc/mdev.conf" | 258 | bool " Support /etc/mdev.conf" |
259 | default n | 259 | default n |
260 | depends on CONFIG_MDEV | 260 | depends on CONFIG_MDEV |
diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 49904d17a..688100c3a 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c | |||
@@ -8,25 +8,31 @@ | |||
8 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 8 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <ctype.h> | ||
11 | #include <dirent.h> | 12 | #include <dirent.h> |
12 | #include <errno.h> | 13 | #include <errno.h> |
13 | #include <fcntl.h> | 14 | #include <fcntl.h> |
14 | #include <stdio.h> | 15 | #include <stdio.h> |
15 | #include <string.h> | 16 | #include <string.h> |
17 | #include <sys/mman.h> | ||
16 | #include <sys/stat.h> | 18 | #include <sys/stat.h> |
17 | #include <sys/types.h> | 19 | #include <sys/types.h> |
18 | #include <unistd.h> | 20 | #include <unistd.h> |
21 | #include "busybox.h" | ||
22 | #include "xregex.h" | ||
19 | 23 | ||
20 | #define DEV_PATH "/dev" | 24 | #define DEV_PATH "/tmp/dev" |
21 | #define DEV_MODE 0660 | ||
22 | 25 | ||
23 | #include <busybox.h> | 26 | #include <busybox.h> |
24 | 27 | ||
25 | /* mknod in /dev based on a path like "/sys/block/hda/hda1" */ | 28 | /* mknod in /dev based on a path like "/sys/block/hda/hda1" */ |
26 | void make_device(char *path) | 29 | static void make_device(char *path) |
27 | { | 30 | { |
28 | char *device_name, *s; | 31 | char *device_name,*s; |
29 | int major,minor,type,len,fd; | 32 | int major,minor,type,len,fd; |
33 | int mode=0660; | ||
34 | uid_t uid=0; | ||
35 | gid_t gid=0; | ||
30 | 36 | ||
31 | RESERVE_CONFIG_BUFFER(temp,PATH_MAX); | 37 | RESERVE_CONFIG_BUFFER(temp,PATH_MAX); |
32 | 38 | ||
@@ -44,8 +50,8 @@ void make_device(char *path) | |||
44 | device_name = strrchr(path, '/') + 1; | 50 | device_name = strrchr(path, '/') + 1; |
45 | type = strncmp(path+5, "block/" ,6) ? S_IFCHR : S_IFBLK; | 51 | type = strncmp(path+5, "block/" ,6) ? S_IFCHR : S_IFBLK; |
46 | major = minor = 0; | 52 | major = minor = 0; |
47 | for(s = temp; *s; s++) { | 53 | for (s = temp; *s; s++) { |
48 | if(*s == ':') { | 54 | if (*s == ':') { |
49 | major = minor; | 55 | major = minor; |
50 | minor = 0; | 56 | minor = 0; |
51 | } else { | 57 | } else { |
@@ -54,14 +60,115 @@ void make_device(char *path) | |||
54 | } | 60 | } |
55 | } | 61 | } |
56 | 62 | ||
57 | /* Open config file here, look up permissions */ | 63 | /* If we have a config file, look up permissions for this device */ |
64 | |||
65 | if (ENABLE_FEATURE_MDEV_CONF) { | ||
66 | char *conf,*pos,*end; | ||
67 | |||
68 | /* mmap the config file */ | ||
69 | if (-1!=(fd=open("/etc/mdev.conf",O_RDONLY))) { | ||
70 | len=lseek(fd,0,SEEK_END); | ||
71 | conf=mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0); | ||
72 | if (conf) { | ||
73 | int line=0; | ||
74 | |||
75 | /* Loop through lines in mmaped file*/ | ||
76 | for (pos=conf;pos-conf<len;) { | ||
77 | int field; | ||
78 | char *end2; | ||
79 | |||
80 | line++; | ||
81 | /* find end of this line */ | ||
82 | for(end=pos;end-conf<len && *end!='\n';end++); | ||
83 | |||
84 | /* Three fields: regex, uid:gid, mode */ | ||
85 | for (field=3;field;field--) { | ||
86 | /* Skip whitespace */ | ||
87 | while (pos<end && isspace(*pos)) pos++; | ||
88 | if (pos==end || *pos=='#') break; | ||
89 | for (end2=pos; | ||
90 | end2<end && !isspace(*end2) && *end2!='#'; end2++); | ||
91 | switch(field) { | ||
92 | /* Regex to match this device */ | ||
93 | case 3: | ||
94 | { | ||
95 | char *regex=strndupa(pos,end2-pos); | ||
96 | regex_t match; | ||
97 | regmatch_t off; | ||
98 | int result; | ||
99 | |||
100 | /* Is this it? */ | ||
101 | xregcomp(&match,regex,REG_EXTENDED); | ||
102 | result=regexec(&match,device_name,1,&off,0); | ||
103 | regfree(&match); | ||
104 | |||
105 | /* If not this device, skip rest of line */ | ||
106 | if(result || off.rm_so | ||
107 | || off.rm_eo!=strlen(device_name)) | ||
108 | goto end_line; | ||
109 | |||
110 | break; | ||
111 | } | ||
112 | /* uid:gid */ | ||
113 | case 2: | ||
114 | { | ||
115 | char *s2; | ||
116 | |||
117 | /* Find : */ | ||
118 | for(s=pos;s<end2 && *s!=':';s++); | ||
119 | if(s==end2) goto end_line; | ||
120 | |||
121 | /* Parse UID */ | ||
122 | uid=strtoul(pos,&s2,10); | ||
123 | if(s!=s2) { | ||
124 | struct passwd *pass; | ||
125 | pass=getpwnam(strndupa(pos,s-pos)); | ||
126 | if(!pass) goto end_line; | ||
127 | uid=pass->pw_uid; | ||
128 | } | ||
129 | s++; | ||
130 | /* parse GID */ | ||
131 | gid=strtoul(s,&s2,10); | ||
132 | if(end2!=s2) { | ||
133 | struct group *grp; | ||
134 | grp=getgrnam(strndupa(s,end2-s)); | ||
135 | if(!grp) goto end_line; | ||
136 | gid=grp->gr_gid; | ||
137 | } | ||
138 | break; | ||
139 | } | ||
140 | /* mode */ | ||
141 | case 1: | ||
142 | { | ||
143 | mode=strtoul(pos,&pos,8); | ||
144 | if(pos!=end2) goto end_line; | ||
145 | goto found_device; | ||
146 | } | ||
147 | } | ||
148 | pos=end2; | ||
149 | } | ||
150 | end_line: | ||
151 | /* Did everything parse happily? */ | ||
152 | if (field && field!=3) | ||
153 | bb_error_msg_and_die("Bad line %d",line); | ||
154 | |||
155 | /* Next line */ | ||
156 | pos=++end; | ||
157 | } | ||
158 | found_device: | ||
159 | munmap(conf,len); | ||
160 | } | ||
161 | close(fd); | ||
162 | } | ||
163 | } | ||
58 | 164 | ||
59 | sprintf(temp, "%s/%s", DEV_PATH, device_name); | 165 | sprintf(temp, "%s/%s", DEV_PATH, device_name); |
60 | if(mknod(temp, DEV_MODE | type, makedev(major, minor)) && errno != EEXIST) | 166 | umask(0); |
167 | if (mknod(temp, mode | type, makedev(major, minor)) && errno != EEXIST) | ||
61 | bb_perror_msg_and_die("mknod %s failed", temp); | 168 | bb_perror_msg_and_die("mknod %s failed", temp); |
62 | |||
63 | /* Perform shellout here */ | ||
64 | 169 | ||
170 | if (ENABLE_FEATURE_MDEV_CONF) chown(temp,uid,gid); | ||
171 | |||
65 | end: | 172 | end: |
66 | RELEASE_CONFIG_BUFFER(temp); | 173 | RELEASE_CONFIG_BUFFER(temp); |
67 | } | 174 | } |
@@ -69,18 +176,18 @@ end: | |||
69 | /* Recursive search of /sys/block or /sys/class. path must be a writeable | 176 | /* Recursive search of /sys/block or /sys/class. path must be a writeable |
70 | * buffer of size PATH_MAX containing the directory string to start at. */ | 177 | * buffer of size PATH_MAX containing the directory string to start at. */ |
71 | 178 | ||
72 | void find_dev(char *path) | 179 | static void find_dev(char *path) |
73 | { | 180 | { |
74 | DIR *dir; | 181 | DIR *dir; |
75 | int len=strlen(path); | 182 | int len=strlen(path); |
76 | 183 | ||
77 | if(!(dir = opendir(path))) | 184 | if (!(dir = opendir(path))) |
78 | bb_perror_msg_and_die("No %s",path); | 185 | bb_perror_msg_and_die("No %s",path); |
79 | 186 | ||
80 | for(;;) { | 187 | for (;;) { |
81 | struct dirent *entry = readdir(dir); | 188 | struct dirent *entry = readdir(dir); |
82 | 189 | ||
83 | if(!entry) break; | 190 | if (!entry) break; |
84 | 191 | ||
85 | /* Skip "." and ".." (also skips hidden files, which is ok) */ | 192 | /* Skip "." and ".." (also skips hidden files, which is ok) */ |
86 | 193 | ||
@@ -103,7 +210,7 @@ void find_dev(char *path) | |||
103 | int mdev_main(int argc, char *argv[]) | 210 | int mdev_main(int argc, char *argv[]) |
104 | { | 211 | { |
105 | if (argc > 1) { | 212 | if (argc > 1) { |
106 | if(argc == 2 && !strcmp(argv[1],"-s")) { | 213 | if (argc == 2 && !strcmp(argv[1],"-s")) { |
107 | RESERVE_CONFIG_BUFFER(temp,PATH_MAX); | 214 | RESERVE_CONFIG_BUFFER(temp,PATH_MAX); |
108 | strcpy(temp,"/sys/block"); | 215 | strcpy(temp,"/sys/block"); |
109 | find_dev(temp); | 216 | find_dev(temp); |