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