xref: /illumos-gate/usr/src/cmd/lp/cmd/lpsched/alerts.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
27 /*	  All Rights Reserved  	*/
28 
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #include "lpsched.h"
33 #include "stdarg.h"
34 
35 static char		*Fa_msg[] =
36 {
37     "Subject: Mount form %s\n\nThe form %s needs to be mounted\non the printer(s):\n",
38     "	%-14s (%d requests)\n",
39     "Total print requests queued for this form: %d\n",
40     "Use the %s ribbon.\n",
41     "Use any ribbon.\n",
42     "Use the %s print wheel, if appropriate.\n",
43     "Use any print wheel, if appropriate.\n",
44 };
45 
46 static char		*Fa_New_msg[] =
47 {
48     "The form `%s' needs to be mounted\non the printer(s):\n",
49     "The form `%s' (paper size: `%s') needs\nto be mounted on the printer(s):\n",
50 };
51 
52 static char		*Pa_msg[] =
53 {
54     "Subject: Mount print-wheel %s\n\nThe print-wheel %s needs to be mounted\non the printer(s):\n",
55     "	%-14s (%d request(s))\n",
56     "Total print requests queued for this print-wheel: %d\n",
57 };
58 
59 static char		*Pf_msg[] =
60 {
61     "Subject: Problem with printer %s\n\nThe printer %s has stopped printing for the reason given below.\n",
62     "Fix the problem and bring the printer back on line\nto resume printing.\n",
63     "Fix the problem and bring the printer back on line, and issue\nan enable command when you want to resume or restart printing.\n",
64     "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",
65     "\nThe reason(s) it stopped (multiple reasons indicate repeated attempts):\n\n"
66 };
67 
68 static void		pformat(),
69 			pwformat(),
70 			fformat();
71 
72 static int		f_count(),
73 			p_count();
74 
75 /*VARARGS1*/
76 void
77 alert (int type, ...)
78 {
79     va_list	args;
80 
81     va_start (args, type);
82 
83     switch (type) {
84 	case A_PRINTER: {
85             PSTATUS	*pr = va_arg(args, PSTATUS *);
86             RSTATUS	*rp = va_arg(args, RSTATUS *);
87 	    char *text = va_arg(args, char *);
88 	    pformat(pr->alert->msgfile, text, pr, rp);
89 	    if (!pr->alert->active)
90 	    {
91 		if (exec(EX_ALERT, pr) == 0)
92 			pr->alert->active = 1;
93 		else
94 		{
95 		    if (errno == EBUSY)
96 			pr->alert->exec->flags |= EXF_RESTART;
97 		    else
98 		        Unlink(pr->alert->msgfile);
99 		}
100 	    }
101 	    break;
102 	    }
103 	case A_PWHEEL: {
104             PWSTATUS	*pp = va_arg(args, PWSTATUS *);
105 	    pwformat(pp->alert->msgfile, pp);
106 	    if (!pp->alert->active) {
107 		if (exec(EX_PALERT, pp) == 0)
108 			pp->alert->active = 1;
109 		else {
110 		    if (errno == EBUSY)
111 			pp->alert->exec->flags |= EXF_RESTART;
112 		    else
113 			Unlink(pp->alert->msgfile);
114 		}
115 	    }
116 	    break;
117 	    }
118 	case A_FORM: {
119 		int isFormMessage;
120 		char *formPath;
121     		FSTATUS	*fp = va_arg(args, FSTATUS *);
122 
123 		isFormMessage = (STREQU(fp->form->alert.shcmd, "showfault"));
124 		if (isFormMessage)
125 			formPath = makepath(Lp_A_Forms, fp->form->name,
126 				FORMMESSAGEFILE, (char * )NULL);
127 		else
128 			formPath = fp->alert->msgfile;
129 
130 		fformat(formPath, fp,isFormMessage);
131 
132 		if (isFormMessage) {
133 			  Free(formPath);
134 			  schedule (EV_FORM_MESSAGE, fp);
135 		} else if (!fp->alert->active) {
136 			if (exec(EX_FALERT, fp) == 0)
137 				fp->alert->active = 1;
138 			else {
139 				if (errno == EBUSY)
140 					fp->alert->exec->flags |= EXF_RESTART;
141 				else
142 					Unlink(fp->alert->msgfile);
143 			}
144 		}
145 		break;
146 		}
147     }
148     va_end(args);
149 }
150 
151 static void
152 pformat(char *file, char *text, PSTATUS *pr, RSTATUS *rp)
153 {
154     int fd;
155 
156     if (Access(pr->alert->msgfile, 0) == 0) {
157 	if ((fd = open_locked(file, "a", MODE_READ)) < 0)
158 		return;
159 	if (text)
160 	    fdprintf(fd, text);
161 	close(fd);
162     } else {
163 	if ((fd = open_locked(file, "w", MODE_READ)) < 0)
164 		return;
165 	fdprintf(fd, Pf_msg[0], NB(pr->printer->name), NB(pr->printer->name));
166 	if (STREQU(pr->printer->fault_rec, NAME_WAIT))
167 	    fdprintf(fd, Pf_msg[2]);
168 	else {
169 	    if (pr->exec->pid > 0)
170 		fdprintf(fd, Pf_msg[1]);
171 	    else if (rp)
172 		fdprintf(fd, Pf_msg[3], rp->secure->req_id);
173 	}
174 	fdprintf(fd, Pf_msg[4]);
175 	if (text) {
176 		while (*text == '\n' || *text == '\r')
177 		    text++;
178 		fdprintf(fd, "%s", text);
179 	}
180 	close(fd);
181     }
182 }
183 
184 static void
185 pwformat(char *file, PWSTATUS *pp)
186 {
187 	int fd, i;
188 
189 	if ((fd = open_locked(file, "w", MODE_READ)) < 0)
190 	    return;
191 	fdprintf(fd, Pa_msg[0], NB(pp->pwheel->name), NB(pp->pwheel->name));
192 	for (i = 0; PStatus != NULL && PStatus[i] != NULL; i++) {
193 	    PSTATUS	*p = PStatus[i];
194 
195 	    if (p->printer->daisy && !SAME(p->pwheel_name, pp->pwheel->name) &&
196 	        searchlist(pp->pwheel->name, p->printer->char_sets)) {
197 		int		n = p_count(pp, p->printer->name);
198 
199 		if (n)
200 		  fdprintf(fd, Pa_msg[1], p->printer->name, n);
201 	    }
202 	}
203 	fdprintf(fd, Pa_msg[2], pp->requests);
204 	close(fd);
205 	pp->requests_last = pp->requests;
206 }
207 
208 static void
209 fformat(char *file, FSTATUS *fp, int isFormMessage)
210 {
211     int fd, i;
212     int		numLines=0;
213 
214 	if ((fd = open_locked(file, "w", MODE_READ)) < 0)
215 	    return;
216 
217 	if (isFormMessage)
218 		if (fp->form->paper)
219 			fdprintf(fd, Fa_New_msg[1], NB(fp->form->name),
220 				fp->form->paper);
221 		else
222 			fdprintf(fd, Fa_New_msg[0], NB(fp->form->name));
223 	else
224 		fdprintf(fd, Fa_msg[0], NB(fp->form->name), NB(fp->form->name));
225 
226 	for (i = 0; PStatus != NULL && PStatus[i] != NULL; i++) {
227 	    	PSTATUS	*p = PStatus[i];
228 
229 		if ((! isFormMountedOnPrinter(p,fp)) &&
230 		    allowed(fp->form->name, p->forms_allowed,
231 		    p->forms_denied)) {
232 
233 			int n = f_count(fp, p->printer->name);
234 
235 			if (n) {
236 				fdprintf(fd, Fa_msg[1], p->printer->name, n);
237 				numLines++;
238 			}
239 		}
240 	}
241 
242 	if (numLines != 1) fdprintf(fd, Fa_msg[2], fp->requests);
243 	if (!isFormMessage) {
244 		if (fp->form->rcolor && !STREQU(fp->form->rcolor, NAME_ANY))
245 			 fdprintf(fd, Fa_msg[3], NB(fp->form->rcolor));
246 		else
247 			 fdprintf(fd, Fa_msg[4]);
248 
249 		if (fp->form->chset && !STREQU(fp->form->chset, NAME_ANY))
250 			 fdprintf(fd, Fa_msg[5], NB(fp->form->chset));
251 		else
252 			 fdprintf(fd, Fa_msg[6]);
253 	}
254 
255 	close(fd);
256 	fp->requests_last = fp->requests;
257 }
258 
259 
260 /* VARARGS1 */
261 void
262 cancel_alert(int type, ...)
263 {
264     ALERT	*ap;
265     va_list	args;
266 
267     va_start (args, type);
268 
269     switch (type)
270     {
271 	case A_PRINTER:
272 	    ap = va_arg(args, PSTATUS *)->alert;
273 	    break;
274 
275 	case A_PWHEEL:
276 	    ap = va_arg(args, PWSTATUS *)->alert;
277 	    break;
278 
279 	case A_FORM:
280 	    ap = va_arg(args, FSTATUS *)->alert;
281 	    break;
282 
283 	default:
284 	    return;
285     }
286     va_end(args);
287 
288     ap->active = 0;
289     terminate(ap->exec);
290     Unlink(ap->msgfile);
291     return;
292 }
293 
294 static int
295 dest_equivalent_printer(char *dest, char *printer)
296 {
297 	CSTATUS *		pc;
298 
299 	return (
300 		STREQU(dest, printer)
301 	     || STREQU(dest, NAME_ANY)
302 	     || (
303 			((pc = search_cstatus(dest)) != NULL)
304 		     && searchlist(printer, pc->class->members)
305 		)
306 	);
307 }
308 
309 static int
310 f_count(FSTATUS *fp, char *name)
311 {
312     int		count = 0;
313     RSTATUS		*rp;
314 
315     for (rp = Request_List; rp != NULL; rp = rp->next)
316 	if ((rp->form == fp ) &&
317 	    (dest_equivalent_printer(rp->request->destination, name)))
318 	    count++;
319 
320     if (
321 	NewRequest
322      && NewRequest->form == fp
323      && dest_equivalent_printer(NewRequest->request->destination, name)
324     )
325 	count++;
326 
327     return(count);
328 }
329 
330 static int
331 p_count(PWSTATUS *pp, char *name)
332 {
333     int		count = 0;
334     RSTATUS		*rp;
335 
336     for (rp = Request_List; rp != NULL; rp = rp->next)
337 	if ((rp->pwheel == pp) &&
338 	    (dest_equivalent_printer(rp->request->destination, name)))
339 	    count++;
340 
341     if (
342 	NewRequest
343      && NewRequest->pwheel == pp
344      && dest_equivalent_printer(NewRequest->request->destination, name)
345     )
346 	count++;
347 
348     return(count);
349 }
350