diff options
author | Erik Andersen <andersen@codepoet.org> | 2000-01-23 01:34:05 +0000 |
---|---|---|
committer | Erik Andersen <andersen@codepoet.org> | 2000-01-23 01:34:05 +0000 |
commit | de552874d2074ac48ea4b834d61c54e1b6971be3 (patch) | |
tree | 0360b39142f1c85e1cac2637e09c6e452cf1a444 | |
parent | f4acea8cf5175de2292c86b58f2f30d262f14345 (diff) | |
download | busybox-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-- | Changelog | 8 | ||||
-rw-r--r-- | Makefile | 22 | ||||
-rw-r--r-- | archival/tar.c | 133 | ||||
-rw-r--r-- | busybox.def.h | 7 | ||||
-rw-r--r-- | busybox.spec | 8 | ||||
-rw-r--r-- | examples/busybox.spec | 8 | ||||
-rw-r--r-- | init.c | 91 | ||||
-rw-r--r-- | init/init.c | 91 | ||||
-rw-r--r-- | logger.c | 59 | ||||
-rw-r--r-- | sysklogd/logger.c | 59 | ||||
-rw-r--r-- | tar.c | 133 |
11 files changed, 364 insertions, 255 deletions
@@ -1,10 +1,18 @@ | |||
1 | 0.42 | 1 | 0.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 |
@@ -17,7 +17,7 @@ | |||
17 | 17 | ||
18 | 18 | ||
19 | PROG=busybox | 19 | PROG=busybox |
20 | VERSION=0.41 | 20 | VERSION=0.42 |
21 | BUILDTIME=$(shell date "+%Y%m%d-%H%M") | 21 | BUILDTIME=$(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 | ||
34 | GCCMAJVERSION=$(shell $(CC) --version | sed -n "s/^\([^\.]*\).*/\1/p" ) | 34 | GCCMAJVERSION=$(shell $(CC) --version | sed -n "s/^\([^\.]*\).*/\1/p" ) |
35 | GCCMINVERSION=$(shell $(CC) --version | sed -n "s/^[^\.]*\.\([^\.]*\)[\.].*/\1/p" ) | 35 | GCCMINVERSION=$(shell $(CC) --version | sed -n "s/^[^\.]*\.\([^\.]*\)[\.].*/\1/p" ) |
36 | GCCEGCS=$(shell $(CC) --version | sed -n "s/.*\(egcs\).*/\1/p" ) | ||
37 | 36 | ||
38 | GCCSUPPORTSOPTSIZE=$(shell \ | 37 | GCCSUPPORTSOPTSIZE=$(shell \ |
39 | if ( test $(GCCMAJVERSION) -eq 2 ) ; then \ | 38 | if ( test $(GCCMAJVERSION) -eq 2 ) ; then \ |
@@ -50,26 +49,11 @@ else \ | |||
50 | fi; \ | 49 | fi; \ |
51 | fi; ) | 50 | fi; ) |
52 | 51 | ||
53 | GCCISEGCS=$(shell \ | ||
54 | if ( test "x$(GCCEGCS)" == "xegcs" ) ; then \ | ||
55 | echo "true"; \ | ||
56 | else \ | ||
57 | echo "false"; \ | ||
58 | fi; ) | ||
59 | |||
60 | EGCSEXTREMEFLAGS = -m386 -mcpu=i386 -march=i386 -malign-jumps=1 -malign-loops=1 -malign-functions=1 | ||
61 | GCCEXTREMEFLAGS = -m386 -malign-jumps=1 -malign-loops=1 -malign-functions=1 | ||
62 | |||
63 | ifeq ($(GCCISEGCS), true) | ||
64 | EXTREMEFLAGS = $(EGCSEXTREMEFLAGS) | ||
65 | else | ||
66 | EXTREMEFLAGS = $(GCCEXTREMEFLAGS) | ||
67 | endif | ||
68 | 52 | ||
69 | ifeq ($(GCCSUPPORTSOPTSIZE), true) | 53 | ifeq ($(GCCSUPPORTSOPTSIZE), true) |
70 | OPTIMIZATION=-Os $(EXTREMEFLAGS) | 54 | OPTIMIZATION=-Os |
71 | else | 55 | else |
72 | OPTIMIZATION=-O2 $(EXTREMEFLAGS) | 56 | OPTIMIZATION=-O2 |
73 | endif | 57 | endif |
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 | */ |
109 | static int listFlag; | 109 | static int listFlag; |
110 | static int extractFlag; | 110 | static int extractFlag; |
111 | #ifdef BB_FEATURE_TAR_CREATE | ||
112 | static int createFlag; | 111 | static int createFlag; |
113 | #endif | ||
114 | static int verboseFlag; | 112 | static int verboseFlag; |
115 | static int tostdoutFlag; | 113 | static 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 | |||
274 | flagError: | ||
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 @@ | |||
1 | Name: busybox | 1 | Name: busybox |
2 | Version: 0.41 | 2 | Version: 0.42 |
3 | Release: 1 | 3 | Release: 1 |
4 | Group: System/Utilities | 4 | Group: System/Utilities |
5 | Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary. | 5 | Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary. |
6 | Copyright: GPL | 6 | Copyright: GPL |
7 | Packager : Erik Andersen <andersen@lineo.com> | 7 | Packager : Erik Andersen <andersen@lineo.com> |
8 | Conflicts: fileutils grep shellutils | 8 | Conflicts: fileutils grep shellutils |
9 | Buildroot: /tmp/%{name}-%{version} | 9 | Buildroot: /tmp/%{Name}-%{Version} |
10 | Source: %{name}-%{version}.tar.gz | 10 | Source: %{Name}-%{Version}.tar.gz |
11 | 11 | ||
12 | %Description | 12 | %Description |
13 | BusyBox is a suite of "tiny" Unix utilities in a multi-call binary. It | 13 | 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 | |||
18 | embedded system. | 18 | embedded 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 |
24 | make | 24 | make |
diff --git a/examples/busybox.spec b/examples/busybox.spec index 73f47e191..03e4feb36 100644 --- a/examples/busybox.spec +++ b/examples/busybox.spec | |||
@@ -1,13 +1,13 @@ | |||
1 | Name: busybox | 1 | Name: busybox |
2 | Version: 0.41 | 2 | Version: 0.42 |
3 | Release: 1 | 3 | Release: 1 |
4 | Group: System/Utilities | 4 | Group: System/Utilities |
5 | Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary. | 5 | Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary. |
6 | Copyright: GPL | 6 | Copyright: GPL |
7 | Packager : Erik Andersen <andersen@lineo.com> | 7 | Packager : Erik Andersen <andersen@lineo.com> |
8 | Conflicts: fileutils grep shellutils | 8 | Conflicts: fileutils grep shellutils |
9 | Buildroot: /tmp/%{name}-%{version} | 9 | Buildroot: /tmp/%{Name}-%{Version} |
10 | Source: %{name}-%{version}.tar.gz | 10 | Source: %{Name}-%{Version}.tar.gz |
11 | 11 | ||
12 | %Description | 12 | %Description |
13 | BusyBox is a suite of "tiny" Unix utilities in a multi-call binary. It | 13 | 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 | |||
18 | embedded system. | 18 | embedded 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 |
24 | make | 24 | make |
@@ -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 |
513 | static 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 | ||
512 | void new_initAction (initActionEnum action, | 590 | void 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 |
513 | static 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 | ||
512 | void new_initAction (initActionEnum action, | 590 | void 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... */ |
@@ -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 | ||
117 | extern int logger_main(int argc, char **argv) | 113 | extern 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 | ||
117 | extern int logger_main(int argc, char **argv) | 113 | extern 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 | ||
@@ -108,9 +108,7 @@ typedef struct { | |||
108 | */ | 108 | */ |
109 | static int listFlag; | 109 | static int listFlag; |
110 | static int extractFlag; | 110 | static int extractFlag; |
111 | #ifdef BB_FEATURE_TAR_CREATE | ||
112 | static int createFlag; | 111 | static int createFlag; |
113 | #endif | ||
114 | static int verboseFlag; | 112 | static int verboseFlag; |
115 | static int tostdoutFlag; | 113 | static 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 | |||
274 | flagError: | ||
275 | fprintf (stderr, "Exactly one of 'c', 'x' or 't' must be specified\n"); | ||
276 | exit (FALSE); | ||
286 | } | 277 | } |
287 | 278 | ||
288 | 279 | ||