2000-02-08 19:58:47 +00:00
|
|
|
/* vi: set sw=4 ts=4: */
|
2006-04-12 18:39:58 +00:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
*/
|
2004-06-05 07:58:18 +00:00
|
|
|
|
2006-06-03 19:49:21 +00:00
|
|
|
#include "busybox.h"
|
2004-06-05 07:58:18 +00:00
|
|
|
|
2005-06-09 10:16:02 +00:00
|
|
|
#ifdef CONFIG_FEATURE_MAKEDEVS_LEAF
|
2000-02-08 19:58:47 +00:00
|
|
|
int makedevs_main(int argc, char **argv)
|
1999-10-05 16:24:54 +00:00
|
|
|
{
|
2002-06-08 12:44:17 +00:00
|
|
|
mode_t mode;
|
|
|
|
char *basedev, *type, *nodname, buf[255];
|
2004-07-26 09:11:12 +00:00
|
|
|
int Smajor, Sminor, S, E;
|
1999-10-05 16:24:54 +00:00
|
|
|
|
2000-04-15 16:34:54 +00:00
|
|
|
if (argc < 7 || *argv[1]=='-')
|
2003-03-19 09:13:01 +00:00
|
|
|
bb_show_usage();
|
2000-04-15 16:34:54 +00:00
|
|
|
|
2002-04-13 14:26:44 +00:00
|
|
|
basedev = argv[1];
|
|
|
|
type = argv[2];
|
2004-07-30 17:48:21 +00:00
|
|
|
Smajor = atoi(argv[3]);
|
|
|
|
Sminor = atoi(argv[4]);
|
2002-04-13 14:26:44 +00:00
|
|
|
S = atoi(argv[5]);
|
|
|
|
E = atoi(argv[6]);
|
2002-06-08 12:44:17 +00:00
|
|
|
nodname = argc == 8 ? basedev : buf;
|
|
|
|
|
|
|
|
mode = 0660;
|
2002-04-13 14:26:44 +00:00
|
|
|
|
1999-10-05 16:24:54 +00:00
|
|
|
switch (type[0]) {
|
2000-02-08 19:58:47 +00:00
|
|
|
case 'c':
|
2002-06-08 12:44:17 +00:00
|
|
|
mode |= S_IFCHR;
|
2000-02-08 19:58:47 +00:00
|
|
|
break;
|
|
|
|
case 'b':
|
2002-06-08 12:44:17 +00:00
|
|
|
mode |= S_IFBLK;
|
2000-02-08 19:58:47 +00:00
|
|
|
break;
|
|
|
|
case 'f':
|
2002-06-08 12:44:17 +00:00
|
|
|
mode |= S_IFIFO;
|
2000-02-08 19:58:47 +00:00
|
|
|
break;
|
|
|
|
default:
|
2003-03-19 09:13:01 +00:00
|
|
|
bb_show_usage();
|
2000-02-08 19:58:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
while (S <= E) {
|
2002-06-08 12:44:17 +00:00
|
|
|
int sz;
|
2000-02-08 19:58:47 +00:00
|
|
|
|
2002-06-08 12:44:17 +00:00
|
|
|
sz = snprintf(buf, sizeof(buf), "%s%d", basedev, S);
|
|
|
|
if(sz<0 || sz>=sizeof(buf)) /* libc different */
|
2003-03-19 09:13:01 +00:00
|
|
|
bb_error_msg_and_die("%s too large", basedev);
|
2000-02-08 19:58:47 +00:00
|
|
|
|
2002-06-08 12:44:17 +00:00
|
|
|
/* if mode != S_IFCHR and != S_IFBLK third param in mknod() ignored */
|
2000-02-08 19:58:47 +00:00
|
|
|
|
2004-07-30 14:36:37 +00:00
|
|
|
if (mknod(nodname, mode, makedev(Smajor, Sminor)))
|
2003-03-19 09:13:01 +00:00
|
|
|
bb_error_msg("Failed to create: %s", nodname);
|
2000-02-08 19:58:47 +00:00
|
|
|
|
2002-06-08 12:44:17 +00:00
|
|
|
if (nodname == basedev) /* ex. /dev/hda - to /dev/hda1 ... */
|
|
|
|
nodname = buf;
|
2000-02-08 19:58:47 +00:00
|
|
|
S++;
|
|
|
|
Sminor++;
|
1999-10-05 16:24:54 +00:00
|
|
|
}
|
|
|
|
|
2000-02-08 19:58:47 +00:00
|
|
|
return 0;
|
1999-10-05 16:24:54 +00:00
|
|
|
}
|
|
|
|
|
2005-06-09 10:16:02 +00:00
|
|
|
#elif defined CONFIG_FEATURE_MAKEDEVS_TABLE
|
|
|
|
|
2005-10-28 09:24:33 +00:00
|
|
|
/* Licensed under the GPL v2 or later, see the file LICENSE in this tarball. */
|
2005-06-09 10:16:02 +00:00
|
|
|
|
2006-03-06 20:47:33 +00:00
|
|
|
int makedevs_main(int argc, char **argv)
|
2005-06-09 10:16:02 +00:00
|
|
|
{
|
2005-07-18 09:28:36 +00:00
|
|
|
FILE *table = stdin;
|
|
|
|
char *rootdir = NULL;
|
|
|
|
char *line = NULL;
|
|
|
|
int linenum = 0;
|
2005-06-09 10:16:02 +00:00
|
|
|
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 17:35:13 +00:00
|
|
|
bb_getopt_ulflags(argc, argv, "d:", &line);
|
2005-10-28 09:24:33 +00:00
|
|
|
if (line)
|
2006-08-03 15:41:12 +00:00
|
|
|
table = xfopen(line, "r");
|
2005-06-09 10:16:02 +00:00
|
|
|
|
2005-07-18 09:28:36 +00:00
|
|
|
if (optind >= argc || (rootdir=argv[optind])==NULL) {
|
2005-07-18 09:45:35 +00:00
|
|
|
bb_error_msg_and_die("root directory not specified");
|
2005-06-09 10:16:02 +00:00
|
|
|
}
|
|
|
|
|
2006-08-03 15:41:12 +00:00
|
|
|
xchdir(rootdir);
|
2005-06-09 10:16:02 +00:00
|
|
|
|
|
|
|
umask(0);
|
|
|
|
|
2005-07-18 09:28:36 +00:00
|
|
|
printf("rootdir=%s\n", rootdir);
|
|
|
|
if (line) {
|
|
|
|
printf("table='%s'\n", line);
|
|
|
|
} else {
|
|
|
|
printf("table=<stdin>\n");
|
|
|
|
}
|
|
|
|
|
2005-06-09 10:16:02 +00:00
|
|
|
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;
|
|
|
|
|
2005-07-18 09:28:36 +00:00
|
|
|
linenum++;
|
|
|
|
|
2005-06-09 10:16:02 +00:00
|
|
|
if ((2 > sscanf(line, "%40s %c %o %40s %40s %u %u %u %u %u", name,
|
2005-07-18 09:28:36 +00:00
|
|
|
&type, &mode, user, group, &major,
|
|
|
|
&minor, &start, &increment, &count)) ||
|
|
|
|
((major | minor | start | count | increment) > 255))
|
|
|
|
{
|
|
|
|
if (*line=='\0' || *line=='#' || isspace(*line))
|
|
|
|
continue;
|
2006-09-06 19:02:46 +00:00
|
|
|
bb_error_msg("line %d invalid: '%s'", linenum, line);
|
2005-06-09 10:16:02 +00:00
|
|
|
ret = EXIT_FAILURE;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (name[0] == '#') {
|
|
|
|
continue;
|
|
|
|
}
|
2005-12-21 15:07:30 +00:00
|
|
|
|
|
|
|
gid = (*group) ? get_ug_id(group, bb_xgetgrnam) : getgid();
|
|
|
|
uid = (*user) ? get_ug_id(user, bb_xgetpwnam) : getuid();
|
2005-06-09 10:16:02 +00:00
|
|
|
full_name = concat_path_file(rootdir, name);
|
|
|
|
|
|
|
|
if (type == 'd') {
|
2005-07-18 09:28:36 +00:00
|
|
|
bb_make_directory(full_name, mode | S_IFDIR, FILEUTILS_RECUR);
|
2005-06-09 10:16:02 +00:00
|
|
|
if (chown(full_name, uid, gid) == -1) {
|
2005-07-18 09:28:36 +00:00
|
|
|
bb_perror_msg("line %d: chown failed for %s", linenum, full_name);
|
2005-06-09 10:16:02 +00:00
|
|
|
ret = EXIT_FAILURE;
|
|
|
|
goto loop;
|
|
|
|
}
|
2005-07-18 22:40:59 +00:00
|
|
|
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
|
|
|
|
{
|
2005-06-09 10:16:02 +00:00
|
|
|
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 09:45:35 +00:00
|
|
|
bb_error_msg("line %d: unsupported file type %c", linenum, type);
|
2005-06-09 10:16:02 +00:00
|
|
|
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 09:45:35 +00:00
|
|
|
bb_perror_msg("line %d: could not create node %s", linenum, full_name_inc);
|
2005-06-09 10:16:02 +00:00
|
|
|
ret = EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
else if (chown(full_name_inc, uid, gid) == -1) {
|
2005-07-18 09:28:36 +00:00
|
|
|
bb_perror_msg("line %d: chown failed for %s", linenum, full_name_inc);
|
2005-06-09 10:16:02 +00:00
|
|
|
ret = EXIT_FAILURE;
|
|
|
|
}
|
2005-07-18 22:40:59 +00:00
|
|
|
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;
|
|
|
|
}
|
2005-06-09 10:16:02 +00:00
|
|
|
}
|
|
|
|
free(full_name_inc);
|
|
|
|
} else {
|
|
|
|
rdev = (major << 8) + minor;
|
|
|
|
if (mknod(full_name, mode, rdev) == -1) {
|
2005-07-18 09:45:35 +00:00
|
|
|
bb_perror_msg("line %d: could not create node %s", linenum, full_name);
|
2005-06-09 10:16:02 +00:00
|
|
|
ret = EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
else if (chown(full_name, uid, gid) == -1) {
|
2005-07-18 09:28:36 +00:00
|
|
|
bb_perror_msg("line %d: chown failed for %s", linenum, full_name);
|
2005-06-09 10:16:02 +00:00
|
|
|
ret = EXIT_FAILURE;
|
|
|
|
}
|
2005-07-18 22:40:59 +00:00
|
|
|
if ((mode != -1) && (chmod(full_name, mode) < 0)){
|
|
|
|
bb_perror_msg("line %d: chmod failed for %s", linenum, full_name);
|
|
|
|
ret = EXIT_FAILURE;
|
|
|
|
}
|
2005-06-09 10:16:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
loop:
|
|
|
|
free(line);
|
|
|
|
free(full_name);
|
|
|
|
}
|
|
|
|
fclose(table);
|
|
|
|
|
2006-04-24 17:41:29 +00:00
|
|
|
return ret;
|
1999-10-05 16:24:54 +00:00
|
|
|
}
|
2005-07-18 09:28:36 +00:00
|
|
|
|
2005-06-09 10:16:02 +00:00
|
|
|
#else
|
2006-03-24 14:30:05 +00:00
|
|
|
# error makedevs configuration error, either leaf or table must be selected
|
2005-06-09 10:16:02 +00:00
|
|
|
#endif
|