aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik Andersen <andersen@codepoet.org>2000-01-23 01:34:05 +0000
committerErik Andersen <andersen@codepoet.org>2000-01-23 01:34:05 +0000
commitde552874d2074ac48ea4b834d61c54e1b6971be3 (patch)
tree0360b39142f1c85e1cac2637e09c6e452cf1a444
parentf4acea8cf5175de2292c86b58f2f30d262f14345 (diff)
downloadbusybox-w32-de552874d2074ac48ea4b834d61c54e1b6971be3.tar.gz
busybox-w32-de552874d2074ac48ea4b834d61c54e1b6971be3.tar.bz2
busybox-w32-de552874d2074ac48ea4b834d61c54e1b6971be3.zip
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
-rw-r--r--Changelog8
-rw-r--r--Makefile22
-rw-r--r--archival/tar.c133
-rw-r--r--busybox.def.h7
-rw-r--r--busybox.spec8
-rw-r--r--examples/busybox.spec8
-rw-r--r--init.c91
-rw-r--r--init/init.c91
-rw-r--r--logger.c59
-rw-r--r--sysklogd/logger.c59
-rw-r--r--tar.c133
11 files changed, 364 insertions, 255 deletions
diff --git a/Changelog b/Changelog
index 095a529bc..4b65b3b27 100644
--- a/Changelog
+++ b/Changelog
@@ -1,10 +1,18 @@
10.42 10.42
2 * Made tar creation support in busybox tar optional. 2 * Made tar creation support in busybox tar optional.
3 You no longer _have_ to put a "-" in front of tar options.
3 * Made grep and grep -h do the right thing wrt printing 4 * Made grep and grep -h do the right thing wrt printing
4 the file name (it failed to print files names in many cases). 5 the file name (it failed to print files names in many cases).
5 * Fix a namespace aliasing problem wereby if du was built in, the 6 * Fix a namespace aliasing problem wereby if du was built in, the
6 symlink for both du and dutmp would be installed, or then rm was 7 symlink for both du and dutmp would be installed, or then rm was
7 built in, the symlinks for both rm and rmmod would be installed. 8 built in, the symlinks for both rm and rmmod would be installed.
9 * Added a closelog() to init.c after loging -- fix thanks to
10 Taketoshi Sano <kgh12351@nifty.ne.jp>
11 * Rewrote and simplified logger. Added the "-t" option, and made it
12 behave itself a bit better.
13 * Optional support contributed by Ben Collins <bcollins@debian.org>
14 for the kernel init chroot patch by Werner Almesberger, which
15 allows init to chroot to a new device, and umount the old one.
8 16
9 17
10 -Erik Andersen 18 -Erik Andersen
diff --git a/Makefile b/Makefile
index 91d4bd1c4..554dd00f5 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@
17 17
18 18
19PROG=busybox 19PROG=busybox
20VERSION=0.41 20VERSION=0.42
21BUILDTIME=$(shell date "+%Y%m%d-%H%M") 21BUILDTIME=$(shell date "+%Y%m%d-%H%M")
22 22
23# Comment out the following to make a debuggable build 23# 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/'`
33 33
34GCCMAJVERSION=$(shell $(CC) --version | sed -n "s/^\([^\.]*\).*/\1/p" ) 34GCCMAJVERSION=$(shell $(CC) --version | sed -n "s/^\([^\.]*\).*/\1/p" )
35GCCMINVERSION=$(shell $(CC) --version | sed -n "s/^[^\.]*\.\([^\.]*\)[\.].*/\1/p" ) 35GCCMINVERSION=$(shell $(CC) --version | sed -n "s/^[^\.]*\.\([^\.]*\)[\.].*/\1/p" )
36GCCEGCS=$(shell $(CC) --version | sed -n "s/.*\(egcs\).*/\1/p" )
37 36
38GCCSUPPORTSOPTSIZE=$(shell \ 37GCCSUPPORTSOPTSIZE=$(shell \
39if ( test $(GCCMAJVERSION) -eq 2 ) ; then \ 38if ( test $(GCCMAJVERSION) -eq 2 ) ; then \
@@ -50,26 +49,11 @@ else \
50 fi; \ 49 fi; \
51fi; ) 50fi; )
52 51
53GCCISEGCS=$(shell \
54if ( test "x$(GCCEGCS)" == "xegcs" ) ; then \
55 echo "true"; \
56 else \
57 echo "false"; \
58 fi; )
59
60EGCSEXTREMEFLAGS = -m386 -mcpu=i386 -march=i386 -malign-jumps=1 -malign-loops=1 -malign-functions=1
61GCCEXTREMEFLAGS = -m386 -malign-jumps=1 -malign-loops=1 -malign-functions=1
62
63ifeq ($(GCCISEGCS), true)
64 EXTREMEFLAGS = $(EGCSEXTREMEFLAGS)
65else
66 EXTREMEFLAGS = $(GCCEXTREMEFLAGS)
67endif
68 52
69ifeq ($(GCCSUPPORTSOPTSIZE), true) 53ifeq ($(GCCSUPPORTSOPTSIZE), true)
70 OPTIMIZATION=-Os $(EXTREMEFLAGS) 54 OPTIMIZATION=-Os
71else 55else
72 OPTIMIZATION=-O2 $(EXTREMEFLAGS) 56 OPTIMIZATION=-O2
73endif 57endif
74 58
75# -D_GNU_SOURCE is needed because environ is used in init.c 59# -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 {
108 */ 108 */
109static int listFlag; 109static int listFlag;
110static int extractFlag; 110static int extractFlag;
111#ifdef BB_FEATURE_TAR_CREATE
112static int createFlag; 111static int createFlag;
113#endif
114static int verboseFlag; 112static int verboseFlag;
115static int tostdoutFlag; 113static int tostdoutFlag;
116 114
@@ -185,9 +183,7 @@ extern int tar_main (int argc, char **argv)
185 183
186 errorFlag = FALSE; 184 errorFlag = FALSE;
187 extractFlag = FALSE; 185 extractFlag = FALSE;
188#ifdef BB_FEATURE_TAR_CREATE
189 createFlag = FALSE; 186 createFlag = FALSE;
190#endif
191 listFlag = FALSE; 187 listFlag = FALSE;
192 verboseFlag = FALSE; 188 verboseFlag = FALSE;
193 tostdoutFlag = FALSE; 189 tostdoutFlag = FALSE;
@@ -199,90 +195,85 @@ extern int tar_main (int argc, char **argv)
199 /* 195 /*
200 * Parse the options. 196 * Parse the options.
201 */ 197 */
202 if (**argv == '-') { 198 if (**argv == '-')
203 options = (*argv++) + 1; 199 options = (*argv++) + 1;
204 argc--; 200 else
205 for (; *options; options++) { 201 options = (*argv++);
206 switch (*options) { 202 argc--;
207 case 'f':
208 if (tarName != NULL) {
209 fprintf (stderr, "Only one 'f' option allowed\n");
210
211 exit (FALSE);
212 }
213
214 tarName = *argv++;
215 argc--;
216
217 break;
218
219 case 't':
220 listFlag = TRUE;
221 break;
222
223 case 'x':
224 extractFlag = TRUE;
225 break;
226#ifdef BB_FEATURE_TAR_CREATE
227 case 'c':
228 createFlag = TRUE;
229 break;
230#else
231 case 'c':
232 fprintf (stderr, "This version of tar was not compiled with tar creation support.\n" );
233
234 exit (FALSE);
235#endif
236
237 case 'v':
238 verboseFlag = TRUE;
239 break;
240
241 case 'O':
242 tostdoutFlag = TRUE;
243 break;
244
245 case '-':
246 usage( tar_usage);
247 break;
248 203
249 default: 204 for (; *options; options++) {
250 fprintf (stderr, "Unknown tar flag '%c'\n" 205 switch (*options) {
251 "Try `tar --help' for more information\n", 206 case 'f':
252 *options); 207 if (tarName != NULL) {
208 fprintf (stderr, "Only one 'f' option allowed\n");
253 209
254 exit (FALSE); 210 exit (FALSE);
255 } 211 }
256 }
257 }
258 212
259 /* 213 tarName = *argv++;
260 * Validate the options. 214 argc--;
261 */ 215
262 if (extractFlag + listFlag 216 break;
263#ifdef BB_FEATURE_TAR_CREATE 217
264 + createFlag 218 case 't':
265#endif 219 if (extractFlag == TRUE || createFlag == TRUE )
266 != (TRUE+FALSE+FALSE)) { 220 goto flagError;
267 fprintf (stderr, 221 listFlag = TRUE;
268 "Exactly one of 'c', 'x' or 't' must be specified\n"); 222 break;
269 223
270 exit (FALSE); 224 case 'x':
225 if (listFlag == TRUE || createFlag == TRUE )
226 goto flagError;
227 extractFlag = TRUE;
228 break;
229 case 'c':
230 if (extractFlag == TRUE || listFlag == TRUE)
231 goto flagError;
232 createFlag = TRUE;
233 break;
234
235 case 'v':
236 verboseFlag = TRUE;
237 break;
238
239 case 'O':
240 tostdoutFlag = TRUE;
241 break;
242
243 case '-':
244 usage( tar_usage);
245 break;
246
247 default:
248 fprintf (stderr, "Unknown tar flag '%c'\n"
249 "Try `tar --help' for more information\n",
250 *options);
251 exit (FALSE);
252 }
271 } 253 }
272 254
273 /* 255 /*
274 * Do the correct type of action supplying the rest of the 256 * Do the correct type of action supplying the rest of the
275 * command line arguments as the list of files to process. 257 * command line arguments as the list of files to process.
276 */ 258 */
277#ifdef BB_FEATURE_TAR_CREATE 259 if (createFlag==TRUE) {
278 if (createFlag==TRUE) 260#ifndef BB_FEATURE_TAR_CREATE
261 fprintf (stderr, "This version of tar was not compiled with tar creation support.\n" );
262 exit (FALSE);
263#else
279 writeTarFile (argc, argv); 264 writeTarFile (argc, argv);
280 else
281#endif 265#endif
266 } else {
282 readTarFile (argc, argv); 267 readTarFile (argc, argv);
283 if (errorFlag==TRUE) 268 }
269 if (errorFlag==TRUE) {
284 fprintf (stderr, "\n"); 270 fprintf (stderr, "\n");
271 }
285 exit (!errorFlag); 272 exit (!errorFlag);
273
274flagError:
275 fprintf (stderr, "Exactly one of 'c', 'x' or 't' must be specified\n");
276 exit (FALSE);
286} 277}
287 278
288 279
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 @@
139// Enable support for creation of tar files. 139// Enable support for creation of tar files.
140//#define BB_FEATURE_TAR_CREATE 140//#define BB_FEATURE_TAR_CREATE
141// 141//
142// Allow init to permenently chroot, and umount the old root fs
143// just like an initrd does. Requires a kernel patch by Werner Almesberger.
144// ftp://icaftp.epfl.ch/pub/people/almesber/misc/umount-root-*.tar.gz
145#ifdef BB_MOUNT
146#define BB_FEATURE_INIT_CHROOT
147#endif
148//
diff --git a/busybox.spec b/busybox.spec
index 73f47e191..03e4feb36 100644
--- a/busybox.spec
+++ b/busybox.spec
@@ -1,13 +1,13 @@
1Name: busybox 1Name: busybox
2Version: 0.41 2Version: 0.42
3Release: 1 3Release: 1
4Group: System/Utilities 4Group: System/Utilities
5Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary. 5Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary.
6Copyright: GPL 6Copyright: GPL
7Packager : Erik Andersen <andersen@lineo.com> 7Packager : Erik Andersen <andersen@lineo.com>
8Conflicts: fileutils grep shellutils 8Conflicts: fileutils grep shellutils
9Buildroot: /tmp/%{name}-%{version} 9Buildroot: /tmp/%{Name}-%{Version}
10Source: %{name}-%{version}.tar.gz 10Source: %{Name}-%{Version}.tar.gz
11 11
12%Description 12%Description
13BusyBox is a suite of "tiny" Unix utilities in a multi-call binary. It 13BusyBox 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
18embedded system. 18embedded system.
19 19
20%Prep 20%Prep
21%setup -q -n %{name}-%{version} 21%setup -q -n %{Name}-%{Version}
22 22
23%Build 23%Build
24make 24make
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 @@
1Name: busybox 1Name: busybox
2Version: 0.41 2Version: 0.42
3Release: 1 3Release: 1
4Group: System/Utilities 4Group: System/Utilities
5Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary. 5Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary.
6Copyright: GPL 6Copyright: GPL
7Packager : Erik Andersen <andersen@lineo.com> 7Packager : Erik Andersen <andersen@lineo.com>
8Conflicts: fileutils grep shellutils 8Conflicts: fileutils grep shellutils
9Buildroot: /tmp/%{name}-%{version} 9Buildroot: /tmp/%{Name}-%{Version}
10Source: %{name}-%{version}.tar.gz 10Source: %{Name}-%{Version}.tar.gz
11 11
12%Description 12%Description
13BusyBox is a suite of "tiny" Unix utilities in a multi-call binary. It 13BusyBox 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
18embedded system. 18embedded system.
19 19
20%Prep 20%Prep
21%setup -q -n %{name}-%{version} 21%setup -q -n %{Name}-%{Version}
22 22
23%Build 23%Build
24make 24make
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, ...)
147 va_start(arguments, fmt); 147 va_start(arguments, fmt);
148 vsnprintf(msg, sizeof(msg), fmt, arguments); 148 vsnprintf(msg, sizeof(msg), fmt, arguments);
149 va_end(arguments); 149 va_end(arguments);
150 openlog( "init", 0, LOG_DAEMON);
150 syslog(LOG_DAEMON|LOG_NOTICE, msg); 151 syslog(LOG_DAEMON|LOG_NOTICE, msg);
152 closelog();
151 } 153 }
152 154
153#else 155#else
@@ -268,7 +270,7 @@ static void console_init()
268#if #cpu(sparc) 270#if #cpu(sparc)
269 /* sparc kernel supports console=tty[ab] parameter which is also 271 /* sparc kernel supports console=tty[ab] parameter which is also
270 * passed to init, so catch it here */ 272 * passed to init, so catch it here */
271 else if ((s = getenv("console")) != NULL) {*/ 273 else if ((s = getenv("console")) != NULL) {
272 /* remap tty[ab] to /dev/ttyS[01] */ 274 /* remap tty[ab] to /dev/ttyS[01] */
273 if (strcmp( s, "ttya" )==0) 275 if (strcmp( s, "ttya" )==0)
274 snprintf(console, sizeof(console)-1, "%s", SERIAL_CON0); 276 snprintf(console, sizeof(console)-1, "%s", SERIAL_CON0);
@@ -507,7 +509,83 @@ static void reboot_signal(int sig)
507 exit(0); 509 exit(0);
508} 510}
509 511
510#endif 512#if defined BB_FEATURE_INIT_CHROOT
513static void check_chroot(int sig)
514{
515 char *argv_init[2] = { "init", NULL, };
516 char *envp_init[3] = { "HOME=/", "TERM=linux", NULL, };
517 char rootpath[256], *tc;
518 int fd;
519
520 if ((fd = open("/proc/sys/kernel/init-chroot", O_RDONLY)) == -1) {
521 message(CONSOLE, "SIGHUP recived, but could not open proc file\r\n");
522 sleep(2);
523 return;
524 }
525 if (read(fd, rootpath, sizeof(rootpath)) == -1) {
526 message(CONSOLE, "SIGHUP recived, but could not read proc file\r\n");
527 sleep(2);
528 return;
529 }
530 close(fd);
531
532 if (rootpath[0] == '\0') {
533 message(CONSOLE, "SIGHUP recived, but new root is not valid: %s\r\n",
534 rootpath);
535 sleep(2);
536 return;
537 }
538
539 tc = strrchr(rootpath, '\n');
540 *tc = '\0';
541
542 /* Ok, making it this far means we commit */
543 message(CONSOLE, "Please stand by, changing root to `%s'.\r\n", rootpath);
544
545 /* kill all other programs first */
546 message(CONSOLE, "Sending SIGTERM to all processes.\r\n");
547 kill(-1, SIGTERM);
548 sleep(2);
549 sync();
550
551 message(CONSOLE, "Sending SIGKILL to all processes.\r\n");
552 kill(-1, SIGKILL);
553 sleep(2);
554 sync();
555
556 /* ok, we don't need /proc anymore. we also assume that the signaling
557 * process left the rest of the filesystems alone for us */
558 umount("/proc");
559
560 /* Ok, now we chroot. Hopefully we only have two things mounted, the
561 * new chroot'd mount point, and the old "/" mount. s,
562 * we go ahead and unmount the old "/". This should trigger the kernel
563 * to set things up the Right Way(tm). */
564
565 if (!chroot(rootpath))
566 umount("/dev/root");
567
568 /* If the chroot fails, we are already too far to turn back, so we
569 * continue and hope that executing init below will revive the system */
570
571 /* close all of our descriptors and open new ones */
572 close(0);
573 close(1);
574 close(2);
575 open("/dev/console", O_RDWR, 0);
576 dup(0);
577 dup(0);
578
579 message(CONSOLE, "Executing real init...\r\n");
580 /* execute init in the (hopefully) new root */
581 execve("/sbin/init",argv_init,envp_init);
582
583 message(CONSOLE, "ERROR: Could not exec new init. Hit ctrl+alt+delete to reboot.\r\n");
584 return;
585}
586#endif /* BB_FEATURE_INIT_CHROOT */
587
588#endif /* ! DEBUG_INIT */
511 589
512void new_initAction (initActionEnum action, 590void new_initAction (initActionEnum action,
513 char* process, char* cons) 591 char* process, char* cons)
@@ -516,10 +594,10 @@ void new_initAction (initActionEnum action,
516 594
517 /* If BusyBox detects that a serial console is in use, 595 /* If BusyBox detects that a serial console is in use,
518 * then entries containing non-empty id fields will _not_ be run. 596 * then entries containing non-empty id fields will _not_ be run.
597 * The exception to this rule is the null device.
519 */ 598 */
520 if (secondConsole == NULL && *cons != '\0') { 599 if (secondConsole == NULL && (*cons != '\0' || strncmp(cons, "null", 4)))
521 return; 600 return;
522 }
523 601
524 newAction = calloc ((size_t)(1), sizeof(initAction)); 602 newAction = calloc ((size_t)(1), sizeof(initAction));
525 if (!newAction) { 603 if (!newAction) {
@@ -662,7 +740,7 @@ extern int init_main(int argc, char **argv)
662 int status; 740 int status;
663 741
664#ifndef DEBUG_INIT 742#ifndef DEBUG_INIT
665 /* Expect to be PID 1 iff we are run as init (not linuxrc) */ 743 /* Expect to be PID 1 if we are run as init (not linuxrc) */
666 if (getpid() != 1 && strstr(argv[0], "init")!=NULL ) { 744 if (getpid() != 1 && strstr(argv[0], "init")!=NULL ) {
667 usage( "init\n\nInit is the parent of all processes.\n\n" 745 usage( "init\n\nInit is the parent of all processes.\n\n"
668 "This version of init is designed to be run only by the kernel\n"); 746 "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)
676 signal(SIGUSR2, reboot_signal); 754 signal(SIGUSR2, reboot_signal);
677 signal(SIGINT, reboot_signal); 755 signal(SIGINT, reboot_signal);
678 signal(SIGTERM, reboot_signal); 756 signal(SIGTERM, reboot_signal);
757#if defined BB_FEATURE_INIT_CHROOT
758 signal(SIGHUP, check_chroot);
759#endif
679 760
680 /* Turn off rebooting via CTL-ALT-DEL -- we get a 761 /* Turn off rebooting via CTL-ALT-DEL -- we get a
681 * SIGINT on CAD so we can shut things down gracefully... */ 762 * 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, ...)
147 va_start(arguments, fmt); 147 va_start(arguments, fmt);
148 vsnprintf(msg, sizeof(msg), fmt, arguments); 148 vsnprintf(msg, sizeof(msg), fmt, arguments);
149 va_end(arguments); 149 va_end(arguments);
150 openlog( "init", 0, LOG_DAEMON);
150 syslog(LOG_DAEMON|LOG_NOTICE, msg); 151 syslog(LOG_DAEMON|LOG_NOTICE, msg);
152 closelog();
151 } 153 }
152 154
153#else 155#else
@@ -268,7 +270,7 @@ static void console_init()
268#if #cpu(sparc) 270#if #cpu(sparc)
269 /* sparc kernel supports console=tty[ab] parameter which is also 271 /* sparc kernel supports console=tty[ab] parameter which is also
270 * passed to init, so catch it here */ 272 * passed to init, so catch it here */
271 else if ((s = getenv("console")) != NULL) {*/ 273 else if ((s = getenv("console")) != NULL) {
272 /* remap tty[ab] to /dev/ttyS[01] */ 274 /* remap tty[ab] to /dev/ttyS[01] */
273 if (strcmp( s, "ttya" )==0) 275 if (strcmp( s, "ttya" )==0)
274 snprintf(console, sizeof(console)-1, "%s", SERIAL_CON0); 276 snprintf(console, sizeof(console)-1, "%s", SERIAL_CON0);
@@ -507,7 +509,83 @@ static void reboot_signal(int sig)
507 exit(0); 509 exit(0);
508} 510}
509 511
510#endif 512#if defined BB_FEATURE_INIT_CHROOT
513static void check_chroot(int sig)
514{
515 char *argv_init[2] = { "init", NULL, };
516 char *envp_init[3] = { "HOME=/", "TERM=linux", NULL, };
517 char rootpath[256], *tc;
518 int fd;
519
520 if ((fd = open("/proc/sys/kernel/init-chroot", O_RDONLY)) == -1) {
521 message(CONSOLE, "SIGHUP recived, but could not open proc file\r\n");
522 sleep(2);
523 return;
524 }
525 if (read(fd, rootpath, sizeof(rootpath)) == -1) {
526 message(CONSOLE, "SIGHUP recived, but could not read proc file\r\n");
527 sleep(2);
528 return;
529 }
530 close(fd);
531
532 if (rootpath[0] == '\0') {
533 message(CONSOLE, "SIGHUP recived, but new root is not valid: %s\r\n",
534 rootpath);
535 sleep(2);
536 return;
537 }
538
539 tc = strrchr(rootpath, '\n');
540 *tc = '\0';
541
542 /* Ok, making it this far means we commit */
543 message(CONSOLE, "Please stand by, changing root to `%s'.\r\n", rootpath);
544
545 /* kill all other programs first */
546 message(CONSOLE, "Sending SIGTERM to all processes.\r\n");
547 kill(-1, SIGTERM);
548 sleep(2);
549 sync();
550
551 message(CONSOLE, "Sending SIGKILL to all processes.\r\n");
552 kill(-1, SIGKILL);
553 sleep(2);
554 sync();
555
556 /* ok, we don't need /proc anymore. we also assume that the signaling
557 * process left the rest of the filesystems alone for us */
558 umount("/proc");
559
560 /* Ok, now we chroot. Hopefully we only have two things mounted, the
561 * new chroot'd mount point, and the old "/" mount. s,
562 * we go ahead and unmount the old "/". This should trigger the kernel
563 * to set things up the Right Way(tm). */
564
565 if (!chroot(rootpath))
566 umount("/dev/root");
567
568 /* If the chroot fails, we are already too far to turn back, so we
569 * continue and hope that executing init below will revive the system */
570
571 /* close all of our descriptors and open new ones */
572 close(0);
573 close(1);
574 close(2);
575 open("/dev/console", O_RDWR, 0);
576 dup(0);
577 dup(0);
578
579 message(CONSOLE, "Executing real init...\r\n");
580 /* execute init in the (hopefully) new root */
581 execve("/sbin/init",argv_init,envp_init);
582
583 message(CONSOLE, "ERROR: Could not exec new init. Hit ctrl+alt+delete to reboot.\r\n");
584 return;
585}
586#endif /* BB_FEATURE_INIT_CHROOT */
587
588#endif /* ! DEBUG_INIT */
511 589
512void new_initAction (initActionEnum action, 590void new_initAction (initActionEnum action,
513 char* process, char* cons) 591 char* process, char* cons)
@@ -516,10 +594,10 @@ void new_initAction (initActionEnum action,
516 594
517 /* If BusyBox detects that a serial console is in use, 595 /* If BusyBox detects that a serial console is in use,
518 * then entries containing non-empty id fields will _not_ be run. 596 * then entries containing non-empty id fields will _not_ be run.
597 * The exception to this rule is the null device.
519 */ 598 */
520 if (secondConsole == NULL && *cons != '\0') { 599 if (secondConsole == NULL && (*cons != '\0' || strncmp(cons, "null", 4)))
521 return; 600 return;
522 }
523 601
524 newAction = calloc ((size_t)(1), sizeof(initAction)); 602 newAction = calloc ((size_t)(1), sizeof(initAction));
525 if (!newAction) { 603 if (!newAction) {
@@ -662,7 +740,7 @@ extern int init_main(int argc, char **argv)
662 int status; 740 int status;
663 741
664#ifndef DEBUG_INIT 742#ifndef DEBUG_INIT
665 /* Expect to be PID 1 iff we are run as init (not linuxrc) */ 743 /* Expect to be PID 1 if we are run as init (not linuxrc) */
666 if (getpid() != 1 && strstr(argv[0], "init")!=NULL ) { 744 if (getpid() != 1 && strstr(argv[0], "init")!=NULL ) {
667 usage( "init\n\nInit is the parent of all processes.\n\n" 745 usage( "init\n\nInit is the parent of all processes.\n\n"
668 "This version of init is designed to be run only by the kernel\n"); 746 "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)
676 signal(SIGUSR2, reboot_signal); 754 signal(SIGUSR2, reboot_signal);
677 signal(SIGINT, reboot_signal); 755 signal(SIGINT, reboot_signal);
678 signal(SIGTERM, reboot_signal); 756 signal(SIGTERM, reboot_signal);
757#if defined BB_FEATURE_INIT_CHROOT
758 signal(SIGHUP, check_chroot);
759#endif
679 760
680 /* Turn off rebooting via CTL-ALT-DEL -- we get a 761 /* Turn off rebooting via CTL-ALT-DEL -- we get a
681 * SIGINT on CAD so we can shut things down gracefully... */ 762 * 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 @@
22 22
23#include "internal.h" 23#include "internal.h"
24#include <stdio.h> 24#include <stdio.h>
25#include <sys/socket.h>
26#include <sys/un.h>
27#include <unistd.h> 25#include <unistd.h>
28#include <time.h>
29#include <sys/types.h> 26#include <sys/types.h>
30#include <sys/stat.h> 27#include <sys/stat.h>
31#include <fcntl.h> 28#include <fcntl.h>
32#include <signal.h>
33#include <ctype.h> 29#include <ctype.h>
34#include <netdb.h>
35 30
36#if !defined BB_SYSLOGD 31#if !defined BB_SYSLOGD
37 32
@@ -56,6 +51,7 @@ static const char logger_usage[] =
56 "Write MESSAGE to the system log. If MESSAGE is '-', log stdin.\n\n" 51 "Write MESSAGE to the system log. If MESSAGE is '-', log stdin.\n\n"
57 "Options:\n" 52 "Options:\n"
58 "\t-s\tLog to stderr as well as the system log.\n" 53 "\t-s\tLog to stderr as well as the system log.\n"
54 "\t-t\tLog using the specified tag (defaults to user name).\n"
59 "\t-p\tEnter the message with the specified priority.\n" 55 "\t-p\tEnter the message with the specified priority.\n"
60 "\t\tThis may be numerical or a ``facility.level'' pair.\n"; 56 "\t\tThis may be numerical or a ``facility.level'' pair.\n";
61 57
@@ -116,14 +112,14 @@ pencode(char* s)
116 112
117extern int logger_main(int argc, char **argv) 113extern int logger_main(int argc, char **argv)
118{ 114{
119 struct sockaddr_un sunx; 115 int pri = LOG_USER|LOG_NOTICE;
120 int fd, pri = LOG_USER|LOG_NOTICE; 116 int option = 0;
121 int fromStdinFlag=FALSE; 117 int fromStdinFlag=FALSE;
122 int toStdErrFlag=FALSE;
123 int stopLookingAtMeLikeThat=FALSE; 118 int stopLookingAtMeLikeThat=FALSE;
124 char *message, buf[1024], buf1[1024]; 119 char *message, buf[1024], name[128];
125 time_t now; 120
126 size_t addrLength; 121 /* Fill out the name string early (may be overwritten later */
122 my_getpwuid(name, geteuid());
127 123
128 /* Parse any options */ 124 /* Parse any options */
129 while (--argc > 0 && **(++argv) == '-') { 125 while (--argc > 0 && **(++argv) == '-') {
@@ -134,7 +130,7 @@ extern int logger_main(int argc, char **argv)
134 while (*(++(*argv)) && stopLookingAtMeLikeThat==FALSE) { 130 while (*(++(*argv)) && stopLookingAtMeLikeThat==FALSE) {
135 switch (**argv) { 131 switch (**argv) {
136 case 's': 132 case 's':
137 toStdErrFlag = TRUE; 133 option |= LOG_PERROR;
138 break; 134 break;
139 case 'p': 135 case 'p':
140 if (--argc == 0) { 136 if (--argc == 0) {
@@ -143,6 +139,13 @@ extern int logger_main(int argc, char **argv)
143 pri = pencode(*(++argv)); 139 pri = pencode(*(++argv));
144 stopLookingAtMeLikeThat=TRUE; 140 stopLookingAtMeLikeThat=TRUE;
145 break; 141 break;
142 case 't':
143 if (--argc == 0) {
144 usage(logger_usage);
145 }
146 strncpy(name, *(++argv), sizeof(name));
147 stopLookingAtMeLikeThat=TRUE;
148 break;
146 default: 149 default:
147 usage(logger_usage); 150 usage(logger_usage);
148 } 151 }
@@ -152,10 +155,10 @@ extern int logger_main(int argc, char **argv)
152 if (fromStdinFlag==TRUE) { 155 if (fromStdinFlag==TRUE) {
153 /* read from stdin */ 156 /* read from stdin */
154 int c, i=0; 157 int c, i=0;
155 while ((c = getc(stdin)) != EOF && i<sizeof(buf1)) { 158 while ((c = getc(stdin)) != EOF && i<sizeof(buf)) {
156 buf1[i++]=c; 159 buf[i++]=c;
157 } 160 }
158 message=buf1; 161 message=buf;
159 } else { 162 } else {
160 if (argc>=1) { 163 if (argc>=1) {
161 message=*argv; 164 message=*argv;
@@ -165,30 +168,10 @@ extern int logger_main(int argc, char **argv)
165 } 168 }
166 } 169 }
167 170
168 memset(&sunx, 0, sizeof(sunx)); 171 openlog( name, option, (pri | LOG_FACMASK));
169 sunx.sun_family = AF_UNIX; /* Unix domain socket */ 172 syslog( pri, message);
170 strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path)); 173 closelog();
171 if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0 ) {
172 perror("Couldn't obtain descriptor for socket " _PATH_LOG);
173 exit( FALSE);
174 }
175
176 addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path);
177
178 if (connect(fd, (struct sockaddr *) &sunx, addrLength)) {
179 perror("Could not connect to socket " _PATH_LOG);
180 exit( FALSE);
181 }
182
183 time(&now);
184 snprintf (buf, sizeof(buf), "<%d>%.15s %s", pri, ctime(&now)+4, message);
185
186 if (toStdErrFlag==TRUE)
187 fprintf(stderr, "%s\n", buf);
188
189 write( fd, buf, strlen(buf)+1);
190 174
191 close(fd);
192 exit( TRUE); 175 exit( TRUE);
193} 176}
194 177
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 @@
22 22
23#include "internal.h" 23#include "internal.h"
24#include <stdio.h> 24#include <stdio.h>
25#include <sys/socket.h>
26#include <sys/un.h>
27#include <unistd.h> 25#include <unistd.h>
28#include <time.h>
29#include <sys/types.h> 26#include <sys/types.h>
30#include <sys/stat.h> 27#include <sys/stat.h>
31#include <fcntl.h> 28#include <fcntl.h>
32#include <signal.h>
33#include <ctype.h> 29#include <ctype.h>
34#include <netdb.h>
35 30
36#if !defined BB_SYSLOGD 31#if !defined BB_SYSLOGD
37 32
@@ -56,6 +51,7 @@ static const char logger_usage[] =
56 "Write MESSAGE to the system log. If MESSAGE is '-', log stdin.\n\n" 51 "Write MESSAGE to the system log. If MESSAGE is '-', log stdin.\n\n"
57 "Options:\n" 52 "Options:\n"
58 "\t-s\tLog to stderr as well as the system log.\n" 53 "\t-s\tLog to stderr as well as the system log.\n"
54 "\t-t\tLog using the specified tag (defaults to user name).\n"
59 "\t-p\tEnter the message with the specified priority.\n" 55 "\t-p\tEnter the message with the specified priority.\n"
60 "\t\tThis may be numerical or a ``facility.level'' pair.\n"; 56 "\t\tThis may be numerical or a ``facility.level'' pair.\n";
61 57
@@ -116,14 +112,14 @@ pencode(char* s)
116 112
117extern int logger_main(int argc, char **argv) 113extern int logger_main(int argc, char **argv)
118{ 114{
119 struct sockaddr_un sunx; 115 int pri = LOG_USER|LOG_NOTICE;
120 int fd, pri = LOG_USER|LOG_NOTICE; 116 int option = 0;
121 int fromStdinFlag=FALSE; 117 int fromStdinFlag=FALSE;
122 int toStdErrFlag=FALSE;
123 int stopLookingAtMeLikeThat=FALSE; 118 int stopLookingAtMeLikeThat=FALSE;
124 char *message, buf[1024], buf1[1024]; 119 char *message, buf[1024], name[128];
125 time_t now; 120
126 size_t addrLength; 121 /* Fill out the name string early (may be overwritten later */
122 my_getpwuid(name, geteuid());
127 123
128 /* Parse any options */ 124 /* Parse any options */
129 while (--argc > 0 && **(++argv) == '-') { 125 while (--argc > 0 && **(++argv) == '-') {
@@ -134,7 +130,7 @@ extern int logger_main(int argc, char **argv)
134 while (*(++(*argv)) && stopLookingAtMeLikeThat==FALSE) { 130 while (*(++(*argv)) && stopLookingAtMeLikeThat==FALSE) {
135 switch (**argv) { 131 switch (**argv) {
136 case 's': 132 case 's':
137 toStdErrFlag = TRUE; 133 option |= LOG_PERROR;
138 break; 134 break;
139 case 'p': 135 case 'p':
140 if (--argc == 0) { 136 if (--argc == 0) {
@@ -143,6 +139,13 @@ extern int logger_main(int argc, char **argv)
143 pri = pencode(*(++argv)); 139 pri = pencode(*(++argv));
144 stopLookingAtMeLikeThat=TRUE; 140 stopLookingAtMeLikeThat=TRUE;
145 break; 141 break;
142 case 't':
143 if (--argc == 0) {
144 usage(logger_usage);
145 }
146 strncpy(name, *(++argv), sizeof(name));
147 stopLookingAtMeLikeThat=TRUE;
148 break;
146 default: 149 default:
147 usage(logger_usage); 150 usage(logger_usage);
148 } 151 }
@@ -152,10 +155,10 @@ extern int logger_main(int argc, char **argv)
152 if (fromStdinFlag==TRUE) { 155 if (fromStdinFlag==TRUE) {
153 /* read from stdin */ 156 /* read from stdin */
154 int c, i=0; 157 int c, i=0;
155 while ((c = getc(stdin)) != EOF && i<sizeof(buf1)) { 158 while ((c = getc(stdin)) != EOF && i<sizeof(buf)) {
156 buf1[i++]=c; 159 buf[i++]=c;
157 } 160 }
158 message=buf1; 161 message=buf;
159 } else { 162 } else {
160 if (argc>=1) { 163 if (argc>=1) {
161 message=*argv; 164 message=*argv;
@@ -165,30 +168,10 @@ extern int logger_main(int argc, char **argv)
165 } 168 }
166 } 169 }
167 170
168 memset(&sunx, 0, sizeof(sunx)); 171 openlog( name, option, (pri | LOG_FACMASK));
169 sunx.sun_family = AF_UNIX; /* Unix domain socket */ 172 syslog( pri, message);
170 strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path)); 173 closelog();
171 if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0 ) {
172 perror("Couldn't obtain descriptor for socket " _PATH_LOG);
173 exit( FALSE);
174 }
175
176 addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path);
177
178 if (connect(fd, (struct sockaddr *) &sunx, addrLength)) {
179 perror("Could not connect to socket " _PATH_LOG);
180 exit( FALSE);
181 }
182
183 time(&now);
184 snprintf (buf, sizeof(buf), "<%d>%.15s %s", pri, ctime(&now)+4, message);
185
186 if (toStdErrFlag==TRUE)
187 fprintf(stderr, "%s\n", buf);
188
189 write( fd, buf, strlen(buf)+1);
190 174
191 close(fd);
192 exit( TRUE); 175 exit( TRUE);
193} 176}
194 177
diff --git a/tar.c b/tar.c
index 5c407864f..adae6c94c 100644
--- a/tar.c
+++ b/tar.c
@@ -108,9 +108,7 @@ typedef struct {
108 */ 108 */
109static int listFlag; 109static int listFlag;
110static int extractFlag; 110static int extractFlag;
111#ifdef BB_FEATURE_TAR_CREATE
112static int createFlag; 111static int createFlag;
113#endif
114static int verboseFlag; 112static int verboseFlag;
115static int tostdoutFlag; 113static int tostdoutFlag;
116 114
@@ -185,9 +183,7 @@ extern int tar_main (int argc, char **argv)
185 183
186 errorFlag = FALSE; 184 errorFlag = FALSE;
187 extractFlag = FALSE; 185 extractFlag = FALSE;
188#ifdef BB_FEATURE_TAR_CREATE
189 createFlag = FALSE; 186 createFlag = FALSE;
190#endif
191 listFlag = FALSE; 187 listFlag = FALSE;
192 verboseFlag = FALSE; 188 verboseFlag = FALSE;
193 tostdoutFlag = FALSE; 189 tostdoutFlag = FALSE;
@@ -199,90 +195,85 @@ extern int tar_main (int argc, char **argv)
199 /* 195 /*
200 * Parse the options. 196 * Parse the options.
201 */ 197 */
202 if (**argv == '-') { 198 if (**argv == '-')
203 options = (*argv++) + 1; 199 options = (*argv++) + 1;
204 argc--; 200 else
205 for (; *options; options++) { 201 options = (*argv++);
206 switch (*options) { 202 argc--;
207 case 'f':
208 if (tarName != NULL) {
209 fprintf (stderr, "Only one 'f' option allowed\n");
210
211 exit (FALSE);
212 }
213
214 tarName = *argv++;
215 argc--;
216
217 break;
218
219 case 't':
220 listFlag = TRUE;
221 break;
222
223 case 'x':
224 extractFlag = TRUE;
225 break;
226#ifdef BB_FEATURE_TAR_CREATE
227 case 'c':
228 createFlag = TRUE;
229 break;
230#else
231 case 'c':
232 fprintf (stderr, "This version of tar was not compiled with tar creation support.\n" );
233
234 exit (FALSE);
235#endif
236
237 case 'v':
238 verboseFlag = TRUE;
239 break;
240
241 case 'O':
242 tostdoutFlag = TRUE;
243 break;
244
245 case '-':
246 usage( tar_usage);
247 break;
248 203
249 default: 204 for (; *options; options++) {
250 fprintf (stderr, "Unknown tar flag '%c'\n" 205 switch (*options) {
251 "Try `tar --help' for more information\n", 206 case 'f':
252 *options); 207 if (tarName != NULL) {
208 fprintf (stderr, "Only one 'f' option allowed\n");
253 209
254 exit (FALSE); 210 exit (FALSE);
255 } 211 }
256 }
257 }
258 212
259 /* 213 tarName = *argv++;
260 * Validate the options. 214 argc--;
261 */ 215
262 if (extractFlag + listFlag 216 break;
263#ifdef BB_FEATURE_TAR_CREATE 217
264 + createFlag 218 case 't':
265#endif 219 if (extractFlag == TRUE || createFlag == TRUE )
266 != (TRUE+FALSE+FALSE)) { 220 goto flagError;
267 fprintf (stderr, 221 listFlag = TRUE;
268 "Exactly one of 'c', 'x' or 't' must be specified\n"); 222 break;
269 223
270 exit (FALSE); 224 case 'x':
225 if (listFlag == TRUE || createFlag == TRUE )
226 goto flagError;
227 extractFlag = TRUE;
228 break;
229 case 'c':
230 if (extractFlag == TRUE || listFlag == TRUE)
231 goto flagError;
232 createFlag = TRUE;
233 break;
234
235 case 'v':
236 verboseFlag = TRUE;
237 break;
238
239 case 'O':
240 tostdoutFlag = TRUE;
241 break;
242
243 case '-':
244 usage( tar_usage);
245 break;
246
247 default:
248 fprintf (stderr, "Unknown tar flag '%c'\n"
249 "Try `tar --help' for more information\n",
250 *options);
251 exit (FALSE);
252 }
271 } 253 }
272 254
273 /* 255 /*
274 * Do the correct type of action supplying the rest of the 256 * Do the correct type of action supplying the rest of the
275 * command line arguments as the list of files to process. 257 * command line arguments as the list of files to process.
276 */ 258 */
277#ifdef BB_FEATURE_TAR_CREATE 259 if (createFlag==TRUE) {
278 if (createFlag==TRUE) 260#ifndef BB_FEATURE_TAR_CREATE
261 fprintf (stderr, "This version of tar was not compiled with tar creation support.\n" );
262 exit (FALSE);
263#else
279 writeTarFile (argc, argv); 264 writeTarFile (argc, argv);
280 else
281#endif 265#endif
266 } else {
282 readTarFile (argc, argv); 267 readTarFile (argc, argv);
283 if (errorFlag==TRUE) 268 }
269 if (errorFlag==TRUE) {
284 fprintf (stderr, "\n"); 270 fprintf (stderr, "\n");
271 }
285 exit (!errorFlag); 272 exit (!errorFlag);
273
274flagError:
275 fprintf (stderr, "Exactly one of 'c', 'x' or 't' must be specified\n");
276 exit (FALSE);
286} 277}
287 278
288 279