Magellan Linux

Annotation of /tags/mkinitrd-6_3_1/busybox/miscutils/makedevs.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1143 - (hide annotations) (download)
Thu Aug 19 12:44:27 2010 UTC (13 years, 10 months ago) by niro
File MIME type: text/plain
File size: 5188 byte(s)
tagged 'mkinitrd-6_3_1'
1 niro 532 /* 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 niro 816 #include "libbb.h"
11 niro 532
12 niro 816 #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     f 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     */
26     int makedevs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
27 niro 532 int makedevs_main(int argc, char **argv)
28     {
29     mode_t mode;
30 niro 816 char *basedev, *type, *nodname, *buf;
31 niro 532 int Smajor, Sminor, S, E;
32    
33 niro 816 if (argc < 7 || argv[1][0] == '-')
34 niro 532 bb_show_usage();
35    
36     basedev = argv[1];
37 niro 816 buf = xasprintf("%s%u", argv[1], (unsigned)-1);
38 niro 532 type = argv[2];
39     Smajor = xatoi_u(argv[3]);
40     Sminor = xatoi_u(argv[4]);
41     S = xatoi_u(argv[5]);
42     E = xatoi_u(argv[6]);
43 niro 816 nodname = argv[7] ? basedev : buf;
44 niro 532
45     mode = 0660;
46     switch (type[0]) {
47     case 'c':
48     mode |= S_IFCHR;
49     break;
50     case 'b':
51     mode |= S_IFBLK;
52     break;
53     case 'f':
54     mode |= S_IFIFO;
55     break;
56     default:
57     bb_show_usage();
58     }
59    
60     while (S <= E) {
61 niro 816 sprintf(buf, "%s%u", basedev, S);
62 niro 532
63 niro 816 /* if mode != S_IFCHR and != S_IFBLK,
64     * third param in mknod() ignored */
65 niro 532 if (mknod(nodname, mode, makedev(Smajor, Sminor)))
66 niro 1123 bb_perror_msg("can't create '%s'", nodname);
67 niro 532
68 niro 816 /*if (nodname == basedev)*/ /* ex. /dev/hda - to /dev/hda1 ... */
69 niro 532 nodname = buf;
70     S++;
71     Sminor++;
72     }
73    
74     return 0;
75     }
76    
77 niro 816 #elif ENABLE_FEATURE_MAKEDEVS_TABLE
78 niro 532
79     /* Licensed under the GPL v2 or later, see the file LICENSE in this tarball. */
80    
81 niro 816 int makedevs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
82     int makedevs_main(int argc UNUSED_PARAM, char **argv)
83 niro 532 {
84 niro 816 parser_t *parser;
85     char *line = (char *)"-";
86 niro 532 int ret = EXIT_SUCCESS;
87    
88 niro 816 opt_complementary = "=1"; /* exactly one param */
89     getopt32(argv, "d:", &line);
90     argv += optind;
91 niro 532
92 niro 816 xchdir(*argv); /* ensure root dir exists */
93 niro 532
94     umask(0);
95    
96 niro 816 printf("rootdir=%s\ntable=", *argv);
97     if (NOT_LONE_DASH(line)) {
98     printf("'%s'\n", line);
99 niro 532 } else {
100 niro 816 puts("<stdin>");
101 niro 532 }
102    
103 niro 816 parser = config_open(line);
104     while (config_read(parser, &line, 1, 1, "# \t", PARSE_NORMAL)) {
105     int linenum;
106 niro 532 char type;
107 niro 816 unsigned mode = 0755;
108     unsigned major = 0;
109     unsigned minor = 0;
110     unsigned count = 0;
111     unsigned increment = 0;
112     unsigned start = 0;
113 niro 532 char name[41];
114     char user[41];
115     char group[41];
116 niro 816 char *full_name = name;
117 niro 532 uid_t uid;
118     gid_t gid;
119    
120 niro 816 linenum = parser->lineno;
121 niro 532
122 niro 816 if ((2 > sscanf(line, "%40s %c %o %40s %40s %u %u %u %u %u",
123     name, &type, &mode, user, group,
124     &major, &minor, &start, &increment, &count))
125     || ((unsigned)(major | minor | start | count | increment) > 255)
126     ) {
127     bb_error_msg("invalid line %d: '%s'", linenum, line);
128 niro 532 ret = EXIT_FAILURE;
129     continue;
130     }
131    
132     gid = (*group) ? get_ug_id(group, xgroup2gid) : getgid();
133     uid = (*user) ? get_ug_id(user, xuname2uid) : getuid();
134 niro 816 /* We are already in the right root dir,
135     * so make absolute paths relative */
136     if ('/' == *full_name)
137     full_name++;
138 niro 532
139     if (type == 'd') {
140     bb_make_directory(full_name, mode | S_IFDIR, FILEUTILS_RECUR);
141     if (chown(full_name, uid, gid) == -1) {
142 niro 816 chown_fail:
143     bb_perror_msg("line %d: can't chown %s", linenum, full_name);
144 niro 532 ret = EXIT_FAILURE;
145 niro 816 continue;
146 niro 532 }
147 niro 816 if (chmod(full_name, mode) < 0) {
148     chmod_fail:
149     bb_perror_msg("line %d: can't chmod %s", linenum, full_name);
150 niro 532 ret = EXIT_FAILURE;
151 niro 816 continue;
152 niro 532 }
153     } else if (type == 'f') {
154     struct stat st;
155     if ((stat(full_name, &st) < 0 || !S_ISREG(st.st_mode))) {
156     bb_perror_msg("line %d: regular file '%s' does not exist", linenum, full_name);
157     ret = EXIT_FAILURE;
158 niro 816 continue;
159 niro 532 }
160 niro 816 if (chown(full_name, uid, gid) < 0)
161     goto chown_fail;
162     if (chmod(full_name, mode) < 0)
163     goto chmod_fail;
164     } else {
165 niro 532 dev_t rdev;
166 niro 816 unsigned i;
167     char *full_name_inc;
168 niro 532
169     if (type == 'p') {
170     mode |= S_IFIFO;
171 niro 816 } else if (type == 'c') {
172 niro 532 mode |= S_IFCHR;
173 niro 816 } else if (type == 'b') {
174 niro 532 mode |= S_IFBLK;
175     } else {
176     bb_error_msg("line %d: unsupported file type %c", linenum, type);
177     ret = EXIT_FAILURE;
178 niro 816 continue;
179 niro 532 }
180    
181 niro 816 full_name_inc = xmalloc(strlen(full_name) + sizeof(int)*3 + 2);
182     if (count)
183     count--;
184     for (i = start; i <= start + count; i++) {
185     sprintf(full_name_inc, count ? "%s%u" : "%s", full_name, i);
186     rdev = makedev(major, minor + (i - start) * increment);
187     if (mknod(full_name_inc, mode, rdev) < 0) {
188     bb_perror_msg("line %d: can't create node %s", linenum, full_name_inc);
189 niro 532 ret = EXIT_FAILURE;
190 niro 816 } else if (chown(full_name_inc, uid, gid) < 0) {
191     bb_perror_msg("line %d: can't chown %s", linenum, full_name_inc);
192 niro 532 ret = EXIT_FAILURE;
193 niro 816 } else if (chmod(full_name_inc, mode) < 0) {
194     bb_perror_msg("line %d: can't chmod %s", linenum, full_name_inc);
195 niro 532 ret = EXIT_FAILURE;
196     }
197     }
198 niro 816 free(full_name_inc);
199 niro 532 }
200     }
201 niro 816 if (ENABLE_FEATURE_CLEAN_UP)
202     config_close(parser);
203 niro 532
204     return ret;
205     }
206    
207     #else
208     # error makedevs configuration error, either leaf or table must be selected
209     #endif