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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * Copyright 2002 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */ 33 34 #include "lpsched.h" 35 #include <syslog.h> 36 37 static char * 38 shortenReason(char *reason) 39 { 40 register char *ptr, *pe; 41 int peLen; 42 43 if (strncmp(reason,"%%[",3) == 0) 44 reason += 3; 45 46 while (*reason == ' ') 47 reason++; 48 49 pe = "PrinterError:"; 50 peLen = strlen(pe); 51 if (strncmp(reason,pe,peLen) == 0) 52 reason += peLen; 53 54 if (((ptr = strchr(reason,']')) != NULL) && (strncmp(ptr,"]%%",3) == 0)) 55 *ptr = 0; 56 57 pe = reason + strlen(reason) -1; 58 pe = reason; 59 while (pe = strchr(pe,'\n')) 60 *pe = ' '; 61 62 pe = reason + strlen(reason) -1; 63 while ((pe > reason) && (*pe == ' ')) { 64 *pe = 0; 65 pe--; 66 } 67 return(reason); 68 } 69 70 /** 71 ** printer_fault() - RECOGNIZE PRINTER FAULT 72 **/ 73 74 void 75 printer_fault(register PSTATUS *pps, register RSTATUS *prs, char *alert_text, 76 int err) 77 { 78 register char *why,*shortWhy; 79 80 pps->status |= PS_FAULTED; 81 82 /* -F wait */ 83 if (STREQU(pps->printer->fault_rec, NAME_WAIT)) 84 disable (pps, CUZ_FAULT, DISABLE_STOP); 85 86 /* -F beginning */ 87 else if (STREQU(pps->printer->fault_rec, NAME_BEGINNING)) 88 terminate (pps->exec); 89 90 /* -F continue AND the interface program died */ 91 else if (!(pps->status & PS_LATER) && !pps->request) { 92 load_str (&pps->dis_reason, CUZ_STOPPED); 93 schedule (EV_LATER, WHEN_PRINTER, EV_ENABLE, pps); 94 } 95 96 if (err) { 97 errno = err; 98 why = makestr(alert_text, "(", PERROR, ")\n", (char *)0); 99 } else if (! alert_text) 100 why = makestr("exec exit fault", (char *) 0); 101 else 102 why = makestr(alert_text, (char *) 0); 103 104 if (!why) 105 why = alert_text; 106 107 shortWhy = (why != alert_text ? shortenReason(why) : why); 108 109 load_str (&pps->fault_reason, shortWhy); 110 dump_fault_status (pps); 111 if (STREQU(pps->printer->fault_alert.shcmd,"show fault")) 112 pps->status |= PS_SHOW_FAULT; 113 else 114 pps->status &= ~PS_SHOW_FAULT; 115 116 note("printer fault. type: %s, status: %x\nmsg: (%s)\n", 117 (pps->printer->fault_alert.shcmd ? 118 pps->printer->fault_alert.shcmd : "??"), 119 pps->status, shortWhy); 120 syslog(LOG_INFO, "fault (%s), type (%s), status(%x): %s", 121 (pps->printer->name ? pps->printer->name : "NULL"), 122 (pps->printer->fault_alert.shcmd ? 123 pps->printer->fault_alert.shcmd : "NULL"), 124 pps->status, (shortWhy ? shortWhy : "NULL")); 125 126 if (pps->status & PS_SHOW_FAULT) 127 schedule (EV_MESSAGE, pps); 128 else { 129 alert(A_PRINTER, pps, prs, shortWhy); 130 } 131 if (why != alert_text) 132 Free (why); 133 } 134 135 /** 136 ** clear_printer_fault() - RECOGNIZE PRINTER FAULT 137 **/ 138 139 void 140 clear_printer_fault(register PSTATUS *pps, char *alert_text) 141 { 142 register char *why, *shortWhy; 143 144 pps->status &= ~PS_FAULTED; 145 146 why = makestr(alert_text, (char *) 0); 147 148 shortWhy = (why ? shortenReason(why) : alert_text); 149 150 load_str (&pps->fault_reason, shortWhy); 151 dump_fault_status (pps); 152 if (STREQU(pps->printer->fault_alert.shcmd,"show fault")) 153 pps->status |= PS_SHOW_FAULT; 154 else 155 pps->status &= ~PS_SHOW_FAULT; 156 157 if (pps->status & PS_SHOW_FAULT) 158 schedule (EV_MESSAGE, pps); 159 if (why != alert_text) 160 Free(why); 161 schedule(EV_ENABLE, pps); 162 } 163 164 /** 165 ** dial_problem() - ADDRESS DIAL-OUT PROBLEM 166 **/ 167 168 void 169 dial_problem(register PSTATUS *pps, RSTATUS *prs, int rc) 170 { 171 static struct problem { 172 char *reason; 173 int retry_max, 174 dial_error; 175 } problems[] = { 176 "DIAL FAILED", 10, 2, /* D_HUNG */ 177 "CALLER SCRIPT FAILED", 10, 3, /* NO_ANS */ 178 "CAN'T ACCESS DEVICE", 0, 6, /* L_PROB */ 179 "DEVICE LOCKED", 20, 8, /* DV_NT_A */ 180 "NO DEVICES AVAILABLE", 0, 10, /* NO_BD_A */ 181 "SYSTEM NOT IN Systems FILE", 0, 13, /* BAD_SYS */ 182 "UNKNOWN dial() FAILURE", 0, 0 183 }; 184 185 register struct problem *p; 186 187 register char *msg; 188 189 #define PREFIX "Connect problem: " 190 #define SUFFIX "This problem has occurred several times.\nPlease check the dialing instructions for this printer.\n" 191 192 193 for (p = problems; p->dial_error; p++) 194 if (p->dial_error == rc) 195 break; 196 197 if (!p->retry_max) { 198 msg = Malloc(strlen(PREFIX) + strlen(p->reason) + 2); 199 sprintf (msg, "%s%s\n", PREFIX, p->reason); 200 printer_fault (pps, prs, msg, 0); 201 Free (msg); 202 203 } else if (pps->last_dial_rc != rc) { 204 pps->nretry = 1; 205 pps->last_dial_rc = (short)rc; 206 207 } else if (pps->nretry++ > p->retry_max) { 208 pps->nretry = 0; 209 pps->last_dial_rc = (short)rc; 210 msg = Malloc( 211 strlen(PREFIX) + strlen(p->reason) + strlen(SUFFIX) + 2 212 ); 213 sprintf (msg, "%s%s%s\n", PREFIX, p->reason, SUFFIX); 214 printer_fault (pps, prs, msg, 0); 215 Free (msg); 216 } 217 218 if (!(pps->status & PS_FAULTED)) { 219 load_str (&pps->dis_reason, p->reason); 220 schedule (EV_LATER, WHEN_PRINTER, EV_ENABLE, pps); 221 } 222 223 return; 224 } 225