1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 */ 6 7 #ifndef lint 8 static char sccsid[] = "@(#)table.c 5.1 (Berkeley) 6/6/85"; 9 #endif not lint 10 11 /* 12 * Routines to handle insertion, deletion, etc on the table 13 * of requests kept by the daemon. Nothing fancy here, linear 14 * search on a double-linked list. A time is kept with each 15 * entry so that overly old invitations can be eliminated. 16 * 17 * Consider this a mis-guided attempt at modularity 18 */ 19 #include <stdio.h> 20 #include <sys/time.h> 21 22 #include "ctl.h" 23 24 #define MAX_ID 16000 /* << 2^15 so I don't have sign troubles */ 25 26 #define NIL ((TABLE_ENTRY *)0) 27 28 extern int debug; 29 struct timeval tp; 30 struct timezone txp; 31 32 typedef struct table_entry TABLE_ENTRY; 33 34 struct table_entry { 35 CTL_MSG request; 36 long time; 37 TABLE_ENTRY *next; 38 TABLE_ENTRY *last; 39 }; 40 41 TABLE_ENTRY *table = NIL; 42 CTL_MSG *find_request(); 43 CTL_MSG *find_match(); 44 char *malloc(); 45 46 /* 47 * Look in the table for an invitation that matches the current 48 * request looking for an invitation 49 */ 50 CTL_MSG * 51 find_match(request) 52 CTL_MSG *request; 53 { 54 TABLE_ENTRY *ptr; 55 extern FILE *debugout; 56 long current_time; 57 58 gettimeofday(&tp, &txp); 59 current_time = tp.tv_sec; 60 if (debug) { 61 fprintf(debugout, "Entering Look-Up with : \n"); 62 print_request(request); 63 } 64 for (ptr = table; ptr != NIL; ptr = ptr->next) { 65 if ((ptr->time - current_time) > MAX_LIFE) { 66 /* the entry is too old */ 67 if (debug) { 68 fprintf(debugout 69 ,"Deleting expired entry : \n"); 70 print_request(&ptr->request); 71 } 72 delete(ptr); 73 continue; 74 } 75 if (debug) 76 print_request(&ptr->request); 77 if (strcmp(request->l_name, ptr->request.r_name) == 0 && 78 strcmp(request->r_name, ptr->request.l_name) == 0 && 79 ptr->request.type == LEAVE_INVITE) 80 return (&ptr->request); 81 } 82 return ((CTL_MSG *)0); 83 } 84 85 /* 86 * Look for an identical request, as opposed to a complimentary 87 * one as find_match does 88 */ 89 CTL_MSG * 90 find_request(request) 91 CTL_MSG *request; 92 { 93 TABLE_ENTRY *ptr; 94 extern FILE *debugout; 95 long current_time; 96 97 gettimeofday(&tp, &txp); 98 current_time = tp.tv_sec; 99 /* 100 * See if this is a repeated message, and check for 101 * out of date entries in the table while we are it. 102 */ 103 if (debug) { 104 fprintf(debugout, "Entering find_request with : \n"); 105 print_request(request); 106 } 107 for (ptr = table; ptr != NIL; ptr = ptr->next) { 108 if ((ptr->time - current_time) > MAX_LIFE) { 109 /* the entry is too old */ 110 if (debug) { 111 fprintf(debugout 112 , "Deleting expired entry : \n"); 113 print_request(&ptr->request); 114 } 115 delete(ptr); 116 continue; 117 } 118 if (debug) 119 print_request(&ptr->request); 120 if (strcmp(request->r_name, ptr->request.r_name) == 0 && 121 strcmp(request->l_name, ptr->request.l_name) == 0 && 122 request->type == ptr->request.type && 123 request->pid == ptr->request.pid) { 124 /* update the time if we 'touch' it */ 125 ptr->time = current_time; 126 return (&ptr->request); 127 } 128 } 129 return ((CTL_MSG *)0); 130 } 131 132 insert_table(request, response) 133 CTL_MSG *request; 134 CTL_RESPONSE *response; 135 { 136 TABLE_ENTRY *ptr; 137 long current_time; 138 139 gettimeofday(&tp, &txp); 140 current_time = tp.tv_sec; 141 response->id_num = request->id_num = new_id(); 142 /* insert a new entry into the top of the list */ 143 ptr = (TABLE_ENTRY *)malloc(sizeof(TABLE_ENTRY)); 144 if (ptr == NIL) { 145 fprintf(stderr, "malloc in insert_table"); 146 exit(1); 147 } 148 ptr->time = current_time; 149 ptr->request = *request; 150 ptr->next = table; 151 if (ptr->next != NIL) 152 ptr->next->last = ptr; 153 ptr->last = NIL; 154 table = ptr; 155 } 156 157 /* 158 * Generate a unique non-zero sequence number 159 */ 160 new_id() 161 { 162 static int current_id = 0; 163 164 current_id = (current_id + 1) % MAX_ID; 165 /* 0 is reserved, helps to pick up bugs */ 166 if (current_id == 0) 167 current_id = 1; 168 return (current_id); 169 } 170 171 /* 172 * Delete the invitation with id 'id_num' 173 */ 174 delete_invite(id_num) 175 int id_num; 176 { 177 TABLE_ENTRY *ptr; 178 extern FILE *debugout; 179 180 ptr = table; 181 182 if (debug) 183 fprintf(debugout,"Entering delete_invite with %d\n", id_num); 184 for (ptr = table; ptr != NIL; ptr = ptr->next) { 185 if (ptr->request.id_num == id_num) 186 break; 187 if (debug) 188 print_request(&ptr->request); 189 } 190 if (ptr != NIL) { 191 delete(ptr); 192 return (SUCCESS); 193 } 194 return (NOT_HERE); 195 } 196 197 /* 198 * Classic delete from a double-linked list 199 */ 200 delete(ptr) 201 TABLE_ENTRY *ptr; 202 { 203 extern FILE *debugout; 204 205 if (debug) { 206 fprintf(debugout, "Deleting : "); 207 print_request(&ptr->request); 208 } 209 if (table == ptr) 210 table = ptr->next; 211 else if (ptr->last != NIL) 212 ptr->last->next = ptr->next; 213 if (ptr->next != NIL) 214 ptr->next->last = ptr->last; 215 free((char *)ptr); 216 } 217