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 { 678 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200, 679 1800, 2400, 4800, 9600, 19200, 38400, 57600, 680 76800, 115200, 153600, 230400, 307200, 460800, 921600 681 }; 682 683 int 684 baudrate() 685 { 686 struct termio tm; 687 struct termios tms; 688 int speed; 689 690 if (ioctl(1, TCGETS, &tms) < 0) { 691 if (ioctl(1, TCGETA, &tm) < 0) 692 return (1200); 693 else 694 speed = tm.c_cflag&CBAUD; 695 } else 696 speed = cfgetospeed(&tms); 697 698 return (speed ? baud_convert[speed] : 1200); 699 } 700