file existed.
* df will not exit on error, but will try to stat all mounted filesystems.
* Fixed tar so uid/gid/permissions on extracted tarballs will be correct.
+ * Fixed find -name so it properly uses shell wildcard patterns
+ (i.e. `*', `?', and `[]') instead of regular expressions, which
+ was causing some confusing and unexpected behavior.
+
+ -Erik Andrsen, Dec 2, 1999
0.37
* Wrote a micro syslogd, and a logger util (to log things to the syslog
PROG=busybox
-VERSION=0.37
+VERSION=0.38
BUILDTIME=$(shell date "+%Y%m%d-%H%M")
# Comment out the following to make a debuggable build
-TODO list for busybox in no particular order
+TODO list for busybox in no particular order. Just because something
+is listed here doesn't mean that it is going to be added to busybox,
+or that doing so is even a good idea. It just means that I _might_ get
+around to it some time. If you have any good ideas, please let me know.
-If you have any good ideas, please let me know.
+ -Erik
+
+-----------
* Allow tar to create archives with sockets, devices, and other special files
-* Add in a mini modprobe, insmod, rmmod
-* poweroff
+* Add in a mini insmod, rmmod, lsmod
* Change init so halt, reboot (and poweroff) work with an initrd
when init is not PID 1
-*
+* poweroff
+* du
+* mkfifo
+* hostname/dnsdomainname
+* ping/traceroute/nslookup/netstat
+* rdate
+* hwclock
+* login/getty
+* free
+* killall
+* tee
+* stty
+* head/tail
+* sort/uniq
+* wc
+* tr
+* expr (maybe)?
+
h=`sort busybox.links | uniq`
for i in $h ; do
- mypath=`echo $i | sed -e 's/\(^.*\/\)\(.*\)/\1/g' `;
- myapp=`echo $i | sed -e 's/\(^.*\/\)\(.*\)/\2/g' `;
- echo " $1$mypath$myapp -> /bin/busybox"
- mkdir -p $1$mypath
- (cd $1$mypath && rm -f $1$mypath$myapp && ln -s /bin/busybox $1$mypath$myapp )
+ echo " $1$i -> /bin/busybox"
+ mkdir -p $1/`echo $i | sed -e 's/\/[^\/]*$//' `
+ rm -f $1$i
+ ln -s /bin/busybox $1$i
done
rm -f $1/bin/busybox
install -m 755 busybox $1/bin/busybox
Name: busybox
-Version: 0.37
+Version: 0.38
Release: 1
Group: System/Utilities
Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary.
}
//lseek(inFd, skipBlocks*blockSize, SEEK_SET);
+ //
+ //TODO: Convert to using fullRead & fullWrite
+ // from utilitity.c
+ // -Erik
while (outTotal < count * blockSize) {
inCc = read (inFd, buf, blockSize);
if (inCc < 0) {
}
//lseek(inFd, skipBlocks*blockSize, SEEK_SET);
+ //
+ //TODO: Convert to using fullRead & fullWrite
+ // from utilitity.c
+ // -Erik
while (outTotal < count * blockSize) {
inCc = read (inFd, buf, blockSize);
if (inCc < 0) {
Name: busybox
-Version: 0.37
+Version: 0.38
Release: 1
Group: System/Utilities
Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary.
{
if (pattern==NULL)
fprintf(stdout, "%s\n", fileName);
- else if (find_match((char*)fileName, pattern, TRUE) == TRUE)
- fprintf(stdout, "%s\n", fileName);
+ else {
+ char* tmp = strrchr( fileName, '/');
+ if (tmp == NULL)
+ tmp = (char*)fileName;
+ else
+ tmp++;
+ if (check_wildcard_match(tmp, pattern) == TRUE)
+ fprintf(stdout, "%s\n", fileName);
+ }
return( TRUE);
}
{
if (pattern==NULL)
fprintf(stdout, "%s\n", fileName);
- else if (find_match((char*)fileName, pattern, TRUE) == TRUE)
- fprintf(stdout, "%s\n", fileName);
+ else {
+ char* tmp = strrchr( fileName, '/');
+ if (tmp == NULL)
+ tmp = (char*)fileName;
+ else
+ tmp++;
+ if (check_wildcard_match(tmp, pattern) == TRUE)
+ fprintf(stdout, "%s\n", fileName);
+ }
return( TRUE);
}
#include <errno.h>
#include <signal.h>
#include <termios.h>
+#include <paths.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <sys/wait.h>
#include <sys/syslog.h>
#endif
-#define DEV_CONSOLE "/dev/console" /* Logical system console */
#define VT_PRIMARY "/dev/tty1" /* Primary virtual console */
#define VT_SECONDARY "/dev/tty2" /* Virtual console */
#define VT_LOG "/dev/tty3" /* Virtual console */
#define SERIAL_CON1 "/dev/ttyS1" /* Serial console */
#define SHELL "/bin/sh" /* Default shell */
#define INITSCRIPT "/etc/init.d/rcS" /* Initscript. */
-#define PATH_DEFAULT "PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin"
#define LOG 0x1
#define CONSOLE 0x2
-static char *console = DEV_CONSOLE;
+static char *console = _PATH_CONSOLE;
static char *second_console = VT_SECONDARY;
static char *log = VT_LOG;
static int kernel_version = 0;
if (device & CONSOLE) {
/* Always send console messages to /dev/console so people will see them. */
- if ((fd = device_open(DEV_CONSOLE, O_WRONLY|O_NOCTTY|O_NDELAY)) >= 0) {
+ if ((fd = device_open(_PATH_CONSOLE, O_WRONLY|O_NOCTTY|O_NDELAY)) >= 0) {
va_start(arguments, fmt);
vdprintf(fd, fmt, arguments);
va_end(arguments);
/* this is linux virtual tty */
snprintf( the_console, sizeof the_console, "/dev/tty%d", vt.v_active );
} else {
- console = DEV_CONSOLE;
+ console = _PATH_CONSOLE;
tried_devcons++;
}
}
/* Can't open selected console -- try /dev/console */
if (!tried_devcons) {
tried_devcons++;
- console = DEV_CONSOLE;
+ console = _PATH_CONSOLE;
continue;
}
/* Can't open selected console -- try vt1 */
"The system is halted. Press CTRL-ALT-DEL or turn off power\r\n");
sync();
#ifndef DEBUG_INIT
+ while (1) sleep(1);
reboot(RB_HALT_SYSTEM);
//reboot(RB_POWER_OFF);
#endif
shutdown_system();
message(CONSOLE, "Please stand by while rebooting the system.\r\n");
sync();
+ while (1) sleep(1);
#ifndef DEBUG_INIT
reboot(RB_AUTOBOOT);
#endif
setsid();
/* Make sure PATH is set to something sane */
- putenv(PATH_DEFAULT);
+ putenv(_PATH_STDPATH);
/* Hello world */
#include <errno.h>
#include <signal.h>
#include <termios.h>
+#include <paths.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <sys/wait.h>
#include <sys/syslog.h>
#endif
-#define DEV_CONSOLE "/dev/console" /* Logical system console */
#define VT_PRIMARY "/dev/tty1" /* Primary virtual console */
#define VT_SECONDARY "/dev/tty2" /* Virtual console */
#define VT_LOG "/dev/tty3" /* Virtual console */
#define SERIAL_CON1 "/dev/ttyS1" /* Serial console */
#define SHELL "/bin/sh" /* Default shell */
#define INITSCRIPT "/etc/init.d/rcS" /* Initscript. */
-#define PATH_DEFAULT "PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin"
#define LOG 0x1
#define CONSOLE 0x2
-static char *console = DEV_CONSOLE;
+static char *console = _PATH_CONSOLE;
static char *second_console = VT_SECONDARY;
static char *log = VT_LOG;
static int kernel_version = 0;
if (device & CONSOLE) {
/* Always send console messages to /dev/console so people will see them. */
- if ((fd = device_open(DEV_CONSOLE, O_WRONLY|O_NOCTTY|O_NDELAY)) >= 0) {
+ if ((fd = device_open(_PATH_CONSOLE, O_WRONLY|O_NOCTTY|O_NDELAY)) >= 0) {
va_start(arguments, fmt);
vdprintf(fd, fmt, arguments);
va_end(arguments);
/* this is linux virtual tty */
snprintf( the_console, sizeof the_console, "/dev/tty%d", vt.v_active );
} else {
- console = DEV_CONSOLE;
+ console = _PATH_CONSOLE;
tried_devcons++;
}
}
/* Can't open selected console -- try /dev/console */
if (!tried_devcons) {
tried_devcons++;
- console = DEV_CONSOLE;
+ console = _PATH_CONSOLE;
continue;
}
/* Can't open selected console -- try vt1 */
"The system is halted. Press CTRL-ALT-DEL or turn off power\r\n");
sync();
#ifndef DEBUG_INIT
+ while (1) sleep(1);
reboot(RB_HALT_SYSTEM);
//reboot(RB_POWER_OFF);
#endif
shutdown_system();
message(CONSOLE, "Please stand by while rebooting the system.\r\n");
sync();
+ while (1) sleep(1);
#ifndef DEBUG_INIT
reboot(RB_AUTOBOOT);
#endif
setsid();
/* Make sure PATH is set to something sane */
- putenv(PATH_DEFAULT);
+ putenv(_PATH_STDPATH);
/* Hello world */
h=`sort busybox.links | uniq`
for i in $h ; do
- mypath=`echo $i | sed -e 's/\(^.*\/\)\(.*\)/\1/g' `;
- myapp=`echo $i | sed -e 's/\(^.*\/\)\(.*\)/\2/g' `;
- echo " $1$mypath$myapp -> /bin/busybox"
- mkdir -p $1$mypath
- (cd $1$mypath && rm -f $1$mypath$myapp && ln -s /bin/busybox $1$mypath$myapp )
+ echo " $1$i -> /bin/busybox"
+ mkdir -p $1/`echo $i | sed -e 's/\/[^\/]*$//' `
+ rm -f $1$i
+ ln -s /bin/busybox $1$i
done
rm -f $1/bin/busybox
install -m 755 busybox $1/bin/busybox
extern void write_mtab(char* blockDevice, char* directory,
char* filesystemType, long flags, char* string_flags);
extern void erase_mtab(const char * name);
+extern int check_wildcard_match(const char* text, const char* pattern);
#if defined BB_MTAB
#include <ctype.h>
-#if ( defined BB_GREP || defined BB_FIND || defined BB_SED)
+#if ( defined BB_GREP || defined BB_SED)
/* This also tries to find a needle in a haystack, but uses
* real regular expressions.... The fake regular expression
#include <signal.h>
#include <ctype.h>
#include <netdb.h>
+#include <sys/klog.h>
+#include <errno.h>
+#include <paths.h>
+
+#define ksyslog klogctl
+extern int ksyslog(int type, char *buf, int len);
/* SYSLOG_NAMES defined to pull some extra junk from syslog.h */
/* Path for the file where all log messages are written */
#define __LOG_FILE "/var/log/messages"
-/* Path to the current console device */
-#define __DEV_CONSOLE "/dev/console"
static char* logFilePath = __LOG_FILE;
"\t-n\tDo not fork into the background (for when run by init)\n"
"\t-O\tSpecify an alternate log file. default=/var/log/messages\n";
-
+static int kmsg;
/* try to open up the specified device */
static int device_open(char *device, int mode)
close(fd);
} else {
/* Always send console messages to /dev/console so people will see them. */
- if ((fd = device_open(__DEV_CONSOLE, O_WRONLY|O_NOCTTY|O_NONBLOCK)) >= 0) {
+ if ((fd = device_open(_PATH_CONSOLE, O_WRONLY|O_NOCTTY|O_NONBLOCK)) >= 0) {
va_start(arguments, fmt);
vdprintf(fd, fmt, arguments);
va_end(arguments);
close(fd);
}
+static void klogd_signal(int sig)
+{
+ //ksyslog(7, NULL, 0);
+ //ksyslog(0, 0, 0);
+ logMessage(LOG_SYSLOG|LOG_INFO, "Kernel log daemon terminating.");
+ exit( TRUE);
+}
+
+
+static void doKlogd(void)
+{
+ int priority=LOG_INFO;
+ struct stat sb;
+ char log_buffer[4096];
+
+ /* Set up sig handlers */
+ signal(SIGINT, klogd_signal);
+ signal(SIGKILL, klogd_signal);
+ signal(SIGTERM, klogd_signal);
+ signal(SIGHUP, klogd_signal);
+ logMessage(LOG_SYSLOG|LOG_INFO, "klogd started: "
+ "BusyBox v" BB_VER " (" BB_BT ") multi-call binary");
+
+ //ksyslog(1, NULL, 0);
+ if ( ((stat(_PATH_KLOG, &sb) < 0) && (errno == ENOENT)) ||
+ ( (kmsg = open(_PATH_KLOG, O_RDONLY)) < 0 ) ) {
+ char message[80];
+ snprintf(message, 79, "klogd: Cannot open %s, " \
+ "%d - %s.\n", _PATH_KLOG, errno, strerror(errno));
+ logMessage(LOG_SYSLOG|LOG_ERR, message);
+ klogd_signal(0);
+ }
+ while (1) {
+ memset(log_buffer, '\0', sizeof(log_buffer));
+ if ( read(kmsg, log_buffer, sizeof(log_buffer)-1) < 0 ) {
+ char message[80];
+ if ( errno == EINTR )
+ continue;
+ snprintf(message, 79, "klogd: Cannot read proc file system: %d - %s.\n",
+ errno, strerror(errno));
+ logMessage(LOG_SYSLOG|LOG_ERR, message);
+ klogd_signal(0);
+ }
+#if 0
+ if ( ksyslog(2, log_buffer, sizeof(log_buffer)) < 0 ) {
+ char message[80];
+ if ( errno == EINTR )
+ continue;
+ snprintf(message, 79, "klogd: Error return from sys_sycall: " \
+ "%d - %s.\n", errno, strerror(errno));
+ logMessage(LOG_SYSLOG|LOG_ERR, message);
+ exit(1);
+ }
+#endif
+ fprintf(stderr, "the kernel says '%s'\n", log_buffer);
+ if ( *log_buffer == '<' )
+ {
+ switch ( *(log_buffer+1) )
+ {
+ case '0':
+ priority = LOG_EMERG;
+ break;
+ case '1':
+ priority = LOG_ALERT;
+ break;
+ case '2':
+ priority = LOG_CRIT;
+ break;
+ case '3':
+ priority = LOG_ERR;
+ break;
+ case '4':
+ priority = LOG_WARNING;
+ break;
+ case '5':
+ priority = LOG_NOTICE;
+ break;
+ case '6':
+ priority = LOG_INFO;
+ break;
+ case '7':
+ default:
+ priority = LOG_DEBUG;
+ }
+ *log_buffer += 3;
+ }
+ logMessage(LOG_KERN|priority, log_buffer);
+ }
+
+}
+
extern int syslogd_main(int argc, char **argv)
{
- int pid;
+ int pid, klogd_pid;
int doFork = TRUE;
+ char **argv1=argv;
- while (--argc > 0 && **(++argv) == '-') {
- while (*(++(*argv))) {
- switch (**argv) {
+ while (--argc > 0 && **(++argv1) == '-') {
+ while (*(++(*argv1))) {
+ switch (**argv1) {
case 'm':
if (--argc == 0) {
usage(syslogd_usage);
}
- MarkInterval = atoi(*(++argv))*60;
+ MarkInterval = atoi(*(++argv1))*60;
break;
case 'n':
doFork = FALSE;
if (--argc == 0) {
usage(syslogd_usage);
}
- logFilePath = *(++argv);
+ logFilePath = *(++argv1);
break;
default:
usage(syslogd_usage);
if ( pid < 0 )
exit( pid);
else if ( pid == 0 ) {
+ strncpy(argv[0], "syslogd",strlen(argv[0]));
doSyslogd();
}
} else {
doSyslogd();
}
+
+ /* Start klogd process */
+ klogd_pid = fork();
+ if (klogd_pid == 0 ) {
+ strncpy(argv[0], "klogd", strlen(argv[0]));
+ doKlogd();
+ }
+
exit( TRUE);
}
#include <signal.h>
#include <ctype.h>
#include <netdb.h>
+#include <sys/klog.h>
+#include <errno.h>
+#include <paths.h>
+
+#define ksyslog klogctl
+extern int ksyslog(int type, char *buf, int len);
/* SYSLOG_NAMES defined to pull some extra junk from syslog.h */
/* Path for the file where all log messages are written */
#define __LOG_FILE "/var/log/messages"
-/* Path to the current console device */
-#define __DEV_CONSOLE "/dev/console"
static char* logFilePath = __LOG_FILE;
"\t-n\tDo not fork into the background (for when run by init)\n"
"\t-O\tSpecify an alternate log file. default=/var/log/messages\n";
-
+static int kmsg;
/* try to open up the specified device */
static int device_open(char *device, int mode)
close(fd);
} else {
/* Always send console messages to /dev/console so people will see them. */
- if ((fd = device_open(__DEV_CONSOLE, O_WRONLY|O_NOCTTY|O_NONBLOCK)) >= 0) {
+ if ((fd = device_open(_PATH_CONSOLE, O_WRONLY|O_NOCTTY|O_NONBLOCK)) >= 0) {
va_start(arguments, fmt);
vdprintf(fd, fmt, arguments);
va_end(arguments);
close(fd);
}
+static void klogd_signal(int sig)
+{
+ //ksyslog(7, NULL, 0);
+ //ksyslog(0, 0, 0);
+ logMessage(LOG_SYSLOG|LOG_INFO, "Kernel log daemon terminating.");
+ exit( TRUE);
+}
+
+
+static void doKlogd(void)
+{
+ int priority=LOG_INFO;
+ struct stat sb;
+ char log_buffer[4096];
+
+ /* Set up sig handlers */
+ signal(SIGINT, klogd_signal);
+ signal(SIGKILL, klogd_signal);
+ signal(SIGTERM, klogd_signal);
+ signal(SIGHUP, klogd_signal);
+ logMessage(LOG_SYSLOG|LOG_INFO, "klogd started: "
+ "BusyBox v" BB_VER " (" BB_BT ") multi-call binary");
+
+ //ksyslog(1, NULL, 0);
+ if ( ((stat(_PATH_KLOG, &sb) < 0) && (errno == ENOENT)) ||
+ ( (kmsg = open(_PATH_KLOG, O_RDONLY)) < 0 ) ) {
+ char message[80];
+ snprintf(message, 79, "klogd: Cannot open %s, " \
+ "%d - %s.\n", _PATH_KLOG, errno, strerror(errno));
+ logMessage(LOG_SYSLOG|LOG_ERR, message);
+ klogd_signal(0);
+ }
+ while (1) {
+ memset(log_buffer, '\0', sizeof(log_buffer));
+ if ( read(kmsg, log_buffer, sizeof(log_buffer)-1) < 0 ) {
+ char message[80];
+ if ( errno == EINTR )
+ continue;
+ snprintf(message, 79, "klogd: Cannot read proc file system: %d - %s.\n",
+ errno, strerror(errno));
+ logMessage(LOG_SYSLOG|LOG_ERR, message);
+ klogd_signal(0);
+ }
+#if 0
+ if ( ksyslog(2, log_buffer, sizeof(log_buffer)) < 0 ) {
+ char message[80];
+ if ( errno == EINTR )
+ continue;
+ snprintf(message, 79, "klogd: Error return from sys_sycall: " \
+ "%d - %s.\n", errno, strerror(errno));
+ logMessage(LOG_SYSLOG|LOG_ERR, message);
+ exit(1);
+ }
+#endif
+ fprintf(stderr, "the kernel says '%s'\n", log_buffer);
+ if ( *log_buffer == '<' )
+ {
+ switch ( *(log_buffer+1) )
+ {
+ case '0':
+ priority = LOG_EMERG;
+ break;
+ case '1':
+ priority = LOG_ALERT;
+ break;
+ case '2':
+ priority = LOG_CRIT;
+ break;
+ case '3':
+ priority = LOG_ERR;
+ break;
+ case '4':
+ priority = LOG_WARNING;
+ break;
+ case '5':
+ priority = LOG_NOTICE;
+ break;
+ case '6':
+ priority = LOG_INFO;
+ break;
+ case '7':
+ default:
+ priority = LOG_DEBUG;
+ }
+ *log_buffer += 3;
+ }
+ logMessage(LOG_KERN|priority, log_buffer);
+ }
+
+}
+
extern int syslogd_main(int argc, char **argv)
{
- int pid;
+ int pid, klogd_pid;
int doFork = TRUE;
+ char **argv1=argv;
- while (--argc > 0 && **(++argv) == '-') {
- while (*(++(*argv))) {
- switch (**argv) {
+ while (--argc > 0 && **(++argv1) == '-') {
+ while (*(++(*argv1))) {
+ switch (**argv1) {
case 'm':
if (--argc == 0) {
usage(syslogd_usage);
}
- MarkInterval = atoi(*(++argv))*60;
+ MarkInterval = atoi(*(++argv1))*60;
break;
case 'n':
doFork = FALSE;
if (--argc == 0) {
usage(syslogd_usage);
}
- logFilePath = *(++argv);
+ logFilePath = *(++argv1);
break;
default:
usage(syslogd_usage);
if ( pid < 0 )
exit( pid);
else if ( pid == 0 ) {
+ strncpy(argv[0], "syslogd",strlen(argv[0]));
doSyslogd();
}
} else {
doSyslogd();
}
+
+ /* Start klogd process */
+ klogd_pid = fork();
+ if (klogd_pid == 0 ) {
+ strncpy(argv[0], "klogd", strlen(argv[0]));
+ doKlogd();
+ }
+
exit( TRUE);
}
#endif
-#if !defined BB_REGEXP && (defined BB_GREP || defined BB_FIND || defined BB_SED)
+#if !defined BB_REGEXP && (defined BB_GREP || defined BB_SED)
/* Do a case insensitive strstr() */
char* stristr(char *haystack, const char *needle)
#endif
+#if defined BB_FIND
+/*
+ * Routine to see if a text string is matched by a wildcard pattern.
+ * Returns TRUE if the text is matched, or FALSE if it is not matched
+ * or if the pattern is invalid.
+ * * matches zero or more characters
+ * ? matches a single character
+ * [abc] matches 'a', 'b' or 'c'
+ * \c quotes character c
+ * Adapted from code written by Ingo Wilken, and
+ * then taken from sash, Copyright (c) 1999 by David I. Bell
+ * Permission is granted to use, distribute, or modify this source,
+ * provided that this copyright notice remains intact.
+ * Permission to distribute this code under the GPL has been granted.
+ */
+extern int
+check_wildcard_match(const char* text, const char* pattern)
+{
+ const char* retryPat;
+ const char* retryText;
+ int ch;
+ int found;
+
+ retryPat = NULL;
+ retryText = NULL;
+
+ while (*text || *pattern)
+ {
+ ch = *pattern++;
+
+ switch (ch)
+ {
+ case '*':
+ retryPat = pattern;
+ retryText = text;
+ break;
+
+ case '[':
+ found = FALSE;
+
+ while ((ch = *pattern++) != ']')
+ {
+ if (ch == '\\')
+ ch = *pattern++;
+
+ if (ch == '\0')
+ return FALSE;
+
+ if (*text == ch)
+ found = TRUE;
+ }
+
+ //if (!found)
+ if (found==TRUE)
+ {
+ pattern = retryPat;
+ text = ++retryText;
+ }
+
+ /* fall into next case */
+
+ case '?':
+ if (*text++ == '\0')
+ return FALSE;
+
+ break;
+
+ case '\\':
+ ch = *pattern++;
+
+ if (ch == '\0')
+ return FALSE;
+
+ /* fall into next case */
+
+ default:
+ if (*text == ch)
+ {
+ if (*text)
+ text++;
+ break;
+ }
+
+ if (*text)
+ {
+ pattern = retryPat;
+ text = ++retryText;
+ break;
+ }
+
+ return FALSE;
+ }
+
+ if (pattern == NULL)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+#endif
+
+
#if defined BB_DF | defined BB_MTAB
/* END CODE */
+
+
+
+
+
+
+