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 * Copyright 2002 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T 28 * All Rights Reserved. 29 */ 30 31 /* 32 * University Copyright- Copyright (c) 1982, 1986, 1988 33 * The Regents of the University of California. 34 * All Rights Reserved. 35 * 36 * University Acknowledgment- Portions of this document are derived from 37 * software developed by the University of California, Berkeley, and its 38 * contributors. 39 */ 40 41 #pragma ident "%Z%%M% %I% %E% SMI" 42 43 44 /* 45 * Routines to handle insertion, deletion, etc on the table 46 * of requests kept by the daemon. Nothing fancy here, linear 47 * search on a double-linked list. A time is kept with each 48 * entry so that overly old invitations can be eliminated. 49 * 50 * Consider this a mis-guided attempt at modularity 51 */ 52 53 #include <sys/time.h> 54 #include <string.h> 55 #include <stdio.h> 56 #include <malloc.h> 57 #include "talkd_impl.h" 58 59 #define MAX_ID 16000 /* << 2^15 so I don't have sign troubles */ 60 61 typedef struct table_entry TABLE_ENTRY; 62 63 struct table_entry { 64 CTL_MSG request; 65 long time; 66 TABLE_ENTRY *next; 67 TABLE_ENTRY *last; 68 }; 69 70 static struct timeval tp; 71 static TABLE_ENTRY *table = NULL; 72 73 static void delete(TABLE_ENTRY *ptr); 74 75 /* 76 * Look in the table for an invitation that matches the current 77 * request looking for an invitation. 78 */ 79 80 CTL_MSG * 81 find_match(CTL_MSG *request) 82 { 83 TABLE_ENTRY *ptr; 84 TABLE_ENTRY *prevp; 85 long current_time; 86 87 (void) gettimeofday(&tp, NULL); 88 current_time = tp.tv_sec; 89 90 ptr = table; 91 92 if (debug) { 93 (void) printf("Entering Look-Up with : \n"); 94 print_request(request); 95 } 96 97 while (ptr != NULL) { 98 99 if ((ptr->time - current_time) > MAX_LIFE) { 100 /* the entry is too old */ 101 if (debug) { 102 (void) printf("Deleting expired entry : \n"); 103 print_request(&ptr->request); 104 } 105 prevp = ptr; 106 ptr = ptr->next; 107 delete(prevp); 108 continue; 109 } 110 111 if (debug) 112 print_request(&ptr->request); 113 114 if (strcmp(request->l_name, ptr->request.r_name) == 0 && 115 strcmp(request->r_name, ptr->request.l_name) == 0 && 116 ptr->request.type == LEAVE_INVITE) { 117 return (&ptr->request); 118 } 119 120 ptr = ptr->next; 121 } 122 123 return (NULL); 124 } 125 126 /* 127 * Look for an identical request, as opposed to a complimentary 128 * one as find_match does. 129 */ 130 131 CTL_MSG * 132 find_request(CTL_MSG *request) 133 { 134 TABLE_ENTRY *ptr; 135 TABLE_ENTRY *prevp; 136 long current_time; 137 138 (void) gettimeofday(&tp, NULL); 139 current_time = tp.tv_sec; 140 141 /* 142 * See if this is a repeated message, and check for 143 * out of date entries in the table while we are it. 144 */ 145 146 ptr = table; 147 148 if (debug) { 149 (void) printf("Entering find_request with : \n"); 150 print_request(request); 151 } 152 153 while (ptr != NULL) { 154 155 if ((ptr->time - current_time) > MAX_LIFE) { 156 /* the entry is too old */ 157 if (debug) { 158 (void) printf("Deleting expired entry : \n"); 159 print_request(&ptr->request); 160 } 161 prevp = ptr; 162 ptr = ptr->next; 163 delete(prevp); 164 continue; 165 } 166 167 if (debug) 168 print_request(&ptr->request); 169 170 if (strcmp(request->r_name, ptr->request.r_name) == 0 && 171 strcmp(request->l_name, ptr->request.l_name) == 0 && 172 request->type == ptr->request.type && 173 request->pid == ptr->request.pid) { 174 175 /* update the time if we 'touch' it */ 176 ptr->time = current_time; 177 return (&ptr->request); 178 } 179 180 ptr = ptr->next; 181 } 182 183 return (NULL); 184 } 185 186 void 187 insert_table(CTL_MSG *request, CTL_RESPONSE *response) 188 { 189 TABLE_ENTRY *ptr; 190 long current_time; 191 192 (void) gettimeofday(&tp, NULL); 193 current_time = tp.tv_sec; 194 195 response->id_num = request->id_num = new_id(); 196 197 /* 198 * Insert a new entry into the top of the list. 199 */ 200 ptr = (TABLE_ENTRY *) malloc(sizeof (TABLE_ENTRY)); 201 202 if (ptr == NULL) { 203 print_error("malloc in insert_table"); 204 } 205 206 ptr->time = current_time; 207 ptr->request = *request; 208 209 ptr->next = table; 210 if (ptr->next != NULL) { 211 ptr->next->last = ptr; 212 } 213 ptr->last = NULL; 214 table = ptr; 215 } 216 217 /* 218 * Generate a unique non-zero sequence number. 219 */ 220 221 int 222 new_id(void) 223 { 224 static int current_id = 0; 225 226 current_id = (current_id + 1) % MAX_ID; 227 228 /* 0 is reserved, helps to pick up bugs */ 229 if (current_id == 0) 230 current_id = 1; 231 232 return (current_id); 233 } 234 235 /* 236 * Delete the invitation with id 'id_num'. 237 */ 238 239 int 240 delete_invite(int id_num) 241 { 242 TABLE_ENTRY *ptr; 243 244 ptr = table; 245 246 if (debug) 247 (void) printf("Entering delete_invite with %d\n", id_num); 248 249 while (ptr != NULL && ptr->request.id_num != id_num) { 250 if (debug) 251 print_request(&ptr->request); 252 ptr = ptr->next; 253 } 254 255 if (ptr != NULL) { 256 delete(ptr); 257 return (SUCCESS); 258 } 259 260 return (NOT_HERE); 261 } 262 263 /* 264 * Classic delete from a double-linked list. 265 */ 266 267 static void 268 delete(TABLE_ENTRY *ptr) 269 { 270 if (debug) { 271 (void) printf("Deleting : "); 272 print_request(&ptr->request); 273 } 274 if (table == ptr) { 275 table = ptr->next; 276 } else if (ptr->last != NULL) { 277 ptr->last->next = ptr->next; 278 } 279 280 if (ptr->next != NULL) { 281 ptr->next->last = ptr->last; 282 } 283 284 free(ptr); 285 } 286