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