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