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