mirror of
https://github.com/sheumann/hush.git
synced 2024-12-26 10:32:02 +00:00
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:
parent
f4acea8cf5
commit
de552874d2
@ -1,10 +1,18 @@
|
|||||||
0.42
|
0.42
|
||||||
* Made tar creation support in busybox tar optional.
|
* 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
|
* Made grep and grep -h do the right thing wrt printing
|
||||||
the file name (it failed to print files names in many cases).
|
the file name (it failed to print files names in many cases).
|
||||||
* Fix a namespace aliasing problem wereby if du was built in, the
|
* 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
|
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.
|
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
|
-Erik Andersen
|
||||||
|
22
Makefile
22
Makefile
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
|
|
||||||
PROG=busybox
|
PROG=busybox
|
||||||
VERSION=0.41
|
VERSION=0.42
|
||||||
BUILDTIME=$(shell date "+%Y%m%d-%H%M")
|
BUILDTIME=$(shell date "+%Y%m%d-%H%M")
|
||||||
|
|
||||||
# Comment out the following to make a debuggable build
|
# 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" )
|
GCCMAJVERSION=$(shell $(CC) --version | sed -n "s/^\([^\.]*\).*/\1/p" )
|
||||||
GCCMINVERSION=$(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 \
|
GCCSUPPORTSOPTSIZE=$(shell \
|
||||||
if ( test $(GCCMAJVERSION) -eq 2 ) ; then \
|
if ( test $(GCCMAJVERSION) -eq 2 ) ; then \
|
||||||
@ -50,26 +49,11 @@ else \
|
|||||||
fi; \
|
fi; \
|
||||||
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)
|
ifeq ($(GCCSUPPORTSOPTSIZE), true)
|
||||||
OPTIMIZATION=-Os $(EXTREMEFLAGS)
|
OPTIMIZATION=-Os
|
||||||
else
|
else
|
||||||
OPTIMIZATION=-O2 $(EXTREMEFLAGS)
|
OPTIMIZATION=-O2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# -D_GNU_SOURCE is needed because environ is used in init.c
|
# -D_GNU_SOURCE is needed because environ is used in init.c
|
||||||
|
133
archival/tar.c
133
archival/tar.c
@ -108,9 +108,7 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
static int listFlag;
|
static int listFlag;
|
||||||
static int extractFlag;
|
static int extractFlag;
|
||||||
#ifdef BB_FEATURE_TAR_CREATE
|
|
||||||
static int createFlag;
|
static int createFlag;
|
||||||
#endif
|
|
||||||
static int verboseFlag;
|
static int verboseFlag;
|
||||||
static int tostdoutFlag;
|
static int tostdoutFlag;
|
||||||
|
|
||||||
@ -185,9 +183,7 @@ extern int tar_main (int argc, char **argv)
|
|||||||
|
|
||||||
errorFlag = FALSE;
|
errorFlag = FALSE;
|
||||||
extractFlag = FALSE;
|
extractFlag = FALSE;
|
||||||
#ifdef BB_FEATURE_TAR_CREATE
|
|
||||||
createFlag = FALSE;
|
createFlag = FALSE;
|
||||||
#endif
|
|
||||||
listFlag = FALSE;
|
listFlag = FALSE;
|
||||||
verboseFlag = FALSE;
|
verboseFlag = FALSE;
|
||||||
tostdoutFlag = FALSE;
|
tostdoutFlag = FALSE;
|
||||||
@ -199,90 +195,85 @@ extern int tar_main (int argc, char **argv)
|
|||||||
/*
|
/*
|
||||||
* Parse the options.
|
* Parse the options.
|
||||||
*/
|
*/
|
||||||
if (**argv == '-') {
|
if (**argv == '-')
|
||||||
options = (*argv++) + 1;
|
options = (*argv++) + 1;
|
||||||
argc--;
|
else
|
||||||
for (; *options; options++) {
|
options = (*argv++);
|
||||||
switch (*options) {
|
argc--;
|
||||||
case 'f':
|
|
||||||
if (tarName != NULL) {
|
|
||||||
fprintf (stderr, "Only one 'f' option allowed\n");
|
|
||||||
|
|
||||||
exit (FALSE);
|
for (; *options; options++) {
|
||||||
}
|
switch (*options) {
|
||||||
|
case 'f':
|
||||||
tarName = *argv++;
|
if (tarName != NULL) {
|
||||||
argc--;
|
fprintf (stderr, "Only one 'f' option allowed\n");
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
exit (FALSE);
|
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
|
* Do the correct type of action supplying the rest of the
|
||||||
* command line arguments as the list of files to process.
|
* 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);
|
writeTarFile (argc, argv);
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
|
} else {
|
||||||
readTarFile (argc, argv);
|
readTarFile (argc, argv);
|
||||||
if (errorFlag==TRUE)
|
}
|
||||||
|
if (errorFlag==TRUE) {
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
|
}
|
||||||
exit (!errorFlag);
|
exit (!errorFlag);
|
||||||
|
|
||||||
|
flagError:
|
||||||
|
fprintf (stderr, "Exactly one of 'c', 'x' or 't' must be specified\n");
|
||||||
|
exit (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -139,3 +139,10 @@
|
|||||||
// Enable support for creation of tar files.
|
// Enable support for creation of tar files.
|
||||||
//#define BB_FEATURE_TAR_CREATE
|
//#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
|
||||||
|
//
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
Name: busybox
|
Name: busybox
|
||||||
Version: 0.41
|
Version: 0.42
|
||||||
Release: 1
|
Release: 1
|
||||||
Group: System/Utilities
|
Group: System/Utilities
|
||||||
Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary.
|
Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary.
|
||||||
Copyright: GPL
|
Copyright: GPL
|
||||||
Packager : Erik Andersen <andersen@lineo.com>
|
Packager : Erik Andersen <andersen@lineo.com>
|
||||||
Conflicts: fileutils grep shellutils
|
Conflicts: fileutils grep shellutils
|
||||||
Buildroot: /tmp/%{name}-%{version}
|
Buildroot: /tmp/%{Name}-%{Version}
|
||||||
Source: %{name}-%{version}.tar.gz
|
Source: %{Name}-%{Version}.tar.gz
|
||||||
|
|
||||||
%Description
|
%Description
|
||||||
BusyBox is a suite of "tiny" Unix utilities in a multi-call binary. It
|
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.
|
embedded system.
|
||||||
|
|
||||||
%Prep
|
%Prep
|
||||||
%setup -q -n %{name}-%{version}
|
%setup -q -n %{Name}-%{Version}
|
||||||
|
|
||||||
%Build
|
%Build
|
||||||
make
|
make
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
Name: busybox
|
Name: busybox
|
||||||
Version: 0.41
|
Version: 0.42
|
||||||
Release: 1
|
Release: 1
|
||||||
Group: System/Utilities
|
Group: System/Utilities
|
||||||
Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary.
|
Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary.
|
||||||
Copyright: GPL
|
Copyright: GPL
|
||||||
Packager : Erik Andersen <andersen@lineo.com>
|
Packager : Erik Andersen <andersen@lineo.com>
|
||||||
Conflicts: fileutils grep shellutils
|
Conflicts: fileutils grep shellutils
|
||||||
Buildroot: /tmp/%{name}-%{version}
|
Buildroot: /tmp/%{Name}-%{Version}
|
||||||
Source: %{name}-%{version}.tar.gz
|
Source: %{Name}-%{Version}.tar.gz
|
||||||
|
|
||||||
%Description
|
%Description
|
||||||
BusyBox is a suite of "tiny" Unix utilities in a multi-call binary. It
|
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.
|
embedded system.
|
||||||
|
|
||||||
%Prep
|
%Prep
|
||||||
%setup -q -n %{name}-%{version}
|
%setup -q -n %{Name}-%{Version}
|
||||||
|
|
||||||
%Build
|
%Build
|
||||||
make
|
make
|
||||||
|
91
init.c
91
init.c
@ -147,7 +147,9 @@ void message(int device, char *fmt, ...)
|
|||||||
va_start(arguments, fmt);
|
va_start(arguments, fmt);
|
||||||
vsnprintf(msg, sizeof(msg), fmt, arguments);
|
vsnprintf(msg, sizeof(msg), fmt, arguments);
|
||||||
va_end(arguments);
|
va_end(arguments);
|
||||||
|
openlog( "init", 0, LOG_DAEMON);
|
||||||
syslog(LOG_DAEMON|LOG_NOTICE, msg);
|
syslog(LOG_DAEMON|LOG_NOTICE, msg);
|
||||||
|
closelog();
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -268,7 +270,7 @@ static void console_init()
|
|||||||
#if #cpu(sparc)
|
#if #cpu(sparc)
|
||||||
/* sparc kernel supports console=tty[ab] parameter which is also
|
/* sparc kernel supports console=tty[ab] parameter which is also
|
||||||
* passed to init, so catch it here */
|
* 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] */
|
/* remap tty[ab] to /dev/ttyS[01] */
|
||||||
if (strcmp( s, "ttya" )==0)
|
if (strcmp( s, "ttya" )==0)
|
||||||
snprintf(console, sizeof(console)-1, "%s", SERIAL_CON0);
|
snprintf(console, sizeof(console)-1, "%s", SERIAL_CON0);
|
||||||
@ -507,7 +509,83 @@ static void reboot_signal(int sig)
|
|||||||
exit(0);
|
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,
|
void new_initAction (initActionEnum action,
|
||||||
char* process, char* cons)
|
char* process, char* cons)
|
||||||
@ -516,10 +594,10 @@ void new_initAction (initActionEnum action,
|
|||||||
|
|
||||||
/* If BusyBox detects that a serial console is in use,
|
/* If BusyBox detects that a serial console is in use,
|
||||||
* then entries containing non-empty id fields will _not_ be run.
|
* 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;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
newAction = calloc ((size_t)(1), sizeof(initAction));
|
newAction = calloc ((size_t)(1), sizeof(initAction));
|
||||||
if (!newAction) {
|
if (!newAction) {
|
||||||
@ -662,7 +740,7 @@ extern int init_main(int argc, char **argv)
|
|||||||
int status;
|
int status;
|
||||||
|
|
||||||
#ifndef DEBUG_INIT
|
#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 ) {
|
if (getpid() != 1 && strstr(argv[0], "init")!=NULL ) {
|
||||||
usage( "init\n\nInit is the parent of all processes.\n\n"
|
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");
|
"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(SIGUSR2, reboot_signal);
|
||||||
signal(SIGINT, reboot_signal);
|
signal(SIGINT, reboot_signal);
|
||||||
signal(SIGTERM, 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
|
/* Turn off rebooting via CTL-ALT-DEL -- we get a
|
||||||
* SIGINT on CAD so we can shut things down gracefully... */
|
* SIGINT on CAD so we can shut things down gracefully... */
|
||||||
|
91
init/init.c
91
init/init.c
@ -147,7 +147,9 @@ void message(int device, char *fmt, ...)
|
|||||||
va_start(arguments, fmt);
|
va_start(arguments, fmt);
|
||||||
vsnprintf(msg, sizeof(msg), fmt, arguments);
|
vsnprintf(msg, sizeof(msg), fmt, arguments);
|
||||||
va_end(arguments);
|
va_end(arguments);
|
||||||
|
openlog( "init", 0, LOG_DAEMON);
|
||||||
syslog(LOG_DAEMON|LOG_NOTICE, msg);
|
syslog(LOG_DAEMON|LOG_NOTICE, msg);
|
||||||
|
closelog();
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -268,7 +270,7 @@ static void console_init()
|
|||||||
#if #cpu(sparc)
|
#if #cpu(sparc)
|
||||||
/* sparc kernel supports console=tty[ab] parameter which is also
|
/* sparc kernel supports console=tty[ab] parameter which is also
|
||||||
* passed to init, so catch it here */
|
* 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] */
|
/* remap tty[ab] to /dev/ttyS[01] */
|
||||||
if (strcmp( s, "ttya" )==0)
|
if (strcmp( s, "ttya" )==0)
|
||||||
snprintf(console, sizeof(console)-1, "%s", SERIAL_CON0);
|
snprintf(console, sizeof(console)-1, "%s", SERIAL_CON0);
|
||||||
@ -507,7 +509,83 @@ static void reboot_signal(int sig)
|
|||||||
exit(0);
|
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,
|
void new_initAction (initActionEnum action,
|
||||||
char* process, char* cons)
|
char* process, char* cons)
|
||||||
@ -516,10 +594,10 @@ void new_initAction (initActionEnum action,
|
|||||||
|
|
||||||
/* If BusyBox detects that a serial console is in use,
|
/* If BusyBox detects that a serial console is in use,
|
||||||
* then entries containing non-empty id fields will _not_ be run.
|
* 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;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
newAction = calloc ((size_t)(1), sizeof(initAction));
|
newAction = calloc ((size_t)(1), sizeof(initAction));
|
||||||
if (!newAction) {
|
if (!newAction) {
|
||||||
@ -662,7 +740,7 @@ extern int init_main(int argc, char **argv)
|
|||||||
int status;
|
int status;
|
||||||
|
|
||||||
#ifndef DEBUG_INIT
|
#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 ) {
|
if (getpid() != 1 && strstr(argv[0], "init")!=NULL ) {
|
||||||
usage( "init\n\nInit is the parent of all processes.\n\n"
|
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");
|
"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(SIGUSR2, reboot_signal);
|
||||||
signal(SIGINT, reboot_signal);
|
signal(SIGINT, reboot_signal);
|
||||||
signal(SIGTERM, 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
|
/* Turn off rebooting via CTL-ALT-DEL -- we get a
|
||||||
* SIGINT on CAD so we can shut things down gracefully... */
|
* SIGINT on CAD so we can shut things down gracefully... */
|
||||||
|
59
logger.c
59
logger.c
@ -22,16 +22,11 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/un.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <time.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <netdb.h>
|
|
||||||
|
|
||||||
#if !defined BB_SYSLOGD
|
#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"
|
"Write MESSAGE to the system log. If MESSAGE is '-', log stdin.\n\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
"\t-s\tLog to stderr as well as the system log.\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-p\tEnter the message with the specified priority.\n"
|
||||||
"\t\tThis may be numerical or a ``facility.level'' pair.\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)
|
extern int logger_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct sockaddr_un sunx;
|
int pri = LOG_USER|LOG_NOTICE;
|
||||||
int fd, pri = LOG_USER|LOG_NOTICE;
|
int option = 0;
|
||||||
int fromStdinFlag=FALSE;
|
int fromStdinFlag=FALSE;
|
||||||
int toStdErrFlag=FALSE;
|
|
||||||
int stopLookingAtMeLikeThat=FALSE;
|
int stopLookingAtMeLikeThat=FALSE;
|
||||||
char *message, buf[1024], buf1[1024];
|
char *message, buf[1024], name[128];
|
||||||
time_t now;
|
|
||||||
size_t addrLength;
|
/* Fill out the name string early (may be overwritten later */
|
||||||
|
my_getpwuid(name, geteuid());
|
||||||
|
|
||||||
/* Parse any options */
|
/* Parse any options */
|
||||||
while (--argc > 0 && **(++argv) == '-') {
|
while (--argc > 0 && **(++argv) == '-') {
|
||||||
@ -134,7 +130,7 @@ extern int logger_main(int argc, char **argv)
|
|||||||
while (*(++(*argv)) && stopLookingAtMeLikeThat==FALSE) {
|
while (*(++(*argv)) && stopLookingAtMeLikeThat==FALSE) {
|
||||||
switch (**argv) {
|
switch (**argv) {
|
||||||
case 's':
|
case 's':
|
||||||
toStdErrFlag = TRUE;
|
option |= LOG_PERROR;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
if (--argc == 0) {
|
if (--argc == 0) {
|
||||||
@ -143,6 +139,13 @@ extern int logger_main(int argc, char **argv)
|
|||||||
pri = pencode(*(++argv));
|
pri = pencode(*(++argv));
|
||||||
stopLookingAtMeLikeThat=TRUE;
|
stopLookingAtMeLikeThat=TRUE;
|
||||||
break;
|
break;
|
||||||
|
case 't':
|
||||||
|
if (--argc == 0) {
|
||||||
|
usage(logger_usage);
|
||||||
|
}
|
||||||
|
strncpy(name, *(++argv), sizeof(name));
|
||||||
|
stopLookingAtMeLikeThat=TRUE;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage(logger_usage);
|
usage(logger_usage);
|
||||||
}
|
}
|
||||||
@ -152,10 +155,10 @@ extern int logger_main(int argc, char **argv)
|
|||||||
if (fromStdinFlag==TRUE) {
|
if (fromStdinFlag==TRUE) {
|
||||||
/* read from stdin */
|
/* read from stdin */
|
||||||
int c, i=0;
|
int c, i=0;
|
||||||
while ((c = getc(stdin)) != EOF && i<sizeof(buf1)) {
|
while ((c = getc(stdin)) != EOF && i<sizeof(buf)) {
|
||||||
buf1[i++]=c;
|
buf[i++]=c;
|
||||||
}
|
}
|
||||||
message=buf1;
|
message=buf;
|
||||||
} else {
|
} else {
|
||||||
if (argc>=1) {
|
if (argc>=1) {
|
||||||
message=*argv;
|
message=*argv;
|
||||||
@ -165,30 +168,10 @@ extern int logger_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&sunx, 0, sizeof(sunx));
|
openlog( name, option, (pri | LOG_FACMASK));
|
||||||
sunx.sun_family = AF_UNIX; /* Unix domain socket */
|
syslog( pri, message);
|
||||||
strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path));
|
closelog();
|
||||||
if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0 ) {
|
|
||||||
perror("Couldn't obtain descriptor for socket " _PATH_LOG);
|
|
||||||
exit( FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
exit( TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,16 +22,11 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/un.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <time.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <netdb.h>
|
|
||||||
|
|
||||||
#if !defined BB_SYSLOGD
|
#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"
|
"Write MESSAGE to the system log. If MESSAGE is '-', log stdin.\n\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
"\t-s\tLog to stderr as well as the system log.\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-p\tEnter the message with the specified priority.\n"
|
||||||
"\t\tThis may be numerical or a ``facility.level'' pair.\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)
|
extern int logger_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct sockaddr_un sunx;
|
int pri = LOG_USER|LOG_NOTICE;
|
||||||
int fd, pri = LOG_USER|LOG_NOTICE;
|
int option = 0;
|
||||||
int fromStdinFlag=FALSE;
|
int fromStdinFlag=FALSE;
|
||||||
int toStdErrFlag=FALSE;
|
|
||||||
int stopLookingAtMeLikeThat=FALSE;
|
int stopLookingAtMeLikeThat=FALSE;
|
||||||
char *message, buf[1024], buf1[1024];
|
char *message, buf[1024], name[128];
|
||||||
time_t now;
|
|
||||||
size_t addrLength;
|
/* Fill out the name string early (may be overwritten later */
|
||||||
|
my_getpwuid(name, geteuid());
|
||||||
|
|
||||||
/* Parse any options */
|
/* Parse any options */
|
||||||
while (--argc > 0 && **(++argv) == '-') {
|
while (--argc > 0 && **(++argv) == '-') {
|
||||||
@ -134,7 +130,7 @@ extern int logger_main(int argc, char **argv)
|
|||||||
while (*(++(*argv)) && stopLookingAtMeLikeThat==FALSE) {
|
while (*(++(*argv)) && stopLookingAtMeLikeThat==FALSE) {
|
||||||
switch (**argv) {
|
switch (**argv) {
|
||||||
case 's':
|
case 's':
|
||||||
toStdErrFlag = TRUE;
|
option |= LOG_PERROR;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
if (--argc == 0) {
|
if (--argc == 0) {
|
||||||
@ -143,6 +139,13 @@ extern int logger_main(int argc, char **argv)
|
|||||||
pri = pencode(*(++argv));
|
pri = pencode(*(++argv));
|
||||||
stopLookingAtMeLikeThat=TRUE;
|
stopLookingAtMeLikeThat=TRUE;
|
||||||
break;
|
break;
|
||||||
|
case 't':
|
||||||
|
if (--argc == 0) {
|
||||||
|
usage(logger_usage);
|
||||||
|
}
|
||||||
|
strncpy(name, *(++argv), sizeof(name));
|
||||||
|
stopLookingAtMeLikeThat=TRUE;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage(logger_usage);
|
usage(logger_usage);
|
||||||
}
|
}
|
||||||
@ -152,10 +155,10 @@ extern int logger_main(int argc, char **argv)
|
|||||||
if (fromStdinFlag==TRUE) {
|
if (fromStdinFlag==TRUE) {
|
||||||
/* read from stdin */
|
/* read from stdin */
|
||||||
int c, i=0;
|
int c, i=0;
|
||||||
while ((c = getc(stdin)) != EOF && i<sizeof(buf1)) {
|
while ((c = getc(stdin)) != EOF && i<sizeof(buf)) {
|
||||||
buf1[i++]=c;
|
buf[i++]=c;
|
||||||
}
|
}
|
||||||
message=buf1;
|
message=buf;
|
||||||
} else {
|
} else {
|
||||||
if (argc>=1) {
|
if (argc>=1) {
|
||||||
message=*argv;
|
message=*argv;
|
||||||
@ -165,30 +168,10 @@ extern int logger_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&sunx, 0, sizeof(sunx));
|
openlog( name, option, (pri | LOG_FACMASK));
|
||||||
sunx.sun_family = AF_UNIX; /* Unix domain socket */
|
syslog( pri, message);
|
||||||
strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path));
|
closelog();
|
||||||
if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0 ) {
|
|
||||||
perror("Couldn't obtain descriptor for socket " _PATH_LOG);
|
|
||||||
exit( FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
exit( TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
133
tar.c
133
tar.c
@ -108,9 +108,7 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
static int listFlag;
|
static int listFlag;
|
||||||
static int extractFlag;
|
static int extractFlag;
|
||||||
#ifdef BB_FEATURE_TAR_CREATE
|
|
||||||
static int createFlag;
|
static int createFlag;
|
||||||
#endif
|
|
||||||
static int verboseFlag;
|
static int verboseFlag;
|
||||||
static int tostdoutFlag;
|
static int tostdoutFlag;
|
||||||
|
|
||||||
@ -185,9 +183,7 @@ extern int tar_main (int argc, char **argv)
|
|||||||
|
|
||||||
errorFlag = FALSE;
|
errorFlag = FALSE;
|
||||||
extractFlag = FALSE;
|
extractFlag = FALSE;
|
||||||
#ifdef BB_FEATURE_TAR_CREATE
|
|
||||||
createFlag = FALSE;
|
createFlag = FALSE;
|
||||||
#endif
|
|
||||||
listFlag = FALSE;
|
listFlag = FALSE;
|
||||||
verboseFlag = FALSE;
|
verboseFlag = FALSE;
|
||||||
tostdoutFlag = FALSE;
|
tostdoutFlag = FALSE;
|
||||||
@ -199,90 +195,85 @@ extern int tar_main (int argc, char **argv)
|
|||||||
/*
|
/*
|
||||||
* Parse the options.
|
* Parse the options.
|
||||||
*/
|
*/
|
||||||
if (**argv == '-') {
|
if (**argv == '-')
|
||||||
options = (*argv++) + 1;
|
options = (*argv++) + 1;
|
||||||
argc--;
|
else
|
||||||
for (; *options; options++) {
|
options = (*argv++);
|
||||||
switch (*options) {
|
argc--;
|
||||||
case 'f':
|
|
||||||
if (tarName != NULL) {
|
|
||||||
fprintf (stderr, "Only one 'f' option allowed\n");
|
|
||||||
|
|
||||||
exit (FALSE);
|
for (; *options; options++) {
|
||||||
}
|
switch (*options) {
|
||||||
|
case 'f':
|
||||||
tarName = *argv++;
|
if (tarName != NULL) {
|
||||||
argc--;
|
fprintf (stderr, "Only one 'f' option allowed\n");
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
exit (FALSE);
|
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
|
* Do the correct type of action supplying the rest of the
|
||||||
* command line arguments as the list of files to process.
|
* 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);
|
writeTarFile (argc, argv);
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
|
} else {
|
||||||
readTarFile (argc, argv);
|
readTarFile (argc, argv);
|
||||||
if (errorFlag==TRUE)
|
}
|
||||||
|
if (errorFlag==TRUE) {
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
|
}
|
||||||
exit (!errorFlag);
|
exit (!errorFlag);
|
||||||
|
|
||||||
|
flagError:
|
||||||
|
fprintf (stderr, "Exactly one of 'c', 'x' or 't' must be specified\n");
|
||||||
|
exit (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user