From 59870e89aeb4be4faab6fcd2dffbd7fc683eab88 Mon Sep 17 00:00:00 2001 From: Glenn L McGrath Date: Sun, 10 Nov 2002 21:52:59 +0000 Subject: Prevent a segfault if no argument, by Geoffrey Lee --- coreutils/od.c | 288 +++++++++++++-------------------------------------------- 1 file changed, 64 insertions(+), 224 deletions(-) (limited to 'coreutils') diff --git a/coreutils/od.c b/coreutils/od.c index a29ed758e..471bae45b 100644 --- a/coreutils/od.c +++ b/coreutils/od.c @@ -1,9 +1,9 @@ /* - * od implementation for busybox - * Based on code from util-linux v 2.11l + * Mini xargs implementation for busybox * - * Copyright (c) 1990 - * The Regents of the University of California. All rights reserved. + * Copyright (C) 1999,2000 by Lineo, inc. and Erik Andersen + * Copyright (C) 1999,2000,2001 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 @@ -19,248 +19,88 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * Original copyright notice is retained at the end of this file. */ -#include -#include +#include #include -#include "dump.h" +#include #include "busybox.h" -extern FS *fshead; /* head of format strings */ -extern int blocksize; /* data block size */ -extern int length; /* max bytes to read */ - -#define ishexdigit(c) \ - ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) - -static void -odoffset(int argc, char ***argvp) +int xargs_main(int argc, char **argv) { - extern off_t skip; - register char *num, *p; - int base; - char *end; + char *cmd_to_be_executed; + char *file_to_act_on; + int i; + int len; /* - * The offset syntax of od(1) was genuinely bizarre. First, if - * it started with a plus it had to be an offset. Otherwise, if - * there were at least two arguments, a number or lower-case 'x' - * followed by a number makes it an offset. By default it was - * octal; if it started with 'x' or '0x' it was hex. If it ended - * in a '.', it was decimal. If a 'b' or 'B' was appended, it - * multiplied the number by 512 or 1024 byte units. There was - * no way to assign a block count to a hex offset. + * No options are supported in this version of xargs; no getopt. * - * We assumes it's a file if the offset is bad. - */ - p = **argvp; - if (*p != '+' && (argc < 2 || - (!isdigit(p[0]) && (p[0] != 'x' || !ishexdigit(p[1]))))) - return; - - base = 0; - /* - * skip over leading '+', 'x[0-9a-fA-f]' or '0x', and - * set base. + * 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. */ - if (p[0] == '+') - ++p; - if (p[0] == 'x' && ishexdigit(p[1])) { - ++p; - base = 16; - } else if (p[0] == '0' && p[1] == 'x') { - p += 2; - base = 16; - } - - /* skip over the number */ - if (base == 16) - for (num = p; ishexdigit(*p); ++p); - else - for (num = p; isdigit(*p); ++p); - - /* check for no number */ - if (num == p) - return; - /* if terminates with a '.', base is decimal */ - if (*p == '.') { - if (base) - return; - base = 10; + argv++; + len = argc; /* arg = count for ' ' + trailing '\0' */ + /* Store the command to be executed (taken from the command line) */ + if (argc == 1) { + /* default behavior is to echo all the filenames */ + argv[0] = "/bin/echo"; + len++; /* space for trailing '\0' */ + } else { + argc--; + } + /* concatenate all the arguments passed to xargs together */ + for (i = 0; i < argc; i++) + len += strlen(argv[i]); + cmd_to_be_executed = xmalloc (len); + for (i = len = 0; i < argc; i++) { + len = sprintf(cmd_to_be_executed + len, "%s ", argv[i]); } - skip = strtol(num, &end, base ? base : 8); + /* 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) { - /* if end isn't the same as p, we got a non-octal digit */ - if (end != p) - skip = 0; - else { - if (*p) { - if (*p == 'b') - skip *= 512; - else if (*p == 'B') - skip *= 1024; - ++p; - } - if (*p) - skip = 0; - else { - ++*argvp; - /* - * If the offset uses a non-octal base, the base of - * the offset is changed as well. This isn't pretty, - * but it's easy. - */ -#define TYPE_OFFSET 7 - if (base == 16) { - fshead->nextfu->fmt[TYPE_OFFSET] = 'x'; - fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x'; - } else if (base == 10) { - fshead->nextfu->fmt[TYPE_OFFSET] = 'd'; - fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd'; - } - } - } -} + FILE *cmd_output; + char *output_line; + char *execstr; -static void odprecede(void) -{ - static int first = 1; + /* eat the newline off the filename. */ + chomp(file_to_act_on); - if (first) { - first = 0; - add("\"%07.7_Ao\n\""); - add("\"%07.7_ao \""); - } else - add("\" \""); -} + /* eat blank lines */ + if (file_to_act_on[0] == 0) + continue; -int od_main(int argc, char **argv) -{ - int ch; - extern enum _vflag vflag; - vflag = FIRST; - length = -1; + /* assemble the command and execute it */ + bb_asprintf(&execstr, "%s%s", cmd_to_be_executed, file_to_act_on); + + cmd_output = popen(execstr, "r"); + if (cmd_output == NULL) + perror_msg_and_die("popen"); - while ((ch = getopt(argc, argv, "aBbcDdeFfHhIiLlOoPpswvXx")) != EOF) - switch (ch) { - case 'a': - odprecede(); - add("16/1 \"%3_u \" \"\\n\""); - break; - case 'B': - case 'o': - odprecede(); - add("8/2 \" %06o \" \"\\n\""); - break; - case 'b': - odprecede(); - add("16/1 \"%03o \" \"\\n\""); - break; - case 'c': - odprecede(); - add("16/1 \"%3_c \" \"\\n\""); - break; - case 'd': - odprecede(); - add("8/2 \" %05u \" \"\\n\""); - break; - case 'D': - odprecede(); - add("4/4 \" %010u \" \"\\n\""); - break; - case 'e': /* undocumented in od */ - case 'F': - odprecede(); - add("2/8 \" %21.14e \" \"\\n\""); - break; - - case 'f': - odprecede(); - add("4/4 \" %14.7e \" \"\\n\""); - break; - case 'H': - case 'X': - odprecede(); - add("4/4 \" %08x \" \"\\n\""); - break; - case 'h': - case 'x': - odprecede(); - add("8/2 \" %04x \" \"\\n\""); - break; - case 'I': - case 'L': - case 'l': - odprecede(); - add("4/4 \" %11d \" \"\\n\""); - break; - case 'i': - odprecede(); - add("8/2 \" %6d \" \"\\n\""); - break; - case 'O': - odprecede(); - add("4/4 \" %011o \" \"\\n\""); - break; - case 'v': - vflag = ALL; - break; - case 'P': - case 'p': - case 's': - case 'w': - case '?': - default: - error_msg("od: od(1) has been deprecated for hexdump(1).\n"); - if (ch != '?') { - error_msg("od: hexdump(1) compatibility doesn't support the -%c option%s\n", - ch, ch == 's' ? "; see strings(1)." : "."); - } - show_usage(); + /* harvest the output */ + while ((output_line = get_line_from_file(cmd_output)) != NULL) { + fputs(output_line, stdout); + free(output_line); } - if (!fshead) { - add("\"%07.7_Ao\n\""); - add("\"%07.7_ao \" 8/2 \"%06o \" \"\\n\""); + /* clean up */ + pclose(cmd_output); + free(execstr); + free(file_to_act_on); } - argc -= optind; - argv += optind; - - odoffset(argc, &argv); +#ifdef CONFIG_FEATURE_CLEAN_UP + free(cmd_to_be_executed); +#endif - return(dump(argv)); + return 0; } -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ +/* vi: set sw=4 ts=4: */ -- cgit v1.2.3