Some busybox updates. You no longer _have_ to put a "-" in front of tar

options, logger is better behaved and has a "-t" option now.  init now supports
the kernel chroot patch, so you can chroot to a new device and umount the old
root.
 -Erik
This commit is contained in:
Erik Andersen 2000-01-23 01:34:05 +00:00
parent f4acea8cf5
commit de552874d2
11 changed files with 364 additions and 255 deletions

View File

@ -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 <kgh12351@nifty.ne.jp>
* Rewrote and simplified logger. Added the "-t" option, and made it
behave itself a bit better.
* Optional support contributed by Ben Collins <bcollins@debian.org>
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

View File

@ -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

View File

@ -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,9 +195,12 @@ extern int tar_main (int argc, char **argv)
/*
* Parse the options.
*/
if (**argv == '-') {
if (**argv == '-')
options = (*argv++) + 1;
else
options = (*argv++);
argc--;
for (; *options; options++) {
switch (*options) {
case 'f':
@ -217,22 +216,21 @@ extern int tar_main (int argc, char **argv)
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;
#ifdef BB_FEATURE_TAR_CREATE
case 'c':
if (extractFlag == TRUE || listFlag == TRUE)
goto flagError;
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;
@ -250,39 +248,32 @@ extern int tar_main (int argc, char **argv)
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);
}

View File

@ -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
//

View File

@ -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 <andersen@lineo.com>
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

View File

@ -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 <andersen@lineo.com>
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

91
init.c
View File

@ -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... */

View File

@ -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... */

View File

@ -22,16 +22,11 @@
#include "internal.h"
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <ctype.h>
#include <netdb.h>
#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<sizeof(buf1)) {
buf1[i++]=c;
while ((c = getc(stdin)) != EOF && i<sizeof(buf)) {
buf[i++]=c;
}
message=buf1;
message=buf;
} else {
if (argc>=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);
}

View File

@ -22,16 +22,11 @@
#include "internal.h"
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <ctype.h>
#include <netdb.h>
#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<sizeof(buf1)) {
buf1[i++]=c;
while ((c = getc(stdin)) != EOF && i<sizeof(buf)) {
buf[i++]=c;
}
message=buf1;
message=buf;
} else {
if (argc>=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);
}

55
tar.c
View File

@ -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,9 +195,12 @@ extern int tar_main (int argc, char **argv)
/*
* Parse the options.
*/
if (**argv == '-') {
if (**argv == '-')
options = (*argv++) + 1;
else
options = (*argv++);
argc--;
for (; *options; options++) {
switch (*options) {
case 'f':
@ -217,22 +216,21 @@ extern int tar_main (int argc, char **argv)
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;
#ifdef BB_FEATURE_TAR_CREATE
case 'c':
if (extractFlag == TRUE || listFlag == TRUE)
goto flagError;
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;
@ -250,39 +248,32 @@ extern int tar_main (int argc, char **argv)
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);
}