Deleted Added
full compact
apply.c (60706) apply.c (67189)
1/*-
2 * Copyright (c) 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Jan-Simon Pendry.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#ifndef lint
38#if 0
39static const char sccsid[] = "@(#)apply.c 8.4 (Berkeley) 4/4/94";
40#endif
41static const char rcsid[] =
1/*-
2 * Copyright (c) 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Jan-Simon Pendry.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#ifndef lint
38#if 0
39static const char sccsid[] = "@(#)apply.c 8.4 (Berkeley) 4/4/94";
40#endif
41static const char rcsid[] =
42 "$FreeBSD: head/usr.bin/apply/apply.c 60706 2000-05-19 09:42:53Z kris $";
42 "$FreeBSD: head/usr.bin/apply/apply.c 67189 2000-10-16 08:13:59Z brian $";
43#endif /* not lint */
44
43#endif /* not lint */
44
45#include <sys/types.h>
46
45#include <sys/wait.h>
46
47#include <ctype.h>
48#include <err.h>
49#include <paths.h>
50#include <signal.h>
51#include <stdio.h>
52#include <stdlib.h>
53#include <string.h>
54#include <unistd.h>
55
56void usage __P((void));
57int system __P((const char *));
58
59int
60main(argc, argv)
61 int argc;
62 char *argv[];
63{
64 int ch, clen, debug, i, l, magic, n, nargs, rval;
65 char *c, *cmd, *p, *q;
66
67 debug = 0;
68 magic = '%'; /* Default magic char is `%'. */
69 nargs = -1;
70 while ((ch = getopt(argc, argv, "a:d0123456789")) != -1)
71 switch (ch) {
72 case 'a':
73 if (optarg[1] != '\0')
74 errx(1,
75 "illegal magic character specification");
76 magic = optarg[0];
77 break;
78 case 'd':
79 debug = 1;
80 break;
81 case '0': case '1': case '2': case '3': case '4':
82 case '5': case '6': case '7': case '8': case '9':
83 if (nargs != -1)
84 errx(1,
85 "only one -# argument may be specified");
86 nargs = optopt - '0';
87 break;
88 default:
89 usage();
90 }
91 argc -= optind;
92 argv += optind;
93
94 if (argc < 2)
95 usage();
96
97 /*
98 * The command to run is argv[0], and the args are argv[1..].
99 * Look for %digit references in the command, remembering the
100 * largest one.
101 */
102 for (n = 0, p = argv[0]; *p != '\0'; ++p)
103 if (p[0] == magic && isdigit(p[1]) && p[1] != '0') {
104 ++p;
105 if (p[0] - '0' > n)
106 n = p[0] - '0';
107 }
108
109 /*
110 * If there were any %digit references, then use those, otherwise
111 * build a new command string with sufficient %digit references at
112 * the end to consume (nargs) arguments each time round the loop.
113 * Allocate enough space to hold the maximum command.
114 */
115 if ((cmd = malloc(sizeof("exec ") - 1 +
116 strlen(argv[0]) + 9 * (sizeof(" %1") - 1) + 1)) == NULL)
117 err(1, NULL);
118
119 if (n == 0) {
120 /* If nargs not set, default to a single argument. */
121 if (nargs == -1)
122 nargs = 1;
123
124 p = cmd;
125 p += sprintf(cmd, "exec %s", argv[0]);
126 for (i = 1; i <= nargs; i++)
127 p += sprintf(p, " %c%d", magic, i);
128
129 /*
130 * If nargs set to the special value 0, eat a single
131 * argument for each command execution.
132 */
133 if (nargs == 0)
134 nargs = 1;
135 } else {
136 (void)sprintf(cmd, "exec %s", argv[0]);
137 nargs = n;
138 }
139
140 /*
141 * Grab some space in which to build the command. Allocate
142 * as necessary later, but no reason to build it up slowly
143 * for the normal case.
144 */
145 if ((c = malloc(clen = 1024)) == NULL)
146 err(1, NULL);
147
148 /*
149 * (argc) and (argv) are still offset by one to make it simpler to
150 * expand %digit references. At the end of the loop check for (argc)
151 * equals 1 means that all the (argv) has been consumed.
152 */
153 for (rval = 0; argc > nargs; argc -= nargs, argv += nargs) {
154 /*
155 * Find a max value for the command length, and ensure
156 * there's enough space to build it.
157 */
158 for (l = strlen(cmd), i = 0; i < nargs; i++)
159 l += strlen(argv[i+1]);
160 if (l > clen && (c = realloc(c, clen = l)) == NULL)
161 err(1, NULL);
162
163 /* Expand command argv references. */
164 for (p = cmd, q = c; *p != '\0'; ++p)
165 if (p[0] == magic && isdigit(p[1]) && p[1] != '0')
166 q += sprintf(q, "%s", argv[(++p)[0] - '0']);
167 else
168 *q++ = *p;
169
170 /* Terminate the command string. */
171 *q = '\0';
172
173 /* Run the command. */
174 if (debug)
175 (void)printf("%s\n", c);
176 else
177 if (system(c))
178 rval = 1;
179 }
180
181 if (argc != 1)
182 errx(1, "expecting additional argument%s after \"%s\"",
183 (nargs - argc) ? "s" : "", argv[argc - 1]);
184 exit(rval);
185}
186
187/*
188 * system --
189 * Private version of system(3). Use the user's SHELL environment
190 * variable as the shell to execute.
191 */
192int
193system(command)
194 const char *command;
195{
196 static char *name, *shell;
197 pid_t pid;
198 int omask, pstat;
199 sig_t intsave, quitsave;
200
201 if (shell == NULL) {
202 if ((shell = getenv("SHELL")) == NULL)
203 shell = _PATH_BSHELL;
204 if ((name = strrchr(shell, '/')) == NULL)
205 name = shell;
206 else
207 ++name;
208 }
209 if (!command) /* just checking... */
210 return(1);
211
212 omask = sigblock(sigmask(SIGCHLD));
213 switch(pid = vfork()) {
214 case -1: /* error */
215 err(1, "vfork");
216 case 0: /* child */
217 (void)sigsetmask(omask);
218 execl(shell, name, "-c", command, NULL);
219 warn("%s", shell);
220 _exit(1);
221 }
222 intsave = signal(SIGINT, SIG_IGN);
223 quitsave = signal(SIGQUIT, SIG_IGN);
224 pid = waitpid(pid, &pstat, 0);
225 (void)sigsetmask(omask);
226 (void)signal(SIGINT, intsave);
227 (void)signal(SIGQUIT, quitsave);
228 return(pid == -1 ? -1 : pstat);
229}
230
231void
232usage()
233{
234
235 (void)fprintf(stderr,
236 "usage: apply [-a magic] [-d] [-0123456789] command arguments ...\n");
237 exit(1);
238}
47#include <sys/wait.h>
48
49#include <ctype.h>
50#include <err.h>
51#include <paths.h>
52#include <signal.h>
53#include <stdio.h>
54#include <stdlib.h>
55#include <string.h>
56#include <unistd.h>
57
58void usage __P((void));
59int system __P((const char *));
60
61int
62main(argc, argv)
63 int argc;
64 char *argv[];
65{
66 int ch, clen, debug, i, l, magic, n, nargs, rval;
67 char *c, *cmd, *p, *q;
68
69 debug = 0;
70 magic = '%'; /* Default magic char is `%'. */
71 nargs = -1;
72 while ((ch = getopt(argc, argv, "a:d0123456789")) != -1)
73 switch (ch) {
74 case 'a':
75 if (optarg[1] != '\0')
76 errx(1,
77 "illegal magic character specification");
78 magic = optarg[0];
79 break;
80 case 'd':
81 debug = 1;
82 break;
83 case '0': case '1': case '2': case '3': case '4':
84 case '5': case '6': case '7': case '8': case '9':
85 if (nargs != -1)
86 errx(1,
87 "only one -# argument may be specified");
88 nargs = optopt - '0';
89 break;
90 default:
91 usage();
92 }
93 argc -= optind;
94 argv += optind;
95
96 if (argc < 2)
97 usage();
98
99 /*
100 * The command to run is argv[0], and the args are argv[1..].
101 * Look for %digit references in the command, remembering the
102 * largest one.
103 */
104 for (n = 0, p = argv[0]; *p != '\0'; ++p)
105 if (p[0] == magic && isdigit(p[1]) && p[1] != '0') {
106 ++p;
107 if (p[0] - '0' > n)
108 n = p[0] - '0';
109 }
110
111 /*
112 * If there were any %digit references, then use those, otherwise
113 * build a new command string with sufficient %digit references at
114 * the end to consume (nargs) arguments each time round the loop.
115 * Allocate enough space to hold the maximum command.
116 */
117 if ((cmd = malloc(sizeof("exec ") - 1 +
118 strlen(argv[0]) + 9 * (sizeof(" %1") - 1) + 1)) == NULL)
119 err(1, NULL);
120
121 if (n == 0) {
122 /* If nargs not set, default to a single argument. */
123 if (nargs == -1)
124 nargs = 1;
125
126 p = cmd;
127 p += sprintf(cmd, "exec %s", argv[0]);
128 for (i = 1; i <= nargs; i++)
129 p += sprintf(p, " %c%d", magic, i);
130
131 /*
132 * If nargs set to the special value 0, eat a single
133 * argument for each command execution.
134 */
135 if (nargs == 0)
136 nargs = 1;
137 } else {
138 (void)sprintf(cmd, "exec %s", argv[0]);
139 nargs = n;
140 }
141
142 /*
143 * Grab some space in which to build the command. Allocate
144 * as necessary later, but no reason to build it up slowly
145 * for the normal case.
146 */
147 if ((c = malloc(clen = 1024)) == NULL)
148 err(1, NULL);
149
150 /*
151 * (argc) and (argv) are still offset by one to make it simpler to
152 * expand %digit references. At the end of the loop check for (argc)
153 * equals 1 means that all the (argv) has been consumed.
154 */
155 for (rval = 0; argc > nargs; argc -= nargs, argv += nargs) {
156 /*
157 * Find a max value for the command length, and ensure
158 * there's enough space to build it.
159 */
160 for (l = strlen(cmd), i = 0; i < nargs; i++)
161 l += strlen(argv[i+1]);
162 if (l > clen && (c = realloc(c, clen = l)) == NULL)
163 err(1, NULL);
164
165 /* Expand command argv references. */
166 for (p = cmd, q = c; *p != '\0'; ++p)
167 if (p[0] == magic && isdigit(p[1]) && p[1] != '0')
168 q += sprintf(q, "%s", argv[(++p)[0] - '0']);
169 else
170 *q++ = *p;
171
172 /* Terminate the command string. */
173 *q = '\0';
174
175 /* Run the command. */
176 if (debug)
177 (void)printf("%s\n", c);
178 else
179 if (system(c))
180 rval = 1;
181 }
182
183 if (argc != 1)
184 errx(1, "expecting additional argument%s after \"%s\"",
185 (nargs - argc) ? "s" : "", argv[argc - 1]);
186 exit(rval);
187}
188
189/*
190 * system --
191 * Private version of system(3). Use the user's SHELL environment
192 * variable as the shell to execute.
193 */
194int
195system(command)
196 const char *command;
197{
198 static char *name, *shell;
199 pid_t pid;
200 int omask, pstat;
201 sig_t intsave, quitsave;
202
203 if (shell == NULL) {
204 if ((shell = getenv("SHELL")) == NULL)
205 shell = _PATH_BSHELL;
206 if ((name = strrchr(shell, '/')) == NULL)
207 name = shell;
208 else
209 ++name;
210 }
211 if (!command) /* just checking... */
212 return(1);
213
214 omask = sigblock(sigmask(SIGCHLD));
215 switch(pid = vfork()) {
216 case -1: /* error */
217 err(1, "vfork");
218 case 0: /* child */
219 (void)sigsetmask(omask);
220 execl(shell, name, "-c", command, NULL);
221 warn("%s", shell);
222 _exit(1);
223 }
224 intsave = signal(SIGINT, SIG_IGN);
225 quitsave = signal(SIGQUIT, SIG_IGN);
226 pid = waitpid(pid, &pstat, 0);
227 (void)sigsetmask(omask);
228 (void)signal(SIGINT, intsave);
229 (void)signal(SIGQUIT, quitsave);
230 return(pid == -1 ? -1 : pstat);
231}
232
233void
234usage()
235{
236
237 (void)fprintf(stderr,
238 "usage: apply [-a magic] [-d] [-0123456789] command arguments ...\n");
239 exit(1);
240}