|
|
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.