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