1 /* vi: set sw=4 ts=4: */
3 * public domain -- Dave 'Kill a Cop' Cinege <dcinege@psychosis.com>
6 * Make ranges of device files quickly.
7 * known bugs: can't deal with alpha ranges
12 #if ENABLE_FEATURE_MAKEDEVS_LEAF
14 makedevs NAME TYPE MAJOR MINOR FIRST LAST [s]
20 FIRST..LAST specify numbers appended to NAME.
21 If 's' is the last argument, the base device is created as well.
23 makedevs /dev/ttyS c 4 66 2 63 -> ttyS2-ttyS63
24 makedevs /dev/hda b 3 0 0 8 s -> hda,hda1-hda8
26 int makedevs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
27 int makedevs_main(int argc, char **argv)
30 char *basedev, *type, *nodname, *buf;
31 int Smajor, Sminor, S, E;
33 if (argc < 7 || argv[1][0] == '-')
37 buf = xasprintf("%s%u", argv[1], (unsigned)-1);
39 Smajor = xatoi_u(argv[3]);
40 Sminor = xatoi_u(argv[4]);
43 nodname = argv[7] ? basedev : buf;
61 sprintf(buf, "%s%u", basedev, S);
63 /* if mode != S_IFCHR and != S_IFBLK,
64 * third param in mknod() ignored */
65 if (mknod(nodname, mode, makedev(Smajor, Sminor)))
66 bb_perror_msg("can't create %s", nodname);
68 /*if (nodname == basedev)*/ /* ex. /dev/hda - to /dev/hda1 ... */
77 #elif ENABLE_FEATURE_MAKEDEVS_TABLE
79 /* Licensed under the GPL v2 or later, see the file LICENSE in this tarball. */
81 int makedevs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
82 int makedevs_main(int argc UNUSED_PARAM, char **argv)
85 char *line = (char *)"-";
86 int ret = EXIT_SUCCESS;
88 opt_complementary = "=1"; /* exactly one param */
89 getopt32(argv, "d:", &line);
92 xchdir(*argv); /* ensure root dir exists */
96 printf("rootdir=%s\ntable=", *argv);
97 if (NOT_LONE_DASH(line)) {
98 printf("'%s'\n", line);
103 parser = config_open(line);
104 while (config_read(parser, &line, 1, 1, "# \t", PARSE_NORMAL)) {
107 unsigned mode = 0755;
111 unsigned increment = 0;
116 char *full_name = name;
120 linenum = parser->lineno;
122 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)
127 bb_error_msg("invalid line %d: '%s'", linenum, line);
132 gid = (*group) ? get_ug_id(group, xgroup2gid) : getgid();
133 uid = (*user) ? get_ug_id(user, xuname2uid) : getuid();
134 /* We are already in the right root dir,
135 * so make absolute paths relative */
136 if ('/' == *full_name)
140 bb_make_directory(full_name, mode | S_IFDIR, FILEUTILS_RECUR);
141 if (chown(full_name, uid, gid) == -1) {
143 bb_perror_msg("line %d: can't chown %s", linenum, full_name);
147 if (chmod(full_name, mode) < 0) {
149 bb_perror_msg("line %d: can't chmod %s", linenum, full_name);
153 } else if (type == 'f') {
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);
160 if (chown(full_name, uid, gid) < 0)
162 if (chmod(full_name, mode) < 0)
171 } else if (type == 'c') {
173 } else if (type == 'b') {
176 bb_error_msg("line %d: unsupported file type %c", linenum, type);
181 full_name_inc = xmalloc(strlen(full_name) + sizeof(int)*3 + 2);
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);
190 } else if (chown(full_name_inc, uid, gid) < 0) {
191 bb_perror_msg("line %d: can't chown %s", linenum, full_name_inc);
193 } else if (chmod(full_name_inc, mode) < 0) {
194 bb_perror_msg("line %d: can't chmod %s", linenum, full_name_inc);
201 if (ENABLE_FEATURE_CLEAN_UP)
202 config_close(parser);
208 # error makedevs configuration error, either leaf or table must be selected