X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=common-src%2Fpipespawn.c;h=16fd67cdda4dfc916cd0e3dc71ec8bd8001049dc;hb=94a044f90357edefa6f4ae9f0b1d5885b0e34aee;hp=8a8af5518f6b2a3cfe136cb002a1580288f48644;hpb=3ab887b9bc819a846c75dd7f2ee5d41fac22b19f;p=debian%2Famanda diff --git a/common-src/pipespawn.c b/common-src/pipespawn.c index 8a8af55..16fd67c 100644 --- a/common-src/pipespawn.c +++ b/common-src/pipespawn.c @@ -2,248 +2,142 @@ #include "pipespawn.h" #include "arglist.h" #include "clock.h" +#include "util.h" char skip_argument[1]; -#ifdef STDC_HEADERS -int pipespawn(char *prog, int pipedef, int *stdinfd, int *stdoutfd, - int *stderrfd, ...) -#else -int pipespawn(prog, pipedef, stdinfd, stdoutfd, stderrfd, va_alist) -char *prog; -int pipedef; -int *stdinfd, *stdoutfd, *stderrfd; -va_dcl -#endif +pid_t pipespawnv_passwd(char *prog, int pipedef, + int *stdinfd, int *stdoutfd, int *stderrfd, + char **my_argv); + + +/* + * this used to be a function in it's own write but became a wrapper around + * pipespawnv to eliminate redundancy... + */ +pid_t +pipespawn( + char * prog, + int pipedef, + int * stdinfd, + int * stdoutfd, + int * stderrfd, + ...) { va_list ap; - int argc; + int argc = 0, i; + pid_t pid; char **argv; - int pid, i, inpipe[2], outpipe[2], errpipe[2], passwdpipe[2]; - char *passwdvar = NULL; - int *passwdfd = NULL; - char number[NUM_STR_SIZE]; - char *arg; - char *e; - int ch; - char **env; - char **newenv; - /* - * Log the command line and count the args. - */ - dbprintf(("%s: spawning %s in pipeline\n", debug_prefix_time(NULL), prog)); - dbprintf(("%s: argument list:", debug_prefix(NULL))); + /* count args */ arglist_start(ap, stderrfd); - if ((pipedef & PASSWD_PIPE) != 0) { - passwdvar = arglist_val(ap, char *); - passwdfd = arglist_val(ap, int *); - } - argc = 0; - while((arg = arglist_val(ap, char *)) != NULL) { - if (arg == skip_argument) { - continue; - } + while(arglist_val(ap, char *) != NULL) { argc++; - dbprintf((" ")); - for(i = 0; (ch = arg[i]) != '\0' && isprint(ch) && ch != ' '; i++) {} - if(ch != '\0' || i == 0) { - dbprintf(("\"")); - } - dbprintf(("%s", arg)); - if(ch != '\0' || i == 0) { - dbprintf(("\"")); - } } arglist_end(ap); - dbprintf(("\n")); /* - * Create the pipes + * Create the argument vector. */ - if ((pipedef & STDIN_PIPE) != 0) { - if(pipe(inpipe) == -1) { - error("error [open pipe to %s: %s]", prog, strerror(errno)); - } - } - if ((pipedef & STDOUT_PIPE) != 0) { - if(pipe(outpipe) == -1) { - error("error [open pipe to %s: %s]", prog, strerror(errno)); - } - } - if ((pipedef & STDERR_PIPE) != 0) { - if(pipe(errpipe) == -1) { - error("error [open pipe to %s: %s]", prog, strerror(errno)); - } - } - if ((pipedef & PASSWD_PIPE) != 0) { - if(pipe(passwdpipe) == -1) { - error("error [open pipe to %s: %s]", prog, strerror(errno)); - } + arglist_start(ap, stderrfd); + argv = (char **)alloc((argc + 1) * SIZEOF(*argv)); + i = 0; + while((argv[i] = arglist_val(ap, char *)) != NULL) { + if (argv[i] != skip_argument) { + i++; + } } + arglist_end(ap); - /* - * Fork and set up the return or run the program. - */ - switch(pid = fork()) { - case -1: - e = strerror(errno); - error("error [fork %s: %s]", prog, e); - default: /* parent process */ - if ((pipedef & STDIN_PIPE) != 0) { - aclose(inpipe[0]); /* close input side of pipe */ - *stdinfd = inpipe[1]; - } - if ((pipedef & STDOUT_PIPE) != 0) { - aclose(outpipe[1]); /* close output side of pipe */ - *stdoutfd = outpipe[0]; - } - if ((pipedef & STDERR_PIPE) != 0) { - aclose(errpipe[1]); /* close output side of pipe */ - *stderrfd = errpipe[0]; - } - if ((pipedef & PASSWD_PIPE) != 0) { - aclose(passwdpipe[0]); /* close input side of pipe */ - *passwdfd = passwdpipe[1]; - } - break; - case 0: /* child process */ - if ((pipedef & STDIN_PIPE) != 0) { - aclose(inpipe[1]); /* close output side of pipe */ - } else { - inpipe[0] = *stdinfd; - } - if ((pipedef & STDOUT_PIPE) != 0) { - aclose(outpipe[0]); /* close input side of pipe */ - } else { - outpipe[1] = *stdoutfd; - } - if ((pipedef & STDERR_PIPE) != 0) { - aclose(errpipe[0]); /* close input side of pipe */ - } else { - errpipe[1] = *stderrfd; - } - if ((pipedef & PASSWD_PIPE) != 0) { - aclose(passwdpipe[1]); /* close output side of pipe */ - } - - /* - * Shift the pipes to the standard file descriptors as requested. - */ - if(dup2(inpipe[0], 0) == -1) { - error("error [spawn %s: dup2 in: %s]", prog, strerror(errno)); - } - if(dup2(outpipe[1], 1) == -1) { - error("error [spawn %s: dup2 out: %s]", prog, strerror(errno)); - } - if(dup2(errpipe[1], 2) == -1) { - error("error [spawn %s: dup2 err: %s]", prog, strerror(errno)); - } - - /* - * Create the argument vector. - */ - arglist_start(ap, stderrfd); - if ((pipedef & PASSWD_PIPE) != 0) { - passwdvar = arglist_val(ap, char *); - passwdfd = arglist_val(ap, int *); - } - argv = (char **)alloc((argc + 1) * sizeof(*argv)); - i = 0; - while((argv[i] = arglist_val(ap, char *)) != NULL) { - if (argv[i] != skip_argument) { - i++; - } - } - arglist_end(ap); - - /* - * Get the "safe" environment. If we are sending a password to - * the child via a pipe, add the environment variable for that. - */ - env = safe_env(); - if ((pipedef & PASSWD_PIPE) != 0) { - for(i = 0; env[i] != NULL; i++) {} - newenv = (char **)alloc((i + 1 + 1) * sizeof(*newenv)); - ap_snprintf(number, sizeof(number), "%d", passwdpipe[0]); - newenv[0] = vstralloc(passwdvar, "=", number, NULL); - for(i = 0; (newenv[i + 1] = env[i]) != NULL; i++) {} - env = newenv; - } - - execve(prog, argv, env); - e = strerror(errno); - error("error [exec %s: %s]", prog, e); - /* NOTREACHED */ - } + pid = pipespawnv_passwd(prog, pipedef, stdinfd, stdoutfd, stderrfd, argv); + amfree(argv); return pid; } -int pipespawnv(prog, pipedef, stdinfd, stdoutfd, stderrfd, my_argv) -char *prog; -int pipedef; -int *stdinfd, *stdoutfd, *stderrfd; -char **my_argv; +pid_t +pipespawnv( + char * prog, + int pipedef, + int * stdinfd, + int * stdoutfd, + int * stderrfd, + char ** my_argv) +{ + return pipespawnv_passwd(prog, pipedef, stdinfd, stdoutfd, stderrfd, + my_argv); +} + +pid_t +pipespawnv_passwd( + char * prog, + int pipedef, + int * stdinfd, + int * stdoutfd, + int * stderrfd, + char ** my_argv) { int argc; - int pid, i, inpipe[2], outpipe[2], errpipe[2], passwdpipe[2]; - char *passwdvar = NULL; - int *passwdfd = NULL; + pid_t pid; + int i, inpipe[2], outpipe[2], errpipe[2], passwdpipe[2]; char number[NUM_STR_SIZE]; char **arg; char *e; - int ch; char **env; + char *cmdline; + char *quoted; char **newenv; + char *passwdvar = NULL; + int *passwdfd = NULL; /* * Log the command line and count the args. */ - dbprintf(("%s: spawning %s in pipeline\n", debug_prefix_time(NULL), prog)); - dbprintf(("%s: argument list:", debug_prefix(NULL))); if ((pipedef & PASSWD_PIPE) != 0) { passwdvar = *my_argv++; - passwdfd = (int *)*my_argv++; + passwdfd = (int *)*my_argv++; } + memset(inpipe, -1, SIZEOF(inpipe)); + memset(outpipe, -1, SIZEOF(outpipe)); + memset(errpipe, -1, SIZEOF(errpipe)); + memset(passwdpipe, -1, SIZEOF(passwdpipe)); argc = 0; + + cmdline = stralloc(prog); for(arg = my_argv; *arg != NULL; arg++) { - if (*arg == skip_argument) { - continue; - } - argc++; - dbprintf((" ")); - for(i = 0; (ch = (*arg)[i]) != '\0' && isprint(ch) && ch != ' '; i++) {} - if(ch != '\0' || i == 0) { - dbprintf(("\"")); - } - dbprintf(("%s", *arg)); - if(ch != '\0' || i == 0) { - dbprintf(("\"")); + if (*arg != skip_argument) { + argc++; + quoted = quote_string(*arg); + cmdline = vstrextend(&cmdline, " ", quoted, NULL); + amfree(quoted); } } - dbprintf(("\n")); + dbprintf(_("Spawning \"%s\" in pipeline\n"), cmdline); /* * Create the pipes */ if ((pipedef & STDIN_PIPE) != 0) { if(pipe(inpipe) == -1) { - error("error [open pipe to %s: %s]", prog, strerror(errno)); + error(_("error [open pipe to %s: %s]"), prog, strerror(errno)); + /*NOTREACHED*/ } } if ((pipedef & STDOUT_PIPE) != 0) { if(pipe(outpipe) == -1) { - error("error [open pipe to %s: %s]", prog, strerror(errno)); + error(_("error [open pipe to %s: %s]"), prog, strerror(errno)); + /*NOTREACHED*/ } } if ((pipedef & STDERR_PIPE) != 0) { if(pipe(errpipe) == -1) { - error("error [open pipe to %s: %s]", prog, strerror(errno)); + error(_("error [open pipe to %s: %s]"), prog, strerror(errno)); + /*NOTREACHED*/ } } if ((pipedef & PASSWD_PIPE) != 0) { if(pipe(passwdpipe) == -1) { - error("error [open pipe to %s: %s]", prog, strerror(errno)); + error(_("error [open pipe to %s: %s]"), prog, strerror(errno)); + /*NOTREACHED*/ } } @@ -253,7 +147,9 @@ char **my_argv; switch(pid = fork()) { case -1: e = strerror(errno); - error("error [fork %s: %s]", prog, e); + error(_("error [fork %s: %s]"), prog, e); + /*NOTREACHED*/ + default: /* parent process */ if ((pipedef & STDIN_PIPE) != 0) { aclose(inpipe[0]); /* close input side of pipe */ @@ -288,18 +184,24 @@ char **my_argv; } else { errpipe[1] = *stderrfd; } + if ((pipedef & PASSWD_PIPE) != 0) { + aclose(passwdpipe[1]); /* close output side of pipe */ + } /* * Shift the pipes to the standard file descriptors as requested. */ if(dup2(inpipe[0], 0) == -1) { - error("error [spawn %s: dup2 in: %s]", prog, strerror(errno)); + error(_("error [spawn %s: dup2 in: %s]"), prog, strerror(errno)); + /*NOTREACHED*/ } if(dup2(outpipe[1], 1) == -1) { - error("error [spawn %s: dup2 out: %s]", prog, strerror(errno)); + error(_("error [spawn %s: dup2 out: %s]"), prog, strerror(errno)); + /*NOTREACHED*/ } if(dup2(errpipe[1], 2) == -1) { - error("error [spawn %s: dup2 err: %s]", prog, strerror(errno)); + error(_("error [spawn %s: dup2 err: %s]"), prog, strerror(errno)); + /*NOTREACHED*/ } /* @@ -308,18 +210,26 @@ char **my_argv; */ env = safe_env(); if ((pipedef & PASSWD_PIPE) != 0) { - for(i = 0; env[i] != NULL; i++) {} - newenv = (char **)alloc((i + 1 + 1) * sizeof(*newenv)); - ap_snprintf(number, sizeof(number), "%d", passwdpipe[0]); + for (i = 0; env[i] != NULL; i++) + (void)i; /* make lint happy and do nothing */ + newenv = (char **)alloc((i + 1 + 1) * SIZEOF(*newenv)); + g_snprintf(number, SIZEOF(number), "%d", passwdpipe[0]); newenv[0] = vstralloc(passwdvar, "=", number, NULL); - for(i = 0; (newenv[i + 1] = env[i]) != NULL; i++) {} + for(i = 0; env[i] != NULL; i++) + newenv[i + 1] = env[i]; + newenv[i + 1] = NULL; + amfree(env); env = newenv; + safe_fd(passwdpipe[0], 1); + } else { + safe_fd(-1, 0); } execve(prog, my_argv, env); e = strerror(errno); - error("error [exec %s: %s]", prog, e); - /* NOTREACHED */ + error(_("error [exec %s: %s]"), prog, e); + /*NOTREACHED*/ } + amfree(cmdline); return pid; }