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