1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <termio.h> 33 #include <sys/types.h> 34 #include <errno.h> 35 #include <signal.h> 36 #include <sys/times.h> 37 #include <string.h> 38 #include <limits.h> 39 #include <sys/prnio.h> 40 41 #include "lp.h" 42 43 #include <locale.h> 44 45 /* 46 * Begin Sun Additions for Parallel ports 47 */ 48 49 #include <string.h> 50 #include <stdarg.h> 51 #include <signal.h> 52 #include <unistd.h> 53 #include <sys/types.h> 54 #include <sys/ioccom.h> 55 #include <sys/ioctl.h> 56 57 #include <sys/bpp_io.h> 58 #include <sys/ecppsys.h> 59 #include <stropts.h> 60 61 /* 62 * the parameter structure for the parallel port 63 */ 64 struct ppc_params_t { 65 int flags; /* same as above */ 66 int state; /* status of the printer interface */ 67 int strobe_w; /* strobe width, in uS */ 68 int data_setup; /* data setup time, in uS */ 69 int ack_timeout; /* ACK timeout, in secs */ 70 int error_timeout; /* PAPER OUT, etc... timeout, in secs */ 71 int busy_timeout; /* BUSY timeout, in seconds */ 72 }; 73 74 75 76 static void printer_info(char *fmt, ...); 77 78 /* These are the routines avaliable to others for use */ 79 int is_a_parallel_bpp(int); 80 int bpp_state(int); 81 int parallel_comm(int, int()); 82 int get_ecpp_status(int fd); 83 int is_a_prnio(int); 84 int prnio_state(int); 85 86 #define PRINTER_ERROR_PAPER_OUT 1 87 #define PRINTER_ERROR_OFFLINE 2 88 #define PRINTER_ERROR_BUSY 3 89 #define PRINTER_ERROR_ERROR 4 90 #define PRINTER_ERROR_CABLE_POWER 5 91 #define PRINTER_ERROR_UNKNOWN 6 92 #define PRINTER_ERROR_TIMEOUT 7 93 #define PRINTER_IO_ERROR 129 94 95 96 /* 97 * for BPP PARALLEL interfaces 98 */ 99 100 int 101 is_a_parallel_bpp(int fd) 102 { 103 if (ioctl(fd, BPPIOC_TESTIO) == 0 || errno == EIO) 104 return (1); 105 return (0); 106 } 107 108 109 #if defined(DEBUG) && defined(NOTDEF) 110 char * 111 BppState(int state) 112 { 113 static char buf[BUFSIZ]; 114 115 memset(buf, 0, sizeof (buf)); 116 sprintf(buf, "State (0x%.4x) - (%s%s%s%s)\n", state, 117 ((state & BPP_SLCT_ERR) ? "offline " : ""), 118 ((state & BPP_BUSY_ERR) ? "busy " : ""), 119 ((state & BPP_PE_ERR) ? "paper " : ""), 120 ((state & BPP_ERR_ERR) ? "error " : "")); 121 122 return (buf); 123 } 124 #endif 125 126 int 127 bpp_state(int fd) 128 { 129 if (ioctl(fd, BPPIOC_TESTIO)) { 130 struct bpp_error_status bpp_stat; 131 int state; 132 133 if (ioctl(fd, BPPIOC_GETERR, &bpp_stat) < 0) 134 exit(PRINTER_IO_ERROR); 135 state = bpp_stat.pin_status; 136 137 #if defined(DEBUG) && defined(NOTDEF) 138 logit("%s", BppState(state)); 139 #endif 140 141 if (state == (BPP_PE_ERR | BPP_ERR_ERR | BPP_SLCT_ERR)) { 142 /* paper is out */ 143 return (PRINTER_ERROR_PAPER_OUT); 144 } else if (state & BPP_BUSY_ERR) { 145 /* printer is busy */ 146 return (PRINTER_ERROR_BUSY); 147 } else if (state & BPP_SLCT_ERR) { 148 /* printer is offline */ 149 return (PRINTER_ERROR_OFFLINE); 150 } else if (state & BPP_ERR_ERR) { 151 /* printer is errored */ 152 return (PRINTER_ERROR_ERROR); 153 } else if (state == BPP_PE_ERR) { 154 /* printer is off/unplugged */ 155 return (PRINTER_ERROR_CABLE_POWER); 156 } else if (state) { 157 return (PRINTER_ERROR_UNKNOWN); 158 } else 159 return (0); 160 } 161 return (0); 162 } 163 164 /* 165 * For ecpp parallel port 166 */ 167 168 int 169 get_ecpp_status(int fd) 170 { 171 int state; 172 struct ecpp_transfer_parms transfer_parms; 173 174 175 if (ioctl(fd, ECPPIOC_GETPARMS, &transfer_parms) == -1) { 176 return (-1); 177 } 178 179 state = transfer_parms.mode; 180 /* 181 * We don't know what all printers will return in 182 * nibble mode, therefore if we support nibble mode we will 183 * force the printer to be in CENTRONICS mode. 184 */ 185 if (state != ECPP_CENTRONICS) { 186 transfer_parms.mode = ECPP_CENTRONICS; 187 if (ioctl(fd, ECPPIOC_SETPARMS, &transfer_parms) == -1) { 188 return (-1); 189 } else { 190 state = ECPP_CENTRONICS; 191 } 192 } 193 194 195 return (state); 196 } 197 198 /* 199 * For prnio(7I) - generic printer interface 200 */ 201 int 202 is_a_prnio(int fd) 203 { 204 uint_t cap; 205 206 /* check if device supports prnio */ 207 if (ioctl(fd, PRNIOC_GET_IFCAP, &cap) == -1) { 208 return (0); 209 } 210 /* we will use 1284 status if available */ 211 if ((cap & PRN_1284_STATUS) == 0) { 212 /* some devices may only support 1284 status in unidir. mode */ 213 if (cap & PRN_BIDI) { 214 cap &= ~PRN_BIDI; 215 (void) ioctl(fd, PRNIOC_SET_IFCAP, &cap); 216 } 217 } 218 return (1); 219 } 220 221 int 222 prnio_state(int fd) 223 { 224 uint_t status; 225 uchar_t pins; 226 227 if ((ioctl(fd, PRNIOC_GET_STATUS, &status) == 0) && 228 (status & PRN_READY)) { 229 return (0); 230 } 231 232 if (ioctl(fd, PRNIOC_GET_1284_STATUS, &pins) != 0) { 233 return (PRINTER_ERROR_UNKNOWN); 234 } 235 236 if ((pins & ~PRN_1284_BUSY) == PRN_1284_PE) { 237 /* paper is out */ 238 return (PRINTER_ERROR_PAPER_OUT); 239 } else if (pins == (PRN_1284_PE | PRN_1284_SELECT | 240 PRN_1284_NOFAULT | PRN_1284_BUSY)) { 241 /* printer is off/unplugged */ 242 return (PRINTER_ERROR_CABLE_POWER); 243 } else if ((pins & PRN_1284_SELECT) == 0) { 244 /* printer is offline */ 245 return (PRINTER_ERROR_OFFLINE); 246 } else if ((pins & PRN_1284_NOFAULT) == 0) { 247 /* printer is errored */ 248 return (PRINTER_ERROR_ERROR); 249 } else if (pins & PRN_1284_PE) { 250 /* paper is out */ 251 return (PRINTER_ERROR_PAPER_OUT); 252 } else if (pins ^ (PRN_1284_SELECT | PRN_1284_NOFAULT)) { 253 return (PRINTER_ERROR_UNKNOWN); 254 } 255 256 return (0); 257 } 258 259 /* 260 * Common routines 261 */ 262 263 /*ARGSUSED0*/ 264 static void 265 ByeByeParallel(int sig) 266 { 267 /* try to shove out the EOT */ 268 (void) write(1, "\004", 1); 269 exit(0); 270 } 271 272 273 /*ARGSUSED0*/ 274 static void 275 printer_info(char *fmt, ...) 276 { 277 char mesg[BUFSIZ]; 278 va_list ap; 279 280 va_start(ap, fmt); 281 vsprintf(mesg, fmt, ap); 282 va_end(ap); 283 /* 284 * fprintf(stderr, 285 * "%%%%[ PrinterError: %s; source: parallel ]%%%%\n", 286 * mesg); 287 */ 288 fprintf(stderr, "%s\n", mesg); 289 fflush(stderr); 290 fsync(2); 291 292 } 293 294 static void 295 printer_error(int error) 296 { 297 switch (error) { 298 case -1: 299 printer_info("ioctl(): %s", strerror(errno)); 300 break; 301 case PRINTER_ERROR_PAPER_OUT: 302 printer_info("out of paper"); 303 break; 304 case PRINTER_ERROR_OFFLINE: 305 printer_info("offline"); 306 break; 307 case PRINTER_ERROR_BUSY: 308 printer_info("busy"); 309 break; 310 case PRINTER_ERROR_ERROR: 311 printer_info("printer error"); 312 break; 313 case PRINTER_ERROR_CABLE_POWER: 314 printer_info("printer powered off or disconnected"); 315 break; 316 case PRINTER_ERROR_UNKNOWN: 317 printer_info("unknown error"); 318 break; 319 case PRINTER_ERROR_TIMEOUT: 320 printer_info("communications timeout"); 321 break; 322 default: 323 printer_info("get_status() failed"); 324 } 325 } 326 327 328 static void 329 wait_state(int fd, int get_state()) 330 { 331 int state; 332 int was_faulted = 0; 333 334 while (state = get_state(fd)) { 335 was_faulted = 1; 336 printer_error(state); 337 sleep(15); 338 } 339 340 if (was_faulted) { 341 fprintf(stderr, "printer ok\n"); 342 fflush(stderr); 343 fsync(2); 344 } 345 } 346 347 /* 348 * end of Sun Additions for parallel port 349 */ 350 #define IDENTICAL(A, B) (A.st_dev == B.st_dev && A.st_ino == B.st_ino) 351 #define ISBLK(A) ((A.st_mode & S_IFMT) == S_IFBLK) 352 #define ISCHR(A) ((A.st_mode & S_IFMT) == S_IFCHR) 353 354 #define E_SUCCESS 0 355 #define E_BAD_INPUT 1 356 #define E_BAD_OUTPUT 2 357 #define E_BAD_TERM 3 358 #define E_IDENTICAL 4 359 #define E_WRITE_FAILED 5 360 #define E_TIMEOUT 6 361 #define E_HANGUP 7 362 #define E_INTERRUPT 8 363 364 #define SAFETY_FACTOR 2.0 365 #define R(F) (int)((F) + .5) 366 #define DELAY(N, D) R(SAFETY_FACTOR * ((N) / (double)(D))) 367 368 char buffer[BUFSIZ]; 369 370 void sighup(), 371 sigint(), 372 sigquit(), 373 sigpipe(), 374 sigalrm(), 375 sigterm(); 376 377 #if defined(baudrate) 378 #undef baudrate 379 #endif 380 381 int baudrate(); 382 383 384 int 385 nop(int fd) 386 { 387 return (0); 388 } 389 390 int bpp_state(int); 391 392 393 /* 394 * main() 395 */ 396 397 int 398 main(int argc, char *argv[]) 399 { 400 int nin, nout, effective_rate, max_delay = 0, n; 401 int report_rate; 402 short print_rate; 403 struct stat in, out; 404 struct tms tms; 405 long epoch_start, epoch_end; 406 char *TERM; 407 int (*func)(int fd); 408 409 /* 410 * The Spooler can hit us with SIGTERM for three reasons: 411 * 412 * - the user's job has been canceled 413 * - the printer has been disabled while we were printing 414 * - the Spooler heard that the printer has a fault, 415 * and the fault recovery is wait or beginning 416 * 417 * We should exit cleanly for the first two cases, 418 * but we have to be careful with the last. If it was THIS 419 * PROGRAM that told the Spooler about the fault, we must 420 * exit consistently. 421 * 422 * The method of avoiding any problem is to turn off the 423 * trapping of SIGTERM before telling the Spooler about 424 * the fault. 425 * 426 * Faults that we can detect: 427 * - hangup (drop of carrier) 428 * - interrupt (printer sent a break or quit character) 429 * - SIGPIPE (output port is a FIFO, and was closed early) 430 * - failed or incomplete write() 431 * - excess delay in write() (handled with SIGALRM later) 432 * 433 * Pseudo-faults (errors in use): 434 * - No input/output, or strange input/output 435 * - Input/output identical 436 * - No TERM defined or trouble reading Terminfo database 437 */ 438 signal(SIGTERM, sigterm); 439 signal(SIGHUP, sighup); 440 signal(SIGINT, sigint); 441 signal(SIGQUIT, sigint); 442 signal(SIGPIPE, sigpipe); 443 444 445 if (argc > 1 && STREQU(argv[1], "-r")) { 446 report_rate = 1; 447 argc--; 448 argv++; 449 } else 450 report_rate = 0; 451 452 (void) setlocale(LC_ALL, ""); 453 #if !defined(TEXT_DOMAIN) 454 #define TEXT_DOMAIN "SYS_TEST" 455 #endif 456 (void) textdomain(TEXT_DOMAIN); 457 458 /* 459 * Stat the standard output to be sure it is defined. 460 */ 461 if (fstat(1, &out) < 0) { 462 signal(SIGTERM, SIG_IGN); 463 fprintf(stderr, gettext("Can't stat output " 464 "(%s);\nincorrect use of lp.cat!\n"), PERROR); 465 exit(E_BAD_OUTPUT); 466 } 467 468 /* 469 * Stat the standard input to be sure it is defined. 470 */ 471 if (fstat(0, &in) < 0) { 472 signal(SIGTERM, SIG_IGN); 473 fprintf(stderr, gettext("Can't stat input " 474 "(%s);\nincorrect use of lp.cat!\n"), PERROR); 475 exit(E_BAD_INPUT); 476 } 477 478 /* 479 * If the standard output is not a character special file or a 480 * block special file, make sure it is not identical to the 481 * standard input. 482 * 483 * If we are an ecpp parallel port in centronics mode treat 484 * ourselves as a bpp compatible device. 485 */ 486 487 if (is_a_prnio(1)) { 488 func = prnio_state; 489 } else if (is_a_parallel_bpp(1) || 490 (get_ecpp_status(1) == ECPP_CENTRONICS)) { 491 func = bpp_state; 492 } else if (isatty(1)) { 493 /* serial connection (probably) - continue as usual */ 494 func = nop; 495 } else { 496 func = nop; 497 } 498 499 if (!ISCHR(out) && !ISBLK(out) && IDENTICAL(out, in)) { 500 signal(SIGTERM, SIG_IGN); 501 fprintf(stderr, gettext("Input and output are identical; " 502 "incorrect use of lp.cat!\n")); 503 exit(E_IDENTICAL); 504 } 505 506 /* 507 * The effective data transfer rate is the lesser 508 * of the transmission rate and print rate. If an 509 * argument was passed to us, it should be a data 510 * rate and it may be lower still. 511 * Based on the effective data transfer rate, 512 * we can predict the maximum delay we should experience. 513 * But there are other factors that could introduce 514 * delay, so let's be generous; after all, we'd rather 515 * err in favor of waiting too long to detect a fault 516 * than err too often on false alarms. 517 */ 518 519 if (!(TERM = getenv("TERM")) || !*TERM) { 520 signal(SIGTERM, SIG_IGN); 521 fprintf(stderr, gettext("No TERM variable defined! " 522 "Trouble with the Spooler!\n")); 523 exit(E_BAD_TERM); 524 } 525 if (!STREQU(TERM, NAME_UNKNOWN) && 526 tidbit(TERM, "cps", &print_rate) == -1) { 527 signal(SIGTERM, SIG_IGN); 528 fprintf(stderr, gettext("Trouble identifying printer " 529 "type \"%s\"; check the Terminfo database.\n"), TERM); 530 exit(E_BAD_TERM); 531 } 532 if (STREQU(TERM, NAME_UNKNOWN)) 533 print_rate = -1; 534 535 effective_rate = baudrate() / 10; /* okay for most bauds */ 536 if (print_rate != -1 && print_rate < effective_rate) 537 effective_rate = print_rate; 538 if (argc > 1 && (n = atoi(argv[1])) >= 0 && n < effective_rate) 539 effective_rate = n; /* 0 means infinite delay */ 540 if (effective_rate) 541 max_delay = DELAY(BUFSIZ, effective_rate); 542 543 /* 544 * We'll use the "alarm()" system call to keep us from 545 * waiting too long to write to a printer in trouble. 546 */ 547 if (max_delay) 548 signal(SIGALRM, sigalrm); 549 550 /* 551 * While not end of standard input, copy blocks to 552 * standard output. 553 */ 554 while ((nin = read(0, buffer, BUFSIZ)) > 0) { 555 char *ptr = buffer; 556 557 /* 558 * We should be safe from incomplete writes to a full 559 * pipe, as long as the size of the buffer we write is 560 * a even divisor of the pipe buffer limit. As long as 561 * we read from files or pipes (not communication devices) 562 * this should be true for all but the last buffer. The 563 * last will be smaller, and won't straddle the pipe max 564 * limit (think about it). 565 */ 566 #if PIPE_BUF < BUFSIZ || (PIPE_MAX % BUFSIZ) 567 this_wont_compile; 568 #endif 569 if (report_rate) 570 epoch_start = times(&tms); 571 do { 572 wait_state(1, func); 573 574 if (max_delay) 575 alarm(max_delay); 576 nout = write(1, ptr, nin); 577 alarm(0); 578 if (nout < 0) { 579 fprintf(stderr, gettext("Write failed " 580 "(%s);\nperhaps the printer has gone " 581 "off-line.\n"), PERROR); 582 fflush(stderr); 583 if (errno != EINTR) 584 /* I/O error on device, get lpcshed to retry */ 585 exit(PRINTER_IO_ERROR); 586 else /* wait for printer to come back online */ 587 sleep(15); 588 } else { 589 nin -= nout; 590 ptr += nout; 591 } 592 } while (nin > 0); 593 594 if (max_delay) 595 alarm(0); 596 else if (report_rate) { 597 epoch_end = times(&tms); 598 if (epoch_end - epoch_start > 0) 599 fprintf(stderr, "%d CPS\n", 600 R((100 * BUFSIZ) / 601 (double)(epoch_end - epoch_start))); 602 } 603 604 } 605 606 return (E_SUCCESS); 607 } 608 609 /* 610 * sighup() - CATCH A HANGUP (LOSS OF CARRIER) 611 */ 612 void 613 sighup() 614 { 615 signal(SIGTERM, SIG_IGN); 616 signal(SIGHUP, SIG_IGN); 617 fprintf(stderr, gettext(HANGUP_FAULT_LPCAT)); 618 exit(E_HANGUP); 619 } 620 621 /* 622 * sigint() - CATCH AN INTERRUPT 623 */ 624 void 625 sigint() 626 { 627 signal(SIGTERM, SIG_IGN); 628 signal(SIGINT, SIG_IGN); 629 fprintf(stderr, gettext(INTERRUPT_FAULT)); 630 exit(E_INTERRUPT); 631 } 632 633 /* 634 * sigpipe() - CATCH EARLY CLOSE OF PIPE 635 */ 636 void 637 sigpipe() 638 { 639 signal(SIGTERM, SIG_IGN); 640 signal(SIGPIPE, SIG_IGN); 641 fprintf(stderr, gettext(PIPE_FAULT)); 642 exit(E_INTERRUPT); 643 } 644 645 /* 646 * sigalrm() - CATCH AN ALARM 647 */ 648 void 649 sigalrm() 650 { 651 signal(SIGTERM, SIG_IGN); 652 fprintf(stderr, gettext("Excessive write delay; " 653 "perhaps the printer has gone off-line.\n")); 654 exit(E_TIMEOUT); 655 } 656 657 /* 658 * sigterm() - CATCH A TERMINATION SIGNAL 659 */ 660 void 661 sigterm() 662 { 663 signal(SIGTERM, SIG_IGN); 664 /* 665 * try to flush the output queue in the case of ecpp port. 666 * ignore the return code as this may not be the ecpp. 667 */ 668 ioctl(1, I_FLUSH, FLUSHW); 669 exit(E_SUCCESS); 670 } 671 672 /* 673 * baudrate() - RETURN BAUD RATE OF OUTPUT LINE 674 */ 675 676 static int baud_convert[] = { 677 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 678 1800, 2400, 4800, 9600, 19200, 38400, 57600, 679 76800, 115200, 153600, 230400, 307200, 460800, 921600, 680 1000000, 1152000, 1500000, 2000000, 2500000, 3000000, 681 3500000, 4000000 682 }; 683 684 int 685 baudrate() 686 { 687 struct termio tm; 688 struct termios tms; 689 int speed; 690 691 if (ioctl(1, TCGETS, &tms) < 0) { 692 if (ioctl(1, TCGETA, &tm) < 0) { 693 return (1200); 694 } else { 695 speed = tm.c_cflag&CBAUD; 696 } 697 } else { 698 speed = cfgetospeed(&tms); 699 } 700 701 return (speed ? baud_convert[speed] : 1200); 702 } 703