From 38b8831b3201a9e44cfb156b5b8577e4f5e8d761 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Mon, 25 Feb 2008 14:48:15 +0000 Subject: lpd: now with "svn add"... --- printutils/lpd.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 printutils/lpd.c diff --git a/printutils/lpd.c b/printutils/lpd.c new file mode 100644 index 000000000..ed3d9d100 --- /dev/null +++ b/printutils/lpd.c @@ -0,0 +1,79 @@ +/* vi: set sw=4 ts=4: */ +/* + * micro lpd - a small non-queueing lpd + * + * Copyright (C) 2008 by Vladimir Dronnikov + * + * Licensed under GPLv2, see file LICENSE in this tarball for details. + */ +#include "libbb.h" + +int lpd_main(int argc, char *argv[]) MAIN_EXTERNALLY_VISIBLE; +int lpd_main(int argc, char *argv[]) +{ + char *s; + + // goto spool directory + // spool directory contains either links to real printer devices or just simple files + // these links or files are called "queues" + if (!argv[1]) + bb_show_usage(); + + xchdir(argv[1]); + + xdup2(1, 2); + + // read command + s = xmalloc_reads(STDIN_FILENO, NULL); + + // N.B. we keep things simple + // only "receive job" command is meaningful here... + if (2 == *s) { + char *queue; + + // parse command: "\x2QUEUE_NAME\n" + queue = s + 1; + *strchrnul(s, '\n') = '\0'; + + while (1) { + // signal OK + write(STDOUT_FILENO, "", 1); + // get subcommand + s = xmalloc_reads(STDIN_FILENO, NULL); + if (!s) + return EXIT_SUCCESS; // EOF (probably) + // valid s must be of form: SUBCMD | LEN | SP | FNAME + // N.B. we bail out on any error + // control or data file follows + if (2 == s[0] || 3 == s[0]) { + int fd; + size_t len; + // 2: control file (ignoring), 3: data file + fd = -1; + if (3 == s[0]) + fd = xopen(queue, O_RDWR | O_APPEND); + // get data length + *strchrnul(s, ' ') = '\0'; + len = xatou(s + 1); + // dump exactly len bytes to file, or die + bb_copyfd_exact_size(STDIN_FILENO, fd, len); + close(fd); // NB: can do close(-1). Who cares? + free(s); + // got no ACK? -> bail out + if (safe_read(STDIN_FILENO, s, 1) <= 0 || s[0]) { + // don't talk to peer - it obviously + // don't follow the protocol + return EXIT_FAILURE; + } + } else { + // any other subcommand aborts receiving job + // N.B. abort subcommand itself doesn't contain + // fname so it failed earlier... + break; + } + } + } + + printf("Command %02x not supported\n", (unsigned char)*s); + return EXIT_FAILURE; +} -- cgit v1.2.3