1041608b7bb6cd9db34ab454af7d550bf9806c24
[oweals/busybox.git] / busybox / patches / makdevs_table.diff
1 Index: include/usage.h
2 ===================================================================
3 RCS file: /var/cvs/busybox/include/usage.h,v
4 retrieving revision 1.211
5 diff -u -r1.211 usage.h
6 --- a/include/usage.h   26 May 2004 22:09:37 -0000      1.211
7 +++ b/include/usage.h   5 Jun 2004 07:51:26 -0000
8 @@ -1536,6 +1536,7 @@
9  #define lsmod_full_usage \
10         "List the currently loaded kernel modules."
11  
12 +#ifdef CONFIG_FEATURE_MAKEDEVS_LEAF
13  #define makedevs_trivial_usage \
14         "NAME TYPE MAJOR MINOR FIRST LAST [s]"
15  #define makedevs_full_usage \
16 @@ -1555,6 +1556,18 @@
17         "[creates ttyS2-ttyS63]\n" \
18         "# makedevs /dev/hda b 3 0 0 8 s\n" \
19         "[creates hda,hda1-hda8]\n"
20 +#endif
21 +
22 +#ifdef CONFIG_FEATURE_MAKEDEVS_TABLE
23 +#define makedevs_trivial_usage \
24 +       "[-r rootdir] [device_table]"
25 +#define makedevs_full_usage \
26 +       "Creates a batch of special files as specified in a device table\n" \
27 +       "The device table has one line per device group, each group is of\n" \
28 +       "the format\n" \
29 +       "\ttype mode user group major minor start increment count\n" \
30 +       "a '-' may be used for blank entries\n"
31 +#endif
32  
33  #ifdef CONFIG_FEATURE_MD5_SHA1_SUM_CHECK
34  #define USAGE_MD5_SHA1_SUM_CHECK(a) a
35 Index: miscutils/Config.in
36 ===================================================================
37 RCS file: /var/cvs/busybox/miscutils/Config.in,v
38 retrieving revision 1.14
39 diff -u -r1.14 Config.in
40 --- a/miscutils/Config.in       15 Mar 2004 08:28:46 -0000      1.14
41 +++ b/miscutils/Config.in       5 Jun 2004 07:51:26 -0000
42 @@ -143,10 +143,32 @@
43         bool "makedevs"
44         default n
45         help
46 -         'makedevs' is a utility used and created by the Linux Router Project.
47 -         It creates a large number of device special files (/dev devices)
48 -         rather quickly, and can be considerably faster then running mknod a
49 -         zillion times.
50 +         'makedevs' is a utility used to create a batch of devices with
51 +         one command.
52 +         .
53 +         There are two choices for command line behaviour, the interface
54 +         as used by LEAF/Linux Router Project, or a device table file.
55 +         . 
56 +         'leaf' is traditionally what busybox follows, it allows multiple
57 +         devices of a particluar type to be created per command.
58 +         e.g. /dev/hda[0-9]
59 +          Device properties are passed as command line arguments.
60 +         .
61 +         'table' reads device properties from a file or stdin, allowing
62 +         a batch of unrelated devices to be makde with one command. 
63 +          User/group names are allowed as an alternative to uid/gid.
64 +
65 +choice
66 +       prompt "Choose makedevs behaviour"
67 +       default CONFIG_FEATURE_MAKDEVS_TABLE
68 +
69 +config CONFIG_FEATURE_MAKEDEVS_LEAF
70 +        bool "leaf"
71 +
72 +config CONFIG_FEATURE_MAKEDEVS_TABLE
73 +       bool "table"
74 +
75 +endchoice
76  
77  config CONFIG_MT
78         bool "mt"
79 Index: miscutils/makedevs.c
80 ===================================================================
81 RCS file: /var/cvs/busybox/miscutils/makedevs.c,v
82 retrieving revision 1.16
83 diff -u -r1.16 makedevs.c
84 --- a/miscutils/makedevs.c      15 Mar 2004 08:28:46 -0000      1.16
85 +++ b/miscutils/makedevs.c      5 Jun 2004 07:51:26 -0000
86 @@ -1,20 +1,27 @@
87  /* vi: set sw=4 ts=4: */
88 -/*
89 - * public domain -- Dave 'Kill a Cop' Cinege <dcinege@psychosis.com>
90 - *
91 - * makedevs
92 - * Make ranges of device files quickly.
93 - * known bugs: can't deal with alpha ranges
94 - */
95  
96 +#include <sys/types.h>
97 +
98 +#include <fcntl.h>
99 +#include <getopt.h>
100  #include <stdio.h>
101  #include <stdlib.h>
102  #include <string.h>
103 -#include <fcntl.h>
104 +#include <time.h>
105  #include <unistd.h>
106 -#include <sys/types.h>
107 +
108  #include "busybox.h"
109  
110 +#ifdef CONFIG_FEATURE_MAKEDEVS_LEAF
111 +
112 +/*
113 + * public domain -- Dave 'Kill a Cop' Cinege <dcinege@psychosis.com>
114 + *
115 + * makedevs
116 + * Make ranges of device files quickly.
117 + * known bugs: can't deal with alpha ranges
118 + */
119
120  int makedevs_main(int argc, char **argv)
121  {
122         mode_t mode;
123 @@ -69,24 +76,153 @@
124         return 0;
125  }
126  
127 +#elif defined CONFIG_FEATURE_MAKEDEVS_TABLE
128 +
129  /*
130 -And this is what this program replaces. The shell is too slow!
131 + *  This program is free software; you can redistribute it and/or modify
132 + *  it under the terms of the GNU General Public License version 2 as
133 + *  published by the Free Software Foundation.
134 + *
135 + *  This program is distributed in the hope that it will be useful,
136 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
137 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
138 + *  GNU Library General Public License for more details.
139 + *
140 + *  You should have received a copy of the GNU General Public License
141 + *  along with this program; if not, write to the Free Software
142 + *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
143 + *
144 + */
145 +
146 +static const struct option makedevs_long_options[] = {
147 +       {"root", 1, NULL, 'r'},
148 +       {0, 0, 0, 0}
149 +};
150  
151 -makedev () {
152 -local basedev=$1; local S=$2; local E=$3
153 -local major=$4; local Sminor=$5; local type=$6
154 -local sbase=$7
155 -
156 -       if [ ! "$sbase" = "" ]; then
157 -               mknod "$basedev" $type $major $Sminor
158 -               S=`expr $S + 1`
159 -               Sminor=`expr $Sminor + 1`
160 -       fi
161 -
162 -       while [ $S -le $E ]; do
163 -               mknod "$basedev$S" $type $major $Sminor
164 -               S=`expr $S + 1`
165 -               Sminor=`expr $Sminor + 1`
166 -       done
167 +extern int makedevs_main(int argc, char **argv)
168 +{
169 +       FILE *table;
170 +       int opt;
171 +       char *rootdir = "./";
172 +       char *line;
173 +       int ret = EXIT_SUCCESS;
174 +
175 +       bb_opt_complementaly = "d~r";
176 +       bb_applet_long_options = makedevs_long_options;
177 +       opt = bb_getopt_ulflags(argc, argv, "d:r:", &rootdir, &rootdir);
178 +
179 +       if (optind + 1 == argc) {
180 +               table = bb_xfopen(argv[optind], "r");
181 +       } else {
182 +               table = stdin;
183 +       }
184 +
185 +       if (chdir(rootdir) == -1) {
186 +               bb_perror_msg_and_die("Couldnt chdor to %s", rootdir);
187 +       }
188 +
189 +       umask(0);
190 +
191 +       while ((line = bb_get_chomped_line_from_file(table))) {
192 +               char type;
193 +               unsigned int mode = 0755;
194 +               unsigned int major = 0;
195 +               unsigned int minor = 0;
196 +               unsigned int count = 0;
197 +               unsigned int increment = 0;
198 +               unsigned int start = 0;
199 +               char name[41];
200 +               char user[41];
201 +               char group[41];
202 +               char *full_name;
203 +               uid_t uid;
204 +               gid_t gid;
205 +
206 +               if ((2 > sscanf(line, "%40s %c %o %40s %40s %u %u %u %u %u", name,
207 +                       &type, &mode, user, group, &major,
208 +                       &minor, &start, &increment, &count)) ||
209 +                       ((major | minor | start | count | increment) > 255)) {
210 +                       bb_error_msg("Ignoring invalid line\n%s\n", line);
211 +                       ret = EXIT_FAILURE;
212 +                       continue;
213 +               }
214 +               if (name[0] == '#') {
215 +                       continue;
216 +               }
217 +               if (group) {
218 +                       gid = get_ug_id(group, my_getgrnam);
219 +               } else {
220 +                       gid = getgid();
221 +               }
222 +               if (user) {
223 +                       uid = get_ug_id(user, my_getpwnam);
224 +               } else {
225 +                       uid = getuid();
226 +               }
227 +               full_name = concat_path_file(rootdir, name);
228 +
229 +               if (type == 'd') {
230 +                       bb_make_directory(full_name, mode | S_IFDIR, 0);
231 +                       if (chown(full_name, uid, gid) == -1) {
232 +                               bb_perror_msg("chown failed for %s", full_name);
233 +                               ret = EXIT_FAILURE;
234 +                               goto loop;
235 +                       }
236 +               } else {
237 +                       dev_t rdev;
238 +
239 +                       if (type == 'p') {
240 +                               mode |= S_IFIFO;
241 +                       }
242 +                       else if (type == 'c') {
243 +                               mode |= S_IFCHR;
244 +                       }
245 +                       else if (type == 'b') {
246 +                               mode |= S_IFBLK;
247 +                       } else {
248 +                               bb_error_msg("Unsupported file type %c", type);
249 +                               ret = EXIT_FAILURE;
250 +                               goto loop;
251 +                       }
252 +
253 +                       if (count > 0) {
254 +                               int i;
255 +                               char *full_name_inc;
256 +
257 +                               full_name_inc = xmalloc(strlen(full_name) + 4);
258 +                               for (i = start; i < count; i++) {
259 +                                       sprintf(full_name_inc, "%s%d", full_name, i);
260 +                                       rdev = (major << 8) + minor + (i * increment - start);
261 +                                       if (mknod(full_name_inc, mode, rdev) == -1) {
262 +                                               bb_perror_msg("Couldnt create node %s", full_name_inc);
263 +                                               ret = EXIT_FAILURE;
264 +                                       }
265 +                                       else if (chown(full_name_inc, uid, gid) == -1) {
266 +                                               bb_perror_msg("chown failed for %s", full_name_inc);
267 +                                               ret = EXIT_FAILURE;
268 +                                       }
269 +                               }
270 +                               free(full_name_inc);
271 +                       } else {
272 +                               rdev = (major << 8) + minor;
273 +                               if (mknod(full_name, mode, rdev) == -1) {
274 +                                       bb_perror_msg("Couldnt create node %s", full_name);
275 +                                       ret = EXIT_FAILURE;
276 +                               }
277 +                               else if (chown(full_name, uid, gid) == -1) {
278 +                                       bb_perror_msg("chown failed for %s", full_name);
279 +                                       ret = EXIT_FAILURE;
280 +                               }
281 +                       }
282 +               }
283 +loop:
284 +               free(line);
285 +               free(full_name);
286 +       }
287 +       fclose(table);
288 +
289 +       return 0;
290  }
291 -*/
292 +#else
293 +# error makdedevs configuration error, either leaf or table must be selected
294 +#endif