1 /*
2 * Line Printer Daemon backend for CUPS.
3 *
4 * Copyright © 2020-2024 by OpenPrinting.
5 * Copyright © 2007-2019 by Apple Inc.
6 * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
7 *
8 * Licensed under Apache License v2.0. See the file "LICENSE" for more
9 * information.
10 */
11
12 /*
13 * Include necessary headers.
14 */
15
16 #include <cups/http-private.h>
17 #include "backend-private.h"
18 #include <stdarg.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <stdio.h>
22
23 #ifdef _WIN32
24 # include <winsock.h>
25 #else
26 # include <sys/socket.h>
27 # include <netinet/in.h>
28 # include <arpa/inet.h>
29 # include <netdb.h>
30 #endif /* _WIN32 */
31 #ifdef __APPLE__
32 # include <CoreFoundation/CFNumber.h>
33 # include <CoreFoundation/CFPreferences.h>
34 #endif /* __APPLE__ */
35
36
37 /*
38 * Globals...
39 */
40
41 static char tmpfilename[1024] = ""; /* Temporary spool file name */
42 static int abort_job = 0; /* Non-zero if we get SIGTERM */
43
44
45 /*
46 * Print mode...
47 */
48
49 #define MODE_STANDARD 0 /* Queue a copy */
50 #define MODE_STREAM 1 /* Stream a copy */
51
52
53 /*
54 * The order for control and data files in LPD requests...
55 */
56
57 #define ORDER_CONTROL_DATA 0 /* Control file first, then data */
58 #define ORDER_DATA_CONTROL 1 /* Data file first, then control */
59
60
61 /*
62 * What to reserve...
63 */
64
65 #define RESERVE_NONE 0 /* Don't reserve a privileged port */
66 #define RESERVE_RFC1179 1 /* Reserve port 721-731 */
67 #define RESERVE_ANY 2 /* Reserve port 512-1023 */
68
69
70 /*
71 * Local functions...
72 */
73
74 static int cups_rresvport(int *port, int min, int family);
75 static int lpd_command(int lpd_fd, char *format, ...)
76 # ifdef __GNUC__
77 __attribute__ ((__format__ (__printf__, 2, 3)))
78 # endif /* __GNUC__ */
79 ;
80 static int lpd_queue(const char *hostname, http_addrlist_t *addrlist, const char *printer, int print_fd, int snmp_fd, int mode, const char *user, const char *title, int copies, int banner, int format, int order, int reserve, int manual_copies, int timeout, int contimeout, const char *orighost) _CUPS_NONNULL((1,2,3,7,8,17));
81 static ssize_t lpd_write(int lpd_fd, char *buffer, size_t length);
82 static void sigterm_handler(int sig);
83
84
85 /*
86 * 'main()' - Send a file to the printer or server.
87 *
88 * Usage:
89 *
90 * printer-uri job-id user title copies options [file]
91 */
92
93 int /* O - Exit status */
main(int argc,char * argv[])94 main(int argc, /* I - Number of command-line arguments (6 or 7) */
95 char *argv[]) /* I - Command-line arguments */
96 {
97 const char *device_uri; /* Device URI */
98 char scheme[255], /* Scheme in URI */
99 hostname[1024], /* Hostname */
100 username[255], /* Username info */
101 resource[1024], /* Resource info (printer name) */
102 *options, /* Pointer to options */
103 *name, /* Name of option */
104 *value, /* Value of option */
105 sep, /* Separator character */
106 title[256]; /* Title string */
107 int port; /* Port number */
108 http_addrlist_t *addrlist; /* List of addresses for printer */
109 int snmp_enabled = 1; /* Is SNMP enabled? */
110 int snmp_fd; /* SNMP socket */
111 int fd; /* Print file */
112 int status; /* Status of LPD job */
113 int mode; /* Print mode */
114 int banner; /* Print banner page? */
115 int format; /* Print format */
116 int order; /* Order of control/data files */
117 int reserve; /* Reserve privileged port? */
118 int sanitize_title; /* Sanitize title string? */
119 int manual_copies, /* Do manual copies? */
120 timeout, /* Timeout */
121 contimeout, /* Connection timeout */
122 copies; /* Number of copies */
123 ssize_t bytes = 0; /* Initial bytes read */
124 char buffer[16384]; /* Initial print buffer */
125 #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
126 struct sigaction action; /* Actions for POSIX signals */
127 #endif /* HAVE_SIGACTION && !HAVE_SIGSET */
128 int num_jobopts; /* Number of job options */
129 cups_option_t *jobopts = NULL; /* Job options */
130
131
132 /*
133 * Make sure status messages are not buffered...
134 */
135
136 setbuf(stderr, NULL);
137
138 /*
139 * Ignore SIGPIPE and catch SIGTERM signals...
140 */
141
142 #ifdef HAVE_SIGSET
143 sigset(SIGPIPE, SIG_IGN);
144 sigset(SIGTERM, sigterm_handler);
145 #elif defined(HAVE_SIGACTION)
146 memset(&action, 0, sizeof(action));
147 action.sa_handler = SIG_IGN;
148 sigaction(SIGPIPE, &action, NULL);
149
150 sigemptyset(&action.sa_mask);
151 sigaddset(&action.sa_mask, SIGTERM);
152 action.sa_handler = sigterm_handler;
153 sigaction(SIGTERM, &action, NULL);
154 #else
155 signal(SIGPIPE, SIG_IGN);
156 signal(SIGTERM, sigterm_handler);
157 #endif /* HAVE_SIGSET */
158
159 /*
160 * Check command-line...
161 */
162
163 if (argc == 1)
164 {
165 printf("network lpd \"Unknown\" \"%s\"\n",
166 _cupsLangString(cupsLangDefault(), _("LPD/LPR Host or Printer")));
167 return (CUPS_BACKEND_OK);
168 }
169 else if (argc != 6 && argc != 7)
170 {
171 _cupsLangPrintf(stderr,
172 _("Usage: %s job-id user title copies options [file]"),
173 argv[0]);
174 return (CUPS_BACKEND_FAILED);
175 }
176
177 num_jobopts = cupsParseOptions(argv[5], 0, &jobopts);
178
179 /*
180 * Extract the hostname and printer name from the URI...
181 */
182
183 while ((device_uri = cupsBackendDeviceURI(argv)) == NULL)
184 {
185 _cupsLangPrintFilter(stderr, "INFO", _("Unable to locate printer."));
186 sleep(10);
187
188 if (getenv("CLASS") != NULL)
189 return (CUPS_BACKEND_FAILED);
190 }
191
192 httpSeparateURI(HTTP_URI_CODING_ALL, device_uri, scheme, sizeof(scheme),
193 username, sizeof(username), hostname, sizeof(hostname), &port,
194 resource, sizeof(resource));
195
196 if (!port)
197 port = 515; /* Default to port 515 */
198
199 if (!username[0])
200 {
201 /*
202 * If no username is in the device URI, then use the print job user...
203 */
204
205 strlcpy(username, argv[2], sizeof(username));
206 }
207
208 /*
209 * See if there are any options...
210 */
211
212 mode = MODE_STANDARD;
213 banner = 0;
214 format = 'l';
215 order = ORDER_CONTROL_DATA;
216 reserve = RESERVE_ANY;
217 manual_copies = 1;
218 timeout = 300;
219 contimeout = 7 * 24 * 60 * 60;
220
221 #ifdef __APPLE__
222 /*
223 * We want to pass UTF-8 characters by default, not re-map them (3071945)
224 */
225
226 sanitize_title = 0;
227 #else
228 /*
229 * Otherwise we want to re-map UTF-8 to "safe" characters by default...
230 */
231
232 sanitize_title = 1;
233 #endif /* __APPLE__ */
234
235 if ((options = strchr(resource, '?')) != NULL)
236 {
237 /*
238 * Yup, terminate the device name string and move to the first
239 * character of the options...
240 */
241
242 *options++ = '\0';
243
244 /*
245 * Parse options...
246 */
247
248 while (*options)
249 {
250 /*
251 * Get the name...
252 */
253
254 name = options;
255
256 while (*options && *options != '=' && *options != '+' && *options != '&')
257 options ++;
258
259 if ((sep = *options) != '\0')
260 *options++ = '\0';
261
262 if (sep == '=')
263 {
264 /*
265 * Get the value...
266 */
267
268 value = options;
269
270 while (*options && *options != '+' && *options != '&')
271 options ++;
272
273 if (*options)
274 *options++ = '\0';
275 }
276 else
277 value = (char *)"";
278
279 /*
280 * Process the option...
281 */
282
283 if (!_cups_strcasecmp(name, "banner"))
284 {
285 /*
286 * Set the banner...
287 */
288
289 banner = !value[0] || !_cups_strcasecmp(value, "on") ||
290 !_cups_strcasecmp(value, "yes") || !_cups_strcasecmp(value, "true");
291 }
292 else if (!_cups_strcasecmp(name, "format") && value[0])
293 {
294 /*
295 * Set output format...
296 */
297
298 if (strchr("cdfglnoprtv", value[0]))
299 format = value[0];
300 else
301 _cupsLangPrintFilter(stderr, "ERROR",
302 _("Unknown format character: \"%c\"."),
303 value[0]);
304 }
305 else if (!_cups_strcasecmp(name, "mode") && value[0])
306 {
307 /*
308 * Set control/data order...
309 */
310
311 if (!_cups_strcasecmp(value, "standard"))
312 mode = MODE_STANDARD;
313 else if (!_cups_strcasecmp(value, "stream"))
314 mode = MODE_STREAM;
315 else
316 _cupsLangPrintFilter(stderr, "ERROR",
317 _("Unknown print mode: \"%s\"."), value);
318 }
319 else if (!_cups_strcasecmp(name, "order") && value[0])
320 {
321 /*
322 * Set control/data order...
323 */
324
325 if (!_cups_strcasecmp(value, "control,data"))
326 order = ORDER_CONTROL_DATA;
327 else if (!_cups_strcasecmp(value, "data,control"))
328 order = ORDER_DATA_CONTROL;
329 else
330 _cupsLangPrintFilter(stderr, "ERROR",
331 _("Unknown file order: \"%s\"."), value);
332 }
333 else if (!_cups_strcasecmp(name, "reserve"))
334 {
335 /*
336 * Set port reservation mode...
337 */
338
339 if (!value[0] || !_cups_strcasecmp(value, "on") ||
340 !_cups_strcasecmp(value, "yes") ||
341 !_cups_strcasecmp(value, "true") ||
342 !_cups_strcasecmp(value, "rfc1179"))
343 reserve = RESERVE_RFC1179;
344 else if (!_cups_strcasecmp(value, "any"))
345 reserve = RESERVE_ANY;
346 else
347 reserve = RESERVE_NONE;
348 }
349 else if (!_cups_strcasecmp(name, "manual_copies"))
350 {
351 /*
352 * Set manual copies...
353 */
354
355 manual_copies = !value[0] || !_cups_strcasecmp(value, "on") ||
356 !_cups_strcasecmp(value, "yes") ||
357 !_cups_strcasecmp(value, "true");
358 }
359 else if (!_cups_strcasecmp(name, "sanitize_title"))
360 {
361 /*
362 * Set sanitize title...
363 */
364
365 sanitize_title = !value[0] || !_cups_strcasecmp(value, "on") ||
366 !_cups_strcasecmp(value, "yes") ||
367 !_cups_strcasecmp(value, "true");
368 }
369 else if (!_cups_strcasecmp(name, "snmp"))
370 {
371 /*
372 * Enable/disable SNMP stuff...
373 */
374
375 snmp_enabled = !value[0] || !_cups_strcasecmp(value, "on") ||
376 !_cups_strcasecmp(value, "yes") ||
377 !_cups_strcasecmp(value, "true");
378 }
379 else if (!_cups_strcasecmp(name, "timeout"))
380 {
381 /*
382 * Set the timeout...
383 */
384
385 if (atoi(value) > 0)
386 timeout = atoi(value);
387 }
388 else if (!_cups_strcasecmp(name, "contimeout"))
389 {
390 /*
391 * Set the connection timeout...
392 */
393
394 if (atoi(value) > 0)
395 contimeout = atoi(value);
396 }
397 }
398 }
399
400 if (mode == MODE_STREAM)
401 order = ORDER_CONTROL_DATA;
402
403 /*
404 * Find the printer...
405 */
406
407 addrlist = backendLookup(hostname, port, NULL);
408
409 /*
410 * See if the printer supports SNMP...
411 */
412
413 if (snmp_enabled)
414 snmp_fd = _cupsSNMPOpen(addrlist->addr.addr.sa_family);
415 else
416 snmp_fd = -1;
417
418 /*
419 * Wait for data from the filter...
420 */
421
422 if (argc == 6)
423 {
424 if (!backendWaitLoop(snmp_fd, &(addrlist->addr), 0, backendNetworkSideCB))
425 return (CUPS_BACKEND_OK);
426 else if (mode == MODE_STANDARD &&
427 (bytes = read(0, buffer, sizeof(buffer))) <= 0)
428 return (CUPS_BACKEND_OK);
429 }
430
431 /*
432 * If we have 7 arguments, print the file named on the command-line.
433 * Otherwise, copy stdin to a temporary file and print the temporary
434 * file.
435 */
436
437 if (argc == 6 && mode == MODE_STANDARD)
438 {
439 /*
440 * Copy stdin to a temporary file...
441 */
442
443 if ((fd = cupsTempFd(tmpfilename, sizeof(tmpfilename))) < 0)
444 {
445 perror("DEBUG: Unable to create temporary file");
446 return (CUPS_BACKEND_FAILED);
447 }
448
449 _cupsLangPrintFilter(stderr, "INFO", _("Copying print data."));
450
451 if (bytes > 0)
452 write(fd, buffer, (size_t)bytes);
453
454 backendRunLoop(-1, fd, snmp_fd, &(addrlist->addr), 0, 0,
455 backendNetworkSideCB);
456 }
457 else if (argc == 6)
458 {
459 /*
460 * Stream from stdin...
461 */
462
463 fd = 0;
464 }
465 else
466 {
467 fd = open(argv[6], O_RDONLY);
468
469 if (fd == -1)
470 {
471 _cupsLangPrintError("ERROR", _("Unable to open print file"));
472 return (CUPS_BACKEND_FAILED);
473 }
474 }
475
476 /*
477 * Sanitize the document title...
478 */
479
480 strlcpy(title, argv[3], sizeof(title));
481
482 if (sanitize_title)
483 {
484 /*
485 * Sanitize the title string so that we don't cause problems on
486 * the remote end...
487 */
488
489 char *ptr;
490
491 for (ptr = title; *ptr; ptr ++)
492 if (!isalnum(*ptr & 255) && !isspace(*ptr & 255))
493 *ptr = '_';
494 }
495
496 /*
497 * Queue the job...
498 */
499
500 if (argc > 6)
501 {
502 if (manual_copies)
503 {
504 manual_copies = atoi(argv[4]);
505 copies = 1;
506 }
507 else
508 {
509 manual_copies = 1;
510 copies = atoi(argv[4]);
511 }
512
513 status = lpd_queue(hostname, addrlist, resource + 1, fd, snmp_fd, mode,
514 username, title, copies, banner, format, order, reserve,
515 manual_copies, timeout, contimeout,
516 cupsGetOption("job-originating-host-name", num_jobopts,
517 jobopts));
518
519 if (!status)
520 fprintf(stderr, "PAGE: 1 %d\n", atoi(argv[4]));
521 }
522 else
523 status = lpd_queue(hostname, addrlist, resource + 1, fd, snmp_fd, mode,
524 username, title, 1, banner, format, order, reserve, 1,
525 timeout, contimeout,
526 cupsGetOption("job-originating-host-name", num_jobopts,
527 jobopts));
528
529 /*
530 * Remove the temporary file if necessary...
531 */
532
533 if (tmpfilename[0])
534 unlink(tmpfilename);
535
536 if (fd)
537 close(fd);
538
539 if (snmp_fd >= 0)
540 _cupsSNMPClose(snmp_fd);
541
542 /*
543 * Return the queue status...
544 */
545
546 return (status);
547 }
548
549
550 /*
551 * 'cups_rresvport()' - A simple implementation of rresvport_af().
552 */
553
554 static int /* O - Socket or -1 on error */
cups_rresvport(int * port,int min,int family)555 cups_rresvport(int *port, /* IO - Port number to bind to */
556 int min, /* I - Minimim port number use */
557 int family) /* I - Address family */
558 {
559 http_addr_t addr; /* Socket address */
560 int fd; /* Socket file descriptor */
561
562
563 /*
564 * Try to create an IPv4 socket...
565 */
566
567 if ((fd = socket(family, SOCK_STREAM, 0)) < 0)
568 return (-1);
569
570 /*
571 * Initialize the address buffer...
572 */
573
574 memset(&addr, 0, sizeof(addr));
575 addr.addr.sa_family = (sa_family_t)family;
576
577 /*
578 * Try to bind the socket to a reserved port...
579 */
580
581 while (*port >= min)
582 {
583 /*
584 * Set the port number...
585 */
586
587 _httpAddrSetPort(&addr, *port);
588
589 /*
590 * Try binding the port to the socket; return if all is OK...
591 */
592
593 if (!bind(fd, (struct sockaddr *)&addr, (socklen_t)httpAddrLength(&addr)))
594 return (fd);
595
596 /*
597 * Stop if we have any error other than "address already in use"...
598 */
599
600 if (errno != EADDRINUSE)
601 {
602 httpAddrClose(NULL, fd);
603
604 return (-1);
605 }
606
607 /*
608 * Try the next port...
609 */
610
611 (*port)--;
612 }
613
614 /*
615 * Wasn't able to bind to a reserved port, so close the socket and return
616 * -1...
617 */
618
619 #ifdef _WIN32
620 closesocket(fd);
621 #else
622 close(fd);
623 #endif /* _WIN32 */
624
625 return (-1);
626 }
627
628
629 /*
630 * 'lpd_command()' - Send an LPR command sequence and wait for a reply.
631 */
632
633 static int /* O - Status of command */
lpd_command(int fd,char * format,...)634 lpd_command(int fd, /* I - Socket connection to LPD host */
635 char *format, /* I - printf()-style format string */
636 ...) /* I - Additional args as necessary */
637 {
638 va_list ap; /* Argument pointer */
639 char buf[1024]; /* Output buffer */
640 ssize_t bytes; /* Number of bytes to output */
641 char status; /* Status from command */
642
643
644 /*
645 * Don't try to send commands if the job has been canceled...
646 */
647
648 if (abort_job)
649 return (-1);
650
651 /*
652 * Format the string...
653 */
654
655 va_start(ap, format);
656 bytes = vsnprintf(buf, sizeof(buf), format, ap);
657 va_end(ap);
658
659 fprintf(stderr, "DEBUG: lpd_command %2.2x %s", buf[0], buf + 1);
660
661 /*
662 * Send the command...
663 */
664
665 fprintf(stderr, "DEBUG: Sending command string (" CUPS_LLFMT " bytes)...\n", CUPS_LLCAST bytes);
666
667 if (lpd_write(fd, buf, (size_t)bytes) < bytes)
668 {
669 perror("DEBUG: Unable to send LPD command");
670 return (-1);
671 }
672
673 /*
674 * Read back the status from the command and return it...
675 */
676
677 fputs("DEBUG: Reading command status...\n", stderr);
678
679 if (recv(fd, &status, 1, 0) < 1)
680 {
681 _cupsLangPrintFilter(stderr, "WARNING", _("The printer did not respond."));
682 status = (char)errno;
683 }
684
685 fprintf(stderr, "DEBUG: lpd_command returning %d\n", status);
686
687 return (status);
688 }
689
690
691 /*
692 * 'lpd_queue()' - Queue a file using the Line Printer Daemon protocol.
693 */
694
695 static int /* O - Zero on success, non-zero on failure */
lpd_queue(const char * hostname,http_addrlist_t * addrlist,const char * printer,int print_fd,int snmp_fd,int mode,const char * user,const char * title,int copies,int banner,int format,int order,int reserve,int manual_copies,int timeout,int contimeout,const char * orighost)696 lpd_queue(const char *hostname, /* I - Host to connect to */
697 http_addrlist_t *addrlist, /* I - List of host addresses */
698 const char *printer, /* I - Printer/queue name */
699 int print_fd, /* I - File to print */
700 int snmp_fd, /* I - SNMP socket */
701 int mode, /* I - Print mode */
702 const char *user, /* I - Requesting user */
703 const char *title, /* I - Job title */
704 int copies, /* I - Number of copies */
705 int banner, /* I - Print LPD banner? */
706 int format, /* I - Format specifier */
707 int order, /* I - Order of data/control files */
708 int reserve, /* I - Reserve ports? */
709 int manual_copies,/* I - Do copies by hand... */
710 int timeout, /* I - Timeout... */
711 int contimeout, /* I - Connection timeout */
712 const char *orighost) /* I - job-originating-host-name */
713 {
714 char localhost[255]; /* Local host name */
715 int error; /* Error number */
716 struct stat filestats; /* File statistics */
717 int lport; /* LPD connection local port */
718 int fd; /* LPD socket */
719 char control[10240], /* LPD control 'file' */
720 *cptr; /* Pointer into control file string */
721 char status; /* Status byte from command */
722 int delay; /* Delay for retries... */
723 char addrname[256]; /* Address name */
724 http_addrlist_t *addr; /* Socket address */
725 int have_supplies; /* Printer supports supply levels? */
726 int copy; /* Copies written */
727 time_t start_time; /* Time of first connect */
728 ssize_t nbytes; /* Number of bytes written */
729 off_t tbytes; /* Total bytes written */
730 char buffer[32768]; /* Output buffer */
731 #ifdef _WIN32
732 DWORD tv; /* Timeout in milliseconds */
733 #else
734 struct timeval tv; /* Timeout in secs and usecs */
735 #endif /* _WIN32 */
736
737
738 /*
739 * Remember when we started trying to connect to the printer...
740 */
741
742 start_time = time(NULL);
743
744 /*
745 * Loop forever trying to print the file...
746 */
747
748 while (!abort_job)
749 {
750 /*
751 * First try to reserve a port for this connection...
752 */
753
754 fprintf(stderr, "DEBUG: Connecting to %s:%d for printer %s\n", hostname,
755 httpAddrPort(&(addrlist->addr)), printer);
756 _cupsLangPrintFilter(stderr, "INFO", _("Connecting to printer."));
757
758 for (lport = reserve == RESERVE_RFC1179 ? 732 : 1024, addr = addrlist,
759 delay = 5;;
760 addr = addr->next)
761 {
762 /*
763 * Stop if this job has been canceled...
764 */
765
766 if (abort_job)
767 return (CUPS_BACKEND_FAILED);
768
769 /*
770 * Choose the next privileged port...
771 */
772
773 if (!addr)
774 addr = addrlist;
775
776 lport --;
777
778 if (lport < 721 && reserve == RESERVE_RFC1179)
779 lport = 731;
780 else if (lport < 512)
781 lport = 1023;
782
783 #ifdef HAVE_GETEUID
784 if (geteuid() || !reserve)
785 #else
786 if (getuid() || !reserve)
787 #endif /* HAVE_GETEUID */
788 {
789 /*
790 * Just create a regular socket...
791 */
792
793 if ((fd = socket(addr->addr.addr.sa_family, SOCK_STREAM, 0)) < 0)
794 {
795 perror("DEBUG: Unable to create socket");
796 sleep(1);
797
798 continue;
799 }
800
801 lport = 0;
802 }
803 else
804 {
805 /*
806 * We're running as root and want to either:
807 * a) comply with RFC 1179 and reserve a lport between 721 and 731
808 * b) just reserve a privileged port between 512 and 1023
809 */
810
811 if ((fd = cups_rresvport(&lport,
812 reserve == RESERVE_RFC1179 ? 721 : 512,
813 addr->addr.addr.sa_family)) < 0)
814 {
815 perror("DEBUG: Unable to reserve port");
816 sleep(1);
817
818 continue;
819 }
820 }
821
822 /*
823 * Connect to the printer or server...
824 */
825
826 if (abort_job)
827 {
828 close(fd);
829
830 return (CUPS_BACKEND_FAILED);
831 }
832
833 if (!connect(fd, &(addr->addr.addr), (socklen_t)httpAddrLength(&(addr->addr))))
834 break;
835
836 error = errno;
837 close(fd);
838
839 if (addr->next)
840 continue;
841
842 if (getenv("CLASS") != NULL)
843 {
844 /*
845 * If the CLASS environment variable is set, the job was submitted
846 * to a class and not to a specific queue. In this case, we want
847 * to abort immediately so that the job can be requeued on the next
848 * available printer in the class.
849 */
850
851 _cupsLangPrintFilter(stderr, "INFO",
852 _("Unable to contact printer, queuing on next "
853 "printer in class."));
854
855 /*
856 * Sleep 5 seconds to keep the job from requeuing too rapidly...
857 */
858
859 sleep(5);
860
861 return (CUPS_BACKEND_FAILED);
862 }
863
864 fprintf(stderr, "DEBUG: Connection error: %s\n", strerror(error));
865
866 if (errno == ECONNREFUSED || errno == EHOSTDOWN || errno == EHOSTUNREACH || errno == ETIMEDOUT || errno == ENOTCONN)
867 {
868 if (contimeout && (time(NULL) - start_time) > contimeout)
869 {
870 _cupsLangPrintFilter(stderr, "ERROR",
871 _("The printer is not responding."));
872 return (CUPS_BACKEND_FAILED);
873 }
874
875 switch (error)
876 {
877 case EHOSTDOWN :
878 _cupsLangPrintFilter(stderr, "WARNING",
879 _("The printer may not exist or "
880 "is unavailable at this time."));
881 break;
882
883 case EHOSTUNREACH :
884 default :
885 _cupsLangPrintFilter(stderr, "WARNING",
886 _("The printer is unreachable at "
887 "this time."));
888 break;
889
890 case ECONNREFUSED :
891 _cupsLangPrintFilter(stderr, "WARNING",
892 _("The printer is in use."));
893 break;
894 }
895
896 sleep((unsigned)delay);
897
898 if (delay < 30)
899 delay += 5;
900 }
901 else if (error == EADDRINUSE)
902 {
903 /*
904 * Try on another port...
905 */
906
907 sleep(1);
908 }
909 else
910 {
911 _cupsLangPrintFilter(stderr, "ERROR",
912 _("The printer is not responding."));
913 sleep(30);
914 }
915 }
916
917 /*
918 * Set the timeout...
919 */
920
921 #ifdef _WIN32
922 tv = (DWORD)(timeout * 1000);
923
924 setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
925 setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv));
926 #else
927 tv.tv_sec = timeout;
928 tv.tv_usec = 0;
929
930 setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
931 setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
932 #endif /* _WIN32 */
933
934 fputs("STATE: -connecting-to-device\n", stderr);
935 _cupsLangPrintFilter(stderr, "INFO", _("Connected to printer."));
936
937 fprintf(stderr, "DEBUG: Connected to %s:%d (local port %d)...\n",
938 httpAddrString(&(addr->addr), addrname, sizeof(addrname)),
939 httpAddrPort(&(addr->addr)), lport);
940
941 /*
942 * See if the printer supports SNMP...
943 */
944
945 if (snmp_fd >= 0)
946 have_supplies = !backendSNMPSupplies(snmp_fd, &(addrlist->addr), NULL,
947 NULL);
948 else
949 have_supplies = 0;
950
951 /*
952 * Check for side-channel requests...
953 */
954
955 backendCheckSideChannel(snmp_fd, &(addrlist->addr));
956
957 /*
958 * Next, open the print file and figure out its size...
959 */
960
961 if (print_fd)
962 {
963 /*
964 * Use the size from the print file...
965 */
966
967 if (fstat(print_fd, &filestats))
968 {
969 close(fd);
970
971 perror("DEBUG: unable to stat print file");
972 return (CUPS_BACKEND_FAILED);
973 }
974
975 filestats.st_size *= manual_copies;
976 }
977 else
978 {
979 /*
980 * Use a "very large value" for the size so that the printer will
981 * keep printing until we close the connection...
982 */
983
984 #ifdef _LARGEFILE_SOURCE
985 filestats.st_size = (size_t)(999999999999.0);
986 #else
987 filestats.st_size = 2147483647;
988 #endif /* _LARGEFILE_SOURCE */
989 }
990
991 /*
992 * Send a job header to the printer, specifying no banner page and
993 * literal output...
994 */
995
996 if (lpd_command(fd, "\002%s\n",
997 printer)) /* Receive print job(s) */
998 {
999 close(fd);
1000 return (CUPS_BACKEND_FAILED);
1001 }
1002
1003 if (orighost && _cups_strcasecmp(orighost, "localhost"))
1004 strlcpy(localhost, orighost, sizeof(localhost));
1005 else
1006 httpGetHostname(NULL, localhost, sizeof(localhost));
1007
1008 snprintf(control, sizeof(control),
1009 "H%.31s\n" /* RFC 1179, Section 7.2 - host name <= 31 chars */
1010 "P%.31s\n" /* RFC 1179, Section 7.2 - user name <= 31 chars */
1011 "J%.99s\n", /* RFC 1179, Section 7.2 - job name <= 99 chars */
1012 localhost, user, title);
1013 cptr = control + strlen(control);
1014
1015 if (banner)
1016 {
1017 snprintf(cptr, sizeof(control) - (size_t)(cptr - control),
1018 "C%.31s\n" /* RFC 1179, Section 7.2 - class name <= 31 chars */
1019 "L%s\n",
1020 localhost, user);
1021 cptr += strlen(cptr);
1022 }
1023
1024 while (copies > 0)
1025 {
1026 snprintf(cptr, sizeof(control) - (size_t)(cptr - control), "%cdfA%03d%.15s\n",
1027 format, (int)getpid() % 1000, localhost);
1028 cptr += strlen(cptr);
1029 copies --;
1030 }
1031
1032 snprintf(cptr, sizeof(control) - (size_t)(cptr - control),
1033 "UdfA%03d%.15s\n"
1034 "N%.131s\n", /* RFC 1179, Section 7.2 - sourcefile name <= 131 chars */
1035 (int)getpid() % 1000, localhost, title);
1036
1037 fprintf(stderr, "DEBUG: Control file is:\n%s", control);
1038
1039 if (order == ORDER_CONTROL_DATA)
1040 {
1041 /*
1042 * Check for side-channel requests...
1043 */
1044
1045 backendCheckSideChannel(snmp_fd, &(addr->addr));
1046
1047 /*
1048 * Send the control file...
1049 */
1050
1051 if (lpd_command(fd, "\002%u cfA%03d%.15s\n", (unsigned)strlen(control),
1052 (int)getpid() % 1000, localhost))
1053 {
1054 close(fd);
1055
1056 return (CUPS_BACKEND_FAILED);
1057 }
1058
1059 fprintf(stderr, "DEBUG: Sending control file (%u bytes)\n",
1060 (unsigned)strlen(control));
1061
1062 if ((size_t)lpd_write(fd, control, strlen(control) + 1) < (strlen(control) + 1))
1063 {
1064 status = (char)errno;
1065 perror("DEBUG: Unable to write control file");
1066
1067 }
1068 else
1069 {
1070 if (read(fd, &status, 1) < 1)
1071 {
1072 _cupsLangPrintFilter(stderr, "WARNING",
1073 _("The printer did not respond."));
1074 status = (char)errno;
1075 }
1076 }
1077
1078 if (status != 0)
1079 _cupsLangPrintFilter(stderr, "ERROR",
1080 _("Remote host did not accept control file (%d)."),
1081 status);
1082 else
1083 _cupsLangPrintFilter(stderr, "INFO",
1084 _("Control file sent successfully."));
1085 }
1086 else
1087 status = 0;
1088
1089 if (status == 0)
1090 {
1091 /*
1092 * Check for side-channel requests...
1093 */
1094
1095 backendCheckSideChannel(snmp_fd, &(addr->addr));
1096
1097 /*
1098 * Send the print file...
1099 */
1100
1101 if (lpd_command(fd, "\003" CUPS_LLFMT " dfA%03d%.15s\n",
1102 CUPS_LLCAST filestats.st_size, (int)getpid() % 1000,
1103 localhost))
1104 {
1105 close(fd);
1106
1107 return (CUPS_BACKEND_FAILED);
1108 }
1109
1110 fprintf(stderr, "DEBUG: Sending data file (" CUPS_LLFMT " bytes)\n",
1111 CUPS_LLCAST filestats.st_size);
1112
1113 tbytes = 0;
1114 for (copy = 0; copy < manual_copies; copy ++)
1115 {
1116 lseek(print_fd, 0, SEEK_SET);
1117
1118 while ((nbytes = read(print_fd, buffer, sizeof(buffer))) > 0)
1119 {
1120 _cupsLangPrintFilter(stderr, "INFO",
1121 _("Spooling job, %.0f%% complete."),
1122 100.0 * tbytes / filestats.st_size);
1123
1124 if (lpd_write(fd, buffer, (size_t)nbytes) < nbytes)
1125 {
1126 perror("DEBUG: Unable to send print file to printer");
1127 break;
1128 }
1129 else
1130 tbytes += nbytes;
1131 }
1132 }
1133
1134 if (mode == MODE_STANDARD)
1135 {
1136 if (tbytes < filestats.st_size)
1137 status = (char)errno;
1138 else if (lpd_write(fd, "", 1) < 1)
1139 {
1140 perror("DEBUG: Unable to send trailing nul to printer");
1141 status = (char)errno;
1142 }
1143 else
1144 {
1145 /*
1146 * Read the status byte from the printer; if we can't read the byte
1147 * back now, we should set status to "errno", however at this point
1148 * we know the printer got the whole file and we don't necessarily
1149 * want to requeue it over and over...
1150 */
1151
1152 if (recv(fd, &status, 1, 0) < 1)
1153 {
1154 _cupsLangPrintFilter(stderr, "WARNING",
1155 _("The printer did not respond."));
1156 status = 0;
1157 }
1158 }
1159 }
1160 else
1161 status = 0;
1162
1163 if (status != 0)
1164 _cupsLangPrintFilter(stderr, "ERROR",
1165 _("Remote host did not accept data file (%d)."),
1166 status);
1167 else
1168 _cupsLangPrintFilter(stderr, "INFO",
1169 _("Data file sent successfully."));
1170 }
1171
1172 if (status == 0 && order == ORDER_DATA_CONTROL)
1173 {
1174 /*
1175 * Check for side-channel requests...
1176 */
1177
1178 backendCheckSideChannel(snmp_fd, &(addr->addr));
1179
1180 /*
1181 * Send control file...
1182 */
1183
1184 if (lpd_command(fd, "\002%u cfA%03d%.15s\n", (unsigned)strlen(control),
1185 (int)getpid() % 1000, localhost))
1186 {
1187 close(fd);
1188
1189 return (CUPS_BACKEND_FAILED);
1190 }
1191
1192 fprintf(stderr, "DEBUG: Sending control file (%u bytes)\n",
1193 (unsigned)strlen(control));
1194
1195 if ((size_t)lpd_write(fd, control, strlen(control) + 1) < (strlen(control) + 1))
1196 {
1197 status = (char)errno;
1198 perror("DEBUG: Unable to write control file");
1199 }
1200 else
1201 {
1202 if (read(fd, &status, 1) < 1)
1203 {
1204 _cupsLangPrintFilter(stderr, "WARNING",
1205 _("The printer did not respond."));
1206 status = (char)errno;
1207 }
1208 }
1209
1210 if (status != 0)
1211 _cupsLangPrintFilter(stderr, "ERROR",
1212 _("Remote host did not accept control file (%d)."),
1213 status);
1214 else
1215 _cupsLangPrintFilter(stderr, "INFO",
1216 _("Control file sent successfully."));
1217 }
1218
1219 fputs("STATE: +cups-waiting-for-job-completed\n", stderr);
1220
1221 /*
1222 * Collect the final supply levels as needed...
1223 */
1224
1225 if (have_supplies)
1226 backendSNMPSupplies(snmp_fd, &(addr->addr), NULL, NULL);
1227
1228 /*
1229 * Close the socket connection and input file...
1230 */
1231
1232 close(fd);
1233
1234 if (status == 0)
1235 return (CUPS_BACKEND_OK);
1236
1237 /*
1238 * Waiting for a retry...
1239 */
1240
1241 sleep(30);
1242 }
1243
1244 /*
1245 * If we get here, then the job has been canceled...
1246 */
1247
1248 return (CUPS_BACKEND_FAILED);
1249 }
1250
1251
1252 /*
1253 * 'lpd_write()' - Write a buffer of data to an LPD server.
1254 */
1255
1256 static ssize_t /* O - Number of bytes written or -1 on error */
lpd_write(int lpd_fd,char * buffer,size_t length)1257 lpd_write(int lpd_fd, /* I - LPD socket */
1258 char *buffer, /* I - Buffer to write */
1259 size_t length) /* I - Number of bytes to write */
1260 {
1261 ssize_t bytes, /* Number of bytes written */
1262 total; /* Total number of bytes written */
1263
1264
1265 if (abort_job)
1266 return (-1);
1267
1268 total = 0;
1269 while ((bytes = send(lpd_fd, buffer, length - (size_t)total, 0)) >= 0)
1270 {
1271 total += bytes;
1272 buffer += bytes;
1273
1274 if ((size_t)total == length)
1275 break;
1276 }
1277
1278 if (bytes < 0)
1279 return (-1);
1280 else
1281 return (total);
1282 }
1283
1284
1285 /*
1286 * 'sigterm_handler()' - Handle 'terminate' signals that stop the backend.
1287 */
1288
1289 static void
sigterm_handler(int sig)1290 sigterm_handler(int sig) /* I - Signal */
1291 {
1292 (void)sig; /* remove compiler warnings... */
1293
1294 abort_job = 1;
1295 }
1296