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 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 #include "lpsched.h" 34 #include <syslog.h> 35 36 CSTATUS **CStatus = NULL; /* Status of same */ 37 PSTATUS **PStatus = NULL; /* Status of same */ 38 FSTATUS **FStatus = NULL; /* status of same */ 39 PWSTATUS **PWStatus = NULL; /* Status of same */ 40 EXEC **Exec_Table = NULL; /* Running processes */ 41 EXEC **Exec_Slow = NULL; /* Slow filters */ 42 EXEC **Exec_Notify = NULL; /* Notifications */ 43 RSTATUS *Request_List = NULL; /* Queue of print requests */ 44 45 int ET_SlowSize = 1, 46 ET_NotifySize = 1; 47 48 static void init_printers(), 49 init_classes(), 50 init_forms(), 51 init_pwheels(), 52 init_exec(); 53 54 55 static void init_requests(); 56 57 void 58 init_memory(void) 59 { 60 init_exec(); 61 init_printers(); 62 init_classes(); 63 init_forms(); 64 init_pwheels(); 65 66 /* 67 * Load the status after the basic structures have been loaded, 68 * but before loading requests still in the queue. This is so 69 * the requests can be compared against accurate status information 70 * (except rejection status--accept the jobs anyway). 71 */ 72 load_status(); 73 74 Loadfilters(Lp_A_Filters); 75 76 init_requests(); 77 } 78 79 static void 80 init_printers() 81 { 82 PRINTER *p; 83 int i = 0; 84 85 while((p = Getprinter(NAME_ALL)) != NULL || errno != ENOENT) { 86 if ((!p) || (p->remote)) /* NULL or this is remote, ignore it */ 87 continue; 88 89 (void) new_pstatus(p); 90 syslog(LOG_DEBUG, "Loaded printer: %s", p->name); 91 } 92 } 93 94 static void 95 init_classes() 96 { 97 CLASS *c; 98 99 while((c = Getclass(NAME_ALL)) != NULL) { 100 (void) new_cstatus(c); 101 syslog(LOG_DEBUG, "Loaded class: %s", c->name); 102 } 103 } 104 105 static void 106 init_forms() 107 { 108 _FORM *f; 109 int i = 0; 110 111 while ((f = Getform(NAME_ALL)) != NULL) { 112 (void) new_fstatus(f); 113 syslog(LOG_DEBUG, "Loaded form: %s", f->name); 114 } 115 } 116 117 static void 118 init_pwheels() 119 { 120 PWHEEL *p; 121 int i = 0; 122 123 while((p = Getpwheel(NAME_ALL)) != NULL || errno != ENOENT) 124 { 125 if (!p) /* NULL, ignore it. */ 126 continue; 127 128 (void) new_pwstatus(p); 129 syslog(LOG_DEBUG, "Loaded print-wheel: %s", p->name); 130 } 131 } 132 133 static void 134 init_requests(void) 135 { 136 RSTATUS **table = NULL; 137 REQUEST *r; 138 SECURE *s; 139 char *name; 140 char *sysdir; 141 char *sysname; 142 char *reqfile = NULL; 143 long addr = -1; 144 long sysaddr = -1; 145 short vr_ret; 146 147 while((sysname = next_dir(Lp_Requests, &addr)) != NULL) { 148 RSTATUS *rsp; 149 150 sysdir = makepath(Lp_Requests, sysname, NULL); 151 152 while((name = next_file(sysdir, &sysaddr)) != NULL) { 153 reqfile = makepath(sysname, name, NULL); 154 Free(name); 155 156 if ((s = Getsecure(reqfile)) == NULL) { 157 RSTATUS tmp; 158 159 memset(&tmp, 0, sizeof (tmp)); 160 tmp.req_file = reqfile; /* fix for 1103890 */ 161 rmfiles(&tmp, 0); 162 free(tmp.req_file); 163 continue; 164 } 165 syslog(LOG_DEBUG, "Loaded request: %s", reqfile); 166 167 if((r = Getrequest(reqfile)) == NULL) { 168 RSTATUS tmp; 169 170 memset(&tmp, 0, sizeof (tmp)); 171 tmp.req_file = reqfile; /* fix for 1103890 */ 172 rmfiles(&tmp, 0); 173 freesecure(s); 174 free(tmp.req_file); 175 continue; 176 } 177 syslog(LOG_DEBUG, "Loaded secure: %s", s->req_id); 178 179 rsp = new_rstatus(r, s); 180 181 r->outcome &= ~RS_ACTIVE; /* it can't be! */ 182 rsp->req_file = reqfile; 183 184 if ((r->outcome & (RS_CANCELLED|RS_FAILED)) && 185 !(r->outcome & RS_NOTIFY)) { 186 rmfiles(rsp, 0); 187 free_rstatus(rsp); 188 continue; 189 } 190 191 /* 192 * So far, the only way RS_NOTIFY can be set without there 193 * being a notification file containing the message to the 194 * user, is if the request was cancelled. This is because 195 * cancelling a request does not cause the creation of the 196 * message if the request is currently printing or filtering. 197 * (The message is created after the child process dies.) 198 * Thus, we know what to say. 199 * 200 * If this behaviour changes, we may have to find another way 201 * of determining what to say in the message. 202 */ 203 if (r->outcome & RS_NOTIFY) { 204 char *file = makereqerr(rsp); 205 206 if (Access(file, F_OK) == -1) { 207 if (!(r->outcome & RS_CANCELLED)) { 208 Free(file); 209 rmfiles(rsp, 0); 210 free_rstatus(rsp); 211 continue; 212 } 213 notify(rsp, NULL, 0, 0, 0); 214 } 215 Free(file); 216 } 217 218 /* fix for bugid 1103709. if validate_request returns 219 * MNODEST, then the printer for the request doesn't exist 220 * anymore! E.g. lpadmin -x was issued, and the request 221 * hasn't been cleaned up. In this case, the "printer" 222 * element of table[] will be NULL, and cancel will 223 * core dump! So we clean this up here. 224 */ 225 226 /* 227 * Well actually this happens with MDENYDEST too. The real problem 228 * is if the printer is NULL, so test for it 229 */ 230 231 if ((vr_ret=validate_request(rsp, NULL, 1)) != MOK) { 232 if (vr_ret == MNODEST || (rsp->printer == NULL)) { 233 rmfiles(rsp, 0); 234 free_rstatus(rsp); 235 continue; 236 } 237 cancel(rsp, 1); 238 } 239 240 list_append((void ***)&table, (void *)rsp); 241 } 242 Free(sysdir); 243 Free(sysname); 244 sysaddr = -1; 245 } 246 247 if (table != NULL) { 248 unsigned long i; 249 250 for (i = 0; table[i] != NULL; i++); 251 252 qsort((void *)table, i, sizeof(RSTATUS *), 253 (int (*)(const void * , const void *))rsort); 254 255 for (i = 0; table[i] != NULL; i++) { 256 table[i]->next = table[i + 1]; 257 if (table[i + 1] != NULL) 258 table[i + 1]->prev = table[i]; 259 } 260 261 Request_List = *table; 262 Free(table); 263 } 264 } 265 266 static void 267 init_exec() 268 { 269 EXEC *ep; 270 int i; 271 272 for (i = 0; i < ET_SlowSize; i++) { 273 ep = new_exec(EX_SLOWF, NULL); 274 list_append((void ***)&Exec_Slow, (void *)ep); 275 } 276 277 for (i = 0; i < ET_NotifySize; i++) { 278 ep = new_exec(EX_NOTIFY, NULL); 279 list_append((void ***)&Exec_Notify, (void *)ep); 280 } 281 } 282