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