diff --git a/Changelog b/Changelog index 0f3b1e055..3bd205f38 100644 --- a/Changelog +++ b/Changelog @@ -7,6 +7,7 @@ * Added new apps chvt and deallocvt * Major adjustment of init.c. Code is now readable IMHO, and much more solid. + * Wrote sed -- weighs in at 1.8k (or 5.8k with full regular expressions!). -Erik Andersen diff --git a/busybox.def.h b/busybox.def.h index b71c53923..57f835e24 100644 --- a/busybox.def.h +++ b/busybox.def.h @@ -15,12 +15,12 @@ #define BB_DMESG //#define BB_DUTMP //#define BB_FDFLUSH -#define BB_FIND +//#define BB_FIND //#define BB_FSCK_MINIX //#define BB_MKFS_MINIX #define BB_CHVT #define BB_DEALLOCVT -#define BB_GREP +//#define BB_GREP //#define BB_HALT #define BB_INIT #define BB_KILL @@ -42,7 +42,7 @@ //#define BB_PRINTF #define BB_PS #define BB_PWD -//#define BB_REGEXP +#define BB_REGEXP #define BB_REBOOT #define BB_RM #define BB_RMDIR diff --git a/editors/sed.c b/editors/sed.c index 0df53a7f8..f0a6a3b48 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -57,7 +57,8 @@ extern int sed_main (int argc, char **argv) char *cp; int ignoreCase=FALSE; int foundOne=FALSE; - int noprintFlag=FALSE; + int printFlag=FALSE; + int quietFlag=FALSE; int stopNow; char *haystack; @@ -75,7 +76,7 @@ extern int sed_main (int argc, char **argv) while (*++cp && stopNow==FALSE) switch (*cp) { case 'n': - noprintFlag = TRUE; + quietFlag = TRUE; break; case 'e': if (*(cp+1)==0 && --argc < 0) { @@ -113,6 +114,23 @@ extern int sed_main (int argc, char **argv) break; } *pos=0; + if (pos+2 != 0) { + while (*++pos) { + fprintf(stderr, "pos='%s'\n", pos); + switch (*pos) { + case 'i': + ignoreCase=TRUE; + break; + case 'p': + printFlag=TRUE; + break; + case 'g': + break; + default: + usage( sed_usage); + } + } + } } cp++; } @@ -135,13 +153,13 @@ extern int sed_main (int argc, char **argv) continue; } - haystack = (char*)malloc( BUF_SIZE); - while (fgets (haystack, BUF_SIZE-1, fp)) { + haystack = (char*)malloc( 1024); + while (fgets (haystack, 1023, fp)) { foundOne = replace_match(haystack, needle, newNeedle, ignoreCase); - if (noprintFlag==TRUE && foundOne==TRUE) - fputs (haystack, stdout); - else + if (foundOne==TRUE && printFlag==TRUE) + fputs (haystack, stdout); + if (quietFlag==FALSE) fputs (haystack, stdout); /* Avoid any mem leaks */ free(haystack); diff --git a/init.c b/init.c index b8cbbf64e..a56e23e5d 100644 --- a/init.c +++ b/init.c @@ -41,6 +41,9 @@ #include /* for vt_stat */ #include +/* Turn this on to debug init so it won't reboot when killed */ +#define DEBUG_INIT + #define CONSOLE "/dev/console" /* Logical system console */ #define VT_PRIMARY "/dev/tty0" /* Virtual console master */ #define VT_SECONDARY "/dev/tty1" /* Virtual console master */ @@ -61,7 +64,7 @@ int device_open(char *device, int mode) { int m, f, fd = -1; - mode = m | O_NONBLOCK; + m = mode | O_NONBLOCK; /* Retry up to 5 times */ for (f = 0; f < 5; f++) @@ -99,25 +102,28 @@ void message(char *device, char *fmt, ...) void set_term( int fd) { struct termios tty; + static const char control_characters[] = { + '\003', '\034', '\177', '\025', '\004', '\0', + '\1', '\0', '\021', '\023', '\032', '\0', '\022', + '\017', '\027', '\026', '\0' + }; tcgetattr(fd, &tty); - tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD; - tty.c_cflag |= HUPCL|CLOCAL; - tty.c_cc[VINTR] = 3; - tty.c_cc[VQUIT] = 28; - tty.c_cc[VERASE] = 127; - tty.c_cc[VKILL] = 24; - tty.c_cc[VEOF] = 4; - tty.c_cc[VTIME] = 0; - tty.c_cc[VMIN] = 1; - tty.c_cc[VSTART] = 17; - tty.c_cc[VSTOP] = 19; - tty.c_cc[VSUSP] = 26; + /* input modes */ + tty.c_iflag = IGNPAR|ICRNL|IXON|IXOFF|IXANY; - tty.c_iflag = IGNPAR|ICRNL|IXON|IXANY; + /* use lineo dicipline 0 */ + tty.c_line = 0; + + /* output modes */ tty.c_oflag = OPOST|ONLCR; - tty.c_lflag = ISIG|ICANON|ECHO|ECHOCTL|ECHOPRT|ECHOKE; + + /* local modes */ + tty.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOPRT|ECHOKE|IEXTEN; + + /* control chars */ + memcpy(tty.c_cc, control_characters, sizeof(control_characters)); tcsetattr(fd, TCSANOW, &tty); } @@ -151,7 +157,7 @@ static void set_free_pages() fclose(f); f = fopen("/proc/sys/vm/freepages", "w"); fprintf(f, "30\t40\t50\n"); - printf("\nIncreased /proc/sys/vm/freepages values to 30/40/50\n"); + message(log, "\nIncreased /proc/sys/vm/freepages values to 30/40/50\n"); } fclose(f); } @@ -165,7 +171,6 @@ static void console_init() int tried_vtmaster = 0; char *s; - fprintf(stderr, "entering console_init()\n"); if ((s = getenv("CONSOLE")) != NULL) console = s; else { @@ -175,6 +180,7 @@ static void console_init() if ( stat(CONSOLE, &statbuf) && S_ISLNK(statbuf.st_mode)) { fprintf(stderr, "Yikes! /dev/console does not exist or is a symlink.\n"); + message(log, "Yikes! /dev/console does not exist or is a symlink.\n"); } while ((fd = open(console, O_RDONLY | O_NONBLOCK)) < 0) { if (!tried_devcons) { @@ -193,7 +199,7 @@ static void console_init() console = "/dev/null"; else close(fd); - fprintf(stderr, "console=%s\n", console); + message(log, "console=%s\n", console); } static int waitfor(int pid) @@ -212,7 +218,7 @@ static int waitfor(int pid) static pid_t run(const char * const* command, char *terminal, int get_enter) { - int i; + int i, f; pid_t pid; static const char press_enter[] = "\nPlease press Enter to activate this console. "; @@ -224,9 +230,9 @@ static pid_t run(const char * const* command, close(2); setsid(); - open(terminal, O_RDWR); - dup(0); - dup(0); + f=open(terminal, O_RDWR); + dup(f); + dup(f); tcsetpgrp(0, getpgrp()); set_term(0); @@ -240,7 +246,7 @@ static pid_t run(const char * const* command, * specifies. */ char c; - write(0, press_enter, sizeof(press_enter) - 1); + write(1, press_enter, sizeof(press_enter) - 1); read(0, &c, 1); } @@ -269,7 +275,7 @@ static pid_t run(const char * const* command, return pid; } - +#ifndef DEBUG_INIT static void shutdown_system(void) { const char* const swap_off_cmd[] = { "/bin/swapoff", "-a", 0}; @@ -314,6 +320,7 @@ static void reboot_signal(int sig) reboot(RB_AUTOBOOT); exit(0); } +#endif extern int init_main(int argc, char **argv) { @@ -326,11 +333,17 @@ extern int init_main(int argc, char **argv) const char* const shell_commands[] = { SHELL, " -", 0}; const char* const* tty0_commands = init_commands; const char* const* tty1_commands = shell_commands; +#ifndef DEBUG_INIT + char *hello_msg_format = + "init(%d) started: BusyBox v%s (%s) multi-call binary\r\n"; +#else char *hello_msg_format = "init started: BusyBox v%s (%s) multi-call binary\r\n"; +#endif const char *no_memory = "Sorry, your computer does not have enough memory.\r\n"; +#ifndef DEBUG_INIT /* Set up sig handlers */ signal(SIGUSR1, halt_signal); signal(SIGSEGV, halt_signal); @@ -344,7 +357,7 @@ extern int init_main(int argc, char **argv) /* Turn off rebooting via CTL-ALT-DEL -- we get a * 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(); @@ -352,7 +365,7 @@ extern int init_main(int argc, char **argv) close(0); close(1); close(2); - //set_term(0); + set_term(0); setsid(); /* Make sure PATH is set to something sane */ @@ -360,17 +373,22 @@ extern int init_main(int argc, char **argv) putenv(PATH_DEFAULT); /* Hello world */ +#ifndef DEBUG_INIT message(log, hello_msg_format, BB_VER, BB_BT); - fprintf(stderr, hello_msg_format, BB_VER, BB_BT); + message(console, hello_msg_format, BB_VER, BB_BT); +#else + message(log, hello_msg_format, getpid(), BB_VER, BB_BT); + message(console, hello_msg_format, getpid(), BB_VER, BB_BT); +#endif /* Mount /proc */ if (mount("/proc", "/proc", "proc", 0, 0) == 0) { - fprintf(stderr, "Mounting /proc: done.\n"); message(log, "Mounting /proc: done.\n"); + message(console, "Mounting /proc: done.\n"); } else { - fprintf(stderr, "Mounting /proc: failed!\n"); message(log, "Mounting /proc: failed!\n"); + message(console, "Mounting /proc: failed!\n"); } /* Make sure there is enough memory to do something useful */ @@ -379,7 +397,7 @@ extern int init_main(int argc, char **argv) int retval; retval = stat("/etc/fstab", &statbuf); if (retval) { - fprintf(stderr, "%s", no_memory); + message(console, "%s", no_memory); while (1) { sleep(1); } @@ -387,7 +405,7 @@ extern int init_main(int argc, char **argv) /* Try to turn on swap */ waitfor(run(swap_on_cmd, console, 0)); if (mem_total() < 2000) { - fprintf(stderr, "%s", no_memory); + message(console, "%s", no_memory); while (1) { sleep(1); } diff --git a/init/init.c b/init/init.c index b8cbbf64e..a56e23e5d 100644 --- a/init/init.c +++ b/init/init.c @@ -41,6 +41,9 @@ #include /* for vt_stat */ #include +/* Turn this on to debug init so it won't reboot when killed */ +#define DEBUG_INIT + #define CONSOLE "/dev/console" /* Logical system console */ #define VT_PRIMARY "/dev/tty0" /* Virtual console master */ #define VT_SECONDARY "/dev/tty1" /* Virtual console master */ @@ -61,7 +64,7 @@ int device_open(char *device, int mode) { int m, f, fd = -1; - mode = m | O_NONBLOCK; + m = mode | O_NONBLOCK; /* Retry up to 5 times */ for (f = 0; f < 5; f++) @@ -99,25 +102,28 @@ void message(char *device, char *fmt, ...) void set_term( int fd) { struct termios tty; + static const char control_characters[] = { + '\003', '\034', '\177', '\025', '\004', '\0', + '\1', '\0', '\021', '\023', '\032', '\0', '\022', + '\017', '\027', '\026', '\0' + }; tcgetattr(fd, &tty); - tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD; - tty.c_cflag |= HUPCL|CLOCAL; - tty.c_cc[VINTR] = 3; - tty.c_cc[VQUIT] = 28; - tty.c_cc[VERASE] = 127; - tty.c_cc[VKILL] = 24; - tty.c_cc[VEOF] = 4; - tty.c_cc[VTIME] = 0; - tty.c_cc[VMIN] = 1; - tty.c_cc[VSTART] = 17; - tty.c_cc[VSTOP] = 19; - tty.c_cc[VSUSP] = 26; + /* input modes */ + tty.c_iflag = IGNPAR|ICRNL|IXON|IXOFF|IXANY; - tty.c_iflag = IGNPAR|ICRNL|IXON|IXANY; + /* use lineo dicipline 0 */ + tty.c_line = 0; + + /* output modes */ tty.c_oflag = OPOST|ONLCR; - tty.c_lflag = ISIG|ICANON|ECHO|ECHOCTL|ECHOPRT|ECHOKE; + + /* local modes */ + tty.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOPRT|ECHOKE|IEXTEN; + + /* control chars */ + memcpy(tty.c_cc, control_characters, sizeof(control_characters)); tcsetattr(fd, TCSANOW, &tty); } @@ -151,7 +157,7 @@ static void set_free_pages() fclose(f); f = fopen("/proc/sys/vm/freepages", "w"); fprintf(f, "30\t40\t50\n"); - printf("\nIncreased /proc/sys/vm/freepages values to 30/40/50\n"); + message(log, "\nIncreased /proc/sys/vm/freepages values to 30/40/50\n"); } fclose(f); } @@ -165,7 +171,6 @@ static void console_init() int tried_vtmaster = 0; char *s; - fprintf(stderr, "entering console_init()\n"); if ((s = getenv("CONSOLE")) != NULL) console = s; else { @@ -175,6 +180,7 @@ static void console_init() if ( stat(CONSOLE, &statbuf) && S_ISLNK(statbuf.st_mode)) { fprintf(stderr, "Yikes! /dev/console does not exist or is a symlink.\n"); + message(log, "Yikes! /dev/console does not exist or is a symlink.\n"); } while ((fd = open(console, O_RDONLY | O_NONBLOCK)) < 0) { if (!tried_devcons) { @@ -193,7 +199,7 @@ static void console_init() console = "/dev/null"; else close(fd); - fprintf(stderr, "console=%s\n", console); + message(log, "console=%s\n", console); } static int waitfor(int pid) @@ -212,7 +218,7 @@ static int waitfor(int pid) static pid_t run(const char * const* command, char *terminal, int get_enter) { - int i; + int i, f; pid_t pid; static const char press_enter[] = "\nPlease press Enter to activate this console. "; @@ -224,9 +230,9 @@ static pid_t run(const char * const* command, close(2); setsid(); - open(terminal, O_RDWR); - dup(0); - dup(0); + f=open(terminal, O_RDWR); + dup(f); + dup(f); tcsetpgrp(0, getpgrp()); set_term(0); @@ -240,7 +246,7 @@ static pid_t run(const char * const* command, * specifies. */ char c; - write(0, press_enter, sizeof(press_enter) - 1); + write(1, press_enter, sizeof(press_enter) - 1); read(0, &c, 1); } @@ -269,7 +275,7 @@ static pid_t run(const char * const* command, return pid; } - +#ifndef DEBUG_INIT static void shutdown_system(void) { const char* const swap_off_cmd[] = { "/bin/swapoff", "-a", 0}; @@ -314,6 +320,7 @@ static void reboot_signal(int sig) reboot(RB_AUTOBOOT); exit(0); } +#endif extern int init_main(int argc, char **argv) { @@ -326,11 +333,17 @@ extern int init_main(int argc, char **argv) const char* const shell_commands[] = { SHELL, " -", 0}; const char* const* tty0_commands = init_commands; const char* const* tty1_commands = shell_commands; +#ifndef DEBUG_INIT + char *hello_msg_format = + "init(%d) started: BusyBox v%s (%s) multi-call binary\r\n"; +#else char *hello_msg_format = "init started: BusyBox v%s (%s) multi-call binary\r\n"; +#endif const char *no_memory = "Sorry, your computer does not have enough memory.\r\n"; +#ifndef DEBUG_INIT /* Set up sig handlers */ signal(SIGUSR1, halt_signal); signal(SIGSEGV, halt_signal); @@ -344,7 +357,7 @@ extern int init_main(int argc, char **argv) /* Turn off rebooting via CTL-ALT-DEL -- we get a * 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(); @@ -352,7 +365,7 @@ extern int init_main(int argc, char **argv) close(0); close(1); close(2); - //set_term(0); + set_term(0); setsid(); /* Make sure PATH is set to something sane */ @@ -360,17 +373,22 @@ extern int init_main(int argc, char **argv) putenv(PATH_DEFAULT); /* Hello world */ +#ifndef DEBUG_INIT message(log, hello_msg_format, BB_VER, BB_BT); - fprintf(stderr, hello_msg_format, BB_VER, BB_BT); + message(console, hello_msg_format, BB_VER, BB_BT); +#else + message(log, hello_msg_format, getpid(), BB_VER, BB_BT); + message(console, hello_msg_format, getpid(), BB_VER, BB_BT); +#endif /* Mount /proc */ if (mount("/proc", "/proc", "proc", 0, 0) == 0) { - fprintf(stderr, "Mounting /proc: done.\n"); message(log, "Mounting /proc: done.\n"); + message(console, "Mounting /proc: done.\n"); } else { - fprintf(stderr, "Mounting /proc: failed!\n"); message(log, "Mounting /proc: failed!\n"); + message(console, "Mounting /proc: failed!\n"); } /* Make sure there is enough memory to do something useful */ @@ -379,7 +397,7 @@ extern int init_main(int argc, char **argv) int retval; retval = stat("/etc/fstab", &statbuf); if (retval) { - fprintf(stderr, "%s", no_memory); + message(console, "%s", no_memory); while (1) { sleep(1); } @@ -387,7 +405,7 @@ extern int init_main(int argc, char **argv) /* Try to turn on swap */ waitfor(run(swap_on_cmd, console, 0)); if (mem_total() < 2000) { - fprintf(stderr, "%s", no_memory); + message(console, "%s", no_memory); while (1) { sleep(1); } diff --git a/regexp.c b/regexp.c index deee238ec..164f88037 100644 --- a/regexp.c +++ b/regexp.c @@ -7,7 +7,7 @@ #include -#if ( defined BB_GREP || defined BB_FIND ) +#if ( defined BB_GREP || defined BB_FIND || defined BB_SED) /* This also tries to find a needle in a haystack, but uses * real regular expressions.... The fake regular expression @@ -25,27 +25,39 @@ extern int find_match(char *haystack, char *needle, int ignoreCase) return( status); } +#if defined BB_SED /* This performs substitutions after a regexp match has been found. * The new string is returned. It is malloc'ed, and do must be freed. */ -extern char* replace_match(char *haystack, char *needle, char *newNeedle, int ignoreCase) +extern int replace_match(char *haystack, char *needle, char *newNeedle, int ignoreCase) { int status; - char* newHaystack; struct regexp* re; - newHaystack = (char *)malloc((unsigned)(strlen(haystack) - - strlen(needle) + strlen(newNeedle)); + char *s, buf[BUF_SIZE], *d = buf; + re = regcomp( needle); status = regexec(re, haystack, FALSE, ignoreCase); + if (status==TRUE) { + s=haystack; - return( newHaystack) -} - - -extern void regsub(regexp* re, char* src, char* dst) - + do { + /* copy stuff from before the match */ + while (s < re->startp[0]) + *d++ = *s++; + /* substitute for the matched part */ + regsub(re, newNeedle, d); + s = re->endp[0]; + d += strlen(d); + } while (regexec(re, s, FALSE, ignoreCase) == TRUE); + /* copy stuff from after the match */ + while ( (*d++ = *s++) ) {} + d[-1] = '\n'; + d[0] = '\0'; + strcpy(haystack, buf); + } free( re); return( status); } +#endif /* code swiped from elvis-tiny 1.4 (a clone of vi) and adjusted to @@ -695,7 +707,7 @@ extern int regexec(struct regexp* re, char* str, int bol, int ignoreCase) - +#if defined BB_SED /* This performs substitutions after a regexp match has been found. */ extern void regsub(regexp* re, char* src, char* dst) { @@ -841,7 +853,7 @@ extern void regsub(regexp* re, char* src, char* dst) if (previous1) strcpy(previous1, start); } - +#endif #endif /* BB_REGEXP */ diff --git a/sed.c b/sed.c index 0df53a7f8..f0a6a3b48 100644 --- a/sed.c +++ b/sed.c @@ -57,7 +57,8 @@ extern int sed_main (int argc, char **argv) char *cp; int ignoreCase=FALSE; int foundOne=FALSE; - int noprintFlag=FALSE; + int printFlag=FALSE; + int quietFlag=FALSE; int stopNow; char *haystack; @@ -75,7 +76,7 @@ extern int sed_main (int argc, char **argv) while (*++cp && stopNow==FALSE) switch (*cp) { case 'n': - noprintFlag = TRUE; + quietFlag = TRUE; break; case 'e': if (*(cp+1)==0 && --argc < 0) { @@ -113,6 +114,23 @@ extern int sed_main (int argc, char **argv) break; } *pos=0; + if (pos+2 != 0) { + while (*++pos) { + fprintf(stderr, "pos='%s'\n", pos); + switch (*pos) { + case 'i': + ignoreCase=TRUE; + break; + case 'p': + printFlag=TRUE; + break; + case 'g': + break; + default: + usage( sed_usage); + } + } + } } cp++; } @@ -135,13 +153,13 @@ extern int sed_main (int argc, char **argv) continue; } - haystack = (char*)malloc( BUF_SIZE); - while (fgets (haystack, BUF_SIZE-1, fp)) { + haystack = (char*)malloc( 1024); + while (fgets (haystack, 1023, fp)) { foundOne = replace_match(haystack, needle, newNeedle, ignoreCase); - if (noprintFlag==TRUE && foundOne==TRUE) - fputs (haystack, stdout); - else + if (foundOne==TRUE && printFlag==TRUE) + fputs (haystack, stdout); + if (quietFlag==FALSE) fputs (haystack, stdout); /* Avoid any mem leaks */ free(haystack); diff --git a/utility.c b/utility.c index e0f9d1246..637368740 100644 --- a/utility.c +++ b/utility.c @@ -777,7 +777,7 @@ int get_console_fd(char* tty_name) #endif -#if !defined BB_REGEXP && (defined BB_GREP || defined BB_FIND ) +#if !defined BB_REGEXP && (defined BB_GREP || defined BB_FIND || defined BB_SED) /* Do a case insensitive strstr() */ char* stristr(char *haystack, const char *needle) @@ -817,7 +817,7 @@ extern int find_match(char *haystack, char *needle, int ignoreCase) /* This performs substitutions after a string match has been found. */ extern int replace_match(char *haystack, char *needle, char *newNeedle, int ignoreCase) { - int foundOne; + int foundOne=0; char *where, *slider, *slider1, *oldhayStack; if (ignoreCase == FALSE) @@ -847,7 +847,7 @@ extern int replace_match(char *haystack, char *needle, char *newNeedle, int igno } free( oldhayStack); - if (foundOne) + if (foundOne > 0) return TRUE; else return FALSE;