diff options
author | Eric Andersen | 2000-06-26 12:14:30 +0000 |
---|---|---|
committer | Eric Andersen | 2000-06-26 12:14:30 +0000 |
commit | 1386e7021015959443a3b601b224660848acdda4 (patch) | |
tree | 05cc6c41012fe0f7ff2df50a4ba84d4b5ced4d8f | |
parent | ef40aa81c5024bc305a4e95f6edb76bae258cc2b (diff) | |
download | busybox-1386e7021015959443a3b601b224660848acdda4.zip busybox-1386e7021015959443a3b601b224660848acdda4.tar.gz |
Fixed segfault with 'cut -f 1 -d:' and added 'cut -s' suport.
Fix thanks to Arne Bernin <arne@matrix.loopback.org>
-Erik
-rw-r--r-- | Changelog | 2 | ||||
-rw-r--r-- | coreutils/cut.c | 30 | ||||
-rw-r--r-- | cut.c | 30 | ||||
-rw-r--r-- | docs/busybox.pod | 13 |
4 files changed, 55 insertions, 20 deletions
@@ -6,6 +6,8 @@ * Fixed a nasty bug in tar when could mess up saved symlinks. * Fixed insmod module option parsing for options lacking an '='. Fix thanks to Marc Nijdam <marc_nijdam@hp.com> + * Fixed segfault with 'cut -f 1 -d:' and added 'cut -s' suport. + Fix thanks to Arne Bernin <arne@matrix.loopback.org> -Erik Andersen diff --git a/coreutils/cut.c b/coreutils/cut.c index 7b183e8..a8a9d7f 100644 --- a/coreutils/cut.c +++ b/coreutils/cut.c @@ -51,15 +51,14 @@ int num_args; #define OPTIONC 2 /* define for mode: option -c */ #define OPTIONB 3 /* define for mode: option -b */ #define NOTSET 0 /* option not selected */ -#define SET 1 /* option selected */ - +#define SET 1 /* option selected */ +#define OPTIONS 1 /*define option -s */ /* Defines for the warnings */ #define DELIMITER_NOT_APPLICABLE 0 #define OVERRIDING_PREVIOUS_MODE 1 #define OPTION_NOT_APPLICABLE 2 #define UNKNOWN_OPTION 3 #define FILE_NOT_READABLE 4 - /* Defines for the fatal errors */ #define SYNTAX_ERROR 101 #define POSITION_ERROR 102 @@ -75,6 +74,7 @@ FILE *fd; char *name; char line[BUFSIZ]; int exit_status; +int option = 0; /* for -s option */ int cut_main(int argc, char **argv); void warn(int warn_number, char *option); @@ -85,7 +85,7 @@ void cut(void); void warn(int warn_number, char *option) { static char *warn_msg[] = { - "%s: Option -d allowed only with -f\n", + "%s: Option -%s allowed only with -f\n", "%s: -%s overrides earlier option\n", "%s: -%s not allowed in current mode\n", "%s: Cannot open %s\n" @@ -161,7 +161,8 @@ void cut() char *columns[MAX_FIELD]; while (fgets(line, BUFSIZ, fd)) { - length = strlen(line) - 1; + maxcol=0; + length = strlen(line) - 1; *(line + length) = 0; switch (mode) { case DUMP_STDIN: @@ -182,11 +183,15 @@ void cut() for (i = 0; i < num_args; i++) { for (j = args[i * 2]; j <= args[i * 2 + 1]; j++) if (j <= maxcol) { + printf("%s", columns[j - 1]); + if (i != num_args - 1 || j != args[i * 2 + 1]) putchar(delim); } } + } else if (option != OPTIONS) { + printf("%s",line); } break; case OPTIONC: @@ -217,7 +222,8 @@ int cut_main(int argc, char **argv) "Options:\n" "\t-b LIST\tOutput only bytes from LIST\n" "\t-c LIST\tOutput only characters from LIST\n" - "\t-d DELIM\tUse DELIM instead of tab as the field delimiter\n" + "\t-d CHAR\tUse CHAR instead of tab as the field delimiter\n" + "\t-s\tOnly output Lines if the include DELIM\n" "\t-f N\tPrint only these fields\n" "\t-n\tIgnored\n" #endif @@ -229,7 +235,10 @@ int cut_main(int argc, char **argv) case 'd': if (mode == OPTIONC || mode == OPTIONB) warn(DELIMITER_NOT_APPLICABLE, "d"); - delim = argv[i++][0]; + if (argc > i) + delim = argv[i++][0]; + else + cuterror(SYNTAX_ERROR); break; case 'f': sprintf(line, "%s", argv[i++]); @@ -249,6 +258,10 @@ int cut_main(int argc, char **argv) warn(OVERRIDING_PREVIOUS_MODE, "c"); mode = OPTIONC; break; + case 's': + option = OPTIONS; + + break; case '\0': /* - means: read from stdin */ numberFilenames++; break; @@ -268,6 +281,9 @@ int cut_main(int argc, char **argv) /* Here follow the checks, if the selected options are reasonable. */ if (mode == OPTIONB) /* since in Minix char := byte */ mode = OPTIONC; + + if (mode != OPTIONF && option == OPTIONS) + warn(DELIMITER_NOT_APPLICABLE,"s"); get_args(); if (numberFilenames != 0) { i = 1; @@ -51,15 +51,14 @@ int num_args; #define OPTIONC 2 /* define for mode: option -c */ #define OPTIONB 3 /* define for mode: option -b */ #define NOTSET 0 /* option not selected */ -#define SET 1 /* option selected */ - +#define SET 1 /* option selected */ +#define OPTIONS 1 /*define option -s */ /* Defines for the warnings */ #define DELIMITER_NOT_APPLICABLE 0 #define OVERRIDING_PREVIOUS_MODE 1 #define OPTION_NOT_APPLICABLE 2 #define UNKNOWN_OPTION 3 #define FILE_NOT_READABLE 4 - /* Defines for the fatal errors */ #define SYNTAX_ERROR 101 #define POSITION_ERROR 102 @@ -75,6 +74,7 @@ FILE *fd; char *name; char line[BUFSIZ]; int exit_status; +int option = 0; /* for -s option */ int cut_main(int argc, char **argv); void warn(int warn_number, char *option); @@ -85,7 +85,7 @@ void cut(void); void warn(int warn_number, char *option) { static char *warn_msg[] = { - "%s: Option -d allowed only with -f\n", + "%s: Option -%s allowed only with -f\n", "%s: -%s overrides earlier option\n", "%s: -%s not allowed in current mode\n", "%s: Cannot open %s\n" @@ -161,7 +161,8 @@ void cut() char *columns[MAX_FIELD]; while (fgets(line, BUFSIZ, fd)) { - length = strlen(line) - 1; + maxcol=0; + length = strlen(line) - 1; *(line + length) = 0; switch (mode) { case DUMP_STDIN: @@ -182,11 +183,15 @@ void cut() for (i = 0; i < num_args; i++) { for (j = args[i * 2]; j <= args[i * 2 + 1]; j++) if (j <= maxcol) { + printf("%s", columns[j - 1]); + if (i != num_args - 1 || j != args[i * 2 + 1]) putchar(delim); } } + } else if (option != OPTIONS) { + printf("%s",line); } break; case OPTIONC: @@ -217,7 +222,8 @@ int cut_main(int argc, char **argv) "Options:\n" "\t-b LIST\tOutput only bytes from LIST\n" "\t-c LIST\tOutput only characters from LIST\n" - "\t-d DELIM\tUse DELIM instead of tab as the field delimiter\n" + "\t-d CHAR\tUse CHAR instead of tab as the field delimiter\n" + "\t-s\tOnly output Lines if the include DELIM\n" "\t-f N\tPrint only these fields\n" "\t-n\tIgnored\n" #endif @@ -229,7 +235,10 @@ int cut_main(int argc, char **argv) case 'd': if (mode == OPTIONC || mode == OPTIONB) warn(DELIMITER_NOT_APPLICABLE, "d"); - delim = argv[i++][0]; + if (argc > i) + delim = argv[i++][0]; + else + cuterror(SYNTAX_ERROR); break; case 'f': sprintf(line, "%s", argv[i++]); @@ -249,6 +258,10 @@ int cut_main(int argc, char **argv) warn(OVERRIDING_PREVIOUS_MODE, "c"); mode = OPTIONC; break; + case 's': + option = OPTIONS; + + break; case '\0': /* - means: read from stdin */ numberFilenames++; break; @@ -268,6 +281,9 @@ int cut_main(int argc, char **argv) /* Here follow the checks, if the selected options are reasonable. */ if (mode == OPTIONB) /* since in Minix char := byte */ mode = OPTIONC; + + if (mode != OPTIONF && option == OPTIONS) + warn(DELIMITER_NOT_APPLICABLE,"s"); get_args(); if (numberFilenames != 0) { i = 1; diff --git a/docs/busybox.pod b/docs/busybox.pod index 3f7152a..5c2c590 100644 --- a/docs/busybox.pod +++ b/docs/busybox.pod @@ -276,11 +276,12 @@ Prints selected fields from each input FILE to standard output. Options: - -b LIST Output only bytes from LIST - -c LIST Output only characters from LIST - -d DELIM Use DELIM instead of tab as the field delimiter - -f N Print only these fields - -n Ignored + -b LIST Output only bytes from LIST + -c LIST Output only characters from LIST + -d CHAR Use CHAR instead of tab as the field delimiter + -s Only output Lines if the include DELIM + -f N Print only these fields + -n Ignored Example: @@ -2062,4 +2063,4 @@ Enrique Zanardi <ezanardi@ull.es> =cut -# $Id: busybox.pod,v 1.51 2000/06/21 22:53:24 andersen Exp $ +# $Id: busybox.pod,v 1.52 2000/06/26 12:14:30 andersen Exp $ |