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