Home | History | Annotate | Download | only in lpsched
      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 *
     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
     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
    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
    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