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