10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*3125Sjacobs * Common Development and Distribution License (the "License").
6*3125Sjacobs * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21*3125Sjacobs
22*3125Sjacobs /*
23*3125Sjacobs * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24*3125Sjacobs * Use is subject to license terms.
25*3125Sjacobs */
26*3125Sjacobs
270Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
280Sstevel@tonic-gate /* All Rights Reserved */
290Sstevel@tonic-gate
300Sstevel@tonic-gate
310Sstevel@tonic-gate
320Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
330Sstevel@tonic-gate /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
340Sstevel@tonic-gate
350Sstevel@tonic-gate #include "lpsched.h"
360Sstevel@tonic-gate #include <syslog.h>
370Sstevel@tonic-gate
380Sstevel@tonic-gate static char *
shortenReason(char * reason)390Sstevel@tonic-gate shortenReason(char *reason)
400Sstevel@tonic-gate {
410Sstevel@tonic-gate register char *ptr, *pe;
420Sstevel@tonic-gate int peLen;
430Sstevel@tonic-gate
440Sstevel@tonic-gate if (strncmp(reason,"%%[",3) == 0)
450Sstevel@tonic-gate reason += 3;
460Sstevel@tonic-gate
470Sstevel@tonic-gate while (*reason == ' ')
480Sstevel@tonic-gate reason++;
490Sstevel@tonic-gate
500Sstevel@tonic-gate pe = "PrinterError:";
510Sstevel@tonic-gate peLen = strlen(pe);
520Sstevel@tonic-gate if (strncmp(reason,pe,peLen) == 0)
530Sstevel@tonic-gate reason += peLen;
540Sstevel@tonic-gate
550Sstevel@tonic-gate if (((ptr = strchr(reason,']')) != NULL) && (strncmp(ptr,"]%%",3) == 0))
560Sstevel@tonic-gate *ptr = 0;
570Sstevel@tonic-gate
580Sstevel@tonic-gate pe = reason + strlen(reason) -1;
590Sstevel@tonic-gate pe = reason;
600Sstevel@tonic-gate while (pe = strchr(pe,'\n'))
610Sstevel@tonic-gate *pe = ' ';
620Sstevel@tonic-gate
630Sstevel@tonic-gate pe = reason + strlen(reason) -1;
640Sstevel@tonic-gate while ((pe > reason) && (*pe == ' ')) {
650Sstevel@tonic-gate *pe = 0;
660Sstevel@tonic-gate pe--;
670Sstevel@tonic-gate }
680Sstevel@tonic-gate return(reason);
690Sstevel@tonic-gate }
700Sstevel@tonic-gate
710Sstevel@tonic-gate /**
720Sstevel@tonic-gate ** printer_fault() - RECOGNIZE PRINTER FAULT
730Sstevel@tonic-gate **/
740Sstevel@tonic-gate
750Sstevel@tonic-gate void
printer_fault(register PSTATUS * pps,register RSTATUS * prs,char * alert_text,int err)760Sstevel@tonic-gate printer_fault(register PSTATUS *pps, register RSTATUS *prs, char *alert_text,
770Sstevel@tonic-gate int err)
780Sstevel@tonic-gate {
790Sstevel@tonic-gate register char *why,*shortWhy;
800Sstevel@tonic-gate
810Sstevel@tonic-gate pps->status |= PS_FAULTED;
820Sstevel@tonic-gate
830Sstevel@tonic-gate /* -F wait */
840Sstevel@tonic-gate if (STREQU(pps->printer->fault_rec, NAME_WAIT))
850Sstevel@tonic-gate disable (pps, CUZ_FAULT, DISABLE_STOP);
860Sstevel@tonic-gate
870Sstevel@tonic-gate /* -F beginning */
880Sstevel@tonic-gate else if (STREQU(pps->printer->fault_rec, NAME_BEGINNING))
890Sstevel@tonic-gate terminate (pps->exec);
900Sstevel@tonic-gate
910Sstevel@tonic-gate /* -F continue AND the interface program died */
920Sstevel@tonic-gate else if (!(pps->status & PS_LATER) && !pps->request) {
930Sstevel@tonic-gate load_str (&pps->dis_reason, CUZ_STOPPED);
940Sstevel@tonic-gate schedule (EV_LATER, WHEN_PRINTER, EV_ENABLE, pps);
950Sstevel@tonic-gate }
960Sstevel@tonic-gate
970Sstevel@tonic-gate if (err) {
980Sstevel@tonic-gate errno = err;
990Sstevel@tonic-gate why = makestr(alert_text, "(", PERROR, ")\n", (char *)0);
1000Sstevel@tonic-gate } else if (! alert_text)
1010Sstevel@tonic-gate why = makestr("exec exit fault", (char *) 0);
1020Sstevel@tonic-gate else
1030Sstevel@tonic-gate why = makestr(alert_text, (char *) 0);
1040Sstevel@tonic-gate
1050Sstevel@tonic-gate if (!why)
1060Sstevel@tonic-gate why = alert_text;
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate shortWhy = (why != alert_text ? shortenReason(why) : why);
1090Sstevel@tonic-gate
1100Sstevel@tonic-gate load_str (&pps->fault_reason, shortWhy);
1110Sstevel@tonic-gate dump_fault_status (pps);
1120Sstevel@tonic-gate if (STREQU(pps->printer->fault_alert.shcmd,"show fault"))
1130Sstevel@tonic-gate pps->status |= PS_SHOW_FAULT;
1140Sstevel@tonic-gate else
1150Sstevel@tonic-gate pps->status &= ~PS_SHOW_FAULT;
1160Sstevel@tonic-gate
1170Sstevel@tonic-gate note("printer fault. type: %s, status: %x\nmsg: (%s)\n",
1180Sstevel@tonic-gate (pps->printer->fault_alert.shcmd ?
1190Sstevel@tonic-gate pps->printer->fault_alert.shcmd : "??"),
1200Sstevel@tonic-gate pps->status, shortWhy);
1210Sstevel@tonic-gate
1220Sstevel@tonic-gate if (pps->status & PS_SHOW_FAULT)
1230Sstevel@tonic-gate schedule (EV_MESSAGE, pps);
1240Sstevel@tonic-gate else {
1250Sstevel@tonic-gate alert(A_PRINTER, pps, prs, shortWhy);
1260Sstevel@tonic-gate }
1270Sstevel@tonic-gate if (why != alert_text)
1280Sstevel@tonic-gate Free (why);
1290Sstevel@tonic-gate }
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate /**
1320Sstevel@tonic-gate ** clear_printer_fault() - RECOGNIZE PRINTER FAULT
1330Sstevel@tonic-gate **/
1340Sstevel@tonic-gate
1350Sstevel@tonic-gate void
clear_printer_fault(register PSTATUS * pps,char * alert_text)1360Sstevel@tonic-gate clear_printer_fault(register PSTATUS *pps, char *alert_text)
1370Sstevel@tonic-gate {
1380Sstevel@tonic-gate register char *why, *shortWhy;
1390Sstevel@tonic-gate
1400Sstevel@tonic-gate pps->status &= ~PS_FAULTED;
1410Sstevel@tonic-gate
1420Sstevel@tonic-gate why = makestr(alert_text, (char *) 0);
1430Sstevel@tonic-gate
1440Sstevel@tonic-gate shortWhy = (why ? shortenReason(why) : alert_text);
1450Sstevel@tonic-gate
1460Sstevel@tonic-gate load_str (&pps->fault_reason, shortWhy);
1470Sstevel@tonic-gate dump_fault_status (pps);
1480Sstevel@tonic-gate if (STREQU(pps->printer->fault_alert.shcmd,"show fault"))
1490Sstevel@tonic-gate pps->status |= PS_SHOW_FAULT;
1500Sstevel@tonic-gate else
1510Sstevel@tonic-gate pps->status &= ~PS_SHOW_FAULT;
1520Sstevel@tonic-gate
1530Sstevel@tonic-gate if (pps->status & PS_SHOW_FAULT)
1540Sstevel@tonic-gate schedule (EV_MESSAGE, pps);
1550Sstevel@tonic-gate if (why != alert_text)
1560Sstevel@tonic-gate Free(why);
1570Sstevel@tonic-gate schedule(EV_ENABLE, pps);
1580Sstevel@tonic-gate }
1590Sstevel@tonic-gate
1600Sstevel@tonic-gate /**
1610Sstevel@tonic-gate ** dial_problem() - ADDRESS DIAL-OUT PROBLEM
1620Sstevel@tonic-gate **/
1630Sstevel@tonic-gate
1640Sstevel@tonic-gate void
dial_problem(register PSTATUS * pps,RSTATUS * prs,int rc)1650Sstevel@tonic-gate dial_problem(register PSTATUS *pps, RSTATUS *prs, int rc)
1660Sstevel@tonic-gate {
1670Sstevel@tonic-gate static struct problem {
1680Sstevel@tonic-gate char *reason;
1690Sstevel@tonic-gate int retry_max,
1700Sstevel@tonic-gate dial_error;
1710Sstevel@tonic-gate } problems[] = {
1720Sstevel@tonic-gate "DIAL FAILED", 10, 2, /* D_HUNG */
1730Sstevel@tonic-gate "CALLER SCRIPT FAILED", 10, 3, /* NO_ANS */
1740Sstevel@tonic-gate "CAN'T ACCESS DEVICE", 0, 6, /* L_PROB */
1750Sstevel@tonic-gate "DEVICE LOCKED", 20, 8, /* DV_NT_A */
1760Sstevel@tonic-gate "NO DEVICES AVAILABLE", 0, 10, /* NO_BD_A */
1770Sstevel@tonic-gate "SYSTEM NOT IN Systems FILE", 0, 13, /* BAD_SYS */
1780Sstevel@tonic-gate "UNKNOWN dial() FAILURE", 0, 0
1790Sstevel@tonic-gate };
1800Sstevel@tonic-gate
1810Sstevel@tonic-gate register struct problem *p;
1820Sstevel@tonic-gate
1830Sstevel@tonic-gate register char *msg;
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate #define PREFIX "Connect problem: "
1860Sstevel@tonic-gate #define SUFFIX "This problem has occurred several times.\nPlease check the dialing instructions for this printer.\n"
1870Sstevel@tonic-gate
1880Sstevel@tonic-gate
1890Sstevel@tonic-gate for (p = problems; p->dial_error; p++)
1900Sstevel@tonic-gate if (p->dial_error == rc)
1910Sstevel@tonic-gate break;
1920Sstevel@tonic-gate
1930Sstevel@tonic-gate if (!p->retry_max) {
1940Sstevel@tonic-gate msg = Malloc(strlen(PREFIX) + strlen(p->reason) + 2);
1950Sstevel@tonic-gate sprintf (msg, "%s%s\n", PREFIX, p->reason);
1960Sstevel@tonic-gate printer_fault (pps, prs, msg, 0);
1970Sstevel@tonic-gate Free (msg);
1980Sstevel@tonic-gate
1990Sstevel@tonic-gate } else if (pps->last_dial_rc != rc) {
2000Sstevel@tonic-gate pps->nretry = 1;
2010Sstevel@tonic-gate pps->last_dial_rc = (short)rc;
2020Sstevel@tonic-gate
2030Sstevel@tonic-gate } else if (pps->nretry++ > p->retry_max) {
2040Sstevel@tonic-gate pps->nretry = 0;
2050Sstevel@tonic-gate pps->last_dial_rc = (short)rc;
2060Sstevel@tonic-gate msg = Malloc(
2070Sstevel@tonic-gate strlen(PREFIX) + strlen(p->reason) + strlen(SUFFIX) + 2
2080Sstevel@tonic-gate );
2090Sstevel@tonic-gate sprintf (msg, "%s%s%s\n", PREFIX, p->reason, SUFFIX);
2100Sstevel@tonic-gate printer_fault (pps, prs, msg, 0);
2110Sstevel@tonic-gate Free (msg);
2120Sstevel@tonic-gate }
2130Sstevel@tonic-gate
2140Sstevel@tonic-gate if (!(pps->status & PS_FAULTED)) {
2150Sstevel@tonic-gate load_str (&pps->dis_reason, p->reason);
2160Sstevel@tonic-gate schedule (EV_LATER, WHEN_PRINTER, EV_ENABLE, pps);
2170Sstevel@tonic-gate }
2180Sstevel@tonic-gate
2190Sstevel@tonic-gate return;
2200Sstevel@tonic-gate }
221