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
init_memory(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
init_printers()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
init_classes()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
init_forms()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
init_pwheels()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
init_requests(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
init_exec()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