Initial import of binutils 2.22 on the new vendor branch
[dragonfly.git] / usr.bin / xargs / xargs.c
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  * @(#) Copyright (c) 1990, 1993 The Regents of the University of California.  All rights reserved.
39  * @(#)xargs.c  8.1 (Berkeley) 6/6/93
40  * $FreeBSD: src/usr.bin/xargs/xargs.c,v 1.9.2.6 2003/06/01 21:40:35 mux Exp $
41  */
42
43 #include <sys/types.h>
44 #include <sys/wait.h>
45
46 #include <err.h>
47 #include <errno.h>
48 #include <fcntl.h>
49 #ifndef BOOTSTRAPPING
50 #include <langinfo.h>
51 #endif
52 #include <locale.h>
53 #include <paths.h>
54 #include <regex.h>
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <string.h>
58 #include <unistd.h>
59
60 #include "pathnames.h"
61
62 static void     parse_input(int, char *[]);
63 static void     prerun(int, char *[]);
64 static int      prompt(void);
65 static void     run(char **);
66 static void     usage(void);
67 void            strnsubst(char **, const char *, const char *, size_t);
68 static void     waitchildren(const char *, int);
69
70 static char echo[] = _PATH_ECHO;
71 static char **av, **bxp, **ep, **expx, **xp;
72 static char *argp, *bbp, *ebp, *inpline, *p, *replstr;
73 static const char *eofstr;
74 static int count, insingle, indouble, oflag, pflag, tflag, Rflag, rval, zflag;
75 static int cnt, Iflag, jfound, Lflag, wasquoted, xflag;
76 static int curprocs, maxprocs;
77 static volatile int childerr;
78
79 extern char **environ;
80
81 int
82 main(int argc, char *argv[])
83 {
84         char *tmp;
85         long arg_max;
86         int ch, Jflag, nargs, nflag, nline;
87         size_t linelen;
88
89         inpline = replstr = NULL;
90         ep = environ;
91         eofstr = "";
92         Jflag = nflag = 0;
93
94         (void)setlocale(LC_MESSAGES, "");
95
96         /*
97          * POSIX.2 limits the exec line length to ARG_MAX - 2K.  Running that
98          * caused some E2BIG errors, so it was changed to ARG_MAX - 4K.  Given
99          * that the smallest argument is 2 bytes in length, this means that
100          * the number of arguments is limited to:
101          *
102          *       (ARG_MAX - 4K - LENGTH(utility + arguments)) / 2.
103          *
104          * We arbitrarily limit the number of arguments to 5000.  This is
105          * allowed by POSIX.2 as long as the resulting minimum exec line is
106          * at least LINE_MAX.  Realloc'ing as necessary is possible, but
107          * probably not worthwhile.
108          */
109         nargs = 5000;
110         if ((arg_max = sysconf(_SC_ARG_MAX)) == -1)
111                 errx(1, "sysconf(_SC_ARG_MAX) failed");
112         nline = arg_max - 4 * 1024;
113         while (*ep != NULL) {
114                 /* 1 byte for each '\0' */
115                 nline -= strlen(*ep++) + 1 + sizeof(*ep);
116         }
117
118         maxprocs = 1;
119         while ((ch = getopt(argc, argv, "0E:I:J:L:n:opP:R:s:tx")) != -1)
120                 switch(ch) {
121                 case 'E':
122                         eofstr = optarg;
123                         break;
124                 case 'I':
125                         Jflag = 0;
126                         Iflag = 1;
127                         Lflag = 1;
128                         replstr = optarg;
129                         break;
130                 case 'J':
131                         Iflag = 0;
132                         Jflag = 1;
133                         replstr = optarg;
134                         break;
135                 case 'L':
136                         Lflag = strtol(optarg, &tmp, 10);
137                         if (*tmp != 0 || *optarg == 0)
138                                 errx(1, "illegal argument count");
139                         break;
140                 case 'n':
141                         nflag = 1;
142                         if ((nargs = atoi(optarg)) <= 0)
143                                 errx(1, "illegal argument count");
144                         break;
145                 case 'o':
146                         oflag = 1;
147                         break;
148                 case 'p':
149                         pflag = 1;
150                         break;
151                 case 'P':
152                         if ((maxprocs = atoi(optarg)) <= 0)
153                                 errx(1, "max.processes must be >0");
154                         break;
155                 case 'R':
156                         if ((Rflag = atoi(optarg)) <= 0)
157                                 errx(1, "illegal number of replacements");
158                         break;
159                 case 's':
160                         nline = atoi(optarg);
161                         break;
162                 case 't':
163                         tflag = 1;
164                         break;
165                 case 'x':
166                         xflag = 1;
167                         break;
168                 case '0':
169                         zflag = 1;
170                         break;
171                 case '?':
172                 default:
173                         usage();
174         }
175         argc -= optind;
176         argv += optind;
177
178         if (!Iflag && Rflag)
179                 usage();
180         if (Iflag && !Rflag)
181                 Rflag = 5;
182         if (xflag && !nflag)
183                 usage();
184         if (Iflag || Lflag)
185                 xflag = 1;
186         if (replstr != NULL && *replstr == '\0')
187                 errx(1, "replstr may not be empty");
188
189         /*
190          * Allocate pointers for the utility name, the utility arguments,
191          * the maximum arguments to be read from stdin and the trailing
192          * NULL.
193          */
194         linelen = 1 + argc + nargs + 1;
195         if ((av = bxp = malloc(linelen * sizeof(char **))) == NULL)
196                 errx(1, "malloc failed");
197
198         /*
199          * Use the user's name for the utility as argv[0], just like the
200          * shell.  Echo is the default.  Set up pointers for the user's
201          * arguments.
202          */
203         if (*argv == NULL)
204                 cnt = strlen(*bxp++ = echo);
205         else {
206                 do {
207                         if (Jflag && strcmp(*argv, replstr) == 0) {
208                                 char **avj;
209                                 jfound = 1;
210                                 argv++;
211                                 for (avj = argv; *avj; avj++)
212                                         cnt += strlen(*avj) + 1;
213                                 break;
214                         }
215                         cnt += strlen(*bxp++ = *argv) + 1;
216                 } while (*++argv != NULL);
217         }
218
219         /*
220          * Set up begin/end/traversing pointers into the array.  The -n
221          * count doesn't include the trailing NULL pointer, so the malloc
222          * added in an extra slot.
223          */
224         expx = (xp = bxp) + nargs;
225
226         /*
227          * Allocate buffer space for the arguments read from stdin and the
228          * trailing NULL.  Buffer space is defined as the default or specified
229          * space, minus the length of the utility name and arguments.  Set up
230          * begin/end/traversing pointers into the array.  The -s count does
231          * include the trailing NULL, so the malloc didn't add in an extra
232          * slot.
233          */
234         nline -= cnt;
235         if (nline <= 0)
236                 errx(1, "insufficient space for command");
237
238         if ((bbp = malloc((size_t)(nline + 1))) == NULL)
239                 errx(1, "malloc failed");
240         ebp = (argp = p = bbp) + nline - 1;
241         for (;;)
242                 parse_input(argc, argv);
243 }
244
245 static void
246 parse_input(int argc, char *argv[])
247 {
248         int ch, foundeof;
249         char **avj;
250
251         foundeof = 0;
252
253         switch(ch = getchar()) {
254         case EOF:
255                 /* No arguments since last exec. */
256                 if (p == bbp) {
257                         waitchildren(*argv, 1);
258                         exit(rval);
259                 }
260                 goto arg1;
261         case ' ':
262         case '\t':
263                 /* Quotes escape tabs and spaces. */
264                 if (insingle || indouble || zflag)
265                         goto addch;
266                 goto arg2;
267         case '\0':
268                 if (zflag)
269                         goto arg2;
270                 goto addch;
271         case '\n':
272                 count++;
273                 if (zflag)
274                         goto addch;
275
276                 /* Quotes do not escape newlines. */
277 arg1:           if (insingle || indouble)
278                         errx(1, "unterminated quote");
279 arg2:
280                 foundeof = *eofstr != '\0' &&
281                     strcmp(argp, eofstr) == 0;
282
283                 /* Do not make empty args unless they are quoted */
284                 if ((argp != p || wasquoted) && !foundeof) {
285                         *p++ = '\0';
286                         *xp++ = argp;
287                         if (Iflag) {
288                                 size_t curlen;
289
290                                 if (inpline == NULL)
291                                         curlen = 0;
292                                 else {
293                                         /*
294                                          * If this string is not zero
295                                          * length, append a space for
296                                          * separation before the next
297                                          * argument.
298                                          */
299                                         if ((curlen = strlen(inpline)))
300                                                 strcat(inpline, " ");
301                                 }
302                                 curlen++;
303                                 /*
304                                  * Allocate enough to hold what we will
305                                  * be holding in a second, and to append
306                                  * a space next time through, if we have
307                                  * to.
308                                  */
309                                 inpline = realloc(inpline, curlen + 2 +
310                                     strlen(argp));
311                                 if (inpline == NULL)
312                                         errx(1, "realloc failed");
313                                 if (curlen == 1)
314                                         strcpy(inpline, argp);
315                                 else
316                                         strcat(inpline, argp);
317                         }
318                 }
319
320                 /*
321                  * If max'd out on args or buffer, or reached EOF,
322                  * run the command.  If xflag and max'd out on buffer
323                  * but not on args, object.  Having reached the limit
324                  * of input lines, as specified by -L is the same as
325                  * maxing out on arguments.
326                  */
327                 if (xp == expx || p > ebp || ch == EOF ||
328                     (Lflag <= count && xflag) || foundeof) {
329                         if (xflag && xp != expx && p > ebp)
330                                 errx(1, "insufficient space for arguments");
331                         if (jfound) {
332                                 for (avj = argv; *avj; avj++)
333                                         *xp++ = *avj;
334                         }
335                         prerun(argc, av);
336                         if (ch == EOF || foundeof) {
337                                 waitchildren(*argv, 1);
338                                 exit(rval);
339                         }
340                         p = bbp;
341                         xp = bxp;
342                         count = 0;
343                 }
344                 argp = p;
345                 wasquoted = 0;
346                 break;
347         case '\'':
348                 if (indouble || zflag)
349                         goto addch;
350                 insingle = !insingle;
351                 wasquoted = 1;
352                 break;
353         case '"':
354                 if (insingle || zflag)
355                         goto addch;
356                 indouble = !indouble;
357                 wasquoted = 1;
358                 break;
359         case '\\':
360                 if (zflag)
361                         goto addch;
362                 /* Backslash escapes anything, is escaped by quotes. */
363                 if (!insingle && !indouble && (ch = getchar()) == EOF)
364                         errx(1, "backslash at EOF");
365                 /* FALLTHROUGH */
366         default:
367 addch:          if (p < ebp) {
368                         *p++ = ch;
369                         break;
370                 }
371
372                 /* If only one argument, not enough buffer space. */
373                 if (bxp == xp)
374                         errx(1, "insufficient space for argument");
375                 /* Didn't hit argument limit, so if xflag object. */
376                 if (xflag)
377                         errx(1, "insufficient space for arguments");
378
379                 if (jfound) {
380                         for (avj = argv; *avj; avj++)
381                                 *xp++ = *avj;
382                 }
383                 prerun(argc, av);
384                 xp = bxp;
385                 cnt = ebp - argp;
386                 memcpy(bbp, argp, (size_t)cnt);
387                 p = (argp = bbp) + cnt;
388                 *p++ = ch;
389                 break;
390         }
391         return;
392 }
393
394 /*
395  * Do things necessary before run()'ing, such as -I substitution,
396  * and then call run().
397  */
398 static void
399 prerun(int argc, char *argv[])
400 {
401         char **tmp, **tmp2, **avj;
402         int repls;
403
404         repls = Rflag;
405
406         if (argc == 0 || repls == 0) {
407                 *xp = NULL;
408                 run(argv);
409                 return;
410         }
411
412         avj = argv;
413
414         /*
415          * Allocate memory to hold the argument list, and
416          * a NULL at the tail.
417          */
418         tmp = malloc((argc + 1) * sizeof(char**));
419         if (tmp == NULL)
420                 errx(1, "malloc failed");
421         tmp2 = tmp;
422
423         /*
424          * Save the first argument and iterate over it, we
425          * cannot do strnsubst() to it.
426          */
427         if ((*tmp++ = strdup(*avj++)) == NULL)
428                 errx(1, "strdup failed");
429
430         /*
431          * For each argument to utility, if we have not used up
432          * the number of replacements we are allowed to do, and
433          * if the argument contains at least one occurrence of
434          * replstr, call strnsubst(), else just save the string.
435          * Iterations over elements of avj and tmp are done
436          * where appropriate.
437          */
438         while (--argc) {
439                 *tmp = *avj++;
440                 if (repls && strstr(*tmp, replstr) != NULL) {
441                         strnsubst(tmp++, replstr, inpline, (size_t)255);
442                         repls--;
443                 } else {
444                         if ((*tmp = strdup(*tmp)) == NULL)
445                                 errx(1, "strdup failed");
446                         tmp++;
447                 }
448         }
449
450         /*
451          * Run it.
452          */
453         *tmp = NULL;
454         run(tmp2);
455
456         /*
457          * Walk from the tail to the head, free along the way.
458          */
459         for (; tmp2 != tmp; tmp--)
460                 free(*tmp);
461         /*
462          * Now free the list itself.
463          */
464         free(tmp2);
465
466         /*
467          * Free the input line buffer, if we have one.
468          */
469         if (inpline != NULL) {
470                 free(inpline);
471                 inpline = NULL;
472         }
473 }
474
475 static void
476 run(char **argv)
477 {
478         char **avec;
479         pid_t pid;
480
481         /*
482          * If the user wants to be notified of each command before it is
483          * executed, notify them.  If they want the notification to be
484          * followed by a prompt, then prompt them.
485          */
486         if (tflag || pflag) {
487                 (void)fprintf(stderr, "%s", *argv);
488                 for (avec = argv + 1; *avec != NULL; ++avec)
489                         (void)fprintf(stderr, " %s", *avec);
490                 /*
491                  * If the user has asked to be prompted, do so.
492                  */
493                 if (pflag)
494                         /*
495                          * If they asked not to exec, return without execution
496                          * but if they asked to, go to the execution.  If we
497                          * could not open their tty, break the switch and drop
498                          * back to -t behaviour.
499                          */
500                         switch (prompt()) {
501                         case 0:
502                                 return;
503                         case 1:
504                                 goto exec;
505                         case 2:
506                                 break;
507                         }
508                 (void)fprintf(stderr, "\n");
509                 (void)fflush(stderr);
510         }
511 exec:
512         childerr = 0;
513         switch(pid = vfork()) {
514         case -1:
515                 err(1, "vfork");
516         case 0:
517                 close(0);
518                 if (oflag) {
519                         if (open("/dev/tty", O_RDONLY) == -1)
520                                 err(1, "open /dev/tty");
521                 } else {
522                         if (open("/dev/null", O_RDONLY) == -1)
523                                 err(1, "open /dev/null");
524                 }
525                 execvp(argv[0], argv);
526                 childerr = errno;
527                 _exit(1);
528         }
529         curprocs++;
530         waitchildren(*argv, 0);
531 }
532
533 /*
534  * Handle child processes.
535  */
536 static void
537 waitchildren(const char *name, int waitall)
538 {
539         pid_t pid;
540         int status;
541
542         while ((pid = wait3(&status, !waitall && curprocs < maxprocs ?
543                 WNOHANG : 0, NULL)) > 0) {
544                 curprocs--;
545
546                 /* If we couldn't invoke the utility, exit. */
547                 if (childerr != 0) {
548                         errno = childerr;
549                         err(errno == ENOENT ? 127 : 126, "%s", name);
550                 }
551
552                 /*
553                  * If utility signaled or exited with a value of 255,
554                  * exit 1-125.
555                  */
556                 if (WIFSIGNALED(status) || WEXITSTATUS(status) == 255)
557                         exit(1);
558                 if (WEXITSTATUS(status))
559                         rval = 1;
560         }
561         if (pid == -1 && errno != ECHILD)
562                 err(1, "wait3");
563 }
564
565 /*
566  * Prompt the user about running a command.
567  */
568 static int
569 prompt(void)
570 {
571         regex_t cre;
572         size_t rsize;
573         int match;
574         char *response;
575         FILE *ttyfp;
576
577         if ((ttyfp = fopen(_PATH_TTY, "r")) == NULL)
578                 return (2);     /* Indicate that the TTY failed to open. */
579         (void)fprintf(stderr, "?...");
580         (void)fflush(stderr);
581         if ((response = fgetln(ttyfp, &rsize)) == NULL ||
582             regcomp(&cre,
583 #ifdef BOOTSTRAPPING
584                 "^[yY]",
585 #else
586                 nl_langinfo(YESEXPR),
587 #endif
588                 REG_BASIC) != 0) {
589                 (void)fclose(ttyfp);
590                 return (0);
591         }
592         match = regexec(&cre, response, 0, NULL, 0);
593         (void)fclose(ttyfp);
594         regfree(&cre);
595         return (match == 0);
596 }
597
598 static void
599 usage(void)
600 {
601         fprintf(stderr,
602 "usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr]\n"
603 "             [-L number] [-n number [-x] [-P maxprocs] [-s size]\n"
604 "             [utility [argument ...]]\n");
605         exit(1);
606 }