xref: /illumos-gate/usr/src/cmd/lp/cmd/lpsched/notify.c (revision defc4c8acfa01dba1ef3c13ca0cafccfcede51c0)
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 
34 static char		*N_Msg[] = {
35 	"Subject: Status of lp request %s\n\nYour request %s destined for %s%s\n",
36 	"has completed successfully on printer %s.\n",
37 	"was canceled by the lpsched daemon%s\n", /* bugfix 1100252 */
38 	"encountered an error during filtering.\n",
39 	"encountered an error while printing on printer %s.\n",
40 	"Filtering stopped with an exit code of %d.\n",
41 	"Printing stopped with an exit code of %d.\n",
42 	"Filtering was interrupted with a signal %d.\n",
43 	"Printing was interrupted with a signal %d.\n",
44 	"\nReason for failure:\n\n%s\n",
45 	"\nReason for being canceled:\n\n%s\n",
46 };
47 
48 static struct reason {
49 	short			reason;
50 	char			*msg;
51 }			N_Reason[] = {
52     {
53 	MNODEST,
54 	"The requested print destination has been removed."
55     }, {
56 	MERRDEST,
57 	"All candidate destinations are rejecting further requests."
58     }, {
59 	MDENYDEST,
60 	"You are no longer allowed to use any printer suitable for\nthe request."
61     }, {
62 	MDENYDEST,
63 	"No candidate printer can handle these characteristics:"
64     }, {
65 	MNOMEDIA,
66 	"The form you requested no longer exists."
67     }, {
68 	MDENYMEDIA,
69 	"You are no longer allowed to use the form you requested."
70     }, {
71 	MDENYMEDIA,
72 	"The form you wanted now requires a different character set."
73     }, {
74 	MNOFILTER,
75 	"There is no longer a filter that will convert your file for printing."
76     }, {
77 	MNOMOUNT,
78 	"The form or print wheel you requested is not allowed on any\nprinter otherwise suitable for the request."
79     }, {
80 	MNOSPACE,
81 	"Memory allocation problem."
82     }, {
83 	-1,
84 	""
85     }
86 };
87 
88 
89 static void print_reason(int, int);
90 
91 
92 /**
93  ** notify() - NOTIFY USER OF FINISHED REQUEST
94  **/
95 
96 void
97 notify(register RSTATUS *prs, char *errbuf, int k, int e, int slow)
98 {
99 	register char		*cp;
100 	char			*file;
101 	int			fd;
102 
103 
104 	/*
105 	 * Screen out cases where no notification is needed.
106 	 */
107 	if (!(prs->request->outcome & RS_NOTIFY))
108 		return;
109 	if (
110 		!(prs->request->actions & (ACT_MAIL|ACT_WRITE|ACT_NOTIFY))
111 	     && !prs->request->alert
112 	     && !(prs->request->outcome & RS_CANCELLED)
113 	     && !e && !k && !errbuf       /* exited normally */
114 	)
115 		return;
116 
117 	/*
118 	 * Create the notification message to the user.
119 	 */
120 	file = makereqerr(prs);
121 	if ((fd = open_locked(file, "w", MODE_NOREAD)) >= 0) {
122 		fdprintf(fd, N_Msg[0], prs->secure->req_id, prs->secure->req_id,
123 			prs->request->destination,
124 			STREQU(prs->request->destination, NAME_ANY)? " printer"
125 				: "");
126 
127 		if (prs->request) {
128 			char file[BUFSIZ];
129 
130 			GetRequestFiles(prs->request, file, sizeof(file));
131 			fdprintf(fd, "\nThe job title was:\t%s\n", file);
132 			fdprintf(fd, "     submitted by:\t%s\n",
133 				prs->request->user);
134 			fdprintf(fd, "               at:\t%s\n",
135 				ctime(&prs->secure->date));
136 		}
137 
138 		if (prs->request->outcome & RS_PRINTED)
139 			fdprintf(fd, N_Msg[1], prs->printer->printer->name);
140 
141 		if (prs->request->outcome & RS_CANCELLED)
142 			fdprintf(fd, N_Msg[2],
143 				(prs->request->outcome & RS_FAILED)? ", and"
144 					: ".");
145 
146 
147 		if (prs->request->outcome & RS_FAILED) {
148 			if (slow)
149 				fdprintf(fd, N_Msg[3]);
150 			else
151 				fdprintf(fd, N_Msg[4],
152 					prs->printer->printer->name);
153 
154 			if (e > 0)
155 				fdprintf(fd, N_Msg[slow? 5 : 6], e);
156 			else if (k)
157 				fdprintf(fd, N_Msg[slow? 7 : 8], k);
158 		}
159 
160 		if (errbuf) {
161 			for (cp = errbuf; *cp && *cp == '\n'; cp++)
162 				;
163 			fdprintf(fd, N_Msg[9], cp);
164 			if (prs->request->outcome & RS_CANCELLED)
165 				fdprintf(fd, "\n");
166 		}
167 
168 		/* start fix for bugid 1100252	*/
169 		if (prs->request->outcome & RS_CANCELLED) {
170 			print_reason (fd, prs->reason);
171 		}
172 
173 		close(fd);
174 		schedule (EV_NOTIFY, prs);
175 
176 	}
177 	if (file)
178 		Free (file);
179 
180 	return;
181 }
182 
183 /**
184  ** print_reason() - PRINT REASON FOR AUTOMATIC CANCEL
185  **/
186 
187 static void
188 print_reason(int fd, int reason)
189 {
190 	register int		i;
191 
192 
193 #define P(BIT,MSG)	if (chkprinter_result & BIT) fdprintf(fd, MSG)
194 
195 	for (i = 0; N_Reason[i].reason != -1; i++)
196 		if (N_Reason[i].reason == reason) {
197 			if (reason == MDENYDEST && chkprinter_result)
198 				i++;
199 			if (reason == MDENYMEDIA && chkprinter_result)
200 				i++;
201 			fdprintf(fd, N_Msg[10], N_Reason[i].msg);
202 			if (reason == MDENYDEST && chkprinter_result) {
203 				P (PCK_TYPE,	"\tprinter type\n");
204 				P (PCK_CHARSET,	"\tcharacter set\n");
205 				P (PCK_CPI,	"\tcharacter pitch\n");
206 				P (PCK_LPI,	"\tline pitch\n");
207 				P (PCK_WIDTH,	"\tpage width\n");
208 				P (PCK_LENGTH,	"\tpage length\n");
209 				P (PCK_BANNER,	"\tno banner\n");
210 			}
211 			break;
212 		}
213 
214 	return;
215 }
216