mirror of https://github.com/mirror/busybox.git
80 lines
2.0 KiB
C
80 lines
2.0 KiB
C
|
/* vi: set sw=4 ts=4: */
|
||
|
/*
|
||
|
* micro lpd - a small non-queueing lpd
|
||
|
*
|
||
|
* Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com>
|
||
|
*
|
||
|
* 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;
|
||
|
}
|