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