xref: /csrg-svn/usr.bin/apply/apply.c (revision 37871)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 char copyright[] =
9 "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10  All rights reserved.\n";
11 #endif not lint
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)apply.c	5.3 (Berkeley) 05/11/89";
15 #endif not lint
16 
17 /*%cc -s -O %
18  * apply - apply a command to a set of arguments
19  *
20  *	apply echo * == ls
21  *	apply -2 cmp A1 B1 A2 B2   compares A's with B's
22  *	apply "ln %1 /usr/fred/dir" *  duplicates a directory
23  */
24 #include <paths.h>
25 #include <stdio.h>
26 
27 char	*cmdp;
28 #define	NCHARS 512
29 char	cmd[512];
30 char	defargs=1;
31 #define	DEFARGCHAR	'%'
32 char	argchar=DEFARGCHAR;
33 int	nchars;
34 extern	char *getenv();
35 
36 main(argc, argv)
37 	char *argv[];
38 {
39 	register n;
40 	while(argc>2 && argv[1][0]=='-'){
41 		if(argv[1][1]=='a'){
42 			argchar=argv[1][2];
43 			if(argchar=='\0')
44 				argchar=DEFARGCHAR;
45 		} else {
46 			defargs = atoi(&argv[1][1]);
47 			if(defargs < 0)
48 				defargs = 1;
49 		}
50 		--argc; ++argv;
51 	}
52 	if(argc<2){
53 		fprintf(stderr, "usage: apply [-#] [-ac] cmd arglist\n");
54 		exit(1);
55 	}
56 	argc -= 2;
57 	cmdp = argv[1];
58 	argv += 2;
59 	while(n=docmd(argc, argv)){
60 		argc -= n;
61 		argv += n;
62 	}
63 }
64 char
65 addc(c)
66 	char c;
67 {
68 	if(nchars++>=NCHARS){
69 		fprintf(stderr, "apply: command too long\n");
70 		exit(1);
71 	}
72 	return(c);
73 }
74 char *
75 addarg(s, t)
76 	register char *s, *t;
77 {
78 	while(*t = addc(*s++))
79 		*t++;
80 	return(t);
81 }
82 docmd(argc, argv)
83 	char *argv[];
84 {
85 	register char *p, *q;
86 	register max, i;
87 	char gotit;
88 	if(argc<=0)
89 		return(0);
90 	nchars = 0;
91 	max = 0;
92 	gotit = 0;
93 	p = cmdp;
94 	q = cmd;
95 	while(*q = addc(*p++)){
96 		if(*q++!=argchar || *p<'1' || '9'<*p)
97 			continue;
98 		if((i= *p++-'1') > max)
99 			max = i;
100 		if(i>=argc){
101 	Toofew:
102 			fprintf(stderr, "apply: expecting argument(s) after `%s'\n", argv[argc-1]);
103 			exit(1);
104 		}
105 		q = addarg(argv[i], q-1);
106 		gotit++;
107 	}
108 	if(defargs!=0 && gotit==0){
109 		if(defargs>argc)
110 			goto Toofew;
111 		for(i=0; i<defargs; i++){
112 			*q++ = addc(' ');
113 			q = addarg(argv[i], q);
114 		}
115 	}
116 	i = system(cmd);
117 	if(i == 127){
118 		fprintf(stderr, "apply: no shell!\n");
119 		exit(1);
120 	}
121 	return(max==0? (defargs==0? 1 : defargs) : max+1);
122 }
123 system(s)
124 char *s;
125 {
126 	int status, pid, w;
127 	char *shell = getenv("SHELL");
128 
129 	if ((pid = fork()) == 0) {
130 		execl(shell ? shell : _PATH_BSHELL, "sh", "-c", s, 0);
131 		_exit(127);
132 	}
133 	if(pid == -1){
134 		fprintf(stderr, "apply: can't fork\n");
135 		exit(1);
136 	}
137 	while ((w = wait(&status)) != pid && w != -1)
138 		;
139 	if (w == -1)
140 		status = -1;
141 	return(status);
142 }
143