/* * xargs() cut argument lists down to size */ #include #include #include #include #include "getopt.h" int max_items=1; /* -n flag: max tokens to put in new command line */ int max_length=128; /* -s flag: max length of new command line */ char *repl_str=0; /* -i flag: do replacements on the command+args */ /* instead of appending them */ char *eof_str=0; /* -e flag: stop reading stdin when we reach this */ /* pattern */ char verbose=0; /* -t flag: echo each line before executing */ char query=0; /* -y flag: ask to run each line before doing it */ char fail_on_overflow=0;/* -x flag: drop dead if a commandline is too long */ char debug=0; /* -d flag: don't actually execute the commands */ char **argheap; /* argument buffer */ int arg_ptr; /* # items in argument buffer */ char *command; /* workarea for xarg commands */ void *xmalloc(); char *xstrdup(); int xatoi(); void badboy(); /* * xargs, in the flesh */ main(argc, argv) char **argv; { register i; static char line[400]; register siz; Getopt_verbose(); while (getopt(argc, argv, "n:s:l:i:e:txd") != EOF) switch (optopt) { case 'l': case 'n': max_items=xatoi(optarg); break; case 's': max_length=xatoi(optarg); break; case 'i': repl_str = optarg; if (strlen(repl_str) != 1) badboy("only 1-character replacement strings, please!");break; break; case 'e': eof_str = optarg; break; case 't': verbose=1; break; case 'x': fail_on_overflow=1; break; case 'd': debug=1; break; default: badboy((char*)0); } argc -= optind; argv += optind; if (argc < 1) badboy("no command to execute"); if (repl_str && argc < 2) badboy("no arguments to replace against?"); for (siz=i=0; i= max_items) xarg_exec(argc, argv); } while (arg_ptr > 0) xarg_exec(argc, argv); exit(0); } /* xargs */ /* * copy_args_in() is a local used by xarg_exec(): it copies all of the * arguments into the string pointed at by p, then returns a pointer to * the new end of that string */ char * copy_args_in(p, to_process) register char *p; { register i; for (i=0; i0) *p++ = ' '; strcpy(p, argheap[i]); p += strlen(argheap[i]); } return p; } /* copy_args_in */ /* * xarg_exec() makes up a command string out of the arguments we've buffered * * if we can't fit all of the arguments into the string, we leave the ones * we can't fit in the buffer, to be handled by the next call to xarg_exec(). */ xarg_exec(argc, argv) char **argv; { register i, j; register char *p, *q; int size; int cmdsize; int process_args; /* compute the length of the command string. */ cmdsize = argc; for (i=0; i0 ? 1 : 0)); if (cmdsize+size > max_length) break; cmdsize += size; } if (fail_on_overflow && process_args < arg_ptr) { fprintf(stderr, "command string overflow\n"); exit(3); } if (process_args == 0) { /* couldn't fit first argument in */ fprintf(stderr, "can't process %s\n", argheap[0]); process_args = 1; goto cleanup; } strcpy(command, argv[0]); p = command+strlen(command); for (i=1; i max_length) break; cmdsize += size; } if (fail_on_overflow && process_args < arg_ptr) { fprintf(stderr, "command string overflow\n"); exit(3); } if (process_args == 0) { /* couldn't fit first argument in */ fprintf(stderr, "can't process %s\n", argheap[0]); process_args = 1; goto cleanup; } command[0] = 0; for (i=0; i 0 for option -%c", optopt); return value; } /* xatoi */