|
|
1.1 ! root 1: /*- ! 2: * Copyright (c) 1990 The Regents of the University of California. ! 3: * 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 are permitted provided ! 9: * that: (1) source distributions retain this entire copyright notice and ! 10: * comment, and (2) distributions including binaries display the following ! 11: * acknowledgement: ``This product includes software developed by the ! 12: * University of California, Berkeley and its contributors'' in the ! 13: * documentation or other materials provided with the distribution and in ! 14: * all advertising materials mentioning features or use of this software. ! 15: * Neither the name of the University nor the names of its contributors may ! 16: * be used to endorse or promote products derived from this software without ! 17: * specific prior written permission. ! 18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 19: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 20: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 21: */ ! 22: ! 23: #ifndef lint ! 24: char copyright[] = ! 25: "@(#) Copyright (c) 1990 The Regents of the University of California.\n\ ! 26: All rights reserved.\n"; ! 27: #endif /* not lint */ ! 28: ! 29: #ifndef lint ! 30: static char sccsid[] = "@(#)xargs.c 5.4 (Berkeley) 6/24/90"; ! 31: #endif /* not lint */ ! 32: ! 33: #include <sys/types.h> ! 34: #include <sys/wait.h> ! 35: #include <errno.h> ! 36: #include <stdio.h> ! 37: #include <string.h> ! 38: #include <limits.h> ! 39: #include "pathnames.h" ! 40: ! 41: #define DEF_ARGC 255 ! 42: ! 43: int tflag; ! 44: ! 45: main(argc, argv) ! 46: int argc; ! 47: char **argv; ! 48: { ! 49: extern int errno, optind; ! 50: extern char *optarg; ! 51: register int ch; ! 52: register char *p, *bp, *endbp, **bxp, **endxp, **xp; ! 53: int cnt, indouble, insingle, nargs, nline; ! 54: char *mark, *prog, **xargs, *malloc(); ! 55: ! 56: nargs = DEF_ARGC; ! 57: nline = _BSD_LINE_MAX; ! 58: ! 59: while ((ch = getopt(argc, argv, "n:s:t")) != EOF) ! 60: switch(ch) { ! 61: case 'n': ! 62: if ((nargs = atoi(optarg)) <= 0) { ! 63: (void)fprintf(stderr, ! 64: "xargs: bad argument count.\n"); ! 65: exit(1); ! 66: } ! 67: break; ! 68: case 's': ! 69: if ((nline = atoi(optarg)) <= 0) { ! 70: (void)fprintf(stderr, ! 71: "xargs: bad command length.\n"); ! 72: exit(1); ! 73: } ! 74: break; ! 75: case 't': ! 76: tflag = 1; ! 77: break; ! 78: case '?': ! 79: default: ! 80: usage(); ! 81: } ! 82: argc -= optind; ! 83: argv += optind; ! 84: ! 85: /* room for the command, leftover arguments and trailing NULL */ ! 86: if (!(xargs = ! 87: (char **)malloc((u_int)(nargs + argc + 2) * sizeof(char **)))) ! 88: enomem(); ! 89: ! 90: if (!(bp = malloc((u_int)nline + 1))) ! 91: enomem(); ! 92: ! 93: xp = xargs + 1; ! 94: if (!*argv) ! 95: prog = _PATH_ECHO; ! 96: else { ! 97: prog = *argv; ! 98: while (*++argv) ! 99: *xp++ = *argv; ! 100: } ! 101: ! 102: if (xargs[0] = rindex(prog, '/')) ! 103: ++xargs[0]; ! 104: else ! 105: xargs[0] = prog; ! 106: ! 107: /* set up the pointers into the buffer and the arguments */ ! 108: *(endxp = (bxp = xp) + nargs) = NULL; ! 109: endbp = (mark = p = bp) + nline; ! 110: ! 111: insingle = indouble = 0; ! 112: for (;;) ! 113: switch(ch = getchar()) { ! 114: case EOF: ! 115: if (p == bp) /* nothing to display */ ! 116: exit(0); ! 117: if (mark == p) { /* nothing since last arg end */ ! 118: run(prog, xargs); ! 119: exit(0); ! 120: } ! 121: goto addarg; ! 122: case ' ': ! 123: case '\t': ! 124: if (insingle || indouble) ! 125: goto addch; ! 126: goto addarg; ! 127: case '\n': ! 128: if (mark == p) /* empty line */ ! 129: continue; ! 130: addarg: *xp++ = mark; ! 131: *p++ = '\0'; ! 132: if (xp == endxp || p >= endbp || ch == EOF) { ! 133: if (insingle || indouble) { ! 134: (void)fprintf(stderr, ! 135: "xargs: unterminated quote.\n"); ! 136: exit(1); ! 137: } ! 138: run(prog, xargs); ! 139: if (ch == EOF) ! 140: exit(0); ! 141: p = bp; ! 142: xp = bxp; ! 143: } ! 144: mark = p; ! 145: break; ! 146: case '\'': ! 147: if (indouble) ! 148: goto addch; ! 149: insingle = !insingle; ! 150: break; ! 151: case '"': ! 152: if (insingle) ! 153: goto addch; ! 154: indouble = !indouble; ! 155: break; ! 156: case '\\': ! 157: if ((ch = getchar()) == EOF) ! 158: ch = '\\'; ! 159: if (ch == '\n') { ! 160: (void)fprintf(stderr, ! 161: "xargs: newline may not be escaped.\n"); ! 162: exit(1); ! 163: } ! 164: /* FALLTHROUGH */ ! 165: default: ! 166: addch: if (p != endbp) { ! 167: *p++ = ch; ! 168: continue; ! 169: } ! 170: if (xp == bxp) { ! 171: (void)fprintf(stderr, ! 172: "xargs: argument too large.\n"); ! 173: exit(1); ! 174: } ! 175: *xp = NULL; ! 176: run(prog, xargs); ! 177: cnt = endbp - mark; ! 178: bcopy(mark, bp, cnt); ! 179: p = (mark = bp) + cnt; ! 180: *p++ = ch; ! 181: xp = bxp; ! 182: break; ! 183: } ! 184: /* NOTREACHED */ ! 185: } ! 186: ! 187: run(prog, argv) ! 188: char *prog, **argv; ! 189: { ! 190: union wait pstat; ! 191: pid_t pid, waitpid(); ! 192: char **p; ! 193: ! 194: if (tflag) { ! 195: (void)fprintf(stderr, "%s", *argv); ! 196: for (p = argv + 1; *p; ++p) ! 197: (void)fprintf(stderr, " %s", *p); ! 198: (void)fprintf(stderr, "\n"); ! 199: (void)fflush(stderr); ! 200: } ! 201: switch(pid = vfork()) { ! 202: case -1: ! 203: (void)fprintf(stderr, ! 204: "xargs: vfork: %s.\n", strerror(errno)); ! 205: exit(1); ! 206: case 0: ! 207: execvp(prog, argv); ! 208: (void)fprintf(stderr, ! 209: "xargs: %s: %s.\n", prog, strerror(errno)); ! 210: _exit(1); ! 211: } ! 212: pid = waitpid(pid, &pstat, 0); ! 213: if (pid == -1) { ! 214: (void)fprintf(stderr, ! 215: "xargs: waitpid: %s.\n", strerror(errno)); ! 216: exit(1); ! 217: } ! 218: if (pstat.w_status) ! 219: exit(1); ! 220: } ! 221: ! 222: enomem() ! 223: { ! 224: (void)fprintf(stderr, "xargs: %s.\n", strerror(ENOMEM)); ! 225: exit(1); ! 226: } ! 227: ! 228: usage() ! 229: { ! 230: (void)fprintf(stderr, ! 231: "xargs: [-t] [-n number] [-s size] [utility [argument ...]]\n"); ! 232: exit(1); ! 233: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.