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