Contents of /trunk/mkinitrd-magellan/busybox/miscutils/makedevs.c
Parent Directory | Revision Log
Revision 532 -
(show annotations)
(download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 5573 byte(s)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 5573 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd
1 | /* vi: set sw=4 ts=4: */ |
2 | /* |
3 | * public domain -- Dave 'Kill a Cop' Cinege <dcinege@psychosis.com> |
4 | * |
5 | * makedevs |
6 | * Make ranges of device files quickly. |
7 | * known bugs: can't deal with alpha ranges |
8 | */ |
9 | |
10 | #include "busybox.h" |
11 | |
12 | #ifdef CONFIG_FEATURE_MAKEDEVS_LEAF |
13 | int makedevs_main(int argc, char **argv) |
14 | { |
15 | mode_t mode; |
16 | char *basedev, *type, *nodname, buf[255]; |
17 | int Smajor, Sminor, S, E; |
18 | |
19 | if (argc < 7 || *argv[1]=='-') |
20 | bb_show_usage(); |
21 | |
22 | basedev = argv[1]; |
23 | type = argv[2]; |
24 | Smajor = xatoi_u(argv[3]); |
25 | Sminor = xatoi_u(argv[4]); |
26 | S = xatoi_u(argv[5]); |
27 | E = xatoi_u(argv[6]); |
28 | nodname = argc == 8 ? basedev : buf; |
29 | |
30 | mode = 0660; |
31 | |
32 | switch (type[0]) { |
33 | case 'c': |
34 | mode |= S_IFCHR; |
35 | break; |
36 | case 'b': |
37 | mode |= S_IFBLK; |
38 | break; |
39 | case 'f': |
40 | mode |= S_IFIFO; |
41 | break; |
42 | default: |
43 | bb_show_usage(); |
44 | } |
45 | |
46 | while (S <= E) { |
47 | int sz; |
48 | |
49 | sz = snprintf(buf, sizeof(buf), "%s%d", basedev, S); |
50 | if(sz<0 || sz>=sizeof(buf)) /* libc different */ |
51 | bb_error_msg_and_die("%s too large", basedev); |
52 | |
53 | /* if mode != S_IFCHR and != S_IFBLK third param in mknod() ignored */ |
54 | |
55 | if (mknod(nodname, mode, makedev(Smajor, Sminor))) |
56 | bb_error_msg("failed to create: %s", nodname); |
57 | |
58 | if (nodname == basedev) /* ex. /dev/hda - to /dev/hda1 ... */ |
59 | nodname = buf; |
60 | S++; |
61 | Sminor++; |
62 | } |
63 | |
64 | return 0; |
65 | } |
66 | |
67 | #elif defined CONFIG_FEATURE_MAKEDEVS_TABLE |
68 | |
69 | /* Licensed under the GPL v2 or later, see the file LICENSE in this tarball. */ |
70 | |
71 | int makedevs_main(int argc, char **argv) |
72 | { |
73 | FILE *table = stdin; |
74 | char *rootdir = NULL; |
75 | char *line = NULL; |
76 | int linenum = 0; |
77 | int ret = EXIT_SUCCESS; |
78 | |
79 | getopt32(argc, argv, "d:", &line); |
80 | if (line) |
81 | table = xfopen(line, "r"); |
82 | |
83 | if (optind >= argc || (rootdir=argv[optind])==NULL) { |
84 | bb_error_msg_and_die("root directory not specified"); |
85 | } |
86 | |
87 | xchdir(rootdir); |
88 | |
89 | umask(0); |
90 | |
91 | printf("rootdir=%s\n", rootdir); |
92 | if (line) { |
93 | printf("table='%s'\n", line); |
94 | } else { |
95 | printf("table=<stdin>\n"); |
96 | } |
97 | |
98 | while ((line = xmalloc_getline(table))) { |
99 | char type; |
100 | unsigned int mode = 0755; |
101 | unsigned int major = 0; |
102 | unsigned int minor = 0; |
103 | unsigned int count = 0; |
104 | unsigned int increment = 0; |
105 | unsigned int start = 0; |
106 | char name[41]; |
107 | char user[41]; |
108 | char group[41]; |
109 | char *full_name; |
110 | uid_t uid; |
111 | gid_t gid; |
112 | |
113 | linenum++; |
114 | |
115 | if ((2 > sscanf(line, "%40s %c %o %40s %40s %u %u %u %u %u", name, |
116 | &type, &mode, user, group, &major, |
117 | &minor, &start, &increment, &count)) || |
118 | ((major | minor | start | count | increment) > 255)) |
119 | { |
120 | if (*line=='\0' || *line=='#' || isspace(*line)) |
121 | continue; |
122 | bb_error_msg("line %d invalid: '%s'", linenum, line); |
123 | ret = EXIT_FAILURE; |
124 | continue; |
125 | } |
126 | if (name[0] == '#') { |
127 | continue; |
128 | } |
129 | |
130 | gid = (*group) ? get_ug_id(group, xgroup2gid) : getgid(); |
131 | uid = (*user) ? get_ug_id(user, xuname2uid) : getuid(); |
132 | full_name = concat_path_file(rootdir, name); |
133 | |
134 | if (type == 'd') { |
135 | bb_make_directory(full_name, mode | S_IFDIR, FILEUTILS_RECUR); |
136 | if (chown(full_name, uid, gid) == -1) { |
137 | bb_perror_msg("line %d: chown failed for %s", linenum, full_name); |
138 | ret = EXIT_FAILURE; |
139 | goto loop; |
140 | } |
141 | if ((mode != -1) && (chmod(full_name, mode) < 0)){ |
142 | bb_perror_msg("line %d: chmod failed for %s", linenum, full_name); |
143 | ret = EXIT_FAILURE; |
144 | goto loop; |
145 | } |
146 | } else if (type == 'f') { |
147 | struct stat st; |
148 | if ((stat(full_name, &st) < 0 || !S_ISREG(st.st_mode))) { |
149 | bb_perror_msg("line %d: regular file '%s' does not exist", linenum, full_name); |
150 | ret = EXIT_FAILURE; |
151 | goto loop; |
152 | } |
153 | if (chown(full_name, uid, gid) == -1) { |
154 | bb_perror_msg("line %d: chown failed for %s", linenum, full_name); |
155 | ret = EXIT_FAILURE; |
156 | goto loop; |
157 | } |
158 | if ((mode != -1) && (chmod(full_name, mode) < 0)){ |
159 | bb_perror_msg("line %d: chmod failed for %s", linenum, full_name); |
160 | ret = EXIT_FAILURE; |
161 | goto loop; |
162 | } |
163 | } else |
164 | { |
165 | dev_t rdev; |
166 | |
167 | if (type == 'p') { |
168 | mode |= S_IFIFO; |
169 | } |
170 | else if (type == 'c') { |
171 | mode |= S_IFCHR; |
172 | } |
173 | else if (type == 'b') { |
174 | mode |= S_IFBLK; |
175 | } else { |
176 | bb_error_msg("line %d: unsupported file type %c", linenum, type); |
177 | ret = EXIT_FAILURE; |
178 | goto loop; |
179 | } |
180 | |
181 | if (count > 0) { |
182 | int i; |
183 | char *full_name_inc; |
184 | |
185 | full_name_inc = xmalloc(strlen(full_name) + 4); |
186 | for (i = start; i < count; i++) { |
187 | sprintf(full_name_inc, "%s%d", full_name, i); |
188 | rdev = (major << 8) + minor + (i * increment - start); |
189 | if (mknod(full_name_inc, mode, rdev) == -1) { |
190 | bb_perror_msg("line %d: cannot create node %s", linenum, full_name_inc); |
191 | ret = EXIT_FAILURE; |
192 | } |
193 | else if (chown(full_name_inc, uid, gid) == -1) { |
194 | bb_perror_msg("line %d: chown failed for %s", linenum, full_name_inc); |
195 | ret = EXIT_FAILURE; |
196 | } |
197 | if ((mode != -1) && (chmod(full_name_inc, mode) < 0)){ |
198 | bb_perror_msg("line %d: chmod failed for %s", linenum, full_name_inc); |
199 | ret = EXIT_FAILURE; |
200 | } |
201 | } |
202 | free(full_name_inc); |
203 | } else { |
204 | rdev = (major << 8) + minor; |
205 | if (mknod(full_name, mode, rdev) == -1) { |
206 | bb_perror_msg("line %d: cannot create node %s", linenum, full_name); |
207 | ret = EXIT_FAILURE; |
208 | } |
209 | else if (chown(full_name, uid, gid) == -1) { |
210 | bb_perror_msg("line %d: chown failed for %s", linenum, full_name); |
211 | ret = EXIT_FAILURE; |
212 | } |
213 | if ((mode != -1) && (chmod(full_name, mode) < 0)){ |
214 | bb_perror_msg("line %d: chmod failed for %s", linenum, full_name); |
215 | ret = EXIT_FAILURE; |
216 | } |
217 | } |
218 | } |
219 | loop: |
220 | free(line); |
221 | free(full_name); |
222 | } |
223 | fclose(table); |
224 | |
225 | return ret; |
226 | } |
227 | |
228 | #else |
229 | # error makedevs configuration error, either leaf or table must be selected |
230 | #endif |