0.41
+ * New App: wc -- contributed by Edward Betts <edward@debian.org>
* Fixed a bug in both cp and mv preventing 'cp foo/README bar'
type commands (file in a directory to another directory)
from working.
* Fixed a logger bug that caused garbage to be written to the syslog
(unless you used busybox syslog, which hid the bug). Thanks
to Alex Holden <alex@linuxhacker.org> for the fix.
+ * /bin/true and /bin/false were echoing a blank line when run. Now fixed.
+ * mkdir -p would print an error when asked to mkdir an existing dir
+ with no interveining subdirectories.
+ * Fixed "syslogd -O" so that it works.
- -Erik Andersen,
+ -Erik Andersen
0.40
* New Apps: sort, uniq. -beppu
PROG=busybox
-VERSION=0.40
+VERSION=0.41
BUILDTIME=$(shell date "+%Y%m%d-%H%M")
# Comment out the following to make a debuggable build
* hwclock
* killall
* stty
-* wc
* tr
* expr (maybe?) (ash builtin?)
static int been_there_done_that = 0;
+#if 0
+void exit (int status) __attribute__ ((noreturn));
+void exit (int status) { _exit(status); };
+void abort (void) __attribute__ ((__noreturn__));
+void abort (void) { _exit(0); };
+int atexit (void (*__func) (void)) { _exit(0); };
+void *__libc_stack_end;
+#endif
+
+
static const struct Applet applets[] = {
#ifdef BB_BUSYBOX //bin
{"true", true_main},
{"false", false_main},
#endif
+#ifdef BB_WC //usr/bin
+ {"wc", wc_main},
+#endif
#ifdef BB_UNAME //bin
{"uname", uname_main},
#endif
{0}
};
+
+
int main(int argc, char **argv)
{
char *s = argv[0];
static int been_there_done_that = 0;
+#if 0
+void exit (int status) __attribute__ ((noreturn));
+void exit (int status) { _exit(status); };
+void abort (void) __attribute__ ((__noreturn__));
+void abort (void) { _exit(0); };
+int atexit (void (*__func) (void)) { _exit(0); };
+void *__libc_stack_end;
+#endif
+
+
static const struct Applet applets[] = {
#ifdef BB_BUSYBOX //bin
{"true", true_main},
{"false", false_main},
#endif
+#ifdef BB_WC //usr/bin
+ {"wc", wc_main},
+#endif
#ifdef BB_UNAME //bin
{"uname", uname_main},
#endif
{0}
};
+
+
int main(int argc, char **argv)
{
char *s = argv[0];
#define BB_SORT
#define BB_SWAPONOFF
#define BB_SYNC
-//#define BB_SYSLOGD
+#define BB_SYSLOGD
#define BB_TAIL
#define BB_TAR
#define BB_TEE
#define BB_TOUCH
#define BB_TRUE_FALSE
+#define BB_WC
#define BB_UMOUNT
#define BB_UNIQ
#define BB_UPDATE
Name: busybox
-Version: 0.40
+Version: 0.41
Release: 1
Group: System/Utilities
Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary.
%setup -q -n %{Name}-%{Version}
%Build
-BB_INIT_SCRIPT='\"/etc/rc.d/init.d/rcS\"' make
+make
%Install
rm -rf $RPM_BUILD_ROOT
strcpy (buf, *argv);
status=stat(buf, &statBuf);
- if (status != -1 && status != ENOENT ) {
+ if (parentFlag == FALSE && status != -1 && status != ENOENT ) {
fprintf(stderr, "%s: File exists\n", buf);
exit( FALSE);
}
createPath(buf, mode);
}
else {
- if (mkdir (buf, mode) != 0) {
+ if (mkdir (buf, mode) != 0 && parentFlag == FALSE) {
perror(buf);
exit( FALSE);
}
BusyBox 0.38, Functions and the Arguments they Support
+New Apps that have been added to BusyBox since this document was written:
+ ping, hostname, mkfifo, free, tail, du, tee, head, sort, uniq, lsmod, rmmod, fbset, and loadacm.
+
______________________________________________________________________________________________________
attributes group permissions and time information.
- -R recursive Copy to the current location and all subdirectories in the tree.
+ -R recursive Copies directories recursively
-r Perform interactive repairs.
- -q Perform automatic repairs
+ -a Perform automatic repairs
-v Verbose
-
sed
+ Usage: sed [-n] -e script [file...]
- Sed scripts are subject to the following format: 's/regexp/replacement/[gp]' which attempts to
-
- to match regexp against the pattern space and if successful, replaces the matched portion with
-
- replacement -r or -R Remove contents of directories recursively.
-
-
-
-
-________________________________________________________________________________________________________
-
-
-
-
+ Allowed sed scripts come in the following form:
+ 'ADDR [!] COMMAND'
-rmdir [OPTION] ... directory
+ where address ADDR can be:
+ NUMBER Match specified line number
+ $ Match last line
+ /REGEXP/ Match specified regexp
+ (! inverts the meaning of the match)
- Remove directories if they are empty.
+ and COMMAND can be:
+ s/regexp/replacement/[igp]
+ which attempt to match regexp against the pattern space
+ and if successful replaces the matched portion with replacement.
+ aTEXT
+ which appends TEXT after the pattern space
+ Options:
+ -e add the script to the commands to be executed
+ -n suppress automatic printing of pattern space
+ This version of sed matches full regular expresions.
-rmdir [OPTION] ... directory
-
- Remove directories if they are empty.
-
-
-
-
-________________________________________________________________________________________________________
-
-
-
-
-
-sed
-
- Sed scripts are subject to the following format: 's/regexp/replacement/[gp]' which attempts to
-
- match regexp against the pattern space and if successful, replaces the matched portion with
-
- replacement. This version of sed matches
-
- full regular expressions.
-
- -e Add the script to the commands to be executed.
-
- -n Suppress automatic printing of pattern space..
-
- -e Add the script to the commands to be executed.
-
- -n Suppress automatic printing of pattern space..
-
- -e Add the script to the commands to be executed.
-
- -n Suppress automatic printing of pattern space.
-
-
-
-
-
-________________________________________________________________________________________________________
-
-
-
-
-
sleep N
Pause for N seconds.
zcat [options] files
- Uncompress file from gzip, gunzip or compress command or standard input if file is '-'.
+ Usage: zcat [OPTION]... FILE
- -c Write output to standard output.
+ Uncompress FILE (or standard input if FILE is '-').
+ (When invoked as zcat, defaults to having -c turned on)
+ Options:
+ -c Write output to standard output
+ -t Test compressed file integrity
-gunzip (Same as zcat)
+gunzip (Same as zcat, but without the "-c" option.)
+gzip [OPTION]... FILE
-gzip (Same as zcat)
-
+ Compress FILE with maximum compression.
+ When FILE is -, reads standard input. Implies -c.
+ Options:
+ -c Write output to standard output instead of FILE.gz
Name: busybox
-Version: 0.40
+Version: 0.41
Release: 1
Group: System/Utilities
Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary.
%setup -q -n %{Name}-%{Version}
%Build
-BB_INIT_SCRIPT='\"/etc/rc.d/init.d/rcS\"' make
+make
%Install
rm -rf $RPM_BUILD_ROOT
static pid_t run(char* command,
char *terminal, int get_enter)
{
- int i;
+ int i, fd;
pid_t pid;
char* tmpCmd;
char* cmd[255];
close(2);
setsid();
- if (device_open(terminal, O_RDWR) < 0) {
- message(LOG|CONSOLE, "Bummer, can't open %s\r\n", terminal);
- exit(1);
- }
- dup(0);
- dup(0);
- tcsetpgrp (0, getpgrp());
- set_term(0);
-
/* Reset signal handlers set for parent process */
signal(SIGUSR1, SIG_DFL);
signal(SIGUSR2, SIG_DFL);
signal(SIGINT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
+ if ((fd = device_open(terminal, O_RDWR)) < 0) {
+ message(LOG|CONSOLE, "Bummer, can't open %s\r\n", terminal);
+ exit(1);
+ }
+ dup(fd);
+ dup(fd);
+ tcsetpgrp (0, getpgrp());
+ set_term(0);
if (get_enter==TRUE) {
/*
read(fileno(stdin), &c, 1);
}
+ /* Log the process name and args */
+ message(LOG|CONSOLE, "Starting pid %d, console %s: '",
+ shell_pgid, terminal, command);
+
/* Convert command (char*) into cmd (char**, one word per string) */
for (tmpCmd=command, i=0; (tmpCmd=strsep(&command, " \t")) != NULL;) {
if (*tmpCmd != '\0') {
cmd[i] = tmpCmd;
+ message(LOG|CONSOLE, "%s ", tmpCmd);
tmpCmd++;
i++;
}
}
cmd[i] = NULL;
-
- /* Log the process name and args */
- message(LOG, "Starting pid %d, console %s: '%s'\r\n",
- shell_pgid, terminal, cmd[0]);
+ message(LOG|CONSOLE, "'\r\n");
/* Now run it. The new program will take over this PID,
* so nothing further in init.c should be run. */
} else
strncpy(newAction->console, console, 255);
newAction->pid = 0;
-// message(LOG|CONSOLE, "process='%s' action='%d' console='%s'\n",
-// newAction->process, newAction->action, newAction->console);
+ message(LOG|CONSOLE, "process='%s' action='%d' console='%s'\n",
+ newAction->process, newAction->action, newAction->console);
}
void delete_initAction (initAction *action)
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");
}
-
- /* from the controlling terminal */
- setsid();
-
- /* Set up sig handlers -- be sure to clear all of these in run() */
+ /* Set up sig handlers -- be sure to
+ * clear all of these in run() */
signal(SIGUSR1, halt_signal);
signal(SIGUSR2, reboot_signal);
signal(SIGINT, reboot_signal);
* SIGINT on CAD so we can shut things down gracefully... */
reboot(RB_DISABLE_CAD);
#endif
-
+
/* Figure out where the default console should be */
console_init();
close(1);
close(2);
set_term(0);
+ setsid();
/* Make sure PATH is set to something sane */
putenv(_PATH_STDPATH);
-
/* Hello world */
#ifndef DEBUG_INIT
message(LOG|CONSOLE,
static pid_t run(char* command,
char *terminal, int get_enter)
{
- int i;
+ int i, fd;
pid_t pid;
char* tmpCmd;
char* cmd[255];
close(2);
setsid();
- if (device_open(terminal, O_RDWR) < 0) {
- message(LOG|CONSOLE, "Bummer, can't open %s\r\n", terminal);
- exit(1);
- }
- dup(0);
- dup(0);
- tcsetpgrp (0, getpgrp());
- set_term(0);
-
/* Reset signal handlers set for parent process */
signal(SIGUSR1, SIG_DFL);
signal(SIGUSR2, SIG_DFL);
signal(SIGINT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
+ if ((fd = device_open(terminal, O_RDWR)) < 0) {
+ message(LOG|CONSOLE, "Bummer, can't open %s\r\n", terminal);
+ exit(1);
+ }
+ dup(fd);
+ dup(fd);
+ tcsetpgrp (0, getpgrp());
+ set_term(0);
if (get_enter==TRUE) {
/*
read(fileno(stdin), &c, 1);
}
+ /* Log the process name and args */
+ message(LOG|CONSOLE, "Starting pid %d, console %s: '",
+ shell_pgid, terminal, command);
+
/* Convert command (char*) into cmd (char**, one word per string) */
for (tmpCmd=command, i=0; (tmpCmd=strsep(&command, " \t")) != NULL;) {
if (*tmpCmd != '\0') {
cmd[i] = tmpCmd;
+ message(LOG|CONSOLE, "%s ", tmpCmd);
tmpCmd++;
i++;
}
}
cmd[i] = NULL;
-
- /* Log the process name and args */
- message(LOG, "Starting pid %d, console %s: '%s'\r\n",
- shell_pgid, terminal, cmd[0]);
+ message(LOG|CONSOLE, "'\r\n");
/* Now run it. The new program will take over this PID,
* so nothing further in init.c should be run. */
} else
strncpy(newAction->console, console, 255);
newAction->pid = 0;
-// message(LOG|CONSOLE, "process='%s' action='%d' console='%s'\n",
-// newAction->process, newAction->action, newAction->console);
+ message(LOG|CONSOLE, "process='%s' action='%d' console='%s'\n",
+ newAction->process, newAction->action, newAction->console);
}
void delete_initAction (initAction *action)
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");
}
-
- /* from the controlling terminal */
- setsid();
-
- /* Set up sig handlers -- be sure to clear all of these in run() */
+ /* Set up sig handlers -- be sure to
+ * clear all of these in run() */
signal(SIGUSR1, halt_signal);
signal(SIGUSR2, reboot_signal);
signal(SIGINT, reboot_signal);
* SIGINT on CAD so we can shut things down gracefully... */
reboot(RB_DISABLE_CAD);
#endif
-
+
/* Figure out where the default console should be */
console_init();
close(1);
close(2);
set_term(0);
+ setsid();
/* Make sure PATH is set to something sane */
putenv(_PATH_STDPATH);
-
/* Hello world */
#ifndef DEBUG_INIT
message(LOG|CONSOLE,
extern int tput_main(int argc, char** argv);
extern int true_main(int argc, char** argv);
extern int tryopen_main(int argc, char** argv);
+extern int wc_main(int argc, char** argv);
extern int umount_main(int argc, char** argv);
extern int uniq_main(int argc, char** argv);
extern int update_main(int argc, char** argv);
strcpy (buf, *argv);
status=stat(buf, &statBuf);
- if (status != -1 && status != ENOENT ) {
+ if (parentFlag == FALSE && status != -1 && status != ENOENT ) {
fprintf(stderr, "%s: File exists\n", buf);
exit( FALSE);
}
createPath(buf, mode);
}
else {
- if (mkdir (buf, mode) != 0) {
+ if (mkdir (buf, mode) != 0 && parentFlag == FALSE) {
perror(buf);
exit( FALSE);
}
echo "Bummer. File copy failed."
exit 0
else
- echo "Cool. File copy is ok."
+ echo "Cool. 'cp tar.c testdir' is ok."
fi
rm -rf testdir
echo "Bummer. File copy to a directory failed."
exit 0
else
- echo "Cool. File copy to a directory is ok."
+ echo "Cool. 'cp tar.c testdir/foo' is ok."
fi
echo "Bummer. File copy to a directory w/ a '/' failed."
exit 0
else
- echo "Cool. File copy to a directory w/ a '/' is ok."
+ echo "Cool. 'cp tar.c testdir/foo/' is ok."
fi
echo "Bummer. Local dir copy failed."
exit 0
else
- echo "Cool. Local dir copy is ok."
+ echo "Cool. 'cp -a X11 testdir' is ok."
fi
rm -rf testdir X11
echo "Bummer. Local dir copy w/ a '/' failed."
exit 0
else
- echo "Cool. Local dir copy w/ a '/' is ok."
+ echo "Cool. 'cp -a X11 testdir/' is ok."
fi
rm -rf testdir X11
echo "Bummer. Local dir copy w/ a src '/' failed."
exit 0
else
- echo "Cool. Local dir copy w/ a src '/' is ok."
+ echo "Cool. 'cp -a X11/ testdir' is ok."
fi
rm -rf testdir X11
echo "Bummer. Local dir copy w/ 2x '/'s failed."
exit 0
else
- echo "Cool. Local dir copy w/ 2x '/'s is ok."
+ echo "Cool. 'cp -a X11/ testdir/' is ok."
fi
rm -rf testdir X11
echo "Bummer. Remote dir copy failed."
exit 0
else
- echo "Cool. Remote dir copy is ok."
+ echo "Cool. 'cp -a /etc/X11 testdir' is ok."
fi
echo "Bummer. Remote dir copy to a directory failed."
exit 0
else
- echo "Cool. Remote dir copy to a directory is ok."
+ echo "Cool. 'cp -a /etc/X11 testdir/foo' is ok."
fi
echo "Bummer. Remote dir copy to a directory w/ a '/' failed."
exit 0
else
- echo "Cool. Remote dir copy to a directory w/ a '/' is ok."
+ echo "Cool. 'cp -a /etc/X11 testdir/foo/' is ok."
fi
rm -rf testdir
echo "Bummer. cp README foo failed."
exit 0
else
- echo "Cool. cp README foo is ok."
+ echo "Cool. 'cp README foo' is ok."
fi
if ! eval ./busybox cp foo/README bar ; then
echo "Bummer. cp foo/README bar failed."
exit 0
else
- echo "Cool. cp foo/README bar is ok."
+ echo "Cool. 'cp foo/README bar' is ok."
+fi
+
+rm -f bar/README
+ENVVAR1=foo
+ENVVAR2=bar
+if ! eval ./busybox cp $ENVVAR1/README $ENVVAR2 ; then
+ echo "Bummer. cp foo/README bar failed."
+ exit 0
+else
+ echo "Cool. 'cp \$ENVVAR1/README \$ENVVAR2' is ok."
fi
rm -rf foo bar
#ifdef BB_KLOGD
int startKlogd = TRUE;
#endif
+ int stopDoingThat = FALSE;
char *p;
char **argv1=argv;
while (--argc > 0 && **(++argv1) == '-') {
- while (*(++(*argv1))) {
+ stopDoingThat = FALSE;
+ while (stopDoingThat == FALSE && *(++(*argv1))) {
switch (**argv1) {
case 'm':
if (--argc == 0) {
usage(syslogd_usage);
}
logFilePath = *(++argv1);
+ stopDoingThat = TRUE;
break;
default:
usage(syslogd_usage);
#ifdef BB_KLOGD
int startKlogd = TRUE;
#endif
+ int stopDoingThat = FALSE;
char *p;
char **argv1=argv;
while (--argc > 0 && **(++argv1) == '-') {
- while (*(++(*argv1))) {
+ stopDoingThat = FALSE;
+ while (stopDoingThat == FALSE && *(++(*argv1))) {
switch (**argv1) {
case 'm':
if (--argc == 0) {
usage(syslogd_usage);
}
logFilePath = *(++argv1);
+ stopDoingThat = TRUE;
break;
default:
usage(syslogd_usage);
extern int
true_main(int argc, char** argv)
{
- return( TRUE);
+ exit( TRUE);
}
extern int
false_main(int argc, char** argv)
{
- return( FALSE);
+ exit( FALSE);
}
int (*dirAction) (const char *fileName, struct stat* statbuf))
{
int status;
- struct stat statbuf;
+ struct stat statbuf, statbuf1;
struct dirent *next;
if (followLinks == TRUE)
else
status = lstat(fileName, &statbuf);
+ status = lstat(fileName, &statbuf);
if (status < 0) {
perror(fileName);
return (FALSE);
return (TRUE);
}
}
+
+ status = lstat(fileName, &statbuf1);
+ if (status < 0) {
+ perror(fileName);
+ return (FALSE);
+ }
- if (S_ISDIR(statbuf.st_mode)) {
+ if (S_ISDIR(statbuf.st_mode) && S_ISDIR(statbuf1.st_mode)) {
DIR *dir;
dir = opendir(fileName);
if (!dir) {