Annotation of researchv10no/cmd/xargs.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.