diff --git a/Changelog b/Changelog index 095a529bc..4b65b3b27 100644 --- a/Changelog +++ b/Changelog @@ -1,10 +1,18 @@ 0.42 * Made tar creation support in busybox tar optional. + You no longer _have_ to put a "-" in front of tar options. * Made grep and grep -h do the right thing wrt printing the file name (it failed to print files names in many cases). * Fix a namespace aliasing problem wereby if du was built in, the symlink for both du and dutmp would be installed, or then rm was built in, the symlinks for both rm and rmmod would be installed. + * Added a closelog() to init.c after loging -- fix thanks to + Taketoshi Sano + * Rewrote and simplified logger. Added the "-t" option, and made it + behave itself a bit better. + * Optional support contributed by Ben Collins + for the kernel init chroot patch by Werner Almesberger, which + allows init to chroot to a new device, and umount the old one. -Erik Andersen diff --git a/Makefile b/Makefile index 91d4bd1c4..554dd00f5 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ PROG=busybox -VERSION=0.41 +VERSION=0.42 BUILDTIME=$(shell date "+%Y%m%d-%H%M") # Comment out the following to make a debuggable build @@ -33,7 +33,6 @@ ARCH=`uname -m | sed -e 's/i.86/i386/' | sed -e 's/sparc.*/sparc/'` GCCMAJVERSION=$(shell $(CC) --version | sed -n "s/^\([^\.]*\).*/\1/p" ) GCCMINVERSION=$(shell $(CC) --version | sed -n "s/^[^\.]*\.\([^\.]*\)[\.].*/\1/p" ) -GCCEGCS=$(shell $(CC) --version | sed -n "s/.*\(egcs\).*/\1/p" ) GCCSUPPORTSOPTSIZE=$(shell \ if ( test $(GCCMAJVERSION) -eq 2 ) ; then \ @@ -50,26 +49,11 @@ else \ fi; \ fi; ) -GCCISEGCS=$(shell \ -if ( test "x$(GCCEGCS)" == "xegcs" ) ; then \ - echo "true"; \ - else \ - echo "false"; \ - fi; ) - -EGCSEXTREMEFLAGS = -m386 -mcpu=i386 -march=i386 -malign-jumps=1 -malign-loops=1 -malign-functions=1 -GCCEXTREMEFLAGS = -m386 -malign-jumps=1 -malign-loops=1 -malign-functions=1 - -ifeq ($(GCCISEGCS), true) - EXTREMEFLAGS = $(EGCSEXTREMEFLAGS) -else - EXTREMEFLAGS = $(GCCEXTREMEFLAGS) -endif ifeq ($(GCCSUPPORTSOPTSIZE), true) - OPTIMIZATION=-Os $(EXTREMEFLAGS) + OPTIMIZATION=-Os else - OPTIMIZATION=-O2 $(EXTREMEFLAGS) + OPTIMIZATION=-O2 endif # -D_GNU_SOURCE is needed because environ is used in init.c diff --git a/archival/tar.c b/archival/tar.c index 5c407864f..adae6c94c 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -108,9 +108,7 @@ typedef struct { */ static int listFlag; static int extractFlag; -#ifdef BB_FEATURE_TAR_CREATE static int createFlag; -#endif static int verboseFlag; static int tostdoutFlag; @@ -185,9 +183,7 @@ extern int tar_main (int argc, char **argv) errorFlag = FALSE; extractFlag = FALSE; -#ifdef BB_FEATURE_TAR_CREATE createFlag = FALSE; -#endif listFlag = FALSE; verboseFlag = FALSE; tostdoutFlag = FALSE; @@ -199,90 +195,85 @@ extern int tar_main (int argc, char **argv) /* * Parse the options. */ - if (**argv == '-') { + if (**argv == '-') options = (*argv++) + 1; - argc--; - for (; *options; options++) { - switch (*options) { - case 'f': - if (tarName != NULL) { - fprintf (stderr, "Only one 'f' option allowed\n"); + else + options = (*argv++); + argc--; - exit (FALSE); - } - - tarName = *argv++; - argc--; - - break; - - case 't': - listFlag = TRUE; - break; - - case 'x': - extractFlag = TRUE; - break; -#ifdef BB_FEATURE_TAR_CREATE - case 'c': - createFlag = TRUE; - break; -#else - case 'c': - fprintf (stderr, "This version of tar was not compiled with tar creation support.\n" ); - - exit (FALSE); -#endif - - case 'v': - verboseFlag = TRUE; - break; - - case 'O': - tostdoutFlag = TRUE; - break; - - case '-': - usage( tar_usage); - break; - - default: - fprintf (stderr, "Unknown tar flag '%c'\n" - "Try `tar --help' for more information\n", - *options); + for (; *options; options++) { + switch (*options) { + case 'f': + if (tarName != NULL) { + fprintf (stderr, "Only one 'f' option allowed\n"); exit (FALSE); } + + tarName = *argv++; + argc--; + + break; + + case 't': + if (extractFlag == TRUE || createFlag == TRUE ) + goto flagError; + listFlag = TRUE; + break; + + case 'x': + if (listFlag == TRUE || createFlag == TRUE ) + goto flagError; + extractFlag = TRUE; + break; + case 'c': + if (extractFlag == TRUE || listFlag == TRUE) + goto flagError; + createFlag = TRUE; + break; + + case 'v': + verboseFlag = TRUE; + break; + + case 'O': + tostdoutFlag = TRUE; + break; + + case '-': + usage( tar_usage); + break; + + default: + fprintf (stderr, "Unknown tar flag '%c'\n" + "Try `tar --help' for more information\n", + *options); + exit (FALSE); } } - /* - * Validate the options. - */ - if (extractFlag + listFlag -#ifdef BB_FEATURE_TAR_CREATE - + createFlag -#endif - != (TRUE+FALSE+FALSE)) { - fprintf (stderr, - "Exactly one of 'c', 'x' or 't' must be specified\n"); - - exit (FALSE); - } - /* * Do the correct type of action supplying the rest of the * command line arguments as the list of files to process. */ -#ifdef BB_FEATURE_TAR_CREATE - if (createFlag==TRUE) + if (createFlag==TRUE) { +#ifndef BB_FEATURE_TAR_CREATE + fprintf (stderr, "This version of tar was not compiled with tar creation support.\n" ); + exit (FALSE); +#else writeTarFile (argc, argv); - else #endif + } else { readTarFile (argc, argv); - if (errorFlag==TRUE) + } + if (errorFlag==TRUE) { fprintf (stderr, "\n"); + } exit (!errorFlag); + +flagError: + fprintf (stderr, "Exactly one of 'c', 'x' or 't' must be specified\n"); + exit (FALSE); } diff --git a/busybox.def.h b/busybox.def.h index 871b152d3..c56f151db 100644 --- a/busybox.def.h +++ b/busybox.def.h @@ -139,3 +139,10 @@ // Enable support for creation of tar files. //#define BB_FEATURE_TAR_CREATE // +// Allow init to permenently chroot, and umount the old root fs +// just like an initrd does. Requires a kernel patch by Werner Almesberger. +// ftp://icaftp.epfl.ch/pub/people/almesber/misc/umount-root-*.tar.gz +#ifdef BB_MOUNT +#define BB_FEATURE_INIT_CHROOT +#endif +// diff --git a/busybox.spec b/busybox.spec index 73f47e191..03e4feb36 100644 --- a/busybox.spec +++ b/busybox.spec @@ -1,13 +1,13 @@ Name: busybox -Version: 0.41 +Version: 0.42 Release: 1 Group: System/Utilities Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary. Copyright: GPL Packager : Erik Andersen Conflicts: fileutils grep shellutils -Buildroot: /tmp/%{name}-%{version} -Source: %{name}-%{version}.tar.gz +Buildroot: /tmp/%{Name}-%{Version} +Source: %{Name}-%{Version}.tar.gz %Description BusyBox is a suite of "tiny" Unix utilities in a multi-call binary. It @@ -18,7 +18,7 @@ is makes an excellent environment for a "rescue" disk or any small or embedded system. %Prep -%setup -q -n %{name}-%{version} +%setup -q -n %{Name}-%{Version} %Build make diff --git a/examples/busybox.spec b/examples/busybox.spec index 73f47e191..03e4feb36 100644 --- a/examples/busybox.spec +++ b/examples/busybox.spec @@ -1,13 +1,13 @@ Name: busybox -Version: 0.41 +Version: 0.42 Release: 1 Group: System/Utilities Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary. Copyright: GPL Packager : Erik Andersen Conflicts: fileutils grep shellutils -Buildroot: /tmp/%{name}-%{version} -Source: %{name}-%{version}.tar.gz +Buildroot: /tmp/%{Name}-%{Version} +Source: %{Name}-%{Version}.tar.gz %Description BusyBox is a suite of "tiny" Unix utilities in a multi-call binary. It @@ -18,7 +18,7 @@ is makes an excellent environment for a "rescue" disk or any small or embedded system. %Prep -%setup -q -n %{name}-%{version} +%setup -q -n %{Name}-%{Version} %Build make diff --git a/init.c b/init.c index 913436353..b0a85829d 100644 --- a/init.c +++ b/init.c @@ -147,7 +147,9 @@ void message(int device, char *fmt, ...) va_start(arguments, fmt); vsnprintf(msg, sizeof(msg), fmt, arguments); va_end(arguments); + openlog( "init", 0, LOG_DAEMON); syslog(LOG_DAEMON|LOG_NOTICE, msg); + closelog(); } #else @@ -268,7 +270,7 @@ static void console_init() #if #cpu(sparc) /* sparc kernel supports console=tty[ab] parameter which is also * passed to init, so catch it here */ - else if ((s = getenv("console")) != NULL) {*/ + else if ((s = getenv("console")) != NULL) { /* remap tty[ab] to /dev/ttyS[01] */ if (strcmp( s, "ttya" )==0) snprintf(console, sizeof(console)-1, "%s", SERIAL_CON0); @@ -507,7 +509,83 @@ static void reboot_signal(int sig) exit(0); } -#endif +#if defined BB_FEATURE_INIT_CHROOT +static void check_chroot(int sig) +{ + char *argv_init[2] = { "init", NULL, }; + char *envp_init[3] = { "HOME=/", "TERM=linux", NULL, }; + char rootpath[256], *tc; + int fd; + + if ((fd = open("/proc/sys/kernel/init-chroot", O_RDONLY)) == -1) { + message(CONSOLE, "SIGHUP recived, but could not open proc file\r\n"); + sleep(2); + return; + } + if (read(fd, rootpath, sizeof(rootpath)) == -1) { + message(CONSOLE, "SIGHUP recived, but could not read proc file\r\n"); + sleep(2); + return; + } + close(fd); + + if (rootpath[0] == '\0') { + message(CONSOLE, "SIGHUP recived, but new root is not valid: %s\r\n", + rootpath); + sleep(2); + return; + } + + tc = strrchr(rootpath, '\n'); + *tc = '\0'; + + /* Ok, making it this far means we commit */ + message(CONSOLE, "Please stand by, changing root to `%s'.\r\n", rootpath); + + /* kill all other programs first */ + message(CONSOLE, "Sending SIGTERM to all processes.\r\n"); + kill(-1, SIGTERM); + sleep(2); + sync(); + + message(CONSOLE, "Sending SIGKILL to all processes.\r\n"); + kill(-1, SIGKILL); + sleep(2); + sync(); + + /* ok, we don't need /proc anymore. we also assume that the signaling + * process left the rest of the filesystems alone for us */ + umount("/proc"); + + /* Ok, now we chroot. Hopefully we only have two things mounted, the + * new chroot'd mount point, and the old "/" mount. s, + * we go ahead and unmount the old "/". This should trigger the kernel + * to set things up the Right Way(tm). */ + + if (!chroot(rootpath)) + umount("/dev/root"); + + /* If the chroot fails, we are already too far to turn back, so we + * continue and hope that executing init below will revive the system */ + + /* close all of our descriptors and open new ones */ + close(0); + close(1); + close(2); + open("/dev/console", O_RDWR, 0); + dup(0); + dup(0); + + message(CONSOLE, "Executing real init...\r\n"); + /* execute init in the (hopefully) new root */ + execve("/sbin/init",argv_init,envp_init); + + message(CONSOLE, "ERROR: Could not exec new init. Hit ctrl+alt+delete to reboot.\r\n"); + return; +} +#endif /* BB_FEATURE_INIT_CHROOT */ + +#endif /* ! DEBUG_INIT */ void new_initAction (initActionEnum action, char* process, char* cons) @@ -516,10 +594,10 @@ void new_initAction (initActionEnum action, /* If BusyBox detects that a serial console is in use, * then entries containing non-empty id fields will _not_ be run. + * The exception to this rule is the null device. */ - if (secondConsole == NULL && *cons != '\0') { + if (secondConsole == NULL && (*cons != '\0' || strncmp(cons, "null", 4))) return; - } newAction = calloc ((size_t)(1), sizeof(initAction)); if (!newAction) { @@ -662,7 +740,7 @@ extern int init_main(int argc, char **argv) int status; #ifndef DEBUG_INIT - /* Expect to be PID 1 iff we are run as init (not linuxrc) */ + /* Expect to be PID 1 if we are run as init (not linuxrc) */ if (getpid() != 1 && strstr(argv[0], "init")!=NULL ) { usage( "init\n\nInit is the parent of all processes.\n\n" "This version of init is designed to be run only by the kernel\n"); @@ -676,6 +754,9 @@ extern int init_main(int argc, char **argv) signal(SIGUSR2, reboot_signal); signal(SIGINT, reboot_signal); signal(SIGTERM, reboot_signal); +#if defined BB_FEATURE_INIT_CHROOT + signal(SIGHUP, check_chroot); +#endif /* Turn off rebooting via CTL-ALT-DEL -- we get a * SIGINT on CAD so we can shut things down gracefully... */ diff --git a/init/init.c b/init/init.c index 913436353..b0a85829d 100644 --- a/init/init.c +++ b/init/init.c @@ -147,7 +147,9 @@ void message(int device, char *fmt, ...) va_start(arguments, fmt); vsnprintf(msg, sizeof(msg), fmt, arguments); va_end(arguments); + openlog( "init", 0, LOG_DAEMON); syslog(LOG_DAEMON|LOG_NOTICE, msg); + closelog(); } #else @@ -268,7 +270,7 @@ static void console_init() #if #cpu(sparc) /* sparc kernel supports console=tty[ab] parameter which is also * passed to init, so catch it here */ - else if ((s = getenv("console")) != NULL) {*/ + else if ((s = getenv("console")) != NULL) { /* remap tty[ab] to /dev/ttyS[01] */ if (strcmp( s, "ttya" )==0) snprintf(console, sizeof(console)-1, "%s", SERIAL_CON0); @@ -507,7 +509,83 @@ static void reboot_signal(int sig) exit(0); } -#endif +#if defined BB_FEATURE_INIT_CHROOT +static void check_chroot(int sig) +{ + char *argv_init[2] = { "init", NULL, }; + char *envp_init[3] = { "HOME=/", "TERM=linux", NULL, }; + char rootpath[256], *tc; + int fd; + + if ((fd = open("/proc/sys/kernel/init-chroot", O_RDONLY)) == -1) { + message(CONSOLE, "SIGHUP recived, but could not open proc file\r\n"); + sleep(2); + return; + } + if (read(fd, rootpath, sizeof(rootpath)) == -1) { + message(CONSOLE, "SIGHUP recived, but could not read proc file\r\n"); + sleep(2); + return; + } + close(fd); + + if (rootpath[0] == '\0') { + message(CONSOLE, "SIGHUP recived, but new root is not valid: %s\r\n", + rootpath); + sleep(2); + return; + } + + tc = strrchr(rootpath, '\n'); + *tc = '\0'; + + /* Ok, making it this far means we commit */ + message(CONSOLE, "Please stand by, changing root to `%s'.\r\n", rootpath); + + /* kill all other programs first */ + message(CONSOLE, "Sending SIGTERM to all processes.\r\n"); + kill(-1, SIGTERM); + sleep(2); + sync(); + + message(CONSOLE, "Sending SIGKILL to all processes.\r\n"); + kill(-1, SIGKILL); + sleep(2); + sync(); + + /* ok, we don't need /proc anymore. we also assume that the signaling + * process left the rest of the filesystems alone for us */ + umount("/proc"); + + /* Ok, now we chroot. Hopefully we only have two things mounted, the + * new chroot'd mount point, and the old "/" mount. s, + * we go ahead and unmount the old "/". This should trigger the kernel + * to set things up the Right Way(tm). */ + + if (!chroot(rootpath)) + umount("/dev/root"); + + /* If the chroot fails, we are already too far to turn back, so we + * continue and hope that executing init below will revive the system */ + + /* close all of our descriptors and open new ones */ + close(0); + close(1); + close(2); + open("/dev/console", O_RDWR, 0); + dup(0); + dup(0); + + message(CONSOLE, "Executing real init...\r\n"); + /* execute init in the (hopefully) new root */ + execve("/sbin/init",argv_init,envp_init); + + message(CONSOLE, "ERROR: Could not exec new init. Hit ctrl+alt+delete to reboot.\r\n"); + return; +} +#endif /* BB_FEATURE_INIT_CHROOT */ + +#endif /* ! DEBUG_INIT */ void new_initAction (initActionEnum action, char* process, char* cons) @@ -516,10 +594,10 @@ void new_initAction (initActionEnum action, /* If BusyBox detects that a serial console is in use, * then entries containing non-empty id fields will _not_ be run. + * The exception to this rule is the null device. */ - if (secondConsole == NULL && *cons != '\0') { + if (secondConsole == NULL && (*cons != '\0' || strncmp(cons, "null", 4))) return; - } newAction = calloc ((size_t)(1), sizeof(initAction)); if (!newAction) { @@ -662,7 +740,7 @@ extern int init_main(int argc, char **argv) int status; #ifndef DEBUG_INIT - /* Expect to be PID 1 iff we are run as init (not linuxrc) */ + /* Expect to be PID 1 if we are run as init (not linuxrc) */ if (getpid() != 1 && strstr(argv[0], "init")!=NULL ) { usage( "init\n\nInit is the parent of all processes.\n\n" "This version of init is designed to be run only by the kernel\n"); @@ -676,6 +754,9 @@ extern int init_main(int argc, char **argv) signal(SIGUSR2, reboot_signal); signal(SIGINT, reboot_signal); signal(SIGTERM, reboot_signal); +#if defined BB_FEATURE_INIT_CHROOT + signal(SIGHUP, check_chroot); +#endif /* Turn off rebooting via CTL-ALT-DEL -- we get a * SIGINT on CAD so we can shut things down gracefully... */ diff --git a/logger.c b/logger.c index 7aada5dbc..d7ae0233e 100644 --- a/logger.c +++ b/logger.c @@ -22,16 +22,11 @@ #include "internal.h" #include -#include -#include #include -#include #include #include #include -#include #include -#include #if !defined BB_SYSLOGD @@ -56,6 +51,7 @@ static const char logger_usage[] = "Write MESSAGE to the system log. If MESSAGE is '-', log stdin.\n\n" "Options:\n" "\t-s\tLog to stderr as well as the system log.\n" + "\t-t\tLog using the specified tag (defaults to user name).\n" "\t-p\tEnter the message with the specified priority.\n" "\t\tThis may be numerical or a ``facility.level'' pair.\n"; @@ -116,14 +112,14 @@ pencode(char* s) extern int logger_main(int argc, char **argv) { - struct sockaddr_un sunx; - int fd, pri = LOG_USER|LOG_NOTICE; + int pri = LOG_USER|LOG_NOTICE; + int option = 0; int fromStdinFlag=FALSE; - int toStdErrFlag=FALSE; int stopLookingAtMeLikeThat=FALSE; - char *message, buf[1024], buf1[1024]; - time_t now; - size_t addrLength; + char *message, buf[1024], name[128]; + + /* Fill out the name string early (may be overwritten later */ + my_getpwuid(name, geteuid()); /* Parse any options */ while (--argc > 0 && **(++argv) == '-') { @@ -134,7 +130,7 @@ extern int logger_main(int argc, char **argv) while (*(++(*argv)) && stopLookingAtMeLikeThat==FALSE) { switch (**argv) { case 's': - toStdErrFlag = TRUE; + option |= LOG_PERROR; break; case 'p': if (--argc == 0) { @@ -143,6 +139,13 @@ extern int logger_main(int argc, char **argv) pri = pencode(*(++argv)); stopLookingAtMeLikeThat=TRUE; break; + case 't': + if (--argc == 0) { + usage(logger_usage); + } + strncpy(name, *(++argv), sizeof(name)); + stopLookingAtMeLikeThat=TRUE; + break; default: usage(logger_usage); } @@ -152,10 +155,10 @@ extern int logger_main(int argc, char **argv) if (fromStdinFlag==TRUE) { /* read from stdin */ int c, i=0; - while ((c = getc(stdin)) != EOF && i=1) { message=*argv; @@ -165,30 +168,10 @@ extern int logger_main(int argc, char **argv) } } - memset(&sunx, 0, sizeof(sunx)); - sunx.sun_family = AF_UNIX; /* Unix domain socket */ - strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path)); - if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0 ) { - perror("Couldn't obtain descriptor for socket " _PATH_LOG); - exit( FALSE); - } + openlog( name, option, (pri | LOG_FACMASK)); + syslog( pri, message); + closelog(); - addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path); - - if (connect(fd, (struct sockaddr *) &sunx, addrLength)) { - perror("Could not connect to socket " _PATH_LOG); - exit( FALSE); - } - - time(&now); - snprintf (buf, sizeof(buf), "<%d>%.15s %s", pri, ctime(&now)+4, message); - - if (toStdErrFlag==TRUE) - fprintf(stderr, "%s\n", buf); - - write( fd, buf, strlen(buf)+1); - - close(fd); exit( TRUE); } diff --git a/sysklogd/logger.c b/sysklogd/logger.c index 7aada5dbc..d7ae0233e 100644 --- a/sysklogd/logger.c +++ b/sysklogd/logger.c @@ -22,16 +22,11 @@ #include "internal.h" #include -#include -#include #include -#include #include #include #include -#include #include -#include #if !defined BB_SYSLOGD @@ -56,6 +51,7 @@ static const char logger_usage[] = "Write MESSAGE to the system log. If MESSAGE is '-', log stdin.\n\n" "Options:\n" "\t-s\tLog to stderr as well as the system log.\n" + "\t-t\tLog using the specified tag (defaults to user name).\n" "\t-p\tEnter the message with the specified priority.\n" "\t\tThis may be numerical or a ``facility.level'' pair.\n"; @@ -116,14 +112,14 @@ pencode(char* s) extern int logger_main(int argc, char **argv) { - struct sockaddr_un sunx; - int fd, pri = LOG_USER|LOG_NOTICE; + int pri = LOG_USER|LOG_NOTICE; + int option = 0; int fromStdinFlag=FALSE; - int toStdErrFlag=FALSE; int stopLookingAtMeLikeThat=FALSE; - char *message, buf[1024], buf1[1024]; - time_t now; - size_t addrLength; + char *message, buf[1024], name[128]; + + /* Fill out the name string early (may be overwritten later */ + my_getpwuid(name, geteuid()); /* Parse any options */ while (--argc > 0 && **(++argv) == '-') { @@ -134,7 +130,7 @@ extern int logger_main(int argc, char **argv) while (*(++(*argv)) && stopLookingAtMeLikeThat==FALSE) { switch (**argv) { case 's': - toStdErrFlag = TRUE; + option |= LOG_PERROR; break; case 'p': if (--argc == 0) { @@ -143,6 +139,13 @@ extern int logger_main(int argc, char **argv) pri = pencode(*(++argv)); stopLookingAtMeLikeThat=TRUE; break; + case 't': + if (--argc == 0) { + usage(logger_usage); + } + strncpy(name, *(++argv), sizeof(name)); + stopLookingAtMeLikeThat=TRUE; + break; default: usage(logger_usage); } @@ -152,10 +155,10 @@ extern int logger_main(int argc, char **argv) if (fromStdinFlag==TRUE) { /* read from stdin */ int c, i=0; - while ((c = getc(stdin)) != EOF && i=1) { message=*argv; @@ -165,30 +168,10 @@ extern int logger_main(int argc, char **argv) } } - memset(&sunx, 0, sizeof(sunx)); - sunx.sun_family = AF_UNIX; /* Unix domain socket */ - strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path)); - if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0 ) { - perror("Couldn't obtain descriptor for socket " _PATH_LOG); - exit( FALSE); - } + openlog( name, option, (pri | LOG_FACMASK)); + syslog( pri, message); + closelog(); - addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path); - - if (connect(fd, (struct sockaddr *) &sunx, addrLength)) { - perror("Could not connect to socket " _PATH_LOG); - exit( FALSE); - } - - time(&now); - snprintf (buf, sizeof(buf), "<%d>%.15s %s", pri, ctime(&now)+4, message); - - if (toStdErrFlag==TRUE) - fprintf(stderr, "%s\n", buf); - - write( fd, buf, strlen(buf)+1); - - close(fd); exit( TRUE); } diff --git a/tar.c b/tar.c index 5c407864f..adae6c94c 100644 --- a/tar.c +++ b/tar.c @@ -108,9 +108,7 @@ typedef struct { */ static int listFlag; static int extractFlag; -#ifdef BB_FEATURE_TAR_CREATE static int createFlag; -#endif static int verboseFlag; static int tostdoutFlag; @@ -185,9 +183,7 @@ extern int tar_main (int argc, char **argv) errorFlag = FALSE; extractFlag = FALSE; -#ifdef BB_FEATURE_TAR_CREATE createFlag = FALSE; -#endif listFlag = FALSE; verboseFlag = FALSE; tostdoutFlag = FALSE; @@ -199,90 +195,85 @@ extern int tar_main (int argc, char **argv) /* * Parse the options. */ - if (**argv == '-') { + if (**argv == '-') options = (*argv++) + 1; - argc--; - for (; *options; options++) { - switch (*options) { - case 'f': - if (tarName != NULL) { - fprintf (stderr, "Only one 'f' option allowed\n"); + else + options = (*argv++); + argc--; - exit (FALSE); - } - - tarName = *argv++; - argc--; - - break; - - case 't': - listFlag = TRUE; - break; - - case 'x': - extractFlag = TRUE; - break; -#ifdef BB_FEATURE_TAR_CREATE - case 'c': - createFlag = TRUE; - break; -#else - case 'c': - fprintf (stderr, "This version of tar was not compiled with tar creation support.\n" ); - - exit (FALSE); -#endif - - case 'v': - verboseFlag = TRUE; - break; - - case 'O': - tostdoutFlag = TRUE; - break; - - case '-': - usage( tar_usage); - break; - - default: - fprintf (stderr, "Unknown tar flag '%c'\n" - "Try `tar --help' for more information\n", - *options); + for (; *options; options++) { + switch (*options) { + case 'f': + if (tarName != NULL) { + fprintf (stderr, "Only one 'f' option allowed\n"); exit (FALSE); } + + tarName = *argv++; + argc--; + + break; + + case 't': + if (extractFlag == TRUE || createFlag == TRUE ) + goto flagError; + listFlag = TRUE; + break; + + case 'x': + if (listFlag == TRUE || createFlag == TRUE ) + goto flagError; + extractFlag = TRUE; + break; + case 'c': + if (extractFlag == TRUE || listFlag == TRUE) + goto flagError; + createFlag = TRUE; + break; + + case 'v': + verboseFlag = TRUE; + break; + + case 'O': + tostdoutFlag = TRUE; + break; + + case '-': + usage( tar_usage); + break; + + default: + fprintf (stderr, "Unknown tar flag '%c'\n" + "Try `tar --help' for more information\n", + *options); + exit (FALSE); } } - /* - * Validate the options. - */ - if (extractFlag + listFlag -#ifdef BB_FEATURE_TAR_CREATE - + createFlag -#endif - != (TRUE+FALSE+FALSE)) { - fprintf (stderr, - "Exactly one of 'c', 'x' or 't' must be specified\n"); - - exit (FALSE); - } - /* * Do the correct type of action supplying the rest of the * command line arguments as the list of files to process. */ -#ifdef BB_FEATURE_TAR_CREATE - if (createFlag==TRUE) + if (createFlag==TRUE) { +#ifndef BB_FEATURE_TAR_CREATE + fprintf (stderr, "This version of tar was not compiled with tar creation support.\n" ); + exit (FALSE); +#else writeTarFile (argc, argv); - else #endif + } else { readTarFile (argc, argv); - if (errorFlag==TRUE) + } + if (errorFlag==TRUE) { fprintf (stderr, "\n"); + } exit (!errorFlag); + +flagError: + fprintf (stderr, "Exactly one of 'c', 'x' or 't' must be specified\n"); + exit (FALSE); }