xref: /original-bsd/usr.bin/apply/apply.c (revision 262b24ac)
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.2 (Berkeley) 04/06/87";
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 <stdio.h>
25 char	*cmdp;
26 #define	NCHARS 512
27 char	cmd[512];
28 char	defargs=1;
29 #define	DEFARGCHAR	'%'
30 char	argchar=DEFARGCHAR;
31 int	nchars;
32 extern	char *getenv();
33 
34 main(argc, argv)
35 	char *argv[];
36 {
37 	register n;
38 	while(argc>2 && argv[1][0]=='-'){
39 		if(argv[1][1]=='a'){
40 			argchar=argv[1][2];
41 			if(argchar=='\0')
42 				argchar=DEFARGCHAR;
43 		} else {
44 			defargs = atoi(&argv[1][1]);
45 			if(defargs < 0)
46 				defargs = 1;
47 		}
48 		--argc; ++argv;
49 	}
50 	if(argc<2){
51 		fprintf(stderr, "usage: apply [-#] [-ac] cmd arglist\n");
52 		exit(1);
53 	}
54 	argc -= 2;
55 	cmdp = argv[1];
56 	argv += 2;
57 	while(n=docmd(argc, argv)){
58 		argc -= n;
59 		argv += n;
60 	}
61 }
62 char
63 addc(c)
64 	char c;
65 {
66 	if(nchars++>=NCHARS){
67 		fprintf(stderr, "apply: command too long\n");
68 		exit(1);
69 	}
70 	return(c);
71 }
72 char *
73 addarg(s, t)
74 	register char *s, *t;
75 {
76 	while(*t = addc(*s++))
77 		*t++;
78 	return(t);
79 }
80 docmd(argc, argv)
81 	char *argv[];
82 {
83 	register char *p, *q;
84 	register max, i;
85 	char gotit;
86 	if(argc<=0)
87 		return(0);
88 	nchars = 0;
89 	max = 0;
90 	gotit = 0;
91 	p = cmdp;
92 	q = cmd;
93 	while(*q = addc(*p++)){
94 		if(*q++!=argchar || *p<'1' || '9'<*p)
95 			continue;
96 		if((i= *p++-'1') > max)
97 			max = i;
98 		if(i>=argc){
99 	Toofew:
100 			fprintf(stderr, "apply: expecting argument(s) after `%s'\n", argv[argc-1]);
101 			exit(1);
102 		}
103 		q = addarg(argv[i], q-1);
104 		gotit++;
105 	}
106 	if(defargs!=0 && gotit==0){
107 		if(defargs>argc)
108 			goto Toofew;
109 		for(i=0; i<defargs; i++){
110 			*q++ = addc(' ');
111 			q = addarg(argv[i], q);
112 		}
113 	}
114 	i = system(cmd);
115 	if(i == 127){
116 		fprintf(stderr, "apply: no shell!\n");
117 		exit(1);
118 	}
119 	return(max==0? (defargs==0? 1 : defargs) : max+1);
120 }
121 system(s)
122 char *s;
123 {
124 	int status, pid, w;
125 	char *shell = getenv("SHELL");
126 
127 	if ((pid = fork()) == 0) {
128 		execl(shell ? shell : "/bin/sh", "sh", "-c", s, 0);
129 		_exit(127);
130 	}
131 	if(pid == -1){
132 		fprintf(stderr, "apply: can't fork\n");
133 		exit(1);
134 	}
135 	while ((w = wait(&status)) != pid && w != -1)
136 		;
137 	if (w == -1)
138 		status = -1;
139 	return(status);
140 }
141