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
notify(register RSTATUS * prs,char * errbuf,int k,int e,int slow)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
print_reason(int fd,int reason)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