[alt.sources] yargs - alternative to xargs

davidsen@sixhub.UUCP (Wm E. Davidsen Jr) (10/24/90)

  There has been some discussion of bugs and security problems with
xargs. Here is a stripped version, without options, features, or
hopefully bugs.

#!/bin/sh
# shar:	Shell Archiver  (v1.27)
#
#	Run the following text with /bin/sh to create:
#	  readme
#	  makefile
#	  yargs.c
#
sed 's/^X//' << 'SHAR_EOF' > readme &&
X                                 YARGS
X
X
X  Many vendors versions of xargs have problems caused by not treating
Xevery input line as a separate argument. Thus shell escapes (as ; and #)
Xand enbedded blanks can cause problems.
X
X  In addition, some vendors limit the length of a data line to 470
Xcharacters, rather than the maximum (often 5120 or more), which causes
Xmultiple forking of the program.
X
X  This is my attempt to solve those problems in a brute force way. The
Xinitial public version has no options. It won't trace, debug, string
Xsubstitute, limit the string lengths or the number of arguments. It does
Xnot sing, not does it dance, it just executes a command using the stdin
Xas arguments, and it does that one thing very well.
X
X  I suppose at some time I will add some features, but for now I would
Xjust like feedback on how well it performs its one major function.
SHAR_EOF
chmod 0644 readme || echo "restore of readme fails"
sed 's/^X//' << 'SHAR_EOF' > makefile &&
X# makefile for yargs
X
XSHAR		= shar
XSHARLIST	= readme makefile yargs.c
X
X# magic makerules for SCCS - prevent making a writable .c file
X.c~.c:
X	get $?
X.c~.o:
X	get $?
X	$(CC) -c $(CFLAGS) $*
X
Xyargs: yargs.o
X	$(CC) -o yargs $(LDFLAGS) yargs.o
X
Xshar:	yargs.shar
Xyargs.shar: $(SHARLIST)
X	$(SHAR) $(SHARLIST) > yargs.shar
SHAR_EOF
chmod 0644 makefile || echo "restore of makefile fails"
sed 's/^X//' << 'SHAR_EOF' > yargs.c &&
X/*
X *  yargs - another implementation of yargs
X *
X *  written to attempt to avoid security problems with several
X *  vendor's versions of yargs.
X *
X**/
X
X/* note - NCARGS is the max number of chars in an exec arglist */
X#include <stdio.h>
X#ifndef NCARGS
X#include <sys/param.h>
X#ifndef NCARGS
X#define NCARGS			470			/* some version like it short */
X#endif
X#endif
X
Xstatic char *Info[] = {
X	"@(#)yargs - v1.4 10/23/90",
X	"Copyright (c) 1990 by Bill Davidsen, all rights reserved.",
X	"This program may be freely used and distributed by anyone",
X	"in the original unmodified form."
X};
X
X#define MAX_IN_LINE		256			/* longest input line */
X#define MAX_ARGS		256			/* args in the vector */
X#define EOS				'\0'		/* end of string */
X
X/* global variables */
Xchar inputline[MAX_IN_LINE+1];		/* input into this buffer */
Xchar *argvect[MAX_ARGS+1];			/* save arg pointers here */
Xint arg_ptr = 0;					/* highest arg # */
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X	char *saveptr = Info[0];
X	int testlen;
X	int roomleft;
X
X	/* no fancy options in this version */
X	if (argc < 2) {
X		fprintf(stderr, "yargs: no arguments!\n");
X		exit(1);
X	}
X	inputline[MAX_IN_LINE] = EOS;
X
X	/* initialize the command line */
X	init_cmd(argc, argv, argvect, &arg_ptr, &roomleft);
X
X	while (fgets(inputline, MAX_IN_LINE, stdin)) {
X		if ((testlen = strlen(inputline)) == MAX_IN_LINE) {
X			/* input line too long */
X			fprintf("yargs: input line too long!\n");
X			exit(1);
X		}
X
X		/* see if room in line */
X		if (strlen(inputline) > roomleft) {
X			if (argvect[arg_ptr+1]) free(argvect[arg_ptr]);
X			argvect[arg_ptr] = NULL;
X			if (execvp(argv[1], argvect)) exit(1);
X
X			/* now setup for another command line */
X			init_cmd(argc, argv, argvect, &arg_ptr, &roomleft);
X		}
X
X		if (argvect[arg_ptr] == NULL) {
X			argvect[arg_ptr] = (char *)malloc(MAX_IN_LINE+1);
X			if (argvect[arg_ptr] == NULL) {
X				/* ran out of memory */
X				fprintf(stderr, "Can't alloc memory for arg list!\n");
X				exit(1);
X			}
X		}
X
X		/* drop the newline and add the argument */
X		inputline[testlen-1] = EOS;
X		strcpy(argvect[arg_ptr++], inputline);
X		roomleft -= (testlen+2);
X	}
X
X	argvect[arg_ptr] = NULL;
X	execvp(argv[1], argvect);
X}
X
Xinit_cmd(argc, argv, argvect, arg_ptr, roomleft)
Xint argc;
Xchar *argv[], *argvect[];
Xint *arg_ptr, *roomleft;
X{
X	register int m;
X
X	*roomleft = NCARGS-10;
X	for (m=1, *arg_ptr=0; m<argc; ) {
X		*roomleft -= (strlen(argv[m])+3);
X		argvect[(*arg_ptr)++] = argv[m++];
X	}
X}
SHAR_EOF
chmod 0444 yargs.c || echo "restore of yargs.c fails"
exit 0

-- 
bill davidsen - davidsen@sixhub.uucp (uunet!crdgw1!sixhub!davidsen)
    sysop *IX BBS and Public Access UNIX
    moderator of comp.binaries.ibm.pc and 80386 mailing list
"Stupidity, like virtue, is its own reward" -me