diff --git a/Changelog b/Changelog index b3f6c45fe..23dbfa7dd 100644 --- a/Changelog +++ b/Changelog @@ -3,6 +3,11 @@ 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 diff --git a/Makefile b/Makefile index 085ad8126..4b174c313 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ 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 diff --git a/TODO b/TODO index 44525cf32..1a65a57a8 100644 --- a/TODO +++ b/TODO @@ -1,10 +1,31 @@ -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)? + diff --git a/applets/install.sh b/applets/install.sh index 458e65ce9..670c0c6e1 100755 --- a/applets/install.sh +++ b/applets/install.sh @@ -10,11 +10,10 @@ fi 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 diff --git a/busybox.spec b/busybox.spec index 92000e7f4..690c7f206 100644 --- a/busybox.spec +++ b/busybox.spec @@ -1,5 +1,5 @@ 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. diff --git a/coreutils/dd.c b/coreutils/dd.c index a2dc1c396..b37038748 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c @@ -185,6 +185,10 @@ extern int dd_main (int argc, char **argv) } //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) { diff --git a/dd.c b/dd.c index a2dc1c396..b37038748 100644 --- a/dd.c +++ b/dd.c @@ -185,6 +185,10 @@ extern int dd_main (int argc, char **argv) } //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) { diff --git a/examples/busybox.spec b/examples/busybox.spec index 92000e7f4..690c7f206 100644 --- a/examples/busybox.spec +++ b/examples/busybox.spec @@ -1,5 +1,5 @@ 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. diff --git a/find.c b/find.c index 0f1f5f189..40a508f05 100644 --- a/find.c +++ b/find.c @@ -51,8 +51,15 @@ static int fileAction(const char *fileName, struct stat* statbuf) { 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); } diff --git a/findutils/find.c b/findutils/find.c index 0f1f5f189..40a508f05 100644 --- a/findutils/find.c +++ b/findutils/find.c @@ -51,8 +51,15 @@ static int fileAction(const char *fileName, struct stat* statbuf) { 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); } diff --git a/init.c b/init.c index 7258d3151..088a890cc 100644 --- a/init.c +++ b/init.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -44,7 +45,6 @@ #include #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 */ @@ -52,11 +52,10 @@ #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; @@ -126,7 +125,7 @@ void message(int device, char *fmt, ...) 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); @@ -242,7 +241,7 @@ static void console_init() /* 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++; } } @@ -251,7 +250,7 @@ static void console_init() /* 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 */ @@ -421,6 +420,7 @@ static void halt_signal(int sig) "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 @@ -432,6 +432,7 @@ static void reboot_signal(int sig) 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 @@ -502,7 +503,7 @@ extern int init_main(int argc, char **argv) setsid(); /* Make sure PATH is set to something sane */ - putenv(PATH_DEFAULT); + putenv(_PATH_STDPATH); /* Hello world */ diff --git a/init/init.c b/init/init.c index 7258d3151..088a890cc 100644 --- a/init/init.c +++ b/init/init.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -44,7 +45,6 @@ #include #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 */ @@ -52,11 +52,10 @@ #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; @@ -126,7 +125,7 @@ void message(int device, char *fmt, ...) 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); @@ -242,7 +241,7 @@ static void console_init() /* 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++; } } @@ -251,7 +250,7 @@ static void console_init() /* 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 */ @@ -421,6 +420,7 @@ static void halt_signal(int sig) "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 @@ -432,6 +432,7 @@ static void reboot_signal(int sig) 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 @@ -502,7 +503,7 @@ extern int init_main(int argc, char **argv) setsid(); /* Make sure PATH is set to something sane */ - putenv(PATH_DEFAULT); + putenv(_PATH_STDPATH); /* Hello world */ diff --git a/install.sh b/install.sh index 458e65ce9..670c0c6e1 100755 --- a/install.sh +++ b/install.sh @@ -10,11 +10,10 @@ fi 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 diff --git a/internal.h b/internal.h index 5cca663b4..85c37c429 100644 --- a/internal.h +++ b/internal.h @@ -150,6 +150,7 @@ extern struct mntent *findMountPoint(const char *name, const char *table); 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 diff --git a/regexp.c b/regexp.c index 9f9b5c28c..02b1fe505 100644 --- a/regexp.c +++ b/regexp.c @@ -7,7 +7,7 @@ #include -#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 diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 736adf7d1..3c7b0170d 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -32,6 +32,12 @@ #include #include #include +#include +#include +#include + +#define ksyslog klogctl +extern int ksyslog(int type, char *buf, int len); /* SYSLOG_NAMES defined to pull some extra junk from syslog.h */ @@ -40,8 +46,6 @@ /* 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; @@ -58,7 +62,7 @@ static const char syslogd_usage[] = "\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) @@ -92,7 +96,7 @@ static void message(char *fmt, ...) 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); @@ -250,20 +254,112 @@ static void doSyslogd(void) 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; @@ -272,7 +368,7 @@ extern int syslogd_main(int argc, char **argv) if (--argc == 0) { usage(syslogd_usage); } - logFilePath = *(++argv); + logFilePath = *(++argv1); break; default: usage(syslogd_usage); @@ -285,11 +381,20 @@ extern int syslogd_main(int argc, char **argv) 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); } diff --git a/syslogd.c b/syslogd.c index 736adf7d1..3c7b0170d 100644 --- a/syslogd.c +++ b/syslogd.c @@ -32,6 +32,12 @@ #include #include #include +#include +#include +#include + +#define ksyslog klogctl +extern int ksyslog(int type, char *buf, int len); /* SYSLOG_NAMES defined to pull some extra junk from syslog.h */ @@ -40,8 +46,6 @@ /* 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; @@ -58,7 +62,7 @@ static const char syslogd_usage[] = "\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) @@ -92,7 +96,7 @@ static void message(char *fmt, ...) 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); @@ -250,20 +254,112 @@ static void doSyslogd(void) 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; @@ -272,7 +368,7 @@ extern int syslogd_main(int argc, char **argv) if (--argc == 0) { usage(syslogd_usage); } - logFilePath = *(++argv); + logFilePath = *(++argv1); break; default: usage(syslogd_usage); @@ -285,11 +381,20 @@ extern int syslogd_main(int argc, char **argv) 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); } diff --git a/utility.c b/utility.c index 011c0cf41..9e56dbe8a 100644 --- a/utility.c +++ b/utility.c @@ -771,7 +771,7 @@ int get_console_fd(char* tty_name) #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) @@ -851,6 +851,108 @@ extern int replace_match(char *haystack, char *needle, char *newNeedle, int igno #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 @@ -910,3 +1012,10 @@ extern void whine_if_fstab_is_missing() /* END CODE */ + + + + + + +