diff options
| author | Eric Andersen <andersen@codepoet.org> | 2000-09-25 18:41:18 +0000 |
|---|---|---|
| committer | Eric Andersen <andersen@codepoet.org> | 2000-09-25 18:41:18 +0000 |
| commit | bf73909f23a00bdcc4f4e12459c64b99b2ebcddb (patch) | |
| tree | 6b1ed235a82cea62302e873815f4bdf52320cb10 /findutils | |
| parent | 944be90b21318902a091ca285e19895369a2caea (diff) | |
| download | busybox-w32-bf73909f23a00bdcc4f4e12459c64b99b2ebcddb.tar.gz busybox-w32-bf73909f23a00bdcc4f4e12459c64b99b2ebcddb.tar.bz2 busybox-w32-bf73909f23a00bdcc4f4e12459c64b99b2ebcddb.zip | |
Be ever so pedantic about escaping chars that the shell might not like...
Diffstat (limited to 'findutils')
| -rw-r--r-- | findutils/xargs.c | 76 |
1 files changed, 59 insertions, 17 deletions
diff --git a/findutils/xargs.c b/findutils/xargs.c index 478e0ee6d..21bfb6bbe 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c | |||
| @@ -29,6 +29,59 @@ | |||
| 29 | #include <getopt.h> | 29 | #include <getopt.h> |
| 30 | #include <ctype.h> | 30 | #include <ctype.h> |
| 31 | 31 | ||
| 32 | /* get_sh_safe_line_from_file() - This function reads an entire line from a text file | ||
| 33 | * up to a newline. It returns a malloc'ed char * which must be stored and | ||
| 34 | * free'ed by the caller. */ | ||
| 35 | extern char *get_sh_safe_line_from_file(FILE *file) | ||
| 36 | { | ||
| 37 | static const int GROWBY = 80; /* how large we will grow strings by */ | ||
| 38 | |||
| 39 | char ch, last_ch = 0; | ||
| 40 | char tmp[]=" "; | ||
| 41 | int idx = 0; | ||
| 42 | char *linebuf = NULL; | ||
| 43 | int linebufsz = 0; | ||
| 44 | |||
| 45 | while (1) { | ||
| 46 | ch = fgetc(file); | ||
| 47 | if (ch == EOF) | ||
| 48 | break; | ||
| 49 | |||
| 50 | /* grow the line buffer as necessary */ | ||
| 51 | while (idx > linebufsz-4) | ||
| 52 | linebuf = xrealloc(linebuf, linebufsz += GROWBY); | ||
| 53 | |||
| 54 | /* Remove any extra spaces */ | ||
| 55 | if (last_ch == ' ' && ch == ' ') | ||
| 56 | continue; | ||
| 57 | |||
| 58 | /* Replace any tabs with spaces */ | ||
| 59 | if (ch == '\t') | ||
| 60 | ch=' '; | ||
| 61 | |||
| 62 | /* Escape any characters that are treated specially by /bin/sh */ | ||
| 63 | *tmp=ch; | ||
| 64 | if (strpbrk(tmp, "\\~`!$^&*()=|{}[];\"'<>?#") != NULL && last_ch!='\\') { | ||
| 65 | linebuf[idx++] = '\\'; | ||
| 66 | } | ||
| 67 | |||
| 68 | linebuf[idx++] = ch; | ||
| 69 | last_ch=ch; | ||
| 70 | |||
| 71 | if (ch == '\n') | ||
| 72 | break; | ||
| 73 | } | ||
| 74 | if (idx == 0 && last_ch!=0) | ||
| 75 | linebuf[idx++]=' '; | ||
| 76 | |||
| 77 | if (idx == 0) | ||
| 78 | return NULL; | ||
| 79 | |||
| 80 | linebuf[idx] = 0; | ||
| 81 | return linebuf; | ||
| 82 | } | ||
| 83 | |||
| 84 | |||
| 32 | 85 | ||
| 33 | int xargs_main(int argc, char **argv) | 86 | int xargs_main(int argc, char **argv) |
| 34 | { | 87 | { |
| @@ -54,7 +107,7 @@ int xargs_main(int argc, char **argv) | |||
| 54 | } | 107 | } |
| 55 | 108 | ||
| 56 | /* Store the command and arguments to be executed (from the command line) */ | 109 | /* Store the command and arguments to be executed (from the command line) */ |
| 57 | if (argc == 1) { | 110 | if (argc == 0) { |
| 58 | len_args_from_cmdline = 6; | 111 | len_args_from_cmdline = 6; |
| 59 | args_from_cmdline = xmalloc(len_args_from_cmdline); | 112 | args_from_cmdline = xmalloc(len_args_from_cmdline); |
| 60 | strcat(args_from_cmdline, "echo "); | 113 | strcat(args_from_cmdline, "echo "); |
| @@ -72,6 +125,7 @@ int xargs_main(int argc, char **argv) | |||
| 72 | } | 125 | } |
| 73 | strcat(args_from_cmdline, *argv); | 126 | strcat(args_from_cmdline, *argv); |
| 74 | strcat(args_from_cmdline, " "); | 127 | strcat(args_from_cmdline, " "); |
| 128 | ++argv; | ||
| 75 | } | 129 | } |
| 76 | } | 130 | } |
| 77 | 131 | ||
| @@ -79,30 +133,19 @@ int xargs_main(int argc, char **argv) | |||
| 79 | len_cmd_to_be_executed=10; | 133 | len_cmd_to_be_executed=10; |
| 80 | cmd_to_be_executed = xcalloc(len_cmd_to_be_executed, sizeof(char)); | 134 | cmd_to_be_executed = xcalloc(len_cmd_to_be_executed, sizeof(char)); |
| 81 | strcpy(cmd_to_be_executed, args_from_cmdline); | 135 | strcpy(cmd_to_be_executed, args_from_cmdline); |
| 82 | strcat(cmd_to_be_executed, " \""); | ||
| 83 | 136 | ||
| 84 | /* Now, read in one line at a time from stdin, and run command+args on it */ | 137 | /* Now, read in one line at a time from stdin, and run command+args on it */ |
| 85 | in_from_stdin = get_line_from_file(stdin); | 138 | in_from_stdin = get_sh_safe_line_from_file(stdin); |
| 86 | for (;in_from_stdin!=NULL;) { | 139 | for (;in_from_stdin!=NULL;) { |
| 87 | char *tmp; | 140 | char *tmp; |
| 88 | opt = strlen(in_from_stdin); | 141 | opt = strlen(in_from_stdin); |
| 89 | len = opt + len_args_from_cmdline; | 142 | len = opt + len_args_from_cmdline; |
| 90 | len_cmd_to_be_executed+=len+3; | 143 | len_cmd_to_be_executed+=len+3; |
| 91 | cmd_to_be_executed=xrealloc(cmd_to_be_executed, len_cmd_to_be_executed); | 144 | cmd_to_be_executed=xrealloc(cmd_to_be_executed, len_cmd_to_be_executed); |
| 92 | 145 | ||
| 93 | /* Strip out the final \n */ | 146 | /* Strip out the final \n */ |
| 94 | in_from_stdin[opt-1]=' '; | 147 | in_from_stdin[opt-1]=' '; |
| 95 | 148 | ||
| 96 | /* Replace any tabs with spaces */ | ||
| 97 | while( (tmp = strchr(in_from_stdin, '\t')) != NULL ) | ||
| 98 | *tmp=' '; | ||
| 99 | |||
| 100 | /* Strip out any extra intra-word spaces */ | ||
| 101 | while( (tmp = strstr(in_from_stdin, " ")) != NULL ) { | ||
| 102 | opt = strlen(in_from_stdin); | ||
| 103 | memmove(tmp, tmp+1, opt-(tmp-in_from_stdin)); | ||
| 104 | } | ||
| 105 | |||
| 106 | /* trim trailing whitespace */ | 149 | /* trim trailing whitespace */ |
| 107 | opt = strlen(in_from_stdin) - 1; | 150 | opt = strlen(in_from_stdin) - 1; |
| 108 | while (isspace(in_from_stdin[opt])) | 151 | while (isspace(in_from_stdin[opt])) |
| @@ -118,10 +161,9 @@ int xargs_main(int argc, char **argv) | |||
| 118 | strcat(cmd_to_be_executed, " "); | 161 | strcat(cmd_to_be_executed, " "); |
| 119 | 162 | ||
| 120 | free(in_from_stdin); | 163 | free(in_from_stdin); |
| 121 | in_from_stdin = get_line_from_file(stdin); | 164 | in_from_stdin = get_sh_safe_line_from_file(stdin); |
| 122 | } | 165 | } |
| 123 | 166 | ||
| 124 | strcat(cmd_to_be_executed, "\""); | ||
| 125 | if (traceflag==1) | 167 | if (traceflag==1) |
| 126 | fputs(cmd_to_be_executed, stderr); | 168 | fputs(cmd_to_be_executed, stderr); |
| 127 | 169 | ||
