X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=xargs.c;h=c5f7b208c425cb2cebc7c168a5c7cca045779655;hb=46f44d24fcc25a5d6e13e0453485881bdf147e91;hp=478e0ee6d630549a3f1727c8de3c240b1a77da1f;hpb=6f283c2f772c32635fbf61f5b6c0a9a37cc50eed;p=oweals%2Fbusybox.git diff --git a/xargs.c b/xargs.c index 478e0ee6d..c5f7b208c 100644 --- a/xargs.c +++ b/xargs.c @@ -1,9 +1,9 @@ -/* vi: set sw=4 ts=4: */ /* * Mini xargs implementation for busybox * * Copyright (C) 2000 by Lineo, inc. * Written by Erik Andersen , + * Remixed by Mark Whitley , * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,126 +21,88 @@ * */ -#include "internal.h" -#include +#include "busybox.h" #include +#include #include -#include -#include -#include - int xargs_main(int argc, char **argv) { - char *in_from_stdin = NULL; - char *args_from_cmdline = NULL; char *cmd_to_be_executed = NULL; - char traceflag = 0; - int len_args_from_cmdline, len_cmd_to_be_executed, len, opt; - - /* Note that we do not use getopt here, since - * we only want to interpret initial options, - * not options passed to commands */ - while (--argc && **(++argv) == '-') { - while (*++(*argv)) { - switch (**argv) { - case 't': - traceflag=1; - break; - default: - fatalError(xargs_usage); - } - } - } - - /* Store the command and arguments to be executed (from the command line) */ + char *file_to_act_on = NULL; + + /* + * No options are supported in this version of xargs; no getopt. + * + * Re: The missing -t flag: Most programs that produce output also print + * the filename, so xargs doesn't really need to do it again. Supporting + * the -t flag =greatly= bloats up the size of this app and the memory it + * uses because you have to buffer all the input file strings in memory. If + * you really want to see the filenames that xargs will act on, just run it + * once with no args and xargs will echo the filename. Simple. + */ + + /* Store the command to be executed (taken from the command line) */ if (argc == 1) { - len_args_from_cmdline = 6; - args_from_cmdline = xmalloc(len_args_from_cmdline); - strcat(args_from_cmdline, "echo "); + /* default behavior is to echo all the filenames */ + cmd_to_be_executed = strdup("/bin/echo "); } else { - opt=strlen(*argv); - len_args_from_cmdline = (opt > 10)? opt : 10; - args_from_cmdline = xcalloc(len_args_from_cmdline, sizeof(char)); - while (argc-- > 0) { - if (strlen(*argv) + strlen(args_from_cmdline) > - len_args_from_cmdline) { - len_args_from_cmdline += strlen(*argv); - args_from_cmdline = - xrealloc(args_from_cmdline, - len_args_from_cmdline+1); - } - strcat(args_from_cmdline, *argv); - strcat(args_from_cmdline, " "); + /* concatenate all the arguments passed to xargs together */ + int i; + int len = 1; /* for the '\0' */ + for (i = 1; i < argc; i++) { + len += strlen(argv[i]); + len += 1; /* for the space between the args */ + cmd_to_be_executed = xrealloc(cmd_to_be_executed, len); + strcat(cmd_to_be_executed, argv[i]); + strcat(cmd_to_be_executed, " "); } } - /* Set up some space for the command to be executed to be held in */ - len_cmd_to_be_executed=10; - cmd_to_be_executed = xcalloc(len_cmd_to_be_executed, sizeof(char)); - strcpy(cmd_to_be_executed, args_from_cmdline); - strcat(cmd_to_be_executed, " \""); - - /* Now, read in one line at a time from stdin, and run command+args on it */ - in_from_stdin = get_line_from_file(stdin); - for (;in_from_stdin!=NULL;) { - char *tmp; - opt = strlen(in_from_stdin); - len = opt + len_args_from_cmdline; - len_cmd_to_be_executed+=len+3; - cmd_to_be_executed=xrealloc(cmd_to_be_executed, len_cmd_to_be_executed); - - /* Strip out the final \n */ - in_from_stdin[opt-1]=' '; - - /* Replace any tabs with spaces */ - while( (tmp = strchr(in_from_stdin, '\t')) != NULL ) - *tmp=' '; - - /* Strip out any extra intra-word spaces */ - while( (tmp = strstr(in_from_stdin, " ")) != NULL ) { - opt = strlen(in_from_stdin); - memmove(tmp, tmp+1, opt-(tmp-in_from_stdin)); + /* Now, read in one line at a time from stdin, and store this + * line to be used later as an argument to the command */ + while ((file_to_act_on = get_line_from_file(stdin)) !=NULL) { + + FILE *cmd_output = NULL; + char *output_line = NULL; + char *execstr = NULL; + + /* eat the newline off the filename. */ + if (file_to_act_on[strlen(file_to_act_on)-1] == '\n') + file_to_act_on[strlen(file_to_act_on)-1] = '\0'; + + /* eat blank lines */ + if (strlen(file_to_act_on) == 0) + continue; + + /* assemble the command and execute it */ + execstr = xcalloc(strlen(cmd_to_be_executed) + + strlen(file_to_act_on) + 1, sizeof(char)); + strcat(execstr, cmd_to_be_executed); + strcat(execstr, file_to_act_on); + cmd_output = popen(execstr, "r"); + if (cmd_output == NULL) { + perror("popen"); + exit(1); } - /* trim trailing whitespace */ - opt = strlen(in_from_stdin) - 1; - while (isspace(in_from_stdin[opt])) - opt--; - in_from_stdin[++opt] = 0; - - /* Strip out any leading whitespace */ - tmp=in_from_stdin; - while(isspace(*tmp)) - tmp++; + /* harvest the output */ + while ((output_line = get_line_from_file(cmd_output)) != NULL) { + fputs(output_line, stdout); + free(output_line); + } - strcat(cmd_to_be_executed, tmp); - strcat(cmd_to_be_executed, " "); - - free(in_from_stdin); - in_from_stdin = get_line_from_file(stdin); + /* clean up */ + pclose(cmd_output); + free(execstr); + free(file_to_act_on); } - strcat(cmd_to_be_executed, "\""); - if (traceflag==1) - fputs(cmd_to_be_executed, stderr); - - if ((system(cmd_to_be_executed) != 0) && (errno != 0)) - fatalError("%s", strerror(errno)); - - #ifdef BB_FEATURE_CLEAN_UP - free(args_from_cmdline); free(cmd_to_be_executed); #endif return 0; } -/* -Local Variables: -c-file-style: "linux" -c-basic-offset: 4 -tab-width: 4 -End: -*/ +/* vi: set sw=4 ts=4: */