busybox/miscutils/makedevs.c

231 lines
5.5 KiB
C
Raw Normal View History

/* vi: set sw=4 ts=4: */
/*
* public domain -- Dave 'Kill a Cop' Cinege <dcinege@psychosis.com>
*
* makedevs
* Make ranges of device files quickly.
* known bugs: can't deal with alpha ranges
*/
#include "busybox.h"
#ifdef CONFIG_FEATURE_MAKEDEVS_LEAF
int makedevs_main(int argc, char **argv)
1999-10-05 21:54:54 +05:30
{
mode_t mode;
char *basedev, *type, *nodname, buf[255];
int Smajor, Sminor, S, E;
1999-10-05 21:54:54 +05:30
if (argc < 7 || *argv[1]=='-')
2003-03-19 14:43:01 +05:30
bb_show_usage();
basedev = argv[1];
type = argv[2];
Smajor = atoi(argv[3]);
Sminor = atoi(argv[4]);
S = atoi(argv[5]);
E = atoi(argv[6]);
nodname = argc == 8 ? basedev : buf;
mode = 0660;
1999-10-05 21:54:54 +05:30
switch (type[0]) {
case 'c':
mode |= S_IFCHR;
break;
case 'b':
mode |= S_IFBLK;
break;
case 'f':
mode |= S_IFIFO;
break;
default:
2003-03-19 14:43:01 +05:30
bb_show_usage();
}
while (S <= E) {
int sz;
sz = snprintf(buf, sizeof(buf), "%s%d", basedev, S);
if(sz<0 || sz>=sizeof(buf)) /* libc different */
2003-03-19 14:43:01 +05:30
bb_error_msg_and_die("%s too large", basedev);
/* if mode != S_IFCHR and != S_IFBLK third param in mknod() ignored */
if (mknod(nodname, mode, makedev(Smajor, Sminor)))
2003-03-19 14:43:01 +05:30
bb_error_msg("Failed to create: %s", nodname);
if (nodname == basedev) /* ex. /dev/hda - to /dev/hda1 ... */
nodname = buf;
S++;
Sminor++;
1999-10-05 21:54:54 +05:30
}
return 0;
1999-10-05 21:54:54 +05:30
}
#elif defined CONFIG_FEATURE_MAKEDEVS_TABLE
/* Licensed under the GPL v2 or later, see the file LICENSE in this tarball. */
int makedevs_main(int argc, char **argv)
{
FILE *table = stdin;
char *rootdir = NULL;
char *line = NULL;
int linenum = 0;
int ret = EXIT_SUCCESS;
- merge -r15463:15564 from busybox_scratch branch through these changesets: ------------------------------------------------------------------------ r15465 | aldot | 2006-06-21 20:48:06 +0200 (Wed, 21 Jun 2006) | 3 lines - use CONFIG_BUSYBOX_EXEC_PATH as before it one was broken by a recent revert. - use xchdir() since all is invain if it fails there anyways, supposedly ------------------------------------------------------------------------ r15466 | aldot | 2006-06-21 20:55:16 +0200 (Wed, 21 Jun 2006) | 2 lines - adjust docs to take CONFIG_BUSYBOX_EXEC_PATH into account. ------------------------------------------------------------------------ r15467 | aldot | 2006-06-21 21:31:24 +0200 (Wed, 21 Jun 2006) | 18 lines - partial fallout of my TREE_USED touchup against gcc-4.2: rip unused vars, save s 144 bytes text data bss dec hex filename 862434 10156 645924 1518514 172bb2 busybox.old 862322 10156 645892 1518370 172b22 busybox function old new delta z_len 4 - -4 textend 4 - -4 part_nb 4 - -4 insize 4 - -4 ifile_size 4 - -4 do_link 4 - -4 new_text 70 60 -10 ipaddr_list_link 33 23 -10 gzip_main 898 822 -76 ------------------------------------------------------------------------------ (add/remove: 0/6 grow/shrink: 0/3 up/down: 0/-120) Total: -120 bytes ------------------------------------------------------------------------ r15468 | aldot | 2006-06-21 21:43:05 +0200 (Wed, 21 Jun 2006) | 19 lines - remove useless global exports function old new delta rpm_main 940 1601 +661 rpm_getstring 107 112 +5 rpm_getint 148 153 +5 loop_through_files 103 106 +3 fileaction_dobackup 115 113 -2 fileaction_list 5 - -5 rpm_getcount 42 - -42 extract_cpio_gz 161 - -161 rpm_gettags 504 - -504 ------------------------------------------------------------------------------ (add/remove: 0/4 grow/shrink: 4/1 up/down: 674/-714) Total: -40 bytes text data bss dec hex filename 862322 10156 645892 1518370 172b22 busybox.old 862290 10156 645892 1518338 172b02 busybox ------------------------------------------------------------------------ r15555 | aldot | 2006-06-30 14:10:11 +0200 (Fri, 30 Jun 2006) | 22 lines - shrink syslog a little bit, move a big buffer (for 'line') off the bss, fold s emaphore stuff into single caller manually. stats: function old new delta logMessage 395 427 +32 message 1245 1257 +12 opts - 4 +4 small 1 - -1 local_logging 4 - -4 doRemoteLog 4 - -4 circular_logging 4 - -4 syslogd_main 1299 1285 -14 static.res 36 16 -20 .rodata 186650 186586 -64 static.line 1025 - -1025 ------------------------------------------------------------------------------ (add/remove: 1/5 grow/shrink: 2/3 up/down: 48/-1136) Total: -1088 bytes cow@s37:~/src/busybox_scratch$ size sysklogd/syslogd.o{.orig,} text data bss dec hex filename 3723 348 5242 9313 2461 sysklogd/syslogd.o.orig 3697 348 4188 8233 2029 sysklogd/syslogd.o ============================================================================== Overall bloatcheck for the changeset mentioned above: function old new delta rpm_main 953 1608 +655 logMessage 395 427 +32 message 1245 1257 +12 opts - 4 +4 rpm_getstring 107 110 +3 rpm_getint 148 151 +3 loop_through_files 103 104 +1 small 1 - -1 fileaction_dobackup 115 113 -2 z_len 4 - -4 textend 4 - -4 part_nb 4 - -4 local_logging 4 - -4 insize 4 - -4 ifile_size 4 - -4 do_link 4 - -4 doRemoteLog 4 - -4 circular_logging 4 - -4 fileaction_list 5 - -5 new_text 70 60 -10 ipaddr_list_link 33 23 -10 clear_bufs 31 21 -10 syslogd_main 1287 1273 -14 builtin_help 190 176 -14 static.res 36 16 -20 builtin_source 229 199 -30 rpm_getcount 42 - -42 gzip_main 842 786 -56 .rodata 227176 227112 -64 lash_main 609 527 -82 busy_loop 3883 3739 -144 extract_cpio_gz 155 - -155 rpm_gettags 501 - -501 static.line 1025 - -1025 ------------------------------------------------------------------------------ (add/remove: 1/15 grow/shrink: 6/12 up/down: 710/-2221) Total: -1511 bytes
2006-08-20 23:05:13 +05:30
bb_getopt_ulflags(argc, argv, "d:", &line);
if (line)
table = xfopen(line, "r");
if (optind >= argc || (rootdir=argv[optind])==NULL) {
2005-07-18 15:15:35 +05:30
bb_error_msg_and_die("root directory not specified");
}
xchdir(rootdir);
umask(0);
printf("rootdir=%s\n", rootdir);
if (line) {
printf("table='%s'\n", line);
} else {
printf("table=<stdin>\n");
}
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;
linenum++;
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))
{
if (*line=='\0' || *line=='#' || isspace(*line))
continue;
bb_error_msg("line %d invalid: '%s'\n", linenum, line);
ret = EXIT_FAILURE;
continue;
}
if (name[0] == '#') {
continue;
}
gid = (*group) ? get_ug_id(group, bb_xgetgrnam) : getgid();
uid = (*user) ? get_ug_id(user, bb_xgetpwnam) : getuid();
full_name = concat_path_file(rootdir, name);
if (type == 'd') {
bb_make_directory(full_name, mode | S_IFDIR, FILEUTILS_RECUR);
if (chown(full_name, uid, gid) == -1) {
bb_perror_msg("line %d: chown failed for %s", linenum, full_name);
ret = EXIT_FAILURE;
goto loop;
}
if ((mode != -1) && (chmod(full_name, mode) < 0)){
bb_perror_msg("line %d: chmod failed for %s", linenum, full_name);
ret = EXIT_FAILURE;
goto loop;
}
} else if (type == 'f') {
struct stat st;
if ((stat(full_name, &st) < 0 || !S_ISREG(st.st_mode))) {
bb_perror_msg("line %d: regular file '%s' does not exist", linenum, full_name);
ret = EXIT_FAILURE;
goto loop;
}
if (chown(full_name, uid, gid) == -1) {
bb_perror_msg("line %d: chown failed for %s", linenum, full_name);
ret = EXIT_FAILURE;
goto loop;
}
if ((mode != -1) && (chmod(full_name, mode) < 0)){
bb_perror_msg("line %d: chmod failed for %s", linenum, 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 {
2005-07-18 15:15:35 +05:30
bb_error_msg("line %d: unsupported file type %c", linenum, 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) {
2005-07-18 15:15:35 +05:30
bb_perror_msg("line %d: could not create node %s", linenum, full_name_inc);
ret = EXIT_FAILURE;
}
else if (chown(full_name_inc, uid, gid) == -1) {
bb_perror_msg("line %d: chown failed for %s", linenum, full_name_inc);
ret = EXIT_FAILURE;
}
if ((mode != -1) && (chmod(full_name_inc, mode) < 0)){
bb_perror_msg("line %d: chmod failed for %s", linenum, full_name_inc);
ret = EXIT_FAILURE;
}
}
free(full_name_inc);
} else {
rdev = (major << 8) + minor;
if (mknod(full_name, mode, rdev) == -1) {
2005-07-18 15:15:35 +05:30
bb_perror_msg("line %d: could not create node %s", linenum, full_name);
ret = EXIT_FAILURE;
}
else if (chown(full_name, uid, gid) == -1) {
bb_perror_msg("line %d: chown failed for %s", linenum, full_name);
ret = EXIT_FAILURE;
}
if ((mode != -1) && (chmod(full_name, mode) < 0)){
bb_perror_msg("line %d: chmod failed for %s", linenum, full_name);
ret = EXIT_FAILURE;
}
}
}
loop:
free(line);
free(full_name);
}
fclose(table);
return ret;
1999-10-05 21:54:54 +05:30
}
#else
2006-03-24 20:00:05 +05:30
# error makedevs configuration error, either leaf or table must be selected
#endif