diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-08-01 02:15:05 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-08-01 02:15:05 +0000 |
commit | e1fa8179958b1d860584b93b649d18a79de31685 (patch) | |
tree | 33d8c0e44d579e9fa2ab5e75bc0c3ea0839ef7ec /miscutils | |
parent | d498131168005ccc4768b9c92d7e3c3547e390df (diff) | |
download | busybox-w32-e1fa8179958b1d860584b93b649d18a79de31685.tar.gz busybox-w32-e1fa8179958b1d860584b93b649d18a79de31685.tar.bz2 busybox-w32-e1fa8179958b1d860584b93b649d18a79de31685.zip |
makedevs: shrink (by Vladimir); testsuite
function old new delta
makedevs_main 1153 1071 -82
Diffstat (limited to 'miscutils')
-rw-r--r-- | miscutils/makedevs.c | 150 |
1 files changed, 64 insertions, 86 deletions
diff --git a/miscutils/makedevs.c b/miscutils/makedevs.c index ed08f7ece..91da16924 100644 --- a/miscutils/makedevs.c +++ b/miscutils/makedevs.c | |||
@@ -10,26 +10,39 @@ | |||
10 | #include "libbb.h" | 10 | #include "libbb.h" |
11 | 11 | ||
12 | #if ENABLE_FEATURE_MAKEDEVS_LEAF | 12 | #if ENABLE_FEATURE_MAKEDEVS_LEAF |
13 | /* | ||
14 | makedevs NAME TYPE MAJOR MINOR FIRST LAST [s] | ||
15 | TYPEs: | ||
16 | b Block device | ||
17 | c Character device | ||
18 | p FIFO | ||
19 | |||
20 | FIRST..LAST specify numbers appended to NAME. | ||
21 | If 's' is the last argument, the base device is created as well. | ||
22 | Examples: | ||
23 | makedevs /dev/ttyS c 4 66 2 63 -> ttyS2-ttyS63 | ||
24 | makedevs /dev/hda b 3 0 0 8 s -> hda,hda1-hda8 | ||
25 | */ | ||
13 | int makedevs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 26 | int makedevs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
14 | int makedevs_main(int argc, char **argv) | 27 | int makedevs_main(int argc, char **argv) |
15 | { | 28 | { |
16 | mode_t mode; | 29 | mode_t mode; |
17 | char *basedev, *type, *nodname, buf[255]; | 30 | char *basedev, *type, *nodname, *buf; |
18 | int Smajor, Sminor, S, E; | 31 | int Smajor, Sminor, S, E; |
19 | 32 | ||
20 | if (argc < 7 || *argv[1]=='-') | 33 | if (argc < 7 || argv[1][0] == '-') |
21 | bb_show_usage(); | 34 | bb_show_usage(); |
22 | 35 | ||
23 | basedev = argv[1]; | 36 | basedev = argv[1]; |
37 | buf = xasprintf("%s%u", argv[1], (unsigned)-1); | ||
24 | type = argv[2]; | 38 | type = argv[2]; |
25 | Smajor = xatoi_u(argv[3]); | 39 | Smajor = xatoi_u(argv[3]); |
26 | Sminor = xatoi_u(argv[4]); | 40 | Sminor = xatoi_u(argv[4]); |
27 | S = xatoi_u(argv[5]); | 41 | S = xatoi_u(argv[5]); |
28 | E = xatoi_u(argv[6]); | 42 | E = xatoi_u(argv[6]); |
29 | nodname = argc == 8 ? basedev : buf; | 43 | nodname = argv[7] ? basedev : buf; |
30 | 44 | ||
31 | mode = 0660; | 45 | mode = 0660; |
32 | |||
33 | switch (type[0]) { | 46 | switch (type[0]) { |
34 | case 'c': | 47 | case 'c': |
35 | mode |= S_IFCHR; | 48 | mode |= S_IFCHR; |
@@ -45,18 +58,14 @@ int makedevs_main(int argc, char **argv) | |||
45 | } | 58 | } |
46 | 59 | ||
47 | while (S <= E) { | 60 | while (S <= E) { |
48 | int sz; | 61 | sprintf(buf, "%s%u", basedev, S); |
49 | |||
50 | sz = snprintf(buf, sizeof(buf), "%s%d", basedev, S); | ||
51 | if (sz < 0 || sz >= sizeof(buf)) /* libc different */ | ||
52 | bb_error_msg_and_die("%s too large", basedev); | ||
53 | |||
54 | /* if mode != S_IFCHR and != S_IFBLK third param in mknod() ignored */ | ||
55 | 62 | ||
63 | /* if mode != S_IFCHR and != S_IFBLK, | ||
64 | * third param in mknod() ignored */ | ||
56 | if (mknod(nodname, mode, makedev(Smajor, Sminor))) | 65 | if (mknod(nodname, mode, makedev(Smajor, Sminor))) |
57 | bb_error_msg("failed to create: %s", nodname); | 66 | bb_perror_msg("can't create %s", nodname); |
58 | 67 | ||
59 | if (nodname == basedev) /* ex. /dev/hda - to /dev/hda1 ... */ | 68 | /*if (nodname == basedev)*/ /* ex. /dev/hda - to /dev/hda1 ... */ |
60 | nodname = buf; | 69 | nodname = buf; |
61 | S++; | 70 | S++; |
62 | Sminor++; | 71 | Sminor++; |
@@ -70,34 +79,31 @@ int makedevs_main(int argc, char **argv) | |||
70 | /* Licensed under the GPL v2 or later, see the file LICENSE in this tarball. */ | 79 | /* Licensed under the GPL v2 or later, see the file LICENSE in this tarball. */ |
71 | 80 | ||
72 | int makedevs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 81 | int makedevs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
73 | int makedevs_main(int argc, char **argv) | 82 | int makedevs_main(int argc UNUSED_PARAM, char **argv) |
74 | { | 83 | { |
75 | FILE *table = stdin; | 84 | parser_t *parser; |
76 | char *rootdir = NULL; | 85 | char *rootdir = NULL; |
77 | char *line = NULL; | 86 | char *line = (char *)"-"; |
78 | int linenum = 0; | 87 | int linenum; |
79 | int ret = EXIT_SUCCESS; | 88 | int ret = EXIT_SUCCESS; |
80 | 89 | ||
90 | opt_complementary = "=1"; /* exactly one param */ | ||
81 | getopt32(argv, "d:", &line); | 91 | getopt32(argv, "d:", &line); |
82 | if (line) | 92 | rootdir = argv[optind]; |
83 | table = xfopen_for_read(line); | 93 | parser = config_open(line); |
84 | |||
85 | if (optind >= argc || (rootdir=argv[optind])==NULL) { | ||
86 | bb_error_msg_and_die("root directory not specified"); | ||
87 | } | ||
88 | 94 | ||
89 | xchdir(rootdir); | 95 | xchdir(rootdir); |
90 | 96 | ||
91 | umask(0); | 97 | umask(0); |
92 | 98 | ||
93 | printf("rootdir=%s\n", rootdir); | 99 | printf("rootdir=%s\n", rootdir); |
94 | if (line) { | 100 | if (NOT_LONE_DASH(line)) { |
95 | printf("table='%s'\n", line); | 101 | printf("table='%s'\n", line); |
96 | } else { | 102 | } else { |
97 | printf("table=<stdin>\n"); | 103 | printf("table=<stdin>\n"); |
98 | } | 104 | } |
99 | 105 | ||
100 | while ((line = xmalloc_fgetline(table)) != NULL) { | 106 | while (config_read(parser, &line, 1, 1, "# \t", PARSE_NORMAL)) { |
101 | char type; | 107 | char type; |
102 | unsigned mode = 0755; | 108 | unsigned mode = 0755; |
103 | unsigned major = 0; | 109 | unsigned major = 0; |
@@ -112,22 +118,17 @@ int makedevs_main(int argc, char **argv) | |||
112 | uid_t uid; | 118 | uid_t uid; |
113 | gid_t gid; | 119 | gid_t gid; |
114 | 120 | ||
115 | linenum++; | 121 | linenum = parser->lineno; |
116 | 122 | ||
117 | if ((2 > sscanf(line, "%40s %c %o %40s %40s %u %u %u %u %u", name, | 123 | if ((2 > sscanf(line, "%40s %c %o %40s %40s %u %u %u %u %u", |
118 | &type, &mode, user, group, &major, | 124 | name, &type, &mode, user, group, |
119 | &minor, &start, &increment, &count)) || | 125 | &major, &minor, &start, &increment, &count)) |
120 | ((major | minor | start | count | increment) > 255)) | 126 | || ((unsigned)(major | minor | start | count | increment) > 255) |
121 | { | 127 | ) { |
122 | if (*line=='\0' || *line=='#' || isspace(*line)) | ||
123 | continue; | ||
124 | bb_error_msg("invalid line %d: '%s'", linenum, line); | 128 | bb_error_msg("invalid line %d: '%s'", linenum, line); |
125 | ret = EXIT_FAILURE; | 129 | ret = EXIT_FAILURE; |
126 | continue; | 130 | continue; |
127 | } | 131 | } |
128 | if (name[0] == '#') { | ||
129 | continue; | ||
130 | } | ||
131 | 132 | ||
132 | gid = (*group) ? get_ug_id(group, xgroup2gid) : getgid(); | 133 | gid = (*group) ? get_ug_id(group, xgroup2gid) : getgid(); |
133 | uid = (*user) ? get_ug_id(user, xuname2uid) : getuid(); | 134 | uid = (*user) ? get_ug_id(user, xuname2uid) : getuid(); |
@@ -136,12 +137,14 @@ int makedevs_main(int argc, char **argv) | |||
136 | if (type == 'd') { | 137 | if (type == 'd') { |
137 | bb_make_directory(full_name, mode | S_IFDIR, FILEUTILS_RECUR); | 138 | bb_make_directory(full_name, mode | S_IFDIR, FILEUTILS_RECUR); |
138 | if (chown(full_name, uid, gid) == -1) { | 139 | if (chown(full_name, uid, gid) == -1) { |
139 | bb_perror_msg("line %d: chown failed for %s", linenum, full_name); | 140 | chown_fail: |
141 | bb_perror_msg("line %d: can't chown %s", linenum, full_name); | ||
140 | ret = EXIT_FAILURE; | 142 | ret = EXIT_FAILURE; |
141 | goto loop; | 143 | goto loop; |
142 | } | 144 | } |
143 | if (chmod(full_name, mode) < 0) { | 145 | if (chmod(full_name, mode) < 0) { |
144 | bb_perror_msg("line %d: chmod failed for %s", linenum, full_name); | 146 | chmod_fail: |
147 | bb_perror_msg("line %d: can't chmod %s", linenum, full_name); | ||
145 | ret = EXIT_FAILURE; | 148 | ret = EXIT_FAILURE; |
146 | goto loop; | 149 | goto loop; |
147 | } | 150 | } |
@@ -152,26 +155,20 @@ int makedevs_main(int argc, char **argv) | |||
152 | ret = EXIT_FAILURE; | 155 | ret = EXIT_FAILURE; |
153 | goto loop; | 156 | goto loop; |
154 | } | 157 | } |
155 | if (chown(full_name, uid, gid) == -1) { | 158 | if (chown(full_name, uid, gid) < 0) |
156 | bb_perror_msg("line %d: chown failed for %s", linenum, full_name); | 159 | goto chown_fail; |
157 | ret = EXIT_FAILURE; | 160 | if (chmod(full_name, mode) < 0) |
158 | goto loop; | 161 | goto chmod_fail; |
159 | } | ||
160 | if (chmod(full_name, mode) < 0) { | ||
161 | bb_perror_msg("line %d: chmod failed for %s", linenum, full_name); | ||
162 | ret = EXIT_FAILURE; | ||
163 | goto loop; | ||
164 | } | ||
165 | } else { | 162 | } else { |
166 | dev_t rdev; | 163 | dev_t rdev; |
164 | unsigned i; | ||
165 | char *full_name_inc; | ||
167 | 166 | ||
168 | if (type == 'p') { | 167 | if (type == 'p') { |
169 | mode |= S_IFIFO; | 168 | mode |= S_IFIFO; |
170 | } | 169 | } else if (type == 'c') { |
171 | else if (type == 'c') { | ||
172 | mode |= S_IFCHR; | 170 | mode |= S_IFCHR; |
173 | } | 171 | } else if (type == 'b') { |
174 | else if (type == 'b') { | ||
175 | mode |= S_IFBLK; | 172 | mode |= S_IFBLK; |
176 | } else { | 173 | } else { |
177 | bb_error_msg("line %d: unsupported file type %c", linenum, type); | 174 | bb_error_msg("line %d: unsupported file type %c", linenum, type); |
@@ -179,49 +176,30 @@ int makedevs_main(int argc, char **argv) | |||
179 | goto loop; | 176 | goto loop; |
180 | } | 177 | } |
181 | 178 | ||
182 | if (count > 0) { | 179 | full_name_inc = xmalloc(strlen(full_name) + sizeof(int)*3 + 2); |
183 | unsigned i; | 180 | if (count) |
184 | char *full_name_inc; | 181 | count--; |
185 | 182 | for (i = start; i <= start + count; i++) { | |
186 | full_name_inc = xmalloc(strlen(full_name) + 4); | 183 | sprintf(full_name_inc, count ? "%s%u" : "%s", full_name, i); |
187 | for (i = start; i < count; i++) { | 184 | rdev = makedev(major, minor + (i - start) * increment); |
188 | sprintf(full_name_inc, "%s%d", full_name, i); | 185 | if (mknod(full_name_inc, mode, rdev) < 0) { |
189 | rdev = makedev(major, minor + (i * increment - start)); | 186 | bb_perror_msg("line %d: can't create node %s", linenum, full_name_inc); |
190 | if (mknod(full_name_inc, mode, rdev) == -1) { | ||
191 | bb_perror_msg("line %d: cannot create node %s", linenum, full_name_inc); | ||
192 | ret = EXIT_FAILURE; | ||
193 | } | ||
194 | else if (chown(full_name_inc, uid, gid) == -1) { | ||
195 | bb_perror_msg("line %d: chown failed for %s", linenum, full_name_inc); | ||
196 | ret = EXIT_FAILURE; | ||
197 | } | ||
198 | if (chmod(full_name_inc, mode) < 0) { | ||
199 | bb_perror_msg("line %d: chmod failed for %s", linenum, full_name_inc); | ||
200 | ret = EXIT_FAILURE; | ||
201 | } | ||
202 | } | ||
203 | free(full_name_inc); | ||
204 | } else { | ||
205 | rdev = makedev(major, minor); | ||
206 | if (mknod(full_name, mode, rdev) == -1) { | ||
207 | bb_perror_msg("line %d: cannot create node %s", linenum, full_name); | ||
208 | ret = EXIT_FAILURE; | 187 | ret = EXIT_FAILURE; |
209 | } | 188 | } else if (chown(full_name_inc, uid, gid) < 0) { |
210 | else if (chown(full_name, uid, gid) == -1) { | 189 | bb_perror_msg("line %d: can't chown %s", linenum, full_name_inc); |
211 | bb_perror_msg("line %d: chown failed for %s", linenum, full_name); | ||
212 | ret = EXIT_FAILURE; | 190 | ret = EXIT_FAILURE; |
213 | } | 191 | } else if (chmod(full_name_inc, mode) < 0) { |
214 | if (chmod(full_name, mode) < 0) { | 192 | bb_perror_msg("line %d: can't chmod %s", linenum, full_name_inc); |
215 | bb_perror_msg("line %d: chmod failed for %s", linenum, full_name); | ||
216 | ret = EXIT_FAILURE; | 193 | ret = EXIT_FAILURE; |
217 | } | 194 | } |
218 | } | 195 | } |
196 | free(full_name_inc); | ||
219 | } | 197 | } |
220 | loop: | 198 | loop: |
221 | free(line); | ||
222 | free(full_name); | 199 | free(full_name); |
223 | } | 200 | } |
224 | fclose(table); | 201 | if (ENABLE_FEATURE_CLEAN_UP) |
202 | config_close(parser); | ||
225 | 203 | ||
226 | return ret; | 204 | return ret; |
227 | } | 205 | } |