source: MondoRescue/branches/2.2.9/mindi-busybox/miscutils/makedevs.c@ 3320

Last change on this file since 3320 was 3320, checked in by Bruno Cornec, 9 years ago
  • Re-add (thanks git BTW) the 2.2.9 branch which had been destroyed in the move to 3.0
  • Property svn:eol-style set to native
File size: 5.1 KB
Line 
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 "libbb.h"
11
12#if ENABLE_FEATURE_MAKEDEVS_LEAF
13/*
14makedevs NAME TYPE MAJOR MINOR FIRST LAST [s]
15TYPEs:
16b Block device
17c Character device
18f FIFO
19
20FIRST..LAST specify numbers appended to NAME.
21If 's' is the last argument, the base device is created as well.
22Examples:
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*/
26int makedevs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
27int makedevs_main(int argc, char **argv)
28{
29 mode_t mode;
30 char *basedev, *type, *nodname, *buf;
31 int Smajor, Sminor, S, E;
32
33 if (argc < 7 || argv[1][0] == '-')
34 bb_show_usage();
35
36 basedev = argv[1];
37 buf = xasprintf("%s%u", argv[1], (unsigned)-1);
38 type = argv[2];
39 Smajor = xatoi_positive(argv[3]);
40 Sminor = xatoi_positive(argv[4]);
41 S = xatoi_positive(argv[5]);
42 E = xatoi_positive(argv[6]);
43 nodname = argv[7] ? basedev : buf;
44
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 sprintf(buf, "%s%u", basedev, S);
62
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);
67
68 /*if (nodname == basedev)*/ /* ex. /dev/hda - to /dev/hda1 ... */
69 nodname = buf;
70 S++;
71 Sminor++;
72 }
73
74 return 0;
75}
76
77#elif ENABLE_FEATURE_MAKEDEVS_TABLE
78
79/* Licensed under GPLv2 or later, see file LICENSE in this source tree. */
80
81int makedevs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
82int makedevs_main(int argc UNUSED_PARAM, char **argv)
83{
84 parser_t *parser;
85 char *line = (char *)"-";
86 int ret = EXIT_SUCCESS;
87
88 opt_complementary = "=1"; /* exactly one param */
89 getopt32(argv, "d:", &line);
90 argv += optind;
91
92 xchdir(*argv); /* ensure root dir exists */
93
94 umask(0);
95
96 printf("rootdir=%s\ntable=", *argv);
97 if (NOT_LONE_DASH(line)) {
98 printf("'%s'\n", line);
99 } else {
100 puts("<stdin>");
101 }
102
103 parser = config_open(line);
104 while (config_read(parser, &line, 1, 1, "# \t", PARSE_NORMAL)) {
105 int linenum;
106 char type;
107 unsigned mode = 0755;
108 unsigned major = 0;
109 unsigned minor = 0;
110 unsigned count = 0;
111 unsigned increment = 0;
112 unsigned start = 0;
113 char name[41];
114 char user[41];
115 char group[41];
116 char *full_name = name;
117 uid_t uid;
118 gid_t gid;
119
120 linenum = parser->lineno;
121
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)
126 ) {
127 bb_error_msg("invalid line %d: '%s'", linenum, line);
128 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 /* We are already in the right root dir,
135 * so make absolute paths relative */
136 if ('/' == *full_name)
137 full_name++;
138
139 if (type == 'd') {
140 bb_make_directory(full_name, mode | S_IFDIR, FILEUTILS_RECUR);
141 if (chown(full_name, uid, gid) == -1) {
142 chown_fail:
143 bb_perror_msg("line %d: can't chown %s", linenum, full_name);
144 ret = EXIT_FAILURE;
145 continue;
146 }
147 if (chmod(full_name, mode) < 0) {
148 chmod_fail:
149 bb_perror_msg("line %d: can't chmod %s", linenum, full_name);
150 ret = EXIT_FAILURE;
151 continue;
152 }
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 continue;
159 }
160 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 dev_t rdev;
166 unsigned i;
167 char *full_name_inc;
168
169 if (type == 'p') {
170 mode |= S_IFIFO;
171 } else if (type == 'c') {
172 mode |= S_IFCHR;
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 continue;
179 }
180
181 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 ret = EXIT_FAILURE;
190 } else if (chown(full_name_inc, uid, gid) < 0) {
191 bb_perror_msg("line %d: can't chown %s", linenum, full_name_inc);
192 ret = EXIT_FAILURE;
193 } else if (chmod(full_name_inc, mode) < 0) {
194 bb_perror_msg("line %d: can't chmod %s", linenum, full_name_inc);
195 ret = EXIT_FAILURE;
196 }
197 }
198 free(full_name_inc);
199 }
200 }
201 if (ENABLE_FEATURE_CLEAN_UP)
202 config_close(parser);
203
204 return ret;
205}
206
207#else
208# error makedevs configuration error, either leaf or table must be selected
209#endif
Note: See TracBrowser for help on using the repository browser.