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 *
shortenReason(char * reason)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
printer_fault(register PSTATUS * pps,register RSTATUS * prs,char * alert_text,int err)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
clear_printer_fault(register PSTATUS * pps,char * alert_text)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
dial_problem(register PSTATUS * pps,RSTATUS * prs,int rc)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