xref: /illumos-gate/usr/src/cmd/lp/cmd/lpsched/faults.c (revision 0a44ef6d)
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