1 #ifndef lint 2 static char sccsid[] = "@(#)table.c 1.3 (Berkeley) 05/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 extern FILE *debugout; 50 long current_time; 51 52 gettimeofday(&tp, &txp); 53 current_time = tp.tv_sec; 54 if (debug) { 55 fprintf(debugout, "Entering Look-Up with : \n"); 56 print_request(request); 57 } 58 for (ptr = table; ptr != NIL; ptr = ptr->next) { 59 if ((ptr->time - current_time) > MAX_LIFE) { 60 /* the entry is too old */ 61 if (debug) { 62 fprintf(debugout 63 ,"Deleting expired entry : \n"); 64 print_request(&ptr->request); 65 } 66 delete(ptr); 67 continue; 68 } 69 if (debug) 70 print_request(&ptr->request); 71 if (strcmp(request->l_name, ptr->request.r_name) == 0 && 72 strcmp(request->r_name, ptr->request.l_name) == 0 && 73 ptr->request.type == LEAVE_INVITE) 74 return (&ptr->request); 75 } 76 return ((CTL_MSG *)0); 77 } 78 79 /* 80 * Look for an identical request, as opposed to a complimentary 81 * one as find_match does 82 */ 83 CTL_MSG * 84 find_request(request) 85 CTL_MSG *request; 86 { 87 TABLE_ENTRY *ptr; 88 extern FILE *debugout; 89 long current_time; 90 91 gettimeofday(&tp, &txp); 92 current_time = tp.tv_sec; 93 /* 94 * See if this is a repeated message, and check for 95 * out of date entries in the table while we are it. 96 */ 97 if (debug) { 98 fprintf(debugout, "Entering find_request with : \n"); 99 print_request(request); 100 } 101 for (ptr = table; ptr != NIL; ptr = ptr->next) { 102 if ((ptr->time - current_time) > MAX_LIFE) { 103 /* the entry is too old */ 104 if (debug) { 105 fprintf(debugout 106 , "Deleting expired entry : \n"); 107 print_request(&ptr->request); 108 } 109 delete(ptr); 110 continue; 111 } 112 if (debug) 113 print_request(&ptr->request); 114 if (strcmp(request->r_name, ptr->request.r_name) == 0 && 115 strcmp(request->l_name, ptr->request.l_name) == 0 && 116 request->type == ptr->request.type && 117 request->pid == ptr->request.pid) { 118 /* update the time if we 'touch' it */ 119 ptr->time = current_time; 120 return (&ptr->request); 121 } 122 } 123 return ((CTL_MSG *)0); 124 } 125 126 insert_table(request, response) 127 CTL_MSG *request; 128 CTL_RESPONSE *response; 129 { 130 TABLE_ENTRY *ptr; 131 long current_time; 132 133 gettimeofday(&tp, &txp); 134 current_time = tp.tv_sec; 135 response->id_num = request->id_num = new_id(); 136 /* insert a new entry into the top of the list */ 137 ptr = (TABLE_ENTRY *)malloc(sizeof(TABLE_ENTRY)); 138 if (ptr == NIL) { 139 fprintf(stderr, "malloc in insert_table"); 140 exit(1); 141 } 142 ptr->time = current_time; 143 ptr->request = *request; 144 ptr->next = table; 145 if (ptr->next != NIL) 146 ptr->next->last = ptr; 147 ptr->last = NIL; 148 table = ptr; 149 } 150 151 /* 152 * Generate a unique non-zero sequence number 153 */ 154 new_id() 155 { 156 static int current_id = 0; 157 158 current_id = (current_id + 1) % MAX_ID; 159 /* 0 is reserved, helps to pick up bugs */ 160 if (current_id == 0) 161 current_id = 1; 162 return (current_id); 163 } 164 165 /* 166 * Delete the invitation with id 'id_num' 167 */ 168 delete_invite(id_num) 169 int id_num; 170 { 171 TABLE_ENTRY *ptr; 172 extern FILE *debugout; 173 174 ptr = table; 175 176 if (debug) 177 fprintf(debugout,"Entering delete_invite with %d\n", id_num); 178 for (ptr = table; ptr != NIL; ptr = ptr->next) { 179 if (ptr->request.id_num == id_num) 180 break; 181 if (debug) 182 print_request(&ptr->request); 183 } 184 if (ptr != NIL) { 185 delete(ptr); 186 return (SUCCESS); 187 } 188 return (NOT_HERE); 189 } 190 191 /* 192 * Classic delete from a double-linked list 193 */ 194 delete(ptr) 195 TABLE_ENTRY *ptr; 196 { 197 extern FILE *debugout; 198 199 if (debug) { 200 fprintf(debugout, "Deleting : "); 201 print_request(&ptr->request); 202 } 203 if (table == ptr) 204 table = ptr->next; 205 else if (ptr->last != NIL) 206 ptr->last->next = ptr->next; 207 if (ptr->next != NIL) 208 ptr->next->last = ptr->last; 209 free((char *)ptr); 210 } 211