Eric Andersen | 5b17693 | 2000-09-22 20:22:28 +0000 | [diff] [blame^] | 1 | /* minix xargs - Make and execute commands |
| 2 | * Author: Ian Nicholls: 1 Mar 90 */ |
Eric Andersen | 92a61c1 | 2000-09-22 20:01:23 +0000 | [diff] [blame] | 3 | |
Eric Andersen | 5b17693 | 2000-09-22 20:22:28 +0000 | [diff] [blame^] | 4 | /* |
| 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 Andersen | 92a61c1 | 2000-09-22 20:01:23 +0000 | [diff] [blame] | 31 | |
Eric Andersen | 92a61c1 | 2000-09-22 20:01:23 +0000 | [diff] [blame] | 32 | #include <errno.h> |
Eric Andersen | 5b17693 | 2000-09-22 20:22:28 +0000 | [diff] [blame^] | 33 | #include <stdlib.h> |
| 34 | #include <string.h> |
| 35 | #include <stdio.h> |
Eric Andersen | 92a61c1 | 2000-09-22 20:01:23 +0000 | [diff] [blame] | 36 | #include <getopt.h> |
| 37 | |
Eric Andersen | 5b17693 | 2000-09-22 20:22:28 +0000 | [diff] [blame^] | 38 | #ifndef MAX_ARGLINE |
| 39 | # define MAX_ARGLINE 1023 |
Eric Andersen | 92a61c1 | 2000-09-22 20:01:23 +0000 | [diff] [blame] | 40 | #endif |
Eric Andersen | 5b17693 | 2000-09-22 20:22:28 +0000 | [diff] [blame^] | 41 | #ifndef min |
| 42 | # define min(a,b) ((a) < (b) ? (a) : (b)) |
Eric Andersen | 92a61c1 | 2000-09-22 20:01:23 +0000 | [diff] [blame] | 43 | #endif |
| 44 | |
Eric Andersen | 5b17693 | 2000-09-22 20:22:28 +0000 | [diff] [blame^] | 45 | char outlin[MAX_ARGLINE]; |
| 46 | char inlin[MAX_ARGLINE]; |
| 47 | char startlin[MAX_ARGLINE]; |
| 48 | char *ending = NULL; |
| 49 | char traceflag = 0; |
Eric Andersen | 92a61c1 | 2000-09-22 20:01:23 +0000 | [diff] [blame] | 50 | |
Eric Andersen | 5b17693 | 2000-09-22 20:22:28 +0000 | [diff] [blame^] | 51 | int xargs_main(int ac, char **av) |
Eric Andersen | 92a61c1 | 2000-09-22 20:01:23 +0000 | [diff] [blame] | 52 | { |
Eric Andersen | 5b17693 | 2000-09-22 20:22:28 +0000 | [diff] [blame^] | 53 | int outlen, inlen, startlen, endlen=0, i; |
| 54 | char errflg = 0; |
| 55 | int maxlin = MAX_ARGLINE; |
Eric Andersen | 92a61c1 | 2000-09-22 20:01:23 +0000 | [diff] [blame] | 56 | |
Eric Andersen | 5b17693 | 2000-09-22 20:22:28 +0000 | [diff] [blame^] | 57 | 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 Andersen | 92a61c1 | 2000-09-22 20:01:23 +0000 | [diff] [blame] | 68 | |
Eric Andersen | 5b17693 | 2000-09-22 20:22:28 +0000 | [diff] [blame^] | 69 | 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 Andersen | 92a61c1 | 2000-09-22 20:01:23 +0000 | [diff] [blame] | 80 | |
Eric Andersen | 5b17693 | 2000-09-22 20:22:28 +0000 | [diff] [blame^] | 81 | strcpy(outlin, startlin); |
| 82 | outlen = startlen; |
Eric Andersen | 92a61c1 | 2000-09-22 20:01:23 +0000 | [diff] [blame] | 83 | |
Eric Andersen | 5b17693 | 2000-09-22 20:22:28 +0000 | [diff] [blame^] | 84 | 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 Andersen | 92a61c1 | 2000-09-22 20:01:23 +0000 | [diff] [blame] | 116 | } |