1/*- 2 * Copyright (c) 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * John B. Roll Jr. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * $xMach: xargs.c,v 1.6 2002/02/23 05:27:47 tim Exp $ 37 */ 38 39#if 0 40#ifndef lint 41static const char copyright[] = 42"@(#) Copyright (c) 1990, 1993\n\ 43 The Regents of the University of California. All rights reserved.\n"; 44#endif /* not lint */ 45 46#ifndef lint 47static char sccsid[] = "@(#)xargs.c 8.1 (Berkeley) 6/6/93"; 48#endif /* not lint */ 49#endif 50#include <sys/cdefs.h> 51__FBSDID("$FreeBSD: src/usr.bin/xargs/xargs.c,v 1.57 2005/02/27 02:01:31 gad Exp $"); 52 53#include <sys/param.h> 54#include <sys/wait.h> 55 56#include <err.h> 57#include <errno.h> 58#include <fcntl.h> 59#include <langinfo.h> 60#include <locale.h> 61#include <paths.h> 62#include <regex.h> 63#include <stdio.h> 64#include <stdlib.h> 65#include <string.h> 66#include <unistd.h> 67 68#include "pathnames.h" 69 70#ifdef __APPLE__ 71#include <get_compat.h> 72#else 73#define COMPAT_MODE(a,b) (1) 74#endif /* __APPLE__ */ 75 76static void parse_input(int, char *[]); 77static void prerun(int, char *[]); 78static int prompt(void); 79static void run(char **); 80static void usage(void); 81void strnsubst(char **, const char *, const char *, size_t); 82static void waitchildren(const char *, int); 83 84static int last_was_newline = 1; 85static int last_was_blank = 0; 86 87static char echo[] = _PATH_ECHO; 88static char **av, **bxp, **ep, **endxp, **xp; 89static char *argp, *bbp, *ebp, *inpline, *p, *replstr; 90static const char *eofstr; 91static int count, insingle, indouble, oflag, pflag, tflag, Rflag, rval, zflag; 92static int cnt, Iflag, jfound, Lflag, wasquoted, xflag; 93static int curprocs, maxprocs; 94static size_t pad9314053; 95 96static volatile int childerr; 97 98extern char **environ; 99 100int 101main(int argc, char *argv[]) 102{ 103 long arg_max; 104 int ch, Jflag, nflag, nline; 105 size_t nargs; 106 size_t linelen; 107 char *endptr; 108 109 inpline = replstr = NULL; 110 ep = environ; 111 eofstr = ""; 112 Jflag = nflag = 0; 113 114 (void)setlocale(LC_ALL, ""); 115 116 /* 117 * POSIX.2 limits the exec line length to ARG_MAX - 2K. Running that 118 * caused some E2BIG errors, so it was changed to ARG_MAX - 4K. Given 119 * that the smallest argument is 2 bytes in length, this means that 120 * the number of arguments is limited to: 121 * 122 * (ARG_MAX - 4K - LENGTH(utility + arguments)) / 2. 123 * 124 * We arbitrarily limit the number of arguments to 5000. This is 125 * allowed by POSIX.2 as long as the resulting minimum exec line is 126 * at least LINE_MAX. Realloc'ing as necessary is possible, but 127 * probably not worthwhile. 128 */ 129 nargs = 5000; 130 if ((arg_max = sysconf(_SC_ARG_MAX)) == -1) 131 errx(1, "sysconf(_SC_ARG_MAX) failed"); 132 nline = arg_max - MAXPATHLEN; /* for argv[0] from execvp() */ 133 pad9314053 = sizeof(char *); /* reserve for string area rounding */ 134 while (*ep != NULL) { 135 /* 1 byte for each '\0' */ 136 nline -= strlen(*ep++) + 1 + sizeof(*ep); 137 } 138 nline -= pad9314053; 139 maxprocs = 1; 140 while ((ch = getopt(argc, argv, "0E:I:J:L:n:oP:pR:s:tx")) != -1) 141 switch(ch) { 142 case 'E': 143 eofstr = optarg; 144 break; 145 case 'I': 146 Jflag = 0; 147 Iflag = 1; 148 Lflag = 1; 149 replstr = optarg; 150 break; 151 case 'J': 152 Iflag = 0; 153 Jflag = 1; 154 replstr = optarg; 155 break; 156 case 'L': 157 Lflag = atoi(optarg); 158 if (COMPAT_MODE("bin/xargs", "Unix2003")) { 159 nflag = 0; /* Override */ 160 nargs = 5000; 161 } 162 break; 163 case 'n': 164 nflag = 1; 165 if ((nargs = strtol(optarg, NULL, 10)) <= 0) 166 errx(1, "illegal argument count"); 167 if (COMPAT_MODE("bin/xargs", "Unix2003")) { 168 Lflag = 0; /* Override */ 169 } 170 break; 171 case 'o': 172 oflag = 1; 173 break; 174 case 'P': 175 if ((maxprocs = atoi(optarg)) <= 0) 176 errx(1, "max. processes must be >0"); 177 break; 178 case 'p': 179 pflag = 1; 180 break; 181 case 'R': 182 Rflag = strtol(optarg, &endptr, 10); 183 if (*endptr != '\0') 184 errx(1, "replacements must be a number"); 185 break; 186 case 's': 187 nline = atoi(optarg); 188 pad9314053 = 0; /* assume the -s value is valid */ 189 break; 190 case 't': 191 tflag = 1; 192 break; 193 case 'x': 194 xflag = 1; 195 break; 196 case '0': 197 zflag = 1; 198 break; 199 case '?': 200 default: 201 usage(); 202 } 203 argc -= optind; 204 argv += optind; 205 206 if (!Iflag && Rflag) 207 usage(); 208 if (Iflag && !Rflag) 209 Rflag = 5; 210 if (xflag && !nflag) 211 usage(); 212 if (Iflag || Lflag) 213 xflag = 1; 214 if (replstr != NULL && *replstr == '\0') 215 errx(1, "replstr may not be empty"); 216 217 /* 218 * Allocate pointers for the utility name, the utility arguments, 219 * the maximum arguments to be read from stdin and the trailing 220 * NULL. 221 */ 222 linelen = 1 + argc + nargs + 1; 223 if ((av = bxp = malloc(linelen * sizeof(char **))) == NULL) 224 errx(1, "malloc failed"); 225 226 /* 227 * Use the user's name for the utility as argv[0], just like the 228 * shell. Echo is the default. Set up pointers for the user's 229 * arguments. 230 */ 231 if (*argv == NULL) 232 cnt = strlen(*bxp++ = echo) + pad9314053; 233 else { 234 do { 235 if (Jflag && strcmp(*argv, replstr) == 0) { 236 char **avj; 237 jfound = 1; 238 argv++; 239 for (avj = argv; *avj; avj++) 240 cnt += strlen(*avj) + 1 + pad9314053; 241 break; 242 } 243 cnt += strlen(*bxp++ = *argv) + 1 + pad9314053; 244 } while (*++argv != NULL); 245 } 246 247 /* 248 * Set up begin/end/traversing pointers into the array. The -n 249 * count doesn't include the trailing NULL pointer, so the malloc 250 * added in an extra slot. 251 */ 252 endxp = (xp = bxp) + nargs; 253 254 /* 255 * Allocate buffer space for the arguments read from stdin and the 256 * trailing NULL. Buffer space is defined as the default or specified 257 * space, minus the length of the utility name and arguments. Set up 258 * begin/end/traversing pointers into the array. The -s count does 259 * include the trailing NULL, so the malloc didn't add in an extra 260 * slot. 261 */ 262 nline -= cnt; 263 if (nline <= 0) 264 errx(1, "insufficient space for command"); 265 266 if ((bbp = malloc((size_t)(nline + 1))) == NULL) 267 errx(1, "malloc failed"); 268 ebp = (argp = p = bbp) + nline - 1; 269 for (;;) 270 parse_input(argc, argv); 271} 272 273static void 274parse_input(int argc, char *argv[]) 275{ 276 int ch, foundeof; 277 char **avj; 278 int last_was_backslashed = 0; 279 280 foundeof = 0; 281 282 switch(ch = getchar()) { 283 case EOF: 284 /* No arguments since last exec. */ 285 if (p == bbp) { 286 waitchildren(*argv, 1); 287 exit(rval); 288 } 289 goto arg1; 290 case ' ': 291 last_was_blank = 1; 292 case '\t': 293 /* Quotes escape tabs and spaces. */ 294 if (insingle || indouble || zflag) 295 goto addch; 296 goto arg2; 297 case '\0': 298 if (zflag) { 299 /* 300 * Increment 'count', so that nulls will be treated 301 * as end-of-line, as well as end-of-argument. This 302 * is needed so -0 works properly with -I and -L. 303 */ 304 count++; 305 goto arg2; 306 } 307 goto addch; 308 case '\n': 309 if (zflag) 310 goto addch; 311 if (COMPAT_MODE("bin/xargs", "Unix2003")) { 312 if (last_was_newline) { 313 /* don't count empty line */ 314 break; 315 } 316 if (!last_was_blank ) { 317 /* only count if NOT continuation line */ 318 count++; 319 } 320 } else { 321 count++; 322 } 323 last_was_newline = 1; 324 325 /* Quotes do not escape newlines. */ 326arg1: if (insingle || indouble) 327 errx(1, "unterminated quote"); 328arg2: 329 foundeof = *eofstr != '\0' && 330 strcmp(argp, eofstr) == 0; 331 332#ifdef __APPLE__ 333 /* 6591323: -I specifies that it processes the entire line, 334 * so only recognize eofstr at the end of a line. */ 335 if (Iflag && !last_was_newline) 336 foundeof = 0; 337 338 /* 6591323: Essentially the same as the EOF handling above. */ 339 if (foundeof && (p - strlen(eofstr) == bbp)) { 340 waitchildren(*argv, 1); 341 exit(rval); 342 } 343#endif 344 345 /* Do not make empty args unless they are quoted */ 346 if ((argp != p || wasquoted) && !foundeof) { 347 *p++ = '\0'; 348 *xp++ = argp; 349 if (Iflag) { 350 size_t curlen; 351 352 if (inpline == NULL) 353 curlen = 0; 354 else { 355 /* 356 * If this string is not zero 357 * length, append a space for 358 * separation before the next 359 * argument. 360 */ 361 if ((curlen = strlen(inpline))) 362 strcat(inpline, " "); 363 } 364 curlen++; 365 /* 366 * Allocate enough to hold what we will 367 * be holding in a second, and to append 368 * a space next time through, if we have 369 * to. 370 */ 371 inpline = realloc(inpline, curlen + 2 + 372 strlen(argp)); 373 if (inpline == NULL) 374 errx(1, "realloc failed"); 375 if (curlen == 1) 376 strcpy(inpline, argp); 377 else 378 strcat(inpline, argp); 379 } 380 } 381 382 /* 383 * If max'd out on args or buffer, or reached EOF, 384 * run the command. If xflag and max'd out on buffer 385 * but not on args, object. Having reached the limit 386 * of input lines, as specified by -L is the same as 387 * maxing out on arguments. 388 */ 389 if (xp == endxp || p + (count * pad9314053) > ebp || ch == EOF || 390 (Lflag <= count && xflag) || foundeof) { 391 if (xflag && xp != endxp && p + (count * pad9314053) > ebp) 392 errx(1, "insufficient space for arguments"); 393 if (jfound) { 394 for (avj = argv; *avj; avj++) 395 *xp++ = *avj; 396 } 397 prerun(argc, av); 398 if (ch == EOF || foundeof) { 399 waitchildren(*argv, 1); 400 exit(rval); 401 } 402 p = bbp; 403 xp = bxp; 404 count = 0; 405 } 406 argp = p; 407 wasquoted = 0; 408 break; 409 case '\'': 410 if (indouble || zflag) 411 goto addch; 412 insingle = !insingle; 413 wasquoted = 1; 414 break; 415 case '"': 416 if (insingle || zflag) 417 goto addch; 418 indouble = !indouble; 419 wasquoted = 1; 420 break; 421 case '\\': 422 last_was_backslashed = 1; 423 if (zflag) 424 goto addch; 425 /* Backslash escapes anything, is escaped by quotes. */ 426 if (!insingle && !indouble && (ch = getchar()) == EOF) 427 errx(1, "backslash at EOF"); 428 /* FALLTHROUGH */ 429 default: 430addch: if (p < ebp) { 431 *p++ = ch; 432 break; 433 } 434 435 /* If only one argument, not enough buffer space. */ 436 if (bxp == xp) 437 errx(1, "insufficient space for argument"); 438 /* Didn't hit argument limit, so if xflag object. */ 439 if (xflag) 440 errx(1, "insufficient space for arguments"); 441 442 if (jfound) { 443 for (avj = argv; *avj; avj++) 444 *xp++ = *avj; 445 } 446 prerun(argc, av); 447 xp = bxp; 448 cnt = ebp - argp; 449 memcpy(bbp, argp, (size_t)cnt); 450 p = (argp = bbp) + cnt; 451 *p++ = ch; 452 break; 453 } 454 if (ch != ' ') 455 last_was_blank = 0; 456 if (ch != '\n' || last_was_backslashed) 457 last_was_newline = 0; 458} 459 460/* 461 * Do things necessary before run()'ing, such as -I substitution, 462 * and then call run(). 463 */ 464static void 465prerun(int argc, char *argv[]) 466{ 467 char **tmp, **tmp2, **avj; 468 int repls; 469 470 repls = Rflag; 471 472 if (argc == 0 || repls == 0) { 473 *xp = NULL; 474 run(argv); 475 return; 476 } 477 478 avj = argv; 479 480 /* 481 * Allocate memory to hold the argument list, and 482 * a NULL at the tail. 483 */ 484 tmp = malloc((argc + 1) * sizeof(char**)); 485 if (tmp == NULL) 486 errx(1, "malloc failed"); 487 tmp2 = tmp; 488 489 /* 490 * Save the first argument and iterate over it, we 491 * cannot do strnsubst() to it. 492 */ 493 if ((*tmp++ = strdup(*avj++)) == NULL) 494 errx(1, "strdup failed"); 495 496 /* 497 * For each argument to utility, if we have not used up 498 * the number of replacements we are allowed to do, and 499 * if the argument contains at least one occurrence of 500 * replstr, call strnsubst(), else just save the string. 501 * Iterations over elements of avj and tmp are done 502 * where appropriate. 503 */ 504 while (--argc) { 505 *tmp = *avj++; 506 if (repls && strstr(*tmp, replstr) != NULL) { 507 strnsubst(tmp++, replstr, inpline, (size_t)255); 508 if (repls > 0) 509 repls--; 510 } else { 511 if ((*tmp = strdup(*tmp)) == NULL) 512 errx(1, "strdup failed"); 513 tmp++; 514 } 515 } 516 517 /* 518 * Run it. 519 */ 520 *tmp = NULL; 521 run(tmp2); 522 523 /* 524 * Walk from the tail to the head, free along the way. 525 */ 526 for (; tmp2 != tmp; tmp--) 527 free(*tmp); 528 /* 529 * Now free the list itself. 530 */ 531 free(tmp2); 532 533 /* 534 * Free the input line buffer, if we have one. 535 */ 536 if (inpline != NULL) { 537 free(inpline); 538 inpline = NULL; 539 } 540} 541 542static void 543run(char **argv) 544{ 545 pid_t pid; 546 int fd; 547 char **avec; 548 549 /* 550 * If the user wants to be notified of each command before it is 551 * executed, notify them. If they want the notification to be 552 * followed by a prompt, then prompt them. 553 */ 554 if (tflag || pflag) { 555 (void)fprintf(stderr, "%s", *argv); 556 for (avec = argv + 1; *avec != NULL; ++avec) 557 (void)fprintf(stderr, " %s", *avec); 558 /* 559 * If the user has asked to be prompted, do so. 560 */ 561 if (pflag) 562 /* 563 * If they asked not to exec, return without execution 564 * but if they asked to, go to the execution. If we 565 * could not open their tty, break the switch and drop 566 * back to -t behaviour. 567 */ 568 switch (prompt()) { 569 case 0: 570 return; 571 case 1: 572 goto exec; 573 case 2: 574 break; 575 } 576 (void)fprintf(stderr, "\n"); 577 (void)fflush(stderr); 578 } 579exec: 580 childerr = 0; 581 switch(pid = vfork()) { 582 case -1: 583 err(1, "vfork"); 584 case 0: 585 if (oflag) { 586 if ((fd = open(_PATH_TTY, O_RDONLY)) == -1) 587 err(1, "can't open /dev/tty"); 588 } else { 589 fd = open(_PATH_DEVNULL, O_RDONLY); 590 } 591 if (fd > STDIN_FILENO) { 592 if (dup2(fd, STDIN_FILENO) != 0) 593 err(1, "can't dup2 to stdin"); 594 close(fd); 595 } 596 execvp(argv[0], argv); 597 childerr = errno; 598 _exit(1); 599 } 600 curprocs++; 601 waitchildren(*argv, 0); 602} 603 604static void 605waitchildren(const char *name, int waitall) 606{ 607 pid_t pid; 608 int status; 609 610 while ((pid = waitpid(-1, &status, !waitall && curprocs < maxprocs ? 611 WNOHANG : 0)) > 0) { 612 curprocs--; 613 /* If we couldn't invoke the utility, exit. */ 614 if (childerr != 0) { 615 errno = childerr; 616 err(errno == ENOENT ? 127 : 126, "%s", name); 617 } 618 /* 619 * If utility signaled or exited with a value of 255, 620 * exit 1-125. 621 */ 622 if (WIFSIGNALED(status) || WEXITSTATUS(status) == 255) 623 exit(1); 624 if (WEXITSTATUS(status)) 625 rval = 1; 626 } 627 if (pid == -1 && errno != ECHILD) 628 err(1, "wait3"); 629} 630 631/* 632 * Prompt the user about running a command. 633 */ 634static int 635prompt(void) 636{ 637 regex_t cre; 638 size_t rsize; 639 int match; 640 char *response; 641 FILE *ttyfp; 642 643 if ((ttyfp = fopen(_PATH_TTY, "r")) == NULL) 644 return (2); /* Indicate that the TTY failed to open. */ 645 (void)fprintf(stderr, "?..."); 646 (void)fflush(stderr); 647 if ((response = fgetln(ttyfp, &rsize)) == NULL || 648 regcomp(&cre, nl_langinfo(YESEXPR), REG_BASIC) != 0) { 649 (void)fclose(ttyfp); 650 return (0); 651 } 652 match = regexec(&cre, response, 0, NULL, 0); 653 (void)fclose(ttyfp); 654 regfree(&cre); 655 return (match == 0); 656} 657 658static void 659usage(void) 660{ 661 fprintf(stderr, 662"usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr]\n" 663" [-L number] [-n number [-x]] [-P maxprocs] [-s size]\n" 664" [utility [argument ...]]\n"); 665 exit(1); 666} 667