xref: /titanic_41/usr/src/cmd/lp/cmd/lpsched/rstatus.c (revision 88f8b78a88cbdc6d8c1af5c3e54bc49d25095c98)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 1998 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"	/* SVr4.0 1.7.1.4	*/
32 
33 #include "lpsched.h"
34 
35 
36 /**
37  ** freerstatus()
38  **/
39 
40 void
41 freerstatus(register RSTATUS *r)
42 {
43 	if (r->exec) {
44 		if (r->exec->pid > 0)
45 			terminate (r->exec);
46 		r->exec->ex.request = 0;
47 	}
48 
49 	remover (r);
50 
51 	if (r->req_file)
52 		Free (r->req_file);
53 	if (r->slow)
54 		Free (r->slow);
55 	if (r->fast)
56 		Free (r->fast);
57 	if (r->pwheel_name)
58 		Free (r->pwheel_name);
59 	if (r->printer_type)
60 		Free (r->printer_type);
61 	if (r->output_type)
62 		Free (r->output_type);
63 	if (r->cpi)
64 		Free (r->cpi);
65 	if (r->lpi)
66 		Free (r->lpi);
67 	if (r->plen)
68 		Free (r->plen);
69 	if (r->pwid)
70 		Free (r->pwid);
71 
72 	if (r->secure) {
73 		freesecure(r->secure);
74 		Free(r->secure);
75 	}
76 
77 	if (r->request) {
78 		freerequest (r->request);
79 		Free(r->request);
80 	}
81 	Free(r);
82 
83 	return;
84 }
85 
86 /**
87  ** allocr()
88  **/
89 
90 RSTATUS *
91 allocr(void)
92 {
93 	register RSTATUS	*prs;
94 	register REQUEST	*req;
95 	register SECURE		*sec;
96 
97 	prs = (RSTATUS *)Malloc(sizeof(RSTATUS));
98 	req = (REQUEST *)Malloc(sizeof(REQUEST));
99 	sec = (SECURE *)Malloc(sizeof(SECURE));
100 
101 	if (prs == NULL || req == NULL || sec == NULL) {
102 		fail("allocr: Malloc failed");
103 	}
104 
105 	memset ((char *)prs, 0, sizeof(RSTATUS));
106 	memset ((char *)(prs->request = req), 0, sizeof(REQUEST));
107 	memset ((char *)(prs->secure = sec), 0, sizeof(SECURE));
108 
109 	return (prs);
110 }
111 
112 /**
113  ** insertr()
114  **/
115 
116 void
117 insertr(RSTATUS *r)
118 {
119 	RSTATUS			*prs;
120 
121 
122 	if (!Request_List) {
123 		Request_List = r;
124 		return;
125 	}
126 
127 	for (prs = Request_List; prs; prs = prs->next) {
128 		if (rsort(&r, &prs) < 0) {
129 			r->prev = prs->prev;
130 			if (r->prev)
131 				r->prev->next = r;
132 			r->next = prs;
133 			prs->prev = r;
134 			if (prs == Request_List)
135 				Request_List = r;
136 			return;
137 		}
138 
139 		if (prs->next)
140 			continue;
141 
142 		r->prev = prs;
143 		prs->next = r;
144 		return;
145 	}
146 }
147 
148 /**
149  ** remover()
150  **/
151 
152 void
153 remover(RSTATUS *r)
154 {
155 	if (r == Request_List)		/* on the request chain */
156 		Request_List = r->next;
157 
158 	if (r->next)
159 		r->next->prev = r->prev;
160 
161 	if (r->prev)
162 		r->prev->next = r->next;
163 
164 	r->next = 0;
165 	r->prev = 0;
166 	return;
167 }
168 
169 /**
170  ** request_by_id()
171  **/
172 
173 RSTATUS *
174 request_by_id(char *id)
175 {
176 	register RSTATUS	*prs;
177 
178 	for (prs = Request_List; prs; prs = prs->next)
179 		if (STREQU(id, prs->secure->req_id))
180 			return (prs);
181 	return (0);
182 }
183 
184 RSTATUS *
185 request_by_id_num( long num )
186 {
187 	register RSTATUS        *prs;
188 
189 	for (prs = Request_List; prs; prs = prs->next)
190 		if (STREQU(Local_System, prs->secure->system) &&
191 		    strncmp(prs->secure->req_id, "(fake)", strlen("(fake)"))) {
192 			char *tmp = strrchr(prs->secure->req_id, '-');
193 
194 			if (tmp && (num == atol(++tmp)))
195 				return (prs);
196 		}
197 	return(0);
198 }
199 
200 
201 /**
202  ** rsort()
203  **/
204 
205 static int		later ( RSTATUS * , RSTATUS * );
206 
207 int
208 rsort (RSTATUS **p1, RSTATUS **p2)
209 {
210 	/*
211 	 * Of two requests needing immediate handling, the first
212 	 * will be the request with the LATER date. In case of a tie,
213 	 * the first is the one with the larger request ID (i.e. the
214 	 * one that came in last).
215 	 */
216 	if ((*p1)->request->outcome & RS_IMMEDIATE)
217 		if ((*p2)->request->outcome & RS_IMMEDIATE)
218 			if (later(*p1, *p2))
219 				return (-1);
220 			else
221 				return (1);
222 		else
223 			return (-1);
224 
225 	else if ((*p2)->request->outcome & RS_IMMEDIATE)
226 		return (1);
227 
228 	/*
229 	 * Of two requests not needing immediate handling, the first
230 	 * will be the request with the highest priority. If both have
231 	 * the same priority, the first is the one with the EARLIER date.
232 	 * In case of a tie, the first is the one with the smaller ID
233 	 * (i.e. the one that came in first).
234 	 */
235 	else if ((*p1)->request->priority == (*p2)->request->priority)
236 		if (!later(*p1, *p2))
237 			return (-1);
238 		else
239 			return (1);
240 
241 	else
242 		return ((*p1)->request->priority - (*p2)->request->priority);
243 	/*NOTREACHED*/
244 }
245 
246 static int
247 later(RSTATUS *prs1, RSTATUS *prs2)
248 {
249 	if (prs1->secure->date > prs2->secure->date)
250 		return (1);
251 
252 	else if (prs1->secure->date < prs2->secure->date)
253 		return (0);
254 
255 	/*
256 	 * The dates are the same, so compare the request IDs.
257 	 * One problem with comparing request IDs is that the order
258 	 * of two IDs may be reversed if the IDs wrapped around. This
259 	 * is a very unlikely problem, because the cycle should take
260 	 * more than one second to wrap!
261 	 */
262 	else {
263 		register int		len1 = strlen(prs1->req_file),
264 					len2 = strlen(prs2->req_file);
265 
266 		/*
267 		 * Use the request file name (ID-0) for comparison,
268 		 * because the real request ID (DEST-ID) won't compare
269 		 * properly because of the destination prefix.
270 		 * The strlen() comparison is necessary, otherwise
271 		 * IDs like "99-0" and "100-0" will compare wrong.
272 		 */
273 		if (len1 > len2)
274 			return (1);
275 		else if (len1 < len2)
276 			return (0);
277 		else
278 			return (strcmp(prs1->req_file, prs2->req_file) > 0);
279 	}
280 	/*NOTREACHED*/
281 }
282