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 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 #include "lpsched.h" 34 35 36 /** 37 ** insertr() 38 **/ 39 40 void 41 insertr(RSTATUS *r) 42 { 43 RSTATUS *prs; 44 45 46 if (!Request_List) { 47 Request_List = r; 48 return; 49 } 50 51 for (prs = Request_List; prs; prs = prs->next) { 52 if (rsort(&r, &prs) < 0) { 53 r->prev = prs->prev; 54 if (r->prev) 55 r->prev->next = r; 56 r->next = prs; 57 prs->prev = r; 58 if (prs == Request_List) 59 Request_List = r; 60 return; 61 } 62 63 if (prs->next) 64 continue; 65 66 r->prev = prs; 67 prs->next = r; 68 return; 69 } 70 } 71 72 /** 73 ** remover() 74 **/ 75 76 void 77 remover(RSTATUS *r) 78 { 79 if (r == Request_List) /* on the request chain */ 80 Request_List = r->next; 81 82 if (r->next) 83 r->next->prev = r->prev; 84 85 if (r->prev) 86 r->prev->next = r->next; 87 88 r->next = 0; 89 r->prev = 0; 90 return; 91 } 92 93 /** 94 ** request_by_id() 95 **/ 96 97 RSTATUS * 98 request_by_id(char *id) 99 { 100 register RSTATUS *prs; 101 102 for (prs = Request_List; prs; prs = prs->next) 103 if (STREQU(id, prs->secure->req_id)) 104 return (prs); 105 return (0); 106 } 107 108 RSTATUS * 109 request_by_id_num( long num ) 110 { 111 register RSTATUS *prs; 112 113 for (prs = Request_List; prs; prs = prs->next) { 114 char *tmp = strrchr(prs->secure->req_id, '-'); 115 116 if (tmp && (num == atol(++tmp))) 117 return (prs); 118 } 119 return(0); 120 } 121 122 123 /** 124 ** rsort() 125 **/ 126 127 static int later ( RSTATUS * , RSTATUS * ); 128 129 int 130 rsort (RSTATUS **p1, RSTATUS **p2) 131 { 132 /* 133 * Of two requests needing immediate handling, the first 134 * will be the request with the LATER date. In case of a tie, 135 * the first is the one with the larger request ID (i.e. the 136 * one that came in last). 137 */ 138 if ((*p1)->request->outcome & RS_IMMEDIATE) 139 if ((*p2)->request->outcome & RS_IMMEDIATE) 140 if (later(*p1, *p2)) 141 return (-1); 142 else 143 return (1); 144 else 145 return (-1); 146 147 else if ((*p2)->request->outcome & RS_IMMEDIATE) 148 return (1); 149 150 /* 151 * Of two requests not needing immediate handling, the first 152 * will be the request with the highest priority. If both have 153 * the same priority, the first is the one with the EARLIER date. 154 * In case of a tie, the first is the one with the smaller ID 155 * (i.e. the one that came in first). 156 */ 157 else if ((*p1)->request->priority == (*p2)->request->priority) 158 if (!later(*p1, *p2)) 159 return (-1); 160 else 161 return (1); 162 163 else 164 return ((*p1)->request->priority - (*p2)->request->priority); 165 /*NOTREACHED*/ 166 } 167 168 static int 169 later(RSTATUS *prs1, RSTATUS *prs2) 170 { 171 if (prs1->secure->date > prs2->secure->date) 172 return (1); 173 174 else if (prs1->secure->date < prs2->secure->date) 175 return (0); 176 177 /* 178 * The dates are the same, so compare the request IDs. 179 * One problem with comparing request IDs is that the order 180 * of two IDs may be reversed if the IDs wrapped around. This 181 * is a very unlikely problem, because the cycle should take 182 * more than one second to wrap! 183 */ 184 else { 185 register int len1 = strlen(prs1->req_file), 186 len2 = strlen(prs2->req_file); 187 188 /* 189 * Use the request file name (ID-0) for comparison, 190 * because the real request ID (DEST-ID) won't compare 191 * properly because of the destination prefix. 192 * The strlen() comparison is necessary, otherwise 193 * IDs like "99-0" and "100-0" will compare wrong. 194 */ 195 if (len1 > len2) 196 return (1); 197 else if (len1 < len2) 198 return (0); 199 else 200 return (strcmp(prs1->req_file, prs2->req_file) > 0); 201 } 202 /*NOTREACHED*/ 203 } 204