]>
git.ipfire.org Git - thirdparty/cups.git/blob - backend/lpd.c
2 * Line Printer Daemon backend for CUPS.
4 * Copyright © 2007-2019 by Apple Inc.
5 * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more
12 * Include necessary headers.
15 #include <cups/http-private.h>
16 #include "backend-private.h"
18 #include <sys/types.h>
25 # include <sys/socket.h>
26 # include <netinet/in.h>
27 # include <arpa/inet.h>
31 # include <CoreFoundation/CFNumber.h>
32 # include <CoreFoundation/CFPreferences.h>
33 #endif /* __APPLE__ */
40 static char tmpfilename
[1024] = ""; /* Temporary spool file name */
41 static int abort_job
= 0; /* Non-zero if we get SIGTERM */
48 #define MODE_STANDARD 0 /* Queue a copy */
49 #define MODE_STREAM 1 /* Stream a copy */
53 * The order for control and data files in LPD requests...
56 #define ORDER_CONTROL_DATA 0 /* Control file first, then data */
57 #define ORDER_DATA_CONTROL 1 /* Data file first, then control */
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 */
73 static int cups_rresvport(int *port
, int family
);
74 static int lpd_command(int lpd_fd
, char *format
, ...)
76 __attribute__ ((__format__ (__printf__
, 2, 3)))
77 # endif /* __GNUC__ */
79 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));
80 static ssize_t
lpd_write(int lpd_fd
, char *buffer
, size_t length
);
81 static void sigterm_handler(int sig
);
85 * 'main()' - Send a file to the printer or server.
89 * printer-uri job-id user title copies options [file]
92 int /* O - Exit status */
93 main(int argc
, /* I - Number of command-line arguments (6 or 7) */
94 char *argv
[]) /* I - Command-line arguments */
96 const char *device_uri
; /* Device URI */
97 char scheme
[255], /* Scheme in URI */
98 hostname
[1024], /* Hostname */
99 username
[255], /* Username info */
100 resource
[1024], /* Resource info (printer name) */
101 *options
, /* Pointer to options */
102 *name
, /* Name of option */
103 *value
, /* Value of option */
104 sep
, /* Separator character */
105 *filename
, /* File to print */
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 priviledged 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 */
133 * Make sure status messages are not buffered...
136 setbuf(stderr
, NULL
);
139 * Ignore SIGPIPE and catch SIGTERM signals...
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
);
150 sigemptyset(&action
.sa_mask
);
151 sigaddset(&action
.sa_mask
, SIGTERM
);
152 action
.sa_handler
= sigterm_handler
;
153 sigaction(SIGTERM
, &action
, NULL
);
155 signal(SIGPIPE
, SIG_IGN
);
156 signal(SIGTERM
, sigterm_handler
);
157 #endif /* HAVE_SIGSET */
160 * Check command-line...
165 printf("network lpd \"Unknown\" \"%s\"\n",
166 _cupsLangString(cupsLangDefault(), _("LPD/LPR Host or Printer")));
167 return (CUPS_BACKEND_OK
);
169 else if (argc
< 6 || argc
> 7)
171 _cupsLangPrintf(stderr
,
172 _("Usage: %s job-id user title copies options [file]"),
174 return (CUPS_BACKEND_FAILED
);
177 num_jobopts
= cupsParseOptions(argv
[5], 0, &jobopts
);
180 * Extract the hostname and printer name from the URI...
183 while ((device_uri
= cupsBackendDeviceURI(argv
)) == NULL
)
185 _cupsLangPrintFilter(stderr
, "INFO", _("Unable to locate printer."));
188 if (getenv("CLASS") != NULL
)
189 return (CUPS_BACKEND_FAILED
);
192 httpSeparateURI(HTTP_URI_CODING_ALL
, device_uri
, scheme
, sizeof(scheme
),
193 username
, sizeof(username
), hostname
, sizeof(hostname
), &port
,
194 resource
, sizeof(resource
));
197 port
= 515; /* Default to port 515 */
202 * If no username is in the device URI, then use the print job user...
205 strlcpy(username
, argv
[2], sizeof(username
));
209 * See if there are any options...
212 mode
= MODE_STANDARD
;
215 order
= ORDER_CONTROL_DATA
;
216 reserve
= RESERVE_ANY
;
219 contimeout
= 7 * 24 * 60 * 60;
223 * We want to pass UTF-8 characters by default, not re-map them (3071945)
229 * Otherwise we want to re-map UTF-8 to "safe" characters by default...
233 #endif /* __APPLE__ */
235 if ((options
= strchr(resource
, '?')) != NULL
)
238 * Yup, terminate the device name string and move to the first
239 * character of the options...
256 while (*options
&& *options
!= '=' && *options
!= '+' && *options
!= '&')
259 if ((sep
= *options
) != '\0')
270 while (*options
&& *options
!= '+' && *options
!= '&')
280 * Process the option...
283 if (!_cups_strcasecmp(name
, "banner"))
289 banner
= !value
[0] || !_cups_strcasecmp(value
, "on") ||
290 !_cups_strcasecmp(value
, "yes") || !_cups_strcasecmp(value
, "true");
292 else if (!_cups_strcasecmp(name
, "format") && value
[0])
295 * Set output format...
298 if (strchr("cdfglnoprtv", value
[0]))
301 _cupsLangPrintFilter(stderr
, "ERROR",
302 _("Unknown format character: \"%c\"."),
305 else if (!_cups_strcasecmp(name
, "mode") && value
[0])
308 * Set control/data order...
311 if (!_cups_strcasecmp(value
, "standard"))
312 mode
= MODE_STANDARD
;
313 else if (!_cups_strcasecmp(value
, "stream"))
316 _cupsLangPrintFilter(stderr
, "ERROR",
317 _("Unknown print mode: \"%s\"."), value
);
319 else if (!_cups_strcasecmp(name
, "order") && value
[0])
322 * Set control/data order...
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
;
330 _cupsLangPrintFilter(stderr
, "ERROR",
331 _("Unknown file order: \"%s\"."), value
);
333 else if (!_cups_strcasecmp(name
, "reserve"))
336 * Set port reservation mode...
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
;
347 reserve
= RESERVE_NONE
;
349 else if (!_cups_strcasecmp(name
, "manual_copies"))
352 * Set manual copies...
355 manual_copies
= !value
[0] || !_cups_strcasecmp(value
, "on") ||
356 !_cups_strcasecmp(value
, "yes") ||
357 !_cups_strcasecmp(value
, "true");
359 else if (!_cups_strcasecmp(name
, "sanitize_title"))
362 * Set sanitize title...
365 sanitize_title
= !value
[0] || !_cups_strcasecmp(value
, "on") ||
366 !_cups_strcasecmp(value
, "yes") ||
367 !_cups_strcasecmp(value
, "true");
369 else if (!_cups_strcasecmp(name
, "snmp"))
372 * Enable/disable SNMP stuff...
375 snmp_enabled
= !value
[0] || !_cups_strcasecmp(value
, "on") ||
376 !_cups_strcasecmp(value
, "yes") ||
377 !_cups_strcasecmp(value
, "true");
379 else if (!_cups_strcasecmp(name
, "timeout"))
386 timeout
= atoi(value
);
388 else if (!_cups_strcasecmp(name
, "contimeout"))
391 * Set the connection timeout...
395 contimeout
= atoi(value
);
400 if (mode
== MODE_STREAM
)
401 order
= ORDER_CONTROL_DATA
;
404 * Find the printer...
407 addrlist
= backendLookup(hostname
, port
, NULL
);
410 * See if the printer supports SNMP...
414 snmp_fd
= _cupsSNMPOpen(addrlist
->addr
.addr
.sa_family
);
419 * Wait for data from the filter...
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
);
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
437 if (argc
== 6 && mode
== MODE_STANDARD
)
440 * Copy stdin to a temporary file...
443 if ((fd
= cupsTempFd(tmpfilename
, sizeof(tmpfilename
))) < 0)
445 perror("DEBUG: Unable to create temporary file");
446 return (CUPS_BACKEND_FAILED
);
449 _cupsLangPrintFilter(stderr
, "INFO", _("Copying print data."));
452 write(fd
, buffer
, (size_t)bytes
);
454 backendRunLoop(-1, fd
, snmp_fd
, &(addrlist
->addr
), 0, 0,
455 backendNetworkSideCB
);
460 * Stream from stdin...
469 fd
= open(filename
, O_RDONLY
);
473 _cupsLangPrintError("ERROR", _("Unable to open print file"));
474 return (CUPS_BACKEND_FAILED
);
479 * Sanitize the document title...
482 strlcpy(title
, argv
[3], sizeof(title
));
487 * Sanitize the title string so that we don't cause problems on
493 for (ptr
= title
; *ptr
; ptr
++)
494 if (!isalnum(*ptr
& 255) && !isspace(*ptr
& 255))
506 manual_copies
= atoi(argv
[4]);
512 copies
= atoi(argv
[4]);
515 status
= lpd_queue(hostname
, addrlist
, resource
+ 1, fd
, snmp_fd
, mode
,
516 username
, title
, copies
, banner
, format
, order
, reserve
,
517 manual_copies
, timeout
, contimeout
,
518 cupsGetOption("job-originating-host-name", num_jobopts
,
522 fprintf(stderr
, "PAGE: 1 %d\n", atoi(argv
[4]));
525 status
= lpd_queue(hostname
, addrlist
, resource
+ 1, fd
, snmp_fd
, mode
,
526 username
, title
, 1, banner
, format
, order
, reserve
, 1,
528 cupsGetOption("job-originating-host-name", num_jobopts
,
532 * Remove the temporary file if necessary...
542 _cupsSNMPClose(snmp_fd
);
545 * Return the queue status...
553 * 'cups_rresvport()' - A simple implementation of rresvport_af().
556 static int /* O - Socket or -1 on error */
557 cups_rresvport(int *port
, /* IO - Port number to bind to */
558 int family
) /* I - Address family */
560 http_addr_t addr
; /* Socket address */
561 int fd
; /* Socket file descriptor */
565 * Try to create an IPv4 socket...
568 if ((fd
= socket(family
, SOCK_STREAM
, 0)) < 0)
572 * Initialize the address buffer...
575 memset(&addr
, 0, sizeof(addr
));
576 addr
.addr
.sa_family
= (sa_family_t
)family
;
579 * Try to bind the socket to a reserved port...
585 * Set the port number...
588 _httpAddrSetPort(&addr
, *port
);
591 * Try binding the port to the socket; return if all is OK...
594 if (!bind(fd
, (struct sockaddr
*)&addr
, (socklen_t
)httpAddrLength(&addr
)))
598 * Stop if we have any error other than "address already in use"...
601 if (errno
!= EADDRINUSE
)
603 httpAddrClose(NULL
, fd
);
609 * Try the next port...
616 * Wasn't able to bind to a reserved port, so close the socket and return
631 * 'lpd_command()' - Send an LPR command sequence and wait for a reply.
634 static int /* O - Status of command */
635 lpd_command(int fd
, /* I - Socket connection to LPD host */
636 char *format
, /* I - printf()-style format string */
637 ...) /* I - Additional args as necessary */
639 va_list ap
; /* Argument pointer */
640 char buf
[1024]; /* Output buffer */
641 ssize_t bytes
; /* Number of bytes to output */
642 char status
; /* Status from command */
646 * Don't try to send commands if the job has been canceled...
653 * Format the string...
656 va_start(ap
, format
);
657 bytes
= vsnprintf(buf
, sizeof(buf
), format
, ap
);
660 fprintf(stderr
, "DEBUG: lpd_command %2.2x %s", buf
[0], buf
+ 1);
663 * Send the command...
666 fprintf(stderr
, "DEBUG: Sending command string (" CUPS_LLFMT
" bytes)...\n", CUPS_LLCAST bytes
);
668 if (lpd_write(fd
, buf
, (size_t)bytes
) < bytes
)
670 perror("DEBUG: Unable to send LPD command");
675 * Read back the status from the command and return it...
678 fputs("DEBUG: Reading command status...\n", stderr
);
680 if (recv(fd
, &status
, 1, 0) < 1)
682 _cupsLangPrintFilter(stderr
, "WARNING", _("The printer did not respond."));
683 status
= (char)errno
;
686 fprintf(stderr
, "DEBUG: lpd_command returning %d\n", status
);
693 * 'lpd_queue()' - Queue a file using the Line Printer Daemon protocol.
696 static int /* O - Zero on success, non-zero on failure */
697 lpd_queue(const char *hostname
, /* I - Host to connect to */
698 http_addrlist_t
*addrlist
, /* I - List of host addresses */
699 const char *printer
, /* I - Printer/queue name */
700 int print_fd
, /* I - File to print */
701 int snmp_fd
, /* I - SNMP socket */
702 int mode
, /* I - Print mode */
703 const char *user
, /* I - Requesting user */
704 const char *title
, /* I - Job title */
705 int copies
, /* I - Number of copies */
706 int banner
, /* I - Print LPD banner? */
707 int format
, /* I - Format specifier */
708 int order
, /* I - Order of data/control files */
709 int reserve
, /* I - Reserve ports? */
710 int manual_copies
,/* I - Do copies by hand... */
711 int timeout
, /* I - Timeout... */
712 int contimeout
, /* I - Connection timeout */
713 const char *orighost
) /* I - job-originating-host-name */
715 char localhost
[255]; /* Local host name */
716 int error
; /* Error number */
717 struct stat filestats
; /* File statistics */
718 int lport
; /* LPD connection local port */
719 int fd
; /* LPD socket */
720 char control
[10240], /* LPD control 'file' */
721 *cptr
; /* Pointer into control file string */
722 char status
; /* Status byte from command */
723 int delay
; /* Delay for retries... */
724 char addrname
[256]; /* Address name */
725 http_addrlist_t
*addr
; /* Socket address */
726 int have_supplies
; /* Printer supports supply levels? */
727 int copy
; /* Copies written */
728 time_t start_time
; /* Time of first connect */
729 ssize_t nbytes
; /* Number of bytes written */
730 off_t tbytes
; /* Total bytes written */
731 char buffer
[32768]; /* Output buffer */
733 DWORD tv
; /* Timeout in milliseconds */
735 struct timeval tv
; /* Timeout in secs and usecs */
740 * Remember when we started trying to connect to the printer...
743 start_time
= time(NULL
);
746 * Loop forever trying to print the file...
752 * First try to reserve a port for this connection...
755 fprintf(stderr
, "DEBUG: Connecting to %s:%d for printer %s\n", hostname
,
756 httpAddrPort(&(addrlist
->addr
)), printer
);
757 _cupsLangPrintFilter(stderr
, "INFO", _("Connecting to printer."));
759 for (lport
= reserve
== RESERVE_RFC1179
? 732 : 1024, addr
= addrlist
,
764 * Stop if this job has been canceled...
768 return (CUPS_BACKEND_FAILED
);
771 * Choose the next priviledged port...
779 if (lport
< 721 && reserve
== RESERVE_RFC1179
)
785 if (geteuid() || !reserve
)
787 if (getuid() || !reserve
)
788 #endif /* HAVE_GETEUID */
791 * Just create a regular socket...
794 if ((fd
= socket(addr
->addr
.addr
.sa_family
, SOCK_STREAM
, 0)) < 0)
796 perror("DEBUG: Unable to create socket");
807 * We're running as root and want to comply with RFC 1179. Reserve a
808 * priviledged lport between 721 and 731...
811 if ((fd
= cups_rresvport(&lport
, addr
->addr
.addr
.sa_family
)) < 0)
813 perror("DEBUG: Unable to reserve port");
821 * Connect to the printer or server...
828 return (CUPS_BACKEND_FAILED
);
831 if (!connect(fd
, &(addr
->addr
.addr
), (socklen_t
)httpAddrLength(&(addr
->addr
))))
840 if (getenv("CLASS") != NULL
)
843 * If the CLASS environment variable is set, the job was submitted
844 * to a class and not to a specific queue. In this case, we want
845 * to abort immediately so that the job can be requeued on the next
846 * available printer in the class.
849 _cupsLangPrintFilter(stderr
, "INFO",
850 _("Unable to contact printer, queuing on next "
851 "printer in class."));
854 * Sleep 5 seconds to keep the job from requeuing too rapidly...
859 return (CUPS_BACKEND_FAILED
);
862 fprintf(stderr
, "DEBUG: Connection error: %s\n", strerror(error
));
864 if (errno
== ECONNREFUSED
|| errno
== EHOSTDOWN
|| errno
== EHOSTUNREACH
|| errno
== ETIMEDOUT
|| errno
== ENOTCONN
)
866 if (contimeout
&& (time(NULL
) - start_time
) > contimeout
)
868 _cupsLangPrintFilter(stderr
, "ERROR",
869 _("The printer is not responding."));
870 return (CUPS_BACKEND_FAILED
);
876 _cupsLangPrintFilter(stderr
, "WARNING",
877 _("The printer may not exist or "
878 "is unavailable at this time."));
883 _cupsLangPrintFilter(stderr
, "WARNING",
884 _("The printer is unreachable at "
889 _cupsLangPrintFilter(stderr
, "WARNING",
890 _("The printer is in use."));
894 sleep((unsigned)delay
);
899 else if (error
== EADDRINUSE
)
902 * Try on another port...
909 _cupsLangPrintFilter(stderr
, "ERROR",
910 _("The printer is not responding."));
920 tv
= (DWORD
)(timeout
* 1000);
922 setsockopt(fd
, SOL_SOCKET
, SO_RCVTIMEO
, (char *)&tv
, sizeof(tv
));
923 setsockopt(fd
, SOL_SOCKET
, SO_SNDTIMEO
, (char *)&tv
, sizeof(tv
));
928 setsockopt(fd
, SOL_SOCKET
, SO_RCVTIMEO
, &tv
, sizeof(tv
));
929 setsockopt(fd
, SOL_SOCKET
, SO_SNDTIMEO
, &tv
, sizeof(tv
));
932 fputs("STATE: -connecting-to-device\n", stderr
);
933 _cupsLangPrintFilter(stderr
, "INFO", _("Connected to printer."));
935 fprintf(stderr
, "DEBUG: Connected to %s:%d (local port %d)...\n",
936 httpAddrString(&(addr
->addr
), addrname
, sizeof(addrname
)),
937 httpAddrPort(&(addr
->addr
)), lport
);
940 * See if the printer supports SNMP...
944 have_supplies
= !backendSNMPSupplies(snmp_fd
, &(addrlist
->addr
), NULL
,
950 * Check for side-channel requests...
953 backendCheckSideChannel(snmp_fd
, &(addrlist
->addr
));
956 * Next, open the print file and figure out its size...
962 * Use the size from the print file...
965 if (fstat(print_fd
, &filestats
))
969 perror("DEBUG: unable to stat print file");
970 return (CUPS_BACKEND_FAILED
);
973 filestats
.st_size
*= manual_copies
;
978 * Use a "very large value" for the size so that the printer will
979 * keep printing until we close the connection...
982 #ifdef _LARGEFILE_SOURCE
983 filestats
.st_size
= (size_t)(999999999999.0);
985 filestats
.st_size
= 2147483647;
986 #endif /* _LARGEFILE_SOURCE */
990 * Send a job header to the printer, specifying no banner page and
994 if (lpd_command(fd
, "\002%s\n",
995 printer
)) /* Receive print job(s) */
998 return (CUPS_BACKEND_FAILED
);
1001 if (orighost
&& _cups_strcasecmp(orighost
, "localhost"))
1002 strlcpy(localhost
, orighost
, sizeof(localhost
));
1004 httpGetHostname(NULL
, localhost
, sizeof(localhost
));
1006 snprintf(control
, sizeof(control
),
1007 "H%.31s\n" /* RFC 1179, Section 7.2 - host name <= 31 chars */
1008 "P%.31s\n" /* RFC 1179, Section 7.2 - user name <= 31 chars */
1009 "J%.99s\n", /* RFC 1179, Section 7.2 - job name <= 99 chars */
1010 localhost
, user
, title
);
1011 cptr
= control
+ strlen(control
);
1015 snprintf(cptr
, sizeof(control
) - (size_t)(cptr
- control
),
1016 "C%.31s\n" /* RFC 1179, Section 7.2 - class name <= 31 chars */
1019 cptr
+= strlen(cptr
);
1024 snprintf(cptr
, sizeof(control
) - (size_t)(cptr
- control
), "%cdfA%03d%.15s\n",
1025 format
, (int)getpid() % 1000, localhost
);
1026 cptr
+= strlen(cptr
);
1030 snprintf(cptr
, sizeof(control
) - (size_t)(cptr
- control
),
1032 "N%.131s\n", /* RFC 1179, Section 7.2 - sourcefile name <= 131 chars */
1033 (int)getpid() % 1000, localhost
, title
);
1035 fprintf(stderr
, "DEBUG: Control file is:\n%s", control
);
1037 if (order
== ORDER_CONTROL_DATA
)
1040 * Check for side-channel requests...
1043 backendCheckSideChannel(snmp_fd
, &(addr
->addr
));
1046 * Send the control file...
1049 if (lpd_command(fd
, "\002%d cfA%03d%.15s\n", (int)strlen(control
),
1050 (int)getpid() % 1000, localhost
))
1054 return (CUPS_BACKEND_FAILED
);
1057 fprintf(stderr
, "DEBUG: Sending control file (%u bytes)\n",
1058 (unsigned)strlen(control
));
1060 if ((size_t)lpd_write(fd
, control
, strlen(control
) + 1) < (strlen(control
) + 1))
1062 status
= (char)errno
;
1063 perror("DEBUG: Unable to write control file");
1068 if (read(fd
, &status
, 1) < 1)
1070 _cupsLangPrintFilter(stderr
, "WARNING",
1071 _("The printer did not respond."));
1072 status
= (char)errno
;
1077 _cupsLangPrintFilter(stderr
, "ERROR",
1078 _("Remote host did not accept control file (%d)."),
1081 _cupsLangPrintFilter(stderr
, "INFO",
1082 _("Control file sent successfully."));
1090 * Check for side-channel requests...
1093 backendCheckSideChannel(snmp_fd
, &(addr
->addr
));
1096 * Send the print file...
1099 if (lpd_command(fd
, "\003" CUPS_LLFMT
" dfA%03d%.15s\n",
1100 CUPS_LLCAST filestats
.st_size
, (int)getpid() % 1000,
1105 return (CUPS_BACKEND_FAILED
);
1108 fprintf(stderr
, "DEBUG: Sending data file (" CUPS_LLFMT
" bytes)\n",
1109 CUPS_LLCAST filestats
.st_size
);
1112 for (copy
= 0; copy
< manual_copies
; copy
++)
1114 lseek(print_fd
, 0, SEEK_SET
);
1116 while ((nbytes
= read(print_fd
, buffer
, sizeof(buffer
))) > 0)
1118 _cupsLangPrintFilter(stderr
, "INFO",
1119 _("Spooling job, %.0f%% complete."),
1120 100.0 * tbytes
/ filestats
.st_size
);
1122 if (lpd_write(fd
, buffer
, (size_t)nbytes
) < nbytes
)
1124 perror("DEBUG: Unable to send print file to printer");
1132 if (mode
== MODE_STANDARD
)
1134 if (tbytes
< filestats
.st_size
)
1135 status
= (char)errno
;
1136 else if (lpd_write(fd
, "", 1) < 1)
1138 perror("DEBUG: Unable to send trailing nul to printer");
1139 status
= (char)errno
;
1144 * Read the status byte from the printer; if we can't read the byte
1145 * back now, we should set status to "errno", however at this point
1146 * we know the printer got the whole file and we don't necessarily
1147 * want to requeue it over and over...
1150 if (recv(fd
, &status
, 1, 0) < 1)
1152 _cupsLangPrintFilter(stderr
, "WARNING",
1153 _("The printer did not respond."));
1162 _cupsLangPrintFilter(stderr
, "ERROR",
1163 _("Remote host did not accept data file (%d)."),
1166 _cupsLangPrintFilter(stderr
, "INFO",
1167 _("Data file sent successfully."));
1170 if (status
== 0 && order
== ORDER_DATA_CONTROL
)
1173 * Check for side-channel requests...
1176 backendCheckSideChannel(snmp_fd
, &(addr
->addr
));
1179 * Send control file...
1182 if (lpd_command(fd
, "\002%d cfA%03d%.15s\n", (int)strlen(control
),
1183 (int)getpid() % 1000, localhost
))
1187 return (CUPS_BACKEND_FAILED
);
1190 fprintf(stderr
, "DEBUG: Sending control file (%lu bytes)\n",
1191 (unsigned long)strlen(control
));
1193 if ((size_t)lpd_write(fd
, control
, strlen(control
) + 1) < (strlen(control
) + 1))
1195 status
= (char)errno
;
1196 perror("DEBUG: Unable to write control file");
1200 if (read(fd
, &status
, 1) < 1)
1202 _cupsLangPrintFilter(stderr
, "WARNING",
1203 _("The printer did not respond."));
1204 status
= (char)errno
;
1209 _cupsLangPrintFilter(stderr
, "ERROR",
1210 _("Remote host did not accept control file (%d)."),
1213 _cupsLangPrintFilter(stderr
, "INFO",
1214 _("Control file sent successfully."));
1217 fputs("STATE: +cups-waiting-for-job-completed\n", stderr
);
1220 * Collect the final supply levels as needed...
1224 backendSNMPSupplies(snmp_fd
, &(addr
->addr
), NULL
, NULL
);
1227 * Close the socket connection and input file...
1233 return (CUPS_BACKEND_OK
);
1236 * Waiting for a retry...
1243 * If we get here, then the job has been canceled...
1246 return (CUPS_BACKEND_FAILED
);
1251 * 'lpd_write()' - Write a buffer of data to an LPD server.
1254 static ssize_t
/* O - Number of bytes written or -1 on error */
1255 lpd_write(int lpd_fd
, /* I - LPD socket */
1256 char *buffer
, /* I - Buffer to write */
1257 size_t length
) /* I - Number of bytes to write */
1259 ssize_t bytes
, /* Number of bytes written */
1260 total
; /* Total number of bytes written */
1267 while ((bytes
= send(lpd_fd
, buffer
, length
- (size_t)total
, 0)) >= 0)
1272 if ((size_t)total
== length
)
1284 * 'sigterm_handler()' - Handle 'terminate' signals that stop the backend.
1288 sigterm_handler(int sig
) /* I - Signal */
1290 (void)sig
; /* remove compiler warnings... */