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