diff options
author | Will Andrews <will@FreeBSD.org> | 2001-01-05 18:15:17 +0000 |
---|---|---|
committer | Will Andrews <will@FreeBSD.org> | 2001-01-05 18:15:17 +0000 |
commit | f69734803487dd14ded1a80b7344707248a84227 (patch) | |
tree | 554f6160ae38bf3181a823e2dd3b683cb145bbcc /usr.bin/apply | |
parent | c05aa33cb07253b4ec096d33d1c7bb51a5642b6b (diff) | |
download | src-test2-f69734803487dd14ded1a80b7344707248a84227.tar.gz src-test2-f69734803487dd14ded1a80b7344707248a84227.zip |
Notes
Diffstat (limited to 'usr.bin/apply')
-rw-r--r-- | usr.bin/apply/apply.c | 99 |
1 files changed, 62 insertions, 37 deletions
diff --git a/usr.bin/apply/apply.c b/usr.bin/apply/apply.c index 05e086d4eaf0..70f3bdfc6439 100644 --- a/usr.bin/apply/apply.c +++ b/usr.bin/apply/apply.c @@ -55,16 +55,16 @@ static const char rcsid[] = #include <string.h> #include <unistd.h> -void usage __P((void)); -int system __P((const char *)); +void usage(void); +static int exec_shell(char *, char *, const char *); + +#define EXEC "exec " int -main(argc, argv) - int argc; - char *argv[]; -{ - int ch, clen, debug, i, l, magic, n, nargs, rval; - char *c, *cmd, *p, *q; +main(int argc, char **argv) { + int ch, debug, i, magic, n, nargs, rval, offset; + size_t clen, l, cmdsize; + char *c, *cmd, *p, *q, *shell, *name, *tmpshell, *slashp; debug = 0; magic = '%'; /* Default magic char is `%'. */ @@ -109,13 +109,31 @@ main(argc, argv) } /* + * Figure out the shell and name arguments to pass to execl() + * in exec_shell(). Always malloc() shell and just set name + * to point at the last part of shell if there are any backslashes, + * otherwise just set it to point at the space malloc()'d. If + * SHELL environment variable exists, replace contents of + * shell with it. + */ + shell = name = NULL; + tmpshell = getenv("SHELL"); + shell = (tmpshell != NULL) ? strdup(tmpshell) : strdup(_PATH_BSHELL); + if (shell == NULL) + err(1, "strdup() failed"); + slashp = strrchr(shell, '/'); + name = (slashp != NULL) ? slashp + 1 : shell; + + /* * If there were any %digit references, then use those, otherwise * build a new command string with sufficient %digit references at * the end to consume (nargs) arguments each time round the loop. - * Allocate enough space to hold the maximum command. + * Allocate enough space to hold the maximum command. Save the + * size to pass to snprintf(). */ - if ((cmd = malloc(sizeof("exec ") - 1 + - strlen(argv[0]) + 9 * (sizeof(" %1") - 1) + 1)) == NULL) + cmdsize = sizeof(EXEC) - 1 + strlen(argv[0]) + 9 * + (sizeof(" %1") - 1) + 1; + if ((cmd = malloc(cmdsize)) == NULL) err(1, NULL); if (n == 0) { @@ -124,9 +142,16 @@ main(argc, argv) nargs = 1; p = cmd; - p += sprintf(cmd, "exec %s", argv[0]); - for (i = 1; i <= nargs; i++) - p += sprintf(p, " %c%d", magic, i); + offset = snprintf(cmd, cmdsize, EXEC "%s", argv[0]); + if ((size_t)offset >= cmdsize) + err(1, "snprintf() failed"); + p += offset; + for (i = 1; i <= nargs; i++) { + offset = snprintf(p, cmdsize, " %c%d", magic, i); + if ((size_t)offset >= cmdsize) + err(1, "snprintf() failed"); + p += offset; + } /* * If nargs set to the special value 0, eat a single @@ -135,7 +160,9 @@ main(argc, argv) if (nargs == 0) nargs = 1; } else { - (void)sprintf(cmd, "exec %s", argv[0]); + offset = snprintf(cmd, cmdsize, EXEC "%s", argv[0]); + if ((size_t)offset >= cmdsize) + err(1, "snprintf() failed"); nargs = n; } @@ -164,9 +191,13 @@ main(argc, argv) /* Expand command argv references. */ for (p = cmd, q = c; *p != '\0'; ++p) - if (p[0] == magic && isdigit(p[1]) && p[1] != '0') - q += sprintf(q, "%s", argv[(++p)[0] - '0']); - else + if (p[0] == magic && isdigit(p[1]) && p[1] != '0') { + offset = snprintf(q, l, "%s", + argv[(++p)[0] - '0']); + if ((size_t)offset >= l) + err(1, "snprintf() failed"); + q += offset; + } else *q++ = *p; /* Terminate the command string. */ @@ -176,38 +207,32 @@ main(argc, argv) if (debug) (void)printf("%s\n", c); else - if (system(c)) + if (exec_shell(shell, name, c)) rval = 1; } if (argc != 1) errx(1, "expecting additional argument%s after \"%s\"", - (nargs - argc) ? "s" : "", argv[argc - 1]); + (nargs - argc) ? "s" : "", argv[argc - 1]); + + free(cmd); + free(c); + free(shell); exit(rval); } /* - * system -- - * Private version of system(3). Use the user's SHELL environment - * variable as the shell to execute. + * exec_shell -- + * Execute a shell command using passed use_shell and use_name + * arguments. */ -int -system(command) - const char *command; +static int +exec_shell(char *use_shell, char *use_name, const char *command) { - static char *name, *shell; pid_t pid; int omask, pstat; sig_t intsave, quitsave; - if (shell == NULL) { - if ((shell = getenv("SHELL")) == NULL) - shell = _PATH_BSHELL; - if ((name = strrchr(shell, '/')) == NULL) - name = shell; - else - ++name; - } if (!command) /* just checking... */ return(1); @@ -217,8 +242,8 @@ system(command) err(1, "vfork"); case 0: /* child */ (void)sigsetmask(omask); - execl(shell, name, "-c", command, NULL); - warn("%s", shell); + execl(use_shell, use_name, "-c", command, NULL); + warn("%s", use_shell); _exit(1); } intsave = signal(SIGINT, SIG_IGN); |