diff --git a/applets/busybox.c b/applets/busybox.c index 05144c472..29a112b12 100644 --- a/applets/busybox.c +++ b/applets/busybox.c @@ -142,6 +142,9 @@ static const struct Applet applets[] = { {"fdisk", sfdisk_main}, {"sfdisk", sfdisk_main}, #endif +#ifdef BB_SED //bin + {"sed", sed_main}, +#endif #ifdef BB_SLEEP //bin {"sleep", sleep_main}, #endif diff --git a/busybox.c b/busybox.c index 05144c472..29a112b12 100644 --- a/busybox.c +++ b/busybox.c @@ -142,6 +142,9 @@ static const struct Applet applets[] = { {"fdisk", sfdisk_main}, {"sfdisk", sfdisk_main}, #endif +#ifdef BB_SED //bin + {"sed", sed_main}, +#endif #ifdef BB_SLEEP //bin {"sleep", sleep_main}, #endif diff --git a/busybox.def.h b/busybox.def.h index a79eaaf4f..b71c53923 100644 --- a/busybox.def.h +++ b/busybox.def.h @@ -47,6 +47,7 @@ #define BB_RM #define BB_RMDIR //#define BB_SFDISK +#define BB_SED #define BB_SLEEP #define BB_SWAPONOFF #define BB_SYNC diff --git a/editors/sed.c b/editors/sed.c index 4dd552a2d..a3e635d3a 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -33,12 +33,10 @@ static const char sed_usage[] = "sed [-n] [-e script] [file...]\n" -"Allowed scripts come in two forms:\n" -"'/regexp/[gp]'\n" -"\tattempt to match regexp against the pattern space\n" +"Allowed scripts come in the following form:\n\n" "'s/regexp/replacement/[gp]'\n" "\tattempt to match regexp against the pattern space\n" -"\tand if successful replaces the matched portion with replacement." +"\tand if successful replaces the matched portion with replacement.\n\n" "Options:\n" "-e\tadd the script to the commands to be executed\n" "-n\tsuppress automatic printing of pattern space\n\n" @@ -49,64 +47,86 @@ static const char sed_usage[] = #endif -static int replaceFlag = FALSE; -static int noprintFlag = FALSE; extern int sed_main (int argc, char **argv) { FILE *fp; - const char *needle; - const char *name; - const char *cp; - int tellName=TRUE; + char *needle=NULL, *newNeedle=NULL; + char *name; + char *cp; int ignoreCase=FALSE; - int tellLine=FALSE; - long line; - char haystack[BUF_SIZE]; - - ignoreCase = FALSE; - tellLine = FALSE; + int foundOne=FALSE; + int noprintFlag=FALSE; + int stopNow; + char *haystack; argc--; argv++; if (argc < 1) { - usage(grep_usage); + usage(sed_usage); } if (**argv == '-') { argc--; cp = *argv++; + stopNow=FALSE; - while (*++cp) + while (*++cp && stopNow==FALSE) switch (*cp) { case 'n': noprintFlag = TRUE; break; case 'e': - if (*(*argv)+1 != '\'' && **argv != '\"') { - if (--argc == 0) - usage( mkdir_usage); - ++argv; - if (*(*argv)+1 != '\'' && **argv != '\"') { - usage( mkdir_usage); + if (*(cp+1)==0 && --argc < 0) { + fprintf(stderr, "A\n"); + usage( sed_usage); } - /* Find the specified modes */ - mode = 0; - if ( parse_mode(*(++argv), &mode) == FALSE ) { - fprintf(stderr, "Unknown mode: %s\n", *argv); - exit( FALSE); + cp = *argv++; + while( *cp ) { + if (*cp == 's' && strlen(cp) > 3 && *(cp+1) == '/') { + char* pos=needle=cp+2; + for(;;) { + pos = strchr(pos, '/'); + if (pos==NULL) { + fprintf(stderr, "B\n"); + usage( sed_usage); + } + if (*(pos-1) == '\\') { + pos++; + continue; + } + break; + } + *pos=0; + newNeedle=++pos; + for(;;) { + pos = strchr(pos, '/'); + if (pos==NULL) { + fprintf(stderr, "C\n"); + usage( sed_usage); + } + if (*(pos-1) == '\\') { + pos++; + continue; + } + break; + } + *pos=0; + } + cp++; } + fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); + stopNow=TRUE; break; default: - usage(grep_usage); + fprintf(stderr, "D\n"); + usage(sed_usage); } } - needle = *argv++; - argc--; - + fprintf(stderr, "argc=%d\n", argc); while (argc-- > 0) { name = *argv++; @@ -115,25 +135,19 @@ extern int sed_main (int argc, char **argv) perror (name); continue; } + fprintf(stderr, "filename is '%s'\n", name); - line = 0; - + haystack = (char*)malloc( 80); while (fgets (haystack, sizeof (haystack), fp)) { - line++; - cp = &haystack[strlen (haystack) - 1]; - - if (*cp != '\n') - fprintf (stderr, "%s: Line too long\n", name); - - if (find_match(haystack, needle, ignoreCase) == TRUE) { - if (tellName==TRUE) - printf ("%s: ", name); - - if (tellLine==TRUE) - printf ("%ld: ", line); + foundOne = replace_match(haystack, needle, newNeedle, ignoreCase); + if (noprintFlag==TRUE && foundOne==TRUE) fputs (haystack, stdout); - } + else + fputs (haystack, stdout); + /* Avoid any mem leaks */ + free(haystack); + haystack = (char*)malloc( BUF_SIZE); } if (ferror (fp)) diff --git a/init.c b/init.c index d950e2bef..b8cbbf64e 100644 --- a/init.c +++ b/init.c @@ -41,8 +41,6 @@ #include /* for vt_stat */ #include -#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 */ @@ -272,7 +270,6 @@ static pid_t run(const char * const* command, } -#ifndef DEBUG_INIT static void shutdown_system(void) { const char* const swap_off_cmd[] = { "/bin/swapoff", "-a", 0}; @@ -318,12 +315,9 @@ static void reboot_signal(int sig) exit(0); } -#endif - extern int init_main(int argc, char **argv) { int run_rc = TRUE; - pid_t pid = 0; pid_t pid1 = 0; pid_t pid2 = 0; struct stat statbuf; @@ -333,13 +327,10 @@ extern int init_main(int argc, char **argv) const char* const* tty0_commands = init_commands; const char* const* tty1_commands = shell_commands; char *hello_msg_format = - "init(%d) started: BusyBox v%s (%s) multi-call binary\r\n"; + "init started: BusyBox v%s (%s) multi-call binary\r\n"; const char *no_memory = "Sorry, your computer does not have enough memory.\r\n"; - pid = getpid(); - -#ifndef DEBUG_INIT /* Set up sig handlers */ signal(SIGUSR1, halt_signal); signal(SIGSEGV, halt_signal); @@ -353,7 +344,6 @@ 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(); @@ -370,8 +360,8 @@ extern int init_main(int argc, char **argv) putenv(PATH_DEFAULT); /* Hello world */ - message(log, hello_msg_format, pid, BB_VER, BB_BT); - fprintf(stderr, hello_msg_format, pid, BB_VER, BB_BT); + message(log, hello_msg_format, BB_VER, BB_BT); + fprintf(stderr, hello_msg_format, BB_VER, BB_BT); /* Mount /proc */ @@ -385,7 +375,7 @@ extern int init_main(int argc, char **argv) /* Make sure there is enough memory to do something useful */ set_free_pages(); - if (mem_total() < 2000) { + if (mem_total() < 3500) { int retval; retval = stat("/etc/fstab", &statbuf); if (retval) { diff --git a/init/init.c b/init/init.c index d950e2bef..b8cbbf64e 100644 --- a/init/init.c +++ b/init/init.c @@ -41,8 +41,6 @@ #include /* for vt_stat */ #include -#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 */ @@ -272,7 +270,6 @@ static pid_t run(const char * const* command, } -#ifndef DEBUG_INIT static void shutdown_system(void) { const char* const swap_off_cmd[] = { "/bin/swapoff", "-a", 0}; @@ -318,12 +315,9 @@ static void reboot_signal(int sig) exit(0); } -#endif - extern int init_main(int argc, char **argv) { int run_rc = TRUE; - pid_t pid = 0; pid_t pid1 = 0; pid_t pid2 = 0; struct stat statbuf; @@ -333,13 +327,10 @@ extern int init_main(int argc, char **argv) const char* const* tty0_commands = init_commands; const char* const* tty1_commands = shell_commands; char *hello_msg_format = - "init(%d) started: BusyBox v%s (%s) multi-call binary\r\n"; + "init started: BusyBox v%s (%s) multi-call binary\r\n"; const char *no_memory = "Sorry, your computer does not have enough memory.\r\n"; - pid = getpid(); - -#ifndef DEBUG_INIT /* Set up sig handlers */ signal(SIGUSR1, halt_signal); signal(SIGSEGV, halt_signal); @@ -353,7 +344,6 @@ 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(); @@ -370,8 +360,8 @@ extern int init_main(int argc, char **argv) putenv(PATH_DEFAULT); /* Hello world */ - message(log, hello_msg_format, pid, BB_VER, BB_BT); - fprintf(stderr, hello_msg_format, pid, BB_VER, BB_BT); + message(log, hello_msg_format, BB_VER, BB_BT); + fprintf(stderr, hello_msg_format, BB_VER, BB_BT); /* Mount /proc */ @@ -385,7 +375,7 @@ extern int init_main(int argc, char **argv) /* Make sure there is enough memory to do something useful */ set_free_pages(); - if (mem_total() < 2000) { + if (mem_total() < 3500) { int retval; retval = stat("/etc/fstab", &statbuf); if (retval) { diff --git a/internal.h b/internal.h index 35f990aa7..81271be94 100644 --- a/internal.h +++ b/internal.h @@ -102,6 +102,7 @@ extern int rm_main(int argc, char** argv); extern int scan_partitions_main(int argc, char** argv); extern int sh_main(int argc, char** argv); extern int sfdisk_main(int argc, char** argv); +extern int sed_main(int argc, char** argv); extern int sleep_main(int argc, char** argv); extern int swap_on_off_main(int argc, char** argv); extern int sync_main(int argc, char** argv); diff --git a/regexp.c b/regexp.c index 6017d79b4..deee238ec 100644 --- a/regexp.c +++ b/regexp.c @@ -25,6 +25,28 @@ extern int find_match(char *haystack, char *needle, int ignoreCase) return( status); } +/* 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) +{ + int status; + char* newHaystack; + struct regexp* re; + newHaystack = (char *)malloc((unsigned)(strlen(haystack) - + strlen(needle) + strlen(newNeedle)); + re = regcomp( needle); + status = regexec(re, haystack, FALSE, ignoreCase); + + return( newHaystack) +} + + +extern void regsub(regexp* re, char* src, char* dst) + + free( re); + return( status); +} + /* code swiped from elvis-tiny 1.4 (a clone of vi) and adjusted to * suit the needs of busybox by Erik Andersen. diff --git a/regexp.h b/regexp.h index 1e324e155..e8880fb4f 100644 --- a/regexp.h +++ b/regexp.h @@ -43,6 +43,7 @@ extern int regexec(struct regexp* re, char* str, int bol, int ignoreCase); extern void regsub(struct regexp* re, char* src, char* dst); extern int find_match(char *haystack, char *needle, int ignoreCase); +extern int replace_match(char *haystack, char *needle, char *newNeedle, int ignoreCase); #endif diff --git a/sed.c b/sed.c index 4dd552a2d..a3e635d3a 100644 --- a/sed.c +++ b/sed.c @@ -33,12 +33,10 @@ static const char sed_usage[] = "sed [-n] [-e script] [file...]\n" -"Allowed scripts come in two forms:\n" -"'/regexp/[gp]'\n" -"\tattempt to match regexp against the pattern space\n" +"Allowed scripts come in the following form:\n\n" "'s/regexp/replacement/[gp]'\n" "\tattempt to match regexp against the pattern space\n" -"\tand if successful replaces the matched portion with replacement." +"\tand if successful replaces the matched portion with replacement.\n\n" "Options:\n" "-e\tadd the script to the commands to be executed\n" "-n\tsuppress automatic printing of pattern space\n\n" @@ -49,64 +47,86 @@ static const char sed_usage[] = #endif -static int replaceFlag = FALSE; -static int noprintFlag = FALSE; extern int sed_main (int argc, char **argv) { FILE *fp; - const char *needle; - const char *name; - const char *cp; - int tellName=TRUE; + char *needle=NULL, *newNeedle=NULL; + char *name; + char *cp; int ignoreCase=FALSE; - int tellLine=FALSE; - long line; - char haystack[BUF_SIZE]; - - ignoreCase = FALSE; - tellLine = FALSE; + int foundOne=FALSE; + int noprintFlag=FALSE; + int stopNow; + char *haystack; argc--; argv++; if (argc < 1) { - usage(grep_usage); + usage(sed_usage); } if (**argv == '-') { argc--; cp = *argv++; + stopNow=FALSE; - while (*++cp) + while (*++cp && stopNow==FALSE) switch (*cp) { case 'n': noprintFlag = TRUE; break; case 'e': - if (*(*argv)+1 != '\'' && **argv != '\"') { - if (--argc == 0) - usage( mkdir_usage); - ++argv; - if (*(*argv)+1 != '\'' && **argv != '\"') { - usage( mkdir_usage); + if (*(cp+1)==0 && --argc < 0) { + fprintf(stderr, "A\n"); + usage( sed_usage); } - /* Find the specified modes */ - mode = 0; - if ( parse_mode(*(++argv), &mode) == FALSE ) { - fprintf(stderr, "Unknown mode: %s\n", *argv); - exit( FALSE); + cp = *argv++; + while( *cp ) { + if (*cp == 's' && strlen(cp) > 3 && *(cp+1) == '/') { + char* pos=needle=cp+2; + for(;;) { + pos = strchr(pos, '/'); + if (pos==NULL) { + fprintf(stderr, "B\n"); + usage( sed_usage); + } + if (*(pos-1) == '\\') { + pos++; + continue; + } + break; + } + *pos=0; + newNeedle=++pos; + for(;;) { + pos = strchr(pos, '/'); + if (pos==NULL) { + fprintf(stderr, "C\n"); + usage( sed_usage); + } + if (*(pos-1) == '\\') { + pos++; + continue; + } + break; + } + *pos=0; + } + cp++; } + fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); + stopNow=TRUE; break; default: - usage(grep_usage); + fprintf(stderr, "D\n"); + usage(sed_usage); } } - needle = *argv++; - argc--; - + fprintf(stderr, "argc=%d\n", argc); while (argc-- > 0) { name = *argv++; @@ -115,25 +135,19 @@ extern int sed_main (int argc, char **argv) perror (name); continue; } + fprintf(stderr, "filename is '%s'\n", name); - line = 0; - + haystack = (char*)malloc( 80); while (fgets (haystack, sizeof (haystack), fp)) { - line++; - cp = &haystack[strlen (haystack) - 1]; - - if (*cp != '\n') - fprintf (stderr, "%s: Line too long\n", name); - - if (find_match(haystack, needle, ignoreCase) == TRUE) { - if (tellName==TRUE) - printf ("%s: ", name); - - if (tellLine==TRUE) - printf ("%ld: ", line); + foundOne = replace_match(haystack, needle, newNeedle, ignoreCase); + if (noprintFlag==TRUE && foundOne==TRUE) fputs (haystack, stdout); - } + else + fputs (haystack, stdout); + /* Avoid any mem leaks */ + free(haystack); + haystack = (char*)malloc( BUF_SIZE); } if (ferror (fp)) diff --git a/utility.c b/utility.c index 6491d834d..41e7ccc14 100644 --- a/utility.c +++ b/utility.c @@ -686,41 +686,6 @@ my_getgrgid(char* group, gid_t gid) -#if !defined BB_REGEXP && (defined BB_GREP || defined BB_FIND ) -/* This tries to find a needle in a haystack, but does so by - * only trying to match literal strings (look 'ma, no regexps!) - * This is short, sweet, and carries _very_ little baggage, - * unlike its beefier cousin a few lines down... - * -Erik Andersen - */ -extern int find_match(char *haystack, char *needle, int ignoreCase) -{ - - if (ignoreCase == FALSE) { - haystack = strstr (haystack, needle); - if (haystack == NULL) - return FALSE; - return TRUE; - } else { - int i; - char needle1[BUF_SIZE]; - char haystack1[BUF_SIZE]; - - strncpy( haystack1, haystack, sizeof(haystack1)); - strncpy( needle1, needle, sizeof(needle1)); - for( i=0; i