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 2006 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 31 32 #pragma ident "%Z%%M% %I% %E% SMI" 33 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */ 34 35 #include "lpsched.h" 36 #include <syslog.h> 37 38 static char * 39 shortenReason(char *reason) 40 { 41 register char *ptr, *pe; 42 int peLen; 43 44 if (strncmp(reason,"%%[",3) == 0) 45 reason += 3; 46 47 while (*reason == ' ') 48 reason++; 49 50 pe = "PrinterError:"; 51 peLen = strlen(pe); 52 if (strncmp(reason,pe,peLen) == 0) 53 reason += peLen; 54 55 if (((ptr = strchr(reason,']')) != NULL) && (strncmp(ptr,"]%%",3) == 0)) 56 *ptr = 0; 57 58 pe = reason + strlen(reason) -1; 59 pe = reason; 60 while (pe = strchr(pe,'\n')) 61 *pe = ' '; 62 63 pe = reason + strlen(reason) -1; 64 while ((pe > reason) && (*pe == ' ')) { 65 *pe = 0; 66 pe--; 67 } 68 return(reason); 69 } 70 71 /** 72 ** printer_fault() - RECOGNIZE PRINTER FAULT 73 **/ 74 75 void 76 printer_fault(register PSTATUS *pps, register RSTATUS *prs, char *alert_text, 77 int err) 78 { 79 register char *why,*shortWhy; 80 81 pps->status |= PS_FAULTED; 82 83 /* -F wait */ 84 if (STREQU(pps->printer->fault_rec, NAME_WAIT)) 85 disable (pps, CUZ_FAULT, DISABLE_STOP); 86 87 /* -F beginning */ 88 else if (STREQU(pps->printer->fault_rec, NAME_BEGINNING)) 89 terminate (pps->exec); 90 91 /* -F continue AND the interface program died */ 92 else if (!(pps->status & PS_LATER) && !pps->request) { 93 load_str (&pps->dis_reason, CUZ_STOPPED); 94 schedule (EV_LATER, WHEN_PRINTER, EV_ENABLE, pps); 95 } 96 97 if (err) { 98 errno = err; 99 why = makestr(alert_text, "(", PERROR, ")\n", (char *)0); 100 } else if (! alert_text) 101 why = makestr("exec exit fault", (char *) 0); 102 else 103 why = makestr(alert_text, (char *) 0); 104 105 if (!why) 106 why = alert_text; 107 108 shortWhy = (why != alert_text ? shortenReason(why) : why); 109 110 load_str (&pps->fault_reason, shortWhy); 111 dump_fault_status (pps); 112 if (STREQU(pps->printer->fault_alert.shcmd,"show fault")) 113 pps->status |= PS_SHOW_FAULT; 114 else 115 pps->status &= ~PS_SHOW_FAULT; 116 117 note("printer fault. type: %s, status: %x\nmsg: (%s)\n", 118 (pps->printer->fault_alert.shcmd ? 119 pps->printer->fault_alert.shcmd : "??"), 120 pps->status, shortWhy); 121 122 if (pps->status & PS_SHOW_FAULT) 123 schedule (EV_MESSAGE, pps); 124 else { 125 alert(A_PRINTER, pps, prs, shortWhy); 126 } 127 if (why != alert_text) 128 Free (why); 129 } 130 131 /** 132 ** clear_printer_fault() - RECOGNIZE PRINTER FAULT 133 **/ 134 135 void 136 clear_printer_fault(register PSTATUS *pps, char *alert_text) 137 { 138 register char *why, *shortWhy; 139 140 pps->status &= ~PS_FAULTED; 141 142 why = makestr(alert_text, (char *) 0); 143 144 shortWhy = (why ? shortenReason(why) : alert_text); 145 146 load_str (&pps->fault_reason, shortWhy); 147 dump_fault_status (pps); 148 if (STREQU(pps->printer->fault_alert.shcmd,"show fault")) 149 pps->status |= PS_SHOW_FAULT; 150 else 151 pps->status &= ~PS_SHOW_FAULT; 152 153 if (pps->status & PS_SHOW_FAULT) 154 schedule (EV_MESSAGE, pps); 155 if (why != alert_text) 156 Free(why); 157 schedule(EV_ENABLE, pps); 158 } 159 160 /** 161 ** dial_problem() - ADDRESS DIAL-OUT PROBLEM 162 **/ 163 164 void 165 dial_problem(register PSTATUS *pps, RSTATUS *prs, int rc) 166 { 167 static struct problem { 168 char *reason; 169 int retry_max, 170 dial_error; 171 } problems[] = { 172 "DIAL FAILED", 10, 2, /* D_HUNG */ 173 "CALLER SCRIPT FAILED", 10, 3, /* NO_ANS */ 174 "CAN'T ACCESS DEVICE", 0, 6, /* L_PROB */ 175 "DEVICE LOCKED", 20, 8, /* DV_NT_A */ 176 "NO DEVICES AVAILABLE", 0, 10, /* NO_BD_A */ 177 "SYSTEM NOT IN Systems FILE", 0, 13, /* BAD_SYS */ 178 "UNKNOWN dial() FAILURE", 0, 0 179 }; 180 181 register struct problem *p; 182 183 register char *msg; 184 185 #define PREFIX "Connect problem: " 186 #define SUFFIX "This problem has occurred several times.\nPlease check the dialing instructions for this printer.\n" 187 188 189 for (p = problems; p->dial_error; p++) 190 if (p->dial_error == rc) 191 break; 192 193 if (!p->retry_max) { 194 msg = Malloc(strlen(PREFIX) + strlen(p->reason) + 2); 195 sprintf (msg, "%s%s\n", PREFIX, p->reason); 196 printer_fault (pps, prs, msg, 0); 197 Free (msg); 198 199 } else if (pps->last_dial_rc != rc) { 200 pps->nretry = 1; 201 pps->last_dial_rc = (short)rc; 202 203 } else if (pps->nretry++ > p->retry_max) { 204 pps->nretry = 0; 205 pps->last_dial_rc = (short)rc; 206 msg = Malloc( 207 strlen(PREFIX) + strlen(p->reason) + strlen(SUFFIX) + 2 208 ); 209 sprintf (msg, "%s%s%s\n", PREFIX, p->reason, SUFFIX); 210 printer_fault (pps, prs, msg, 0); 211 Free (msg); 212 } 213 214 if (!(pps->status & PS_FAULTED)) { 215 load_str (&pps->dis_reason, p->reason); 216 schedule (EV_LATER, WHEN_PRINTER, EV_ENABLE, pps); 217 } 218 219 return; 220 } 221