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