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