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