|
|
1.1 ! root 1: #define FALSE 0 ! 2: #define TRUE 1 ! 3: #define MAXSBUF 255 ! 4: #define MAXIBUF 512 ! 5: #define MAXINSERTS 5 ! 6: #define BUFSIZE 570 ! 7: #define MAXARGS 255 ! 8: #define EXITSHIFT 8 * (sizeof (int) - 1) ! 9: char Errstr[BUFSIZE]; ! 10: char *arglist[MAXARGS+1]; ! 11: char argbuf[BUFSIZE+1]; ! 12: char *next = argbuf; ! 13: char *lastarg = ""; ! 14: char **ARGV = arglist; ! 15: char *LEOF = "_"; ! 16: char *INSPAT = "{}"; ! 17: struct inserts { ! 18: char **p_ARGV; /* where to put newarg ptr in arg list */ ! 19: char *p_skel; /* ptr to arg template */ ! 20: } saveargv[MAXINSERTS]; ! 21: char ins_buf[MAXIBUF]; ! 22: char *p_ibuf; ! 23: int PROMPT = -1; ! 24: int BUFLIM = BUFSIZE-100; ! 25: int N_ARGS = 0; ! 26: int N_args = 0; ! 27: int N_lines = 0; ! 28: int DASHX = FALSE; ! 29: int MORE = TRUE; ! 30: int PER_LINE = FALSE; ! 31: int ERR = FALSE; ! 32: int OK = TRUE; ! 33: int LEGAL = FALSE; ! 34: int TRACE = FALSE; ! 35: int INSERT = FALSE; ! 36: int linesize = 0; ! 37: int ibufsize = 0; ! 38: ! 39: main(argc,argv) ! 40: int argc; ! 41: char **argv; { ! 42: extern char *addarg(), *getarg(), *checklen(), *insert(), *strcpy(); ! 43: char *cmdname, *initbuf, **initlist, *flagval; ! 44: int initsize; ! 45: register int j, n_inserts; ! 46: register struct inserts *psave; ! 47: ! 48: static char Sccsid[] = "@(#)xargs.c 2.2"; ! 49: ! 50: /* initialization */ ! 51: ! 52: argc--; argv++; ! 53: n_inserts = 0; ! 54: psave = saveargv; ! 55: ! 56: /* look for flag arguments */ ! 57: ! 58: while ( (*argv)[0] == '-' ) { ! 59: flagval = *argv+1; ! 60: switch ( *flagval++ ) { ! 61: case 'x': DASHX = LEGAL = TRUE; ! 62: break; ! 63: case 'l': PER_LINE = LEGAL = TRUE; ! 64: N_ARGS = 0; ! 65: INSERT = FALSE; ! 66: if( *flagval && (PER_LINE=atoi(flagval)) <= 0 ) { ! 67: sprintf(Errstr, "#lines must be positive int: %s\n", *argv); ! 68: ermsg(Errstr); ! 69: } ! 70: break; ! 71: case 'i': INSERT = PER_LINE = LEGAL = TRUE; ! 72: N_ARGS = 0; ! 73: if ( *flagval ) { ! 74: INSPAT = flagval; ! 75: } ! 76: break; ! 77: case 't': TRACE = TRUE; ! 78: break; ! 79: case 'e': LEOF = flagval; ! 80: break; ! 81: case 's': BUFLIM = atoi(flagval); ! 82: if( BUFLIM>470 || BUFLIM<=0 ) { ! 83: sprintf(Errstr, "0 < max-cmd-line-size <= 470: %s\n", *argv); ! 84: ermsg(Errstr); ! 85: } ! 86: break; ! 87: case 'n': if( (N_ARGS = atoi(flagval)) <= 0 ) { ! 88: sprintf(Errstr, "#args must be positive int: %s\n", *argv); ! 89: ermsg(Errstr); ! 90: } ! 91: else { ! 92: LEGAL = DASHX || N_ARGS==1; ! 93: INSERT = PER_LINE = FALSE; ! 94: } ! 95: break; ! 96: case 'p': if( (PROMPT = open("/dev/tty",0)) == -1) { ! 97: ermsg("can't read from tty for -p\n"); ! 98: } ! 99: else ! 100: TRACE = TRUE; ! 101: break; ! 102: default: sprintf(Errstr, "unknown option: %s\n", *argv); ! 103: ermsg(Errstr); ! 104: break; ! 105: } ! 106: argv++; ! 107: if ( --argc < 1 ) break; ! 108: } ! 109: if( ! OK ) ! 110: ERR = TRUE; ! 111: ! 112: /* pick up command name */ ! 113: ! 114: if ( argc == 0 ) { ! 115: cmdname = "/bin/echo"; ! 116: *ARGV++ = addarg(cmdname); ! 117: } ! 118: else ! 119: cmdname = *argv; ! 120: ! 121: /* pick up args on command line */ ! 122: ! 123: while ( OK && argc-- ) { ! 124: if ( INSERT && ! ERR ) { ! 125: if ( xindex(*argv, INSPAT) != -1 ) { ! 126: if ( ++n_inserts > MAXINSERTS ) { ! 127: sprintf(Errstr, "too many args with %s\n", INSPAT); ! 128: ermsg(Errstr); ! 129: ERR = TRUE; ! 130: } ! 131: psave->p_ARGV = ARGV; ! 132: (psave++)->p_skel = *argv; ! 133: } ! 134: } ! 135: *ARGV++ = addarg( *argv++ ); ! 136: } ! 137: ! 138: /* pick up args from standard input */ ! 139: ! 140: initbuf = next; ! 141: initlist = ARGV; ! 142: initsize = linesize; ! 143: ! 144: while ( OK && MORE ) { ! 145: next = initbuf; ! 146: ARGV = initlist; ! 147: linesize = initsize; ! 148: if ( *lastarg ) ! 149: *ARGV++ = addarg( lastarg ); ! 150: ! 151: while ( (*ARGV++ = getarg()) && OK ); ! 152: ! 153: /* insert arg if requested */ ! 154: ! 155: if ( !ERR && INSERT ) { ! 156: p_ibuf = ins_buf; ! 157: ARGV--; ! 158: j = ibufsize = 0; ! 159: for ( psave=saveargv; ++j<=n_inserts; ++psave ) { ! 160: addibuf(psave); ! 161: if ( ERR ) break; ! 162: } ! 163: } ! 164: *ARGV = 0; ! 165: ! 166: /* exec command */ ! 167: ! 168: if ( ! ERR ) { ! 169: if ( ! MORE && (PER_LINE && N_lines==0 || N_ARGS && N_args==0) ) exit (0); ! 170: OK = TRUE; ! 171: j = TRACE ? echoargs() : TRUE; ! 172: if( j ) { ! 173: if ( lcall(cmdname, arglist) != -1 ) continue; ! 174: sprintf(Errstr, "%s not executed or returned -1\n", cmdname); ! 175: ermsg(Errstr); ! 176: } ! 177: } ! 178: } ! 179: if ( OK ) exit (0); else exit (1); ! 180: } ! 181: ! 182: char * ! 183: checklen(arg) ! 184: char *arg; ! 185: { ! 186: register int oklen; ! 187: ! 188: oklen = TRUE; ! 189: if ( (linesize += strlen(arg)+1) > BUFLIM ) { ! 190: lastarg = arg; ! 191: oklen = OK = FALSE; ! 192: if ( LEGAL ) { ! 193: ERR = TRUE; ! 194: ermsg("arg list too long\n"); ! 195: } ! 196: else if( N_args > 1 ) ! 197: N_args = 1; ! 198: else { ! 199: ermsg("a single arg was greater than the max arglist size\n"); ! 200: ERR = TRUE; ! 201: } ! 202: } ! 203: return ( oklen ? arg : 0 ); ! 204: } ! 205: ! 206: char * ! 207: addarg(arg) ! 208: char *arg; ! 209: { ! 210: strcpy(next, arg); ! 211: arg = next; ! 212: next += strlen(arg)+1; ! 213: return ( checklen(arg) ); ! 214: } ! 215: ! 216: char * ! 217: getarg() ! 218: { ! 219: register char c, c1, *arg; ! 220: char *retarg; ! 221: ! 222: while ( (c=getchr()) == ' ' ! 223: || c == '\n' ! 224: || c == '\t' ); ! 225: if ( c == '\0' ) { ! 226: MORE = FALSE; ! 227: return 0; ! 228: } ! 229: ! 230: arg = next; ! 231: for ( ; ; c = getchr() ) ! 232: switch ( c ) { ! 233: ! 234: case '\t': ! 235: case ' ' : ! 236: if ( INSERT ) { *next++ = c; ! 237: break; ! 238: } ! 239: case '\0': ! 240: case '\n': ! 241: *next++ = '\0'; ! 242: if( !strcmp(arg,LEOF) || c=='\0' ) { ! 243: MORE = FALSE; ! 244: if( c != '\n' ) ! 245: while( c=getchr() ) ! 246: if( c=='\n' ) break; ! 247: return 0; ! 248: } ! 249: else { ! 250: ++N_args; ! 251: if( retarg = checklen(arg) ) { ! 252: if( (PER_LINE && c=='\n' && ++N_lines>=PER_LINE) ! 253: || (N_ARGS && N_args>=N_ARGS) ) { ! 254: N_lines = N_args = 0; ! 255: lastarg = ""; ! 256: OK = FALSE; ! 257: } ! 258: } ! 259: return retarg; ! 260: } ! 261: ! 262: case '\\': ! 263: *next++ = getchr(); ! 264: break; ! 265: ! 266: case '"': ! 267: case '\'': ! 268: while( (c1=getchr()) != c) { ! 269: if( c1 == '\0' || c1 == '\n' ) { ! 270: *next++ = '\0'; ! 271: sprintf(Errstr, "missing quote?: %s\n", arg); ! 272: ermsg(Errstr); ! 273: ERR = TRUE; ! 274: return (0); ! 275: } ! 276: *next++ = c1; ! 277: } ! 278: break; ! 279: ! 280: default: ! 281: *next++ = c; ! 282: break; ! 283: } ! 284: } ! 285: ermsg(messages) ! 286: char *messages; ! 287: { ! 288: write(2,"xargs: ",7); ! 289: write(2,messages,strlen(messages)); ! 290: OK = FALSE; ! 291: } ! 292: ! 293: echoargs() ! 294: { ! 295: register char **anarg; ! 296: char yesorno[1], junk[1]; ! 297: register int j; ! 298: ! 299: anarg = arglist-1; ! 300: while ( *++anarg ) { ! 301: write(2, *anarg, strlen(*anarg) ); ! 302: write(2," ",1); ! 303: } ! 304: if( PROMPT == -1 ) { ! 305: write(2,"\n",1); ! 306: return TRUE; ! 307: } ! 308: write(2,"?...",4); ! 309: if( read(PROMPT,yesorno,1) == 0 ) ! 310: exit(0); ! 311: if( yesorno[0] == '\n' ) ! 312: return FALSE; ! 313: while( ((j=read(PROMPT,junk,1))==1) && (junk[0]!='\n') ); ! 314: if( j==0 ) ! 315: exit (0); ! 316: return ( yesorno[0]=='y' ); ! 317: } ! 318: ! 319: char * ! 320: insert(pattern, subst) ! 321: char *pattern, *subst; ! 322: { ! 323: static char buffer[MAXSBUF+1]; ! 324: int len, ipatlen; ! 325: register char *pat; ! 326: register char *bufend; ! 327: register char *pbuf; ! 328: ! 329: len = strlen(subst); ! 330: ipatlen = strlen(INSPAT)-1; ! 331: pat = pattern-1; ! 332: pbuf = buffer; ! 333: bufend = &buffer[MAXSBUF]; ! 334: ! 335: while ( *++pat ) { ! 336: if( xindex(pat,INSPAT) == 0 ) { ! 337: if ( pbuf+len >= bufend ) break; ! 338: else { ! 339: strcpy(pbuf, subst); ! 340: pat += ipatlen; ! 341: pbuf += len; ! 342: } ! 343: } ! 344: else { ! 345: *pbuf++ = *pat; ! 346: if (pbuf >= bufend ) break; ! 347: } ! 348: } ! 349: ! 350: if ( ! *pat ) { ! 351: *pbuf = '\0'; ! 352: return (buffer); ! 353: } ! 354: else { ! 355: sprintf(Errstr, "max arg size with insertion via %s's exceeded\n", INSPAT); ! 356: ermsg(Errstr); ! 357: ERR = TRUE; ! 358: return 0; ! 359: } ! 360: } ! 361: ! 362: addibuf(p) ! 363: struct inserts *p; ! 364: { ! 365: register char *newarg, *skel, *sub; ! 366: int l; ! 367: ! 368: skel = p->p_skel; ! 369: sub = *ARGV; ! 370: linesize -= strlen(skel)+1; ! 371: newarg = insert(skel,sub); ! 372: if ( checklen(newarg) ) { ! 373: if( (ibufsize += (l=strlen(newarg)+1)) > MAXIBUF) { ! 374: ermsg("insert-buffer overflow\n"); ! 375: ERR = TRUE; ! 376: } ! 377: strcpy(p_ibuf, newarg); ! 378: *(p->p_ARGV) = p_ibuf; ! 379: p_ibuf += l; ! 380: } ! 381: } ! 382: getchr() { ! 383: char c; ! 384: if ( read(0,&c,1) == 1 ) return (c); ! 385: return (0); ! 386: } ! 387: int lcall(sub,subargs) ! 388: char *sub, **subargs; ! 389: { ! 390: ! 391: int retcode; ! 392: register int iwait, child; ! 393: ! 394: switch( child=fork() ) { ! 395: default: ! 396: while( (iwait=wait(&retcode))!=child && iwait!= -1 ); ! 397: if( iwait == -1 || retcode<<EXITSHIFT ) ! 398: return -1; ! 399: return( retcode>>EXITSHIFT ); ! 400: case 0: ! 401: execvp(sub,subargs); ! 402: exit (-1); ! 403: case -1: ! 404: return (-1); ! 405: } ! 406: } ! 407: static char Isccsid[] = "@(#)xindex 1.1"; ! 408: /* ! 409: If `s2' is a substring of `s1' return the offset of the first ! 410: occurrence of `s2' in `s1', ! 411: else return -1. ! 412: */ ! 413: ! 414: xindex(as1,as2) ! 415: char *as1,*as2; ! 416: { ! 417: register char *s1,*s2,c; ! 418: int offset; ! 419: ! 420: s1 = as1; ! 421: s2 = as2; ! 422: c = *s2; ! 423: ! 424: while (*s1) ! 425: if (*s1++ == c) { ! 426: offset = s1 - as1 - 1; ! 427: s2++; ! 428: while ((c = *s2++) == *s1++ && c) ; ! 429: if (c == 0) ! 430: return(offset); ! 431: s1 = offset + as1 + 1; ! 432: s2 = as2; ! 433: c = *s2; ! 434: } ! 435: return(-1); ! 436: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.