X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=printutils%2Flpd.c;h=43c22948ff868020ced54365edd8df401b348b40;hb=729ecb87bfbbaf9250837d8b8748503c5e97bfd6;hp=f4c902c79719648c46fe9395f91a3181cedc66de;hpb=f39653e3060427b4a48f70e486d7c71729bffd96;p=oweals%2Fbusybox.git diff --git a/printutils/lpd.c b/printutils/lpd.c index f4c902c79..43c22948f 100644 --- a/printutils/lpd.c +++ b/printutils/lpd.c @@ -87,43 +87,6 @@ static char *sane(char *str) return str; } -// we can use leaky setenv since we are about to exec or exit -static void exec_helper(char **filenames, char **argv) ATTRIBUTE_NORETURN; -static void exec_helper(char **filenames, char **argv) -{ - char *p, *q; - char var[2]; - - var[1] = '\0'; - - // read and delete ctrlfile - q = xmalloc_open_read_close(filenames[0], NULL); - unlink(filenames[0]); - // provide datafile name - xsetenv("DATAFILE", filenames[1]); - // parse control file by "\n" - while ((p = strchr(q, '\n')) != NULL - && isalpha(*q) - ) { - *p++ = '\0'; - // q is a line of , - // we are setting environment string =. - // Ignoring "l", exporting others: - if (*q != 'l') { - var[0] = *q++; - xsetenv(var, q); - } - // next line, plz! - q = p; - } - // we are the helper, we wanna be silent. - // this call reopens stdio fds to "/dev/null" - // (no daemonization is done) - bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO | DAEMON_ONLY_SANITIZE, NULL); - BB_EXECVP(*argv, argv); - exit(127); // it IS error if helper cannot be executed! -} - static char *xmalloc_read_stdin(void) { // SECURITY: @@ -132,7 +95,7 @@ static char *xmalloc_read_stdin(void) } int lpd_main(int argc, char *argv[]) MAIN_EXTERNALLY_VISIBLE; -int lpd_main(int argc ATTRIBUTE_UNUSED, char *argv[]) +int lpd_main(int argc UNUSED_PARAM, char *argv[]) { int spooling = spooling; // for compiler char *s, *queue; @@ -184,12 +147,42 @@ int lpd_main(int argc ATTRIBUTE_UNUSED, char *argv[]) // N.B. we bail out on any error s = xmalloc_read_stdin(); if (!s) { // (probably) EOF - if (spooling /* && 7 != spooling - always true */) { - // we didn't see both ctrlfile & datafile! - goto err_exit; + char *p, *q, var[2]; + + // non-spooling mode or no spool helper specified + if (!spooling || !*argv) + return EXIT_SUCCESS; // the only non-error exit + // spooling mode but we didn't see both ctrlfile & datafile + if (spooling != 7) + goto err_exit; // reject job + + // spooling mode and spool helper specified -> exec spool helper + // (we exit 127 if helper cannot be executed) + var[1] = '\0'; + // read and delete ctrlfile + q = xmalloc_xopen_read_close(filenames[0], NULL); + unlink(filenames[0]); + // provide datafile name + // we can use leaky setenv since we are about to exec or exit + xsetenv("DATAFILE", filenames[1]); + // parse control file by "\n" + while ((p = strchr(q, '\n')) != NULL && isalpha(*q)) { + *p++ = '\0'; + // q is a line of , + // we are setting environment string =. + // Ignoring "l", exporting others: + if (*q != 'l') { + var[0] = *q++; + xsetenv(var, q); + } + q = p; // next line } - // one of only two non-error exits - return EXIT_SUCCESS; + // helper should not talk over network. + // this call reopens stdio fds to "/dev/null" + // (no daemonization is done) + bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO | DAEMON_ONLY_SANITIZE, NULL); + BB_EXECVP(*argv, argv); + exit(127); } // validate input. @@ -243,6 +236,9 @@ int lpd_main(int argc ATTRIBUTE_UNUSED, char *argv[]) fd = xopen(queue, O_RDWR | O_APPEND); } + // signal OK + safe_write(STDOUT_FILENO, "", 1); + // copy the file real_len = bb_copyfd_size(STDIN_FILENO, fd, expected_len); if (real_len != expected_len) { @@ -250,7 +246,7 @@ int lpd_main(int argc ATTRIBUTE_UNUSED, char *argv[]) expected_len, real_len); goto err_exit; } - // get ACK and see whether it is NUL (ok) + // get EOF indicator, see whether it is NUL (ok) // (and don't trash s[0]!) if (safe_read(STDIN_FILENO, &s[1], 1) != 1 || s[1] != 0) { // don't send error msg to peer - it obviously @@ -270,13 +266,8 @@ int lpd_main(int argc ATTRIBUTE_UNUSED, char *argv[]) free(s); close(fd); // NB: can do close(-1). Who cares? - // spawn spool helper and exit if all files are dumped - if (7 == spooling && *argv) { - // signal OK - safe_write(STDOUT_FILENO, "", 1); - // does not return (exits 0) - exec_helper(filenames, argv); - } + // NB: don't do "signal OK" write here, it will be done + // at the top of the loop } // while (1) err_exit: