xref: /illumos-gate/usr/src/cmd/lp/cmd/lpsched/alerts.c (revision 355b4669e025ff377602b6fc7caaf30dbc218371)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 1998 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 #pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.11.1.4	*/
32 
33 #include "lpsched.h"
34 #include "stdarg.h"
35 
36 static char		*Fa_msg[] =
37 {
38     "Subject: Mount form %s\n\nThe form %s needs to be mounted\non the printer(s):\n",
39     "	%-14s (%d requests)\n",
40     "Total print requests queued for this form: %d\n",
41     "Use the %s ribbon.\n",
42     "Use any ribbon.\n",
43     "Use the %s print wheel, if appropriate.\n",
44     "Use any print wheel, if appropriate.\n",
45 };
46 
47 static char		*Fa_New_msg[] =
48 {
49     "The form `%s' needs to be mounted\non the printer(s):\n",
50     "The form `%s' (paper size: `%s') needs\nto be mounted on the printer(s):\n",
51 };
52 
53 static char		*Pa_msg[] =
54 {
55     "Subject: Mount print-wheel %s\n\nThe print-wheel %s needs to be mounted\non the printer(s):\n",
56     "	%-14s (%d request(s))\n",
57     "Total print requests queued for this print-wheel: %d\n",
58 };
59 
60 static char		*Pf_msg[] =
61 {
62     "Subject: Problem with printer %s\n\nThe printer %s has stopped printing for the reason given below.\n",
63     "Fix the problem and bring the printer back on line\nto resume printing.\n",
64     "Fix the problem and bring the printer back on line, and issue\nan enable command when you want to resume or restart printing.\n",
65     "Fix the problem and bring the printer back on line.\nPrinting has stopped, but will be restarted in a few minutes;\nissue an enable command if you want to restart sooner.\nUnless someone issues a change request\n\n\tlp -i %s -P ...\n\nto change the page list to print, the current request will be reprinted from\nthe beginning.\n",
66     "\nThe reason(s) it stopped (multiple reasons indicate repeated attempts):\n\n"
67 };
68 
69 static void		pformat(),
70 			pwformat(),
71 			fformat();
72 
73 static int		f_count(),
74 			p_count();
75 
76 /*VARARGS1*/
77 void
78 alert (int type, ...)
79 {
80     PSTATUS	*pr;
81     RSTATUS	*rp;
82     FSTATUS	*fp;
83     PWSTATUS	*pp;
84     char	*text;
85     va_list	args;
86 
87     va_start (args, type);
88 
89     switch (type) {
90 	case A_PRINTER:
91 	    pr = va_arg(args, PSTATUS *);
92 	    rp = va_arg(args, RSTATUS *);
93 	    text = va_arg(args, char *);
94 	    pformat(pr->alert->msgfile, text, pr, rp);
95 	    if (!pr->alert->active)
96 	    {
97 		if (exec(EX_ALERT, pr) == 0)
98 			pr->alert->active = 1;
99 		else
100 		{
101 		    if (errno == EBUSY)
102 			pr->alert->exec->flags |= EXF_RESTART;
103 		    else
104 		        Unlink(pr->alert->msgfile);
105 		}
106 	    }
107 	    break;
108 
109 	case A_PWHEEL:
110 	    pp = va_arg(args, PWSTATUS *);
111 	    pwformat(pp->alert->msgfile, pp);
112 	    if (!pp->alert->active) {
113 		if (exec(EX_PALERT, pp) == 0)
114 			pp->alert->active = 1;
115 		else {
116 		    if (errno == EBUSY)
117 			pp->alert->exec->flags |= EXF_RESTART;
118 		    else
119 			Unlink(pp->alert->msgfile);
120 		}
121 	    }
122 	    break;
123 
124 	case A_FORM: {
125 		int isFormMessage;
126 		char *formPath;
127 
128 		fp = va_arg(args, FSTATUS *);
129 		isFormMessage = (STREQU(fp->form->alert.shcmd, "showfault"));
130 		if (isFormMessage)
131 			formPath = makepath(Lp_A_Forms, fp->form->name,
132 				FORMMESSAGEFILE, (char * )NULL);
133 		else
134 			formPath = fp->alert->msgfile;
135 
136 		fformat(formPath, fp,isFormMessage);
137 
138 		if (isFormMessage) {
139 			  Free(formPath);
140 			  schedule (EV_FORM_MESSAGE, fp);
141 		} else if (!fp->alert->active) {
142 			if (exec(EX_FALERT, fp) == 0)
143 				fp->alert->active = 1;
144 			else {
145 				if (errno == EBUSY)
146 					fp->alert->exec->flags |= EXF_RESTART;
147 				else
148 					Unlink(fp->alert->msgfile);
149 			}
150 		}
151 		break;
152 		}
153     }
154     va_end(args);
155 }
156 
157 static void
158 pformat(char *file, char *text, PSTATUS *pr, RSTATUS *rp)
159 {
160     int fd;
161 
162     if (Access(pr->alert->msgfile, 0) == 0) {
163 	if ((fd = open_locked(file, "a", MODE_READ)) < 0)
164 		return;
165 	if (text)
166 	    fdprintf(fd, text);
167 	close(fd);
168     } else {
169 	if ((fd = open_locked(file, "w", MODE_READ)) < 0)
170 		return;
171 	fdprintf(fd, Pf_msg[0], NB(pr->printer->name), NB(pr->printer->name));
172 	if (STREQU(pr->printer->fault_rec, NAME_WAIT))
173 	    fdprintf(fd, Pf_msg[2]);
174 	else {
175 	    if (pr->exec->pid > 0)
176 		fdprintf(fd, Pf_msg[1]);
177 	    else if (rp)
178 		fdprintf(fd, Pf_msg[3], rp->secure->req_id);
179 	}
180 	fdprintf(fd, Pf_msg[4]);
181 	if (text)
182 	{
183 		while (*text == '\n' || *text == '\r')
184 		    text++;
185 		fdprintf(fd, "%s", text);
186 	}
187 	close(fd);
188     }
189 }
190 
191 static void
192 pwformat(char *file, PWSTATUS *pp)
193 {
194 	int fd;
195 	PSTATUS	*p;
196 
197 	if ((fd = open_locked(file, "w", MODE_READ)) < 0)
198 	    return;
199 	fdprintf(fd, Pa_msg[0], NB(pp->pwheel->name), NB(pp->pwheel->name));
200 	for (p = walk_ptable(1); p; p = walk_ptable(0))
201 	    if (
202 		p->printer->daisy
203 	     && !SAME(p->pwheel_name, pp->pwheel->name)
204 	     && searchlist(pp->pwheel->name, p->printer->char_sets)
205 	    )
206 	    {
207 		register int		n = p_count(pp, p->printer->name);
208 
209 		if (n)
210 		  fdprintf(fd, Pa_msg[1], p->printer->name, n);
211 	    }
212 	fdprintf(fd, Pa_msg[2], pp->requests);
213 	close(fd);
214 	pp->requests_last = pp->requests;
215 }
216 
217 static void
218 fformat(char *file, FSTATUS *fp, int isFormMessage)
219 {
220     int fd;
221     PSTATUS	*p;
222     int		numLines=0;
223 
224 	if ((fd = open_locked(file, "w", MODE_READ)) < 0)
225 	    return;
226 
227 	if (isFormMessage)
228 		if (fp->form->paper)
229 			fdprintf(fd, Fa_New_msg[1], NB(fp->form->name),
230 				fp->form->paper);
231 		else
232 			fdprintf(fd, Fa_New_msg[0], NB(fp->form->name));
233 	else
234 		fdprintf(fd, Fa_msg[0], NB(fp->form->name), NB(fp->form->name));
235 
236 	for (p = walk_ptable(1); p; p = walk_ptable(0))
237 		if ((! isFormMountedOnPrinter(p,fp)) &&
238 		    allowed(fp->form->name, p->forms_allowed,
239 		    p->forms_denied)) {
240 
241 			register int n = f_count(fp, p->printer->name);
242 
243 			if (n) {
244 				fdprintf(fd, Fa_msg[1], p->printer->name, n);
245 				numLines++;
246 			}
247 		}
248 
249 	if (numLines != 1) fdprintf(fd, Fa_msg[2], fp->requests);
250 	if (!isFormMessage) {
251 		if (fp->form->rcolor && !STREQU(fp->form->rcolor, NAME_ANY))
252 			 fdprintf(fd, Fa_msg[3], NB(fp->form->rcolor));
253 		else
254 			 fdprintf(fd, Fa_msg[4]);
255 
256 		if (fp->form->chset && !STREQU(fp->form->chset, NAME_ANY))
257 			 fdprintf(fd, Fa_msg[5], NB(fp->form->chset));
258 		else
259 			 fdprintf(fd, Fa_msg[6]);
260 	}
261 
262 	close(fd);
263 	fp->requests_last = fp->requests;
264 }
265 
266 
267 /* VARARGS1 */
268 void
269 cancel_alert(int type, ...)
270 {
271     ALERT	*ap;
272     va_list	args;
273 
274     va_start (args, type);
275 
276     switch (type)
277     {
278 	case A_PRINTER:
279 	    ap = va_arg(args, PSTATUS *)->alert;
280 	    break;
281 
282 	case A_PWHEEL:
283 	    ap = va_arg(args, PWSTATUS *)->alert;
284 	    break;
285 
286 	case A_FORM:
287 	    ap = va_arg(args, FSTATUS *)->alert;
288 	    break;
289 
290 	default:
291 	    return;
292     }
293     va_end(args);
294 
295     ap->active = 0;
296     terminate(ap->exec);
297     Unlink(ap->msgfile);
298     return;
299 }
300 
301 static int
302 dest_equivalent_printer(char *dest, char *printer)
303 {
304 	CSTATUS *		pc;
305 
306 	return (
307 		STREQU(dest, printer)
308 	     || STREQU(dest, NAME_ANY)
309 	     || (
310 			((pc = search_ctable(dest)) != NULL)
311 		     && searchlist(printer, pc->class->members)
312 		)
313 	);
314 }
315 
316 static int
317 f_count(fp, name)
318 register FSTATUS 	*fp;
319 register char		*name;
320 {
321     register int		count = 0;
322     register RSTATUS		*rp;
323 
324     BEGIN_WALK_BY_FORM_LOOP(rp, fp)
325 	if (dest_equivalent_printer(rp->request->destination, name))
326 	    count++;
327     END_WALK_LOOP
328     if (
329 	NewRequest
330      && NewRequest->form == fp
331      && dest_equivalent_printer(NewRequest->request->destination, name)
332     )
333 	count++;
334     return(count);
335 }
336 
337 static int
338 p_count(pp, name)
339 register PWSTATUS 	*pp;
340 register char		*name;
341 {
342     register int		count = 0;
343     register RSTATUS		*rp;
344 
345     BEGIN_WALK_LOOP(rp, rp->pwheel == pp)
346 	if (dest_equivalent_printer(rp->request->destination, name))
347 	    count++;
348     END_WALK_LOOP
349     if (
350 	NewRequest
351      && NewRequest->pwheel == pp
352      && dest_equivalent_printer(NewRequest->request->destination, name)
353     )
354 	count++;
355     return(count);
356 }
357