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