/*
 * Mini xargs implementation for busybox
 * Options are supported: "-prtx -n max_arg -s max_chars -e[ouf_str]"
 *
 * (C) 2002,2003 by Vladimir Oleynik <dzo@simtreas.ru>
 *
 * Special thanks
 * - Mark Whitley and Glenn McGrath for stimulus to rewrite :)
 * - Mike Rendell <michael@cs.mun.ca>
 * and David MacKenzie <djm@gnu.ai.mit.edu>.
 *
 * 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
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * xargs is described in the Single Unix Specification v3 at
 * http://www.opengroup.org/onlinepubs/007904975/utilities/xargs.html
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "busybox.h"

/* COMPAT:  SYSV version defaults size (and has a max value of) to 470.
   We try to make it as large as possible. */
#if !defined(ARG_MAX) && defined(_SC_ARG_MAX)
#define ARG_MAX sysconf (_SC_ARG_MAX)
#endif
#ifndef ARG_MAX
#define ARG_MAX 470
#endif


#ifdef TEST
# ifndef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION
#  define CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION
# endif
# ifndef CONFIG_FEATURE_XARGS_SUPPORT_QUOTES
#  define CONFIG_FEATURE_XARGS_SUPPORT_QUOTES
# endif
# ifndef CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT
#  define CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT
# endif
# ifndef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM
#  define CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM
# endif
#endif

/*
   This function have special algorithm.
   Don`t use fork and include to main!
*/
static int xargs_exec(char *const *args)
{
	pid_t p;
	volatile int exec_errno = 0;    /* shared vfork stack */

	if ((p = vfork()) >= 0) {
		if (p == 0) {
			/* vfork -- child */
			execvp(args[0], args);
			exec_errno = errno;     /* set error to shared stack */
			_exit(1);
		} else {
			/* vfork -- parent */
			int status;

			while (wait(&status) == (pid_t) - 1)
				if (errno != EINTR)
					break;
			if (exec_errno) {
				errno = exec_errno;
				bb_perror_msg("%s", args[0]);
				return exec_errno == ENOENT ? 127 : 126;
			} else {
				if (WEXITSTATUS(status) == 255) {
					bb_error_msg("%s: exited with status 255; aborting", args[0]);
					return 124;
				}
				if (WIFSTOPPED(status)) {
					bb_error_msg("%s: stopped by signal %d",
						args[0], WSTOPSIG(status));
					return 125;
				}
				if (WIFSIGNALED(status)) {
					bb_error_msg("%s: terminated by signal %d",
						args[0], WTERMSIG(status));
					return 125;
				}
				if (WEXITSTATUS(status) != 0)
					return 123;
				return 0;
			}
		}
	} else {
		bb_perror_msg_and_die("vfork");
	}
}


typedef struct xlist_s {
	char *data;
	size_t lenght;
	struct xlist_s *link;
} xlist_t;

static int eof_stdin_detected;

#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
#define ISSPACE(c) (ISBLANK (c) || (c) == '\n' || (c) == '\r' \
		    || (c) == '\f' || (c) == '\v')

#ifdef CONFIG_FEATURE_XARGS_SUPPORT_QUOTES
static xlist_t *process_stdin(xlist_t * list_arg,
	const char *eof_str, size_t mc, char *buf)
{
#define NORM      0
#define QUOTE     1
#define BACKSLASH 2
#define SPACE     4

	char *s = NULL;         /* start word */
	char *p = NULL;         /* pointer to end word */
	char q = 0;             /* quote char */
	char state = NORM;
	char eof_str_detected = 0;
	size_t line_l = 0;      /* size loaded args line */
	int c;                  /* current char */
	xlist_t *cur;
	xlist_t *prev;

	for (prev = cur = list_arg; cur; cur = cur->link) {
		line_l += cur->lenght;  /* previous allocated */
		if (prev != cur)
			prev = prev->link;
	}

	while (!eof_stdin_detected) {
		c = getchar();
		if (c == EOF) {
			eof_stdin_detected++;
			if (s)
				goto unexpected_eof;
			break;
		}
		if (eof_str_detected)
			continue;
		if (state == BACKSLASH) {
			state = NORM;
			goto set;
		} else if (state == QUOTE) {
			if (c == q) {
				q = 0;
				state = NORM;
			} else {
				goto set;
			}
		} else { /* if(state == NORM) */

			if (ISSPACE(c)) {
				if (s) {
unexpected_eof:
					state = SPACE;
					c = 0;
					goto set;
				}
			} else {
				if (s == NULL)
					s = p = buf;
				if (c == '\\') {
					state = BACKSLASH;
				} else if (c == '\'' || c == '"') {
					q = c;
					state = QUOTE;
				} else {
set:
					if ((size_t)(p - buf) >= mc)
						bb_error_msg_and_die("argument line too long");
					*p++ = c;
				}
			}
		}
		if (state == SPACE) {   /* word's delimiter or EOF detected */
			if (q) {
				bb_error_msg_and_die("unmatched %s quote",
					q == '\'' ? "single" : "double");
			}
			/* word loaded */
			if (eof_str) {
				eof_str_detected = strcmp(s, eof_str) == 0;
			}
			if (!eof_str_detected) {
				size_t lenght = (p - buf);

				cur = xmalloc(sizeof(xlist_t) + lenght);
				cur->data = memcpy(cur + 1, s, lenght);
				cur->lenght = lenght;
				cur->link = NULL;
				if (prev == NULL) {
					list_arg = cur;
				} else {
					prev->link = cur;
				}
				prev = cur;
				line_l += lenght;
				if (line_l > mc) {
					/* stop memory usage :-) */
					break;
				}
			}
			s = NULL;
			state = NORM;
		}
	}
	return list_arg;
}
#else
/* The variant does not support single quotes, double quotes or backslash */
static xlist_t *process_stdin(xlist_t * list_arg,
	const char *eof_str, size_t mc, char *buf)
{

	int c;                  /* current char */
	int eof_str_detected = 0;
	char *s = NULL;         /* start word */
	char *p = NULL;         /* pointer to end word */
	size_t line_l = 0;      /* size loaded args line */
	xlist_t *cur;
	xlist_t *prev;

	for (prev = cur = list_arg; cur; cur = cur->link) {
		line_l += cur->lenght;  /* previous allocated */
		if (prev != cur)
			prev = prev->link;
	}

	while (!eof_stdin_detected) {
		c = getchar();
		if (c == EOF) {
			eof_stdin_detected++;
		}
		if (eof_str_detected)
			continue;
		if (c == EOF || ISSPACE(c)) {
			if (s == NULL)
				continue;
			c = EOF;
		}
		if (s == NULL)
			s = p = buf;
		if ((p - buf) >= mc)
			bb_error_msg_and_die("argument line too long");
		*p++ = c == EOF ? 0 : c;
		if (c == EOF) { /* word's delimiter or EOF detected */
			/* word loaded */
			if (eof_str) {
				eof_str_detected = strcmp(s, eof_str) == 0;
			}
			if (!eof_str_detected) {
				size_t lenght = (p - buf);

				cur = xmalloc(sizeof(xlist_t) + lenght);
				cur->data = memcpy(cur + 1, s, lenght);
				cur->lenght = lenght;
				cur->link = NULL;
				if (prev == NULL) {
					list_arg = cur;
				} else {
					prev->link = cur;
				}
				prev = cur;
				line_l += lenght;
				if (line_l > mc) {
					/* stop memory usage :-) */
					break;
				}
				s = NULL;
			}
		}
	}
	return list_arg;
}
#endif /* CONFIG_FEATURE_XARGS_SUPPORT_QUOTES */


#ifdef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION
/* Prompt the user for a response, and
   if the user responds affirmatively, return true;
   otherwise, return false. Used "/dev/tty", not stdin. */
static int xargs_ask_confirmation(void)
{
	static FILE *tty_stream;
	int c, savec;

	if (!tty_stream) {
		tty_stream = bb_xfopen(CURRENT_TTY, "r");
		/* pranoidal security by vodz */
		fcntl(fileno(tty_stream), F_SETFD, FD_CLOEXEC);
	}
	fputs(" ?...", stderr);
	fflush(stderr);
	c = savec = getc(tty_stream);
	while (c != EOF && c != '\n')
		c = getc(tty_stream);
	if (savec == 'y' || savec == 'Y')
		return 1;
	return 0;
}

# define OPT_INC_P 1
#else
# define OPT_INC_P 0
# define xargs_ask_confirmation() 1
#endif /* CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION */

#ifdef CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT
# define OPT_INC_X 1
#else
# define OPT_INC_X 0
#endif

#ifdef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM
static xlist_t *process0_stdin(xlist_t * list_arg, const char *eof_str ATTRIBUTE_UNUSED,
							   size_t mc, char *buf)
{
	int c;                  /* current char */
	char *s = NULL;         /* start word */
	char *p = NULL;         /* pointer to end word */
	size_t line_l = 0;      /* size loaded args line */
	xlist_t *cur;
	xlist_t *prev;

	for (prev = cur = list_arg; cur; cur = cur->link) {
		line_l += cur->lenght;  /* previous allocated */
		if (prev != cur)
			prev = prev->link;
	}

	while (!eof_stdin_detected) {
		c = getchar();
		if (c == EOF) {
			eof_stdin_detected++;
			if (s == NULL)
				break;
			c = 0;
		}
		if (s == NULL)
			s = p = buf;
		if ((size_t)(p - buf) >= mc)
			bb_error_msg_and_die("argument line too long");
		*p++ = c;
		if (c == 0) {   /* word's delimiter or EOF detected */
			/* word loaded */
			size_t lenght = (p - buf);

			cur = xmalloc(sizeof(xlist_t) + lenght);
			cur->data = memcpy(cur + 1, s, lenght);
			cur->lenght = lenght;
			cur->link = NULL;
			if (prev == NULL) {
				list_arg = cur;
			} else {
				prev->link = cur;
			}
			prev = cur;
			line_l += lenght;
			if (line_l > mc) {
				/* stop memory usage :-) */
				break;
			}
			s = NULL;
		}
	}
	return list_arg;
}

# define READ_ARGS(l, e, nmc, mc) (*read_args)(l, e, nmc, mc)
# define OPT_INC_0 1    /* future use */
#else
# define OPT_INC_0 0    /* future use */
# define READ_ARGS(l, e, nmc, mc) process_stdin(l, e, nmc, mc)
#endif /* CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM */


#define OPT_VERBOSE     (1<<0)
#define OPT_NO_EMPTY    (1<<1)
#define OPT_UPTO_NUMBER (1<<2)
#define OPT_UPTO_SIZE   (1<<3)
#define OPT_EOF_STRING  (1<<4)
#ifdef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION
#define OPT_INTERACTIVE (1<<5)
#else
#define OPT_INTERACTIVE (0)     /* require for algorithm &| */
#endif
#define OPT_TERMINATE   (1<<(5+OPT_INC_P))
#define OPT_ZEROTERM    (1<<(5+OPT_INC_P+OPT_INC_X))
/* next future
#define OPT_NEXT_OTHER  (1<<(5+OPT_INC_P+OPT_INC_X+OPT_INC_0))
*/

int xargs_main(int argc, char **argv)
{
	char **args;
	int i, a, n;
	xlist_t *list = NULL;
	xlist_t *cur;
	int child_error = 0;
	char *max_args, *max_chars;
	int n_max_arg;
	size_t n_chars = 0;
	long orig_arg_max;
	const char *eof_str = "_";
	unsigned long opt;
	size_t n_max_chars;

#ifdef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM
	xlist_t *(*read_args) (xlist_t *, const char *, size_t, char *) = process_stdin;
#endif

#ifdef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION
	bb_opt_complementally = "pt";
#endif

	opt = bb_getopt_ulflags(argc, argv, "+trn:s:e::"
#ifdef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION
	"p"
#endif
#ifdef CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT
	"x"
#endif
#ifdef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM
	"0"
#endif
	,&max_args, &max_chars, &eof_str);

	a = argc - optind;
	argv += optind;
	if (a == 0) {
		/* default behavior is to echo all the filenames */
		*argv = "echo";
		a++;
	}

	orig_arg_max = ARG_MAX;
	if (orig_arg_max == -1)
		orig_arg_max = LONG_MAX;
	orig_arg_max -= 2048;   /* POSIX.2 requires subtracting 2048.  */
	if ((opt & OPT_UPTO_SIZE)) {
		n_max_chars = bb_xgetularg10_bnd(max_chars, 1, orig_arg_max);
		for (i = 0; i < a; i++) {
			n_chars += strlen(*argv) + 1;
		}
		if (n_max_chars < n_chars) {
			bb_error_msg_and_die("can not fit single argument within argument list size limit");
		}
		n_max_chars -= n_chars;
	} else {
		/* Sanity check for systems with huge ARG_MAX defines (e.g., Suns which
		   have it at 1 meg).  Things will work fine with a large ARG_MAX but it
		   will probably hurt the system more than it needs to; an array of this
		   size is allocated.  */
		if (orig_arg_max > 20 * 1024)
			orig_arg_max = 20 * 1024;
		n_max_chars = orig_arg_max;
	}
	max_chars = xmalloc(n_max_chars);

	if ((opt & OPT_UPTO_NUMBER)) {
		n_max_arg = bb_xgetularg10_bnd(max_args, 1, INT_MAX);
	} else {
		n_max_arg = n_max_chars;
	}

#ifdef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM
	if (opt & OPT_ZEROTERM)
		read_args = process0_stdin;
#endif

	while ((list = READ_ARGS(list, eof_str, n_max_chars, max_chars)) != NULL ||
		(opt & OPT_NO_EMPTY) == 0)
	{
		opt |= OPT_NO_EMPTY;
		n = 0;
		n_chars = 0;
#ifdef CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT
		for (cur = list; cur;) {
			n_chars += cur->lenght;
			n++;
			cur = cur->link;
			if (n_chars > n_max_chars || (n == n_max_arg && cur)) {
				if (opt & OPT_TERMINATE)
					bb_error_msg_and_die("argument list too long");
				break;
			}
		}
#else
		for (cur = list; cur; cur = cur->link) {
			n_chars += cur->lenght;
			n++;
			if (n_chars > n_max_chars || n == n_max_arg) {
				break;
			}
		}
#endif /* CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT */

		/* allocating pointers for execvp:
		   a*arg, n*arg from stdin, NULL */
		args = xcalloc(n + a + 1, sizeof(char *));

		/* Store the command to be executed
		   (taken from the command line) */
		for (i = 0; i < a; i++)
			args[i] = argv[i];
		/* (taken from stdin) */
		for (cur = list; n; cur = cur->link) {
			args[i++] = cur->data;
			n--;
		}

		if ((opt & (OPT_INTERACTIVE | OPT_VERBOSE))) {
			for (i = 0; args[i]; i++) {
				if (i)
					fputc(' ', stderr);
				fputs(args[i], stderr);
			}
			if ((opt & OPT_INTERACTIVE) == 0)
				fputc('\n', stderr);
		}
		if ((opt & OPT_INTERACTIVE) == 0 || xargs_ask_confirmation() != 0) {
			child_error = xargs_exec(args);
		}

		/* clean up */
		for (i = a; args[i]; i++) {
			cur = list;
			list = list->link;
			free(cur);
		}
		free(args);
		if (child_error > 0 && child_error != 123) {
			break;
		}
	}
#ifdef CONFIG_FEATURE_CLEAN_UP
	free(max_chars);
#endif
	return child_error;
}


#ifdef TEST

const char *bb_applet_name = "debug stuff usage";

void bb_show_usage(void)
{
	fprintf(stderr, "Usage: %s [-p] [-r] [-t] -[x] [-n max_arg] [-s max_chars]\n",
		bb_applet_name);
	exit(1);
}

int main(int argc, char **argv)
{
	return xargs_main(argc, argv);
}
#endif /* TEST */
