Index: include/usage.h =================================================================== RCS file: /var/cvs/busybox/include/usage.h,v retrieving revision 1.211 diff -u -r1.211 usage.h --- a/include/usage.h 26 May 2004 22:09:37 -0000 1.211 +++ b/include/usage.h 5 Jun 2004 07:51:26 -0000 @@ -1536,6 +1536,7 @@ #define lsmod_full_usage \ "List the currently loaded kernel modules." +#ifdef CONFIG_FEATURE_MAKEDEVS_LEAF #define makedevs_trivial_usage \ "NAME TYPE MAJOR MINOR FIRST LAST [s]" #define makedevs_full_usage \ @@ -1555,6 +1556,18 @@ "[creates ttyS2-ttyS63]\n" \ "# makedevs /dev/hda b 3 0 0 8 s\n" \ "[creates hda,hda1-hda8]\n" +#endif + +#ifdef CONFIG_FEATURE_MAKEDEVS_TABLE +#define makedevs_trivial_usage \ + "[-r rootdir] [device_table]" +#define makedevs_full_usage \ + "Creates a batch of special files as specified in a device table\n" \ + "The device table has one line per device group, each group is of\n" \ + "the format\n" \ + "\ttype mode user group major minor start increment count\n" \ + "a '-' may be used for blank entries\n" +#endif #ifdef CONFIG_FEATURE_MD5_SHA1_SUM_CHECK #define USAGE_MD5_SHA1_SUM_CHECK(a) a Index: miscutils/Config.in =================================================================== RCS file: /var/cvs/busybox/miscutils/Config.in,v retrieving revision 1.14 diff -u -r1.14 Config.in --- a/miscutils/Config.in 15 Mar 2004 08:28:46 -0000 1.14 +++ b/miscutils/Config.in 5 Jun 2004 07:51:26 -0000 @@ -143,10 +143,32 @@ bool "makedevs" default n help - 'makedevs' is a utility used and created by the Linux Router Project. - It creates a large number of device special files (/dev devices) - rather quickly, and can be considerably faster then running mknod a - zillion times. + 'makedevs' is a utility used to create a batch of devices with + one command. + . + There are two choices for command line behaviour, the interface + as used by LEAF/Linux Router Project, or a device table file. + . + 'leaf' is traditionally what busybox follows, it allows multiple + devices of a particluar type to be created per command. + e.g. /dev/hda[0-9] + Device properties are passed as command line arguments. + . + 'table' reads device properties from a file or stdin, allowing + a batch of unrelated devices to be makde with one command. + User/group names are allowed as an alternative to uid/gid. + +choice + prompt "Choose makedevs behaviour" + default CONFIG_FEATURE_MAKDEVS_TABLE + +config CONFIG_FEATURE_MAKEDEVS_LEAF + bool "leaf" + +config CONFIG_FEATURE_MAKEDEVS_TABLE + bool "table" + +endchoice config CONFIG_MT bool "mt" Index: miscutils/makedevs.c =================================================================== RCS file: /var/cvs/busybox/miscutils/makedevs.c,v retrieving revision 1.16 diff -u -r1.16 makedevs.c --- a/miscutils/makedevs.c 15 Mar 2004 08:28:46 -0000 1.16 +++ b/miscutils/makedevs.c 5 Jun 2004 07:51:26 -0000 @@ -1,20 +1,27 @@ /* vi: set sw=4 ts=4: */ -/* - * public domain -- Dave 'Kill a Cop' Cinege - * - * makedevs - * Make ranges of device files quickly. - * known bugs: can't deal with alpha ranges - */ +#include + +#include +#include #include #include #include -#include +#include #include -#include + #include "busybox.h" +#ifdef CONFIG_FEATURE_MAKEDEVS_LEAF + +/* + * public domain -- Dave 'Kill a Cop' Cinege + * + * makedevs + * Make ranges of device files quickly. + * known bugs: can't deal with alpha ranges + */ + int makedevs_main(int argc, char **argv) { mode_t mode; @@ -69,24 +76,153 @@ return 0; } +#elif defined CONFIG_FEATURE_MAKEDEVS_TABLE + /* -And this is what this program replaces. The shell is too slow! + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +static const struct option makedevs_long_options[] = { + {"root", 1, NULL, 'r'}, + {0, 0, 0, 0} +}; -makedev () { -local basedev=$1; local S=$2; local E=$3 -local major=$4; local Sminor=$5; local type=$6 -local sbase=$7 - - if [ ! "$sbase" = "" ]; then - mknod "$basedev" $type $major $Sminor - S=`expr $S + 1` - Sminor=`expr $Sminor + 1` - fi - - while [ $S -le $E ]; do - mknod "$basedev$S" $type $major $Sminor - S=`expr $S + 1` - Sminor=`expr $Sminor + 1` - done +extern int makedevs_main(int argc, char **argv) +{ + FILE *table; + int opt; + char *rootdir = "./"; + char *line; + int ret = EXIT_SUCCESS; + + bb_opt_complementaly = "d~r"; + bb_applet_long_options = makedevs_long_options; + opt = bb_getopt_ulflags(argc, argv, "d:r:", &rootdir, &rootdir); + + if (optind + 1 == argc) { + table = bb_xfopen(argv[optind], "r"); + } else { + table = stdin; + } + + if (chdir(rootdir) == -1) { + bb_perror_msg_and_die("Couldnt chdor to %s", rootdir); + } + + umask(0); + + while ((line = bb_get_chomped_line_from_file(table))) { + char type; + unsigned int mode = 0755; + unsigned int major = 0; + unsigned int minor = 0; + unsigned int count = 0; + unsigned int increment = 0; + unsigned int start = 0; + char name[41]; + char user[41]; + char group[41]; + char *full_name; + uid_t uid; + gid_t gid; + + if ((2 > sscanf(line, "%40s %c %o %40s %40s %u %u %u %u %u", name, + &type, &mode, user, group, &major, + &minor, &start, &increment, &count)) || + ((major | minor | start | count | increment) > 255)) { + bb_error_msg("Ignoring invalid line\n%s\n", line); + ret = EXIT_FAILURE; + continue; + } + if (name[0] == '#') { + continue; + } + if (group) { + gid = get_ug_id(group, my_getgrnam); + } else { + gid = getgid(); + } + if (user) { + uid = get_ug_id(user, my_getpwnam); + } else { + uid = getuid(); + } + full_name = concat_path_file(rootdir, name); + + if (type == 'd') { + bb_make_directory(full_name, mode | S_IFDIR, 0); + if (chown(full_name, uid, gid) == -1) { + bb_perror_msg("chown failed for %s", full_name); + ret = EXIT_FAILURE; + goto loop; + } + } else { + dev_t rdev; + + if (type == 'p') { + mode |= S_IFIFO; + } + else if (type == 'c') { + mode |= S_IFCHR; + } + else if (type == 'b') { + mode |= S_IFBLK; + } else { + bb_error_msg("Unsupported file type %c", type); + ret = EXIT_FAILURE; + goto loop; + } + + if (count > 0) { + int i; + char *full_name_inc; + + full_name_inc = xmalloc(strlen(full_name) + 4); + for (i = start; i < count; i++) { + sprintf(full_name_inc, "%s%d", full_name, i); + rdev = (major << 8) + minor + (i * increment - start); + if (mknod(full_name_inc, mode, rdev) == -1) { + bb_perror_msg("Couldnt create node %s", full_name_inc); + ret = EXIT_FAILURE; + } + else if (chown(full_name_inc, uid, gid) == -1) { + bb_perror_msg("chown failed for %s", full_name_inc); + ret = EXIT_FAILURE; + } + } + free(full_name_inc); + } else { + rdev = (major << 8) + minor; + if (mknod(full_name, mode, rdev) == -1) { + bb_perror_msg("Couldnt create node %s", full_name); + ret = EXIT_FAILURE; + } + else if (chown(full_name, uid, gid) == -1) { + bb_perror_msg("chown failed for %s", full_name); + ret = EXIT_FAILURE; + } + } + } +loop: + free(line); + free(full_name); + } + fclose(table); + + return 0; } -*/ +#else +# error makdedevs configuration error, either leaf or table must be selected +#endif