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