blob: be1fada78ba458c79ac1476fe577bf114345e5e7 [file] [log] [blame]
Eric Andersen5b176932000-09-22 20:22:28 +00001/* minix xargs - Make and execute commands
2 * Author: Ian Nicholls: 1 Mar 90 */
Eric Andersen92a61c12000-09-22 20:01:23 +00003
Eric Andersen5b176932000-09-22 20:22:28 +00004/*
5 * xargs - Accept words from stdin until, combined with the arguments
6 * given on the command line, just fit into the command line limit.
7 * Then, execute the result.
8 * e.g. ls | xargs compress
9 * find . -name '*.s' -print | xargs ar qv libc.a
10 *
11 * flags: -t Print the command just before it is run
12 * -l len Use len as maximum line length (default 490, max 1023)
13 * -e ending Append ending to the command before executing it.
14 *
15 * Exits with: 0 No errors.
16 * 1 If any system(3) call returns a nonzero status.
17 * 2 Usage error
18 * 3 Line length too short to contain some single argument.
19 *
20 * Examples: xargs ar qv libc.a < liborder # Create a new libc.a
21 * find . -name '*.s' -print | xargs rm # Remove all .s files
22 * find . -type f ! -name '*.Z' \ # Compress old files.
23 * -atime +60 -print | xargs compress -v
24 *
25 * Bugs: If the command contains unquoted wildflags, then the system(3) call
26 * call may expand this to larger than the maximum line size.
27 * The command is not executed if nothing was read from stdin.
28 * xargs may give up too easily when the command returns nonzero.
29 */
30#define USAGE "usage: xargs [-t] [-l len] [-e endargs] command [args...]\n"
Eric Andersen92a61c12000-09-22 20:01:23 +000031
Eric Andersen92a61c12000-09-22 20:01:23 +000032#include <errno.h>
Eric Andersen5b176932000-09-22 20:22:28 +000033#include <stdlib.h>
34#include <string.h>
35#include <stdio.h>
Eric Andersen92a61c12000-09-22 20:01:23 +000036#include <getopt.h>
37
Eric Andersen5b176932000-09-22 20:22:28 +000038#ifndef MAX_ARGLINE
39# define MAX_ARGLINE 1023
Eric Andersen92a61c12000-09-22 20:01:23 +000040#endif
Eric Andersen5b176932000-09-22 20:22:28 +000041#ifndef min
42# define min(a,b) ((a) < (b) ? (a) : (b))
Eric Andersen92a61c12000-09-22 20:01:23 +000043#endif
44
Eric Andersen5b176932000-09-22 20:22:28 +000045char outlin[MAX_ARGLINE];
46char inlin[MAX_ARGLINE];
47char startlin[MAX_ARGLINE];
48char *ending = NULL;
49char traceflag = 0;
Eric Andersen92a61c12000-09-22 20:01:23 +000050
Eric Andersen5b176932000-09-22 20:22:28 +000051int xargs_main(int ac, char **av)
Eric Andersen92a61c12000-09-22 20:01:23 +000052{
Eric Andersen5b176932000-09-22 20:22:28 +000053 int outlen, inlen, startlen, endlen=0, i;
54 char errflg = 0;
55 int maxlin = MAX_ARGLINE;
Eric Andersen92a61c12000-09-22 20:01:23 +000056
Eric Andersen5b176932000-09-22 20:22:28 +000057 while ((i = getopt(ac, av, "tl:e:")) != EOF)
58 switch (i) {
59 case 't': traceflag = 1; break;
60 case 'l': maxlin = min(MAX_ARGLINE, atoi(optarg)); break;
61 case 'e': ending = optarg; break;
62 case '?': errflg++; break;
63 }
64 if (errflg) {
65 fprintf(stderr, USAGE);
66 exit(2);
67 }
Eric Andersen92a61c12000-09-22 20:01:23 +000068
Eric Andersen5b176932000-09-22 20:22:28 +000069 startlin[0] = 0;
70 if (optind == ac) {
71 strcat(startlin, "echo ");
72 }
73 else for ( ; optind < ac; optind++) {
74 strcat(startlin, av[optind]);
75 strcat(startlin, " ");
76 }
77 startlen = strlen(startlin);
78 if (ending) endlen = strlen(ending);
79 maxlin = maxlin - 1 - endlen; /* Pre-compute */
Eric Andersen92a61c12000-09-22 20:01:23 +000080
Eric Andersen5b176932000-09-22 20:22:28 +000081 strcpy(outlin, startlin);
82 outlen = startlen;
Eric Andersen92a61c12000-09-22 20:01:23 +000083
Eric Andersen5b176932000-09-22 20:22:28 +000084 while (gets(inlin) != NULL) {
85 inlen = strlen(inlin);
86 if (maxlin <= (outlen + inlen)) {
87 if (outlen == startlen) {
88 fprintf(stderr, "%s: Line length too short to process '%s'\n",
89 av[0], inlin);
90 exit(3);
91 }
92 if (ending) strcat(outlin, ending);
93 if (traceflag) fputs(outlin,stderr);
94 errno = 0;
95 if (0 != system(outlin)) {
96 if (errno != 0) perror("xargs");
97 exit(1);
98 }
99 strcpy(outlin, startlin);
100 outlen = startlen;
101 }
102 strcat(outlin, inlin);
103 strcat(outlin, " ");
104 outlen = outlen + inlen + 1;
105 }
106 if (outlen != startlen) {
107 if (ending) strcat(outlin, ending);
108 if (traceflag) fputs(outlin,stderr);
109 errno = 0;
110 if (0 != system(outlin)) {
111 if (errno != 0) perror("xargs");
112 exit(1);
113 }
114 }
115 return 0;
Eric Andersen92a61c12000-09-22 20:01:23 +0000116}