1*16366Skarels #ifndef lint 2*16366Skarels static char sccsid[] = "@(#)table.c 1.2 (Berkeley) 04/11/84"; 3*16366Skarels #endif 416356Skarels 5*16366Skarels /* 6*16366Skarels * Routines to handle insertion, deletion, etc on the table 7*16366Skarels * of requests kept by the daemon. Nothing fancy here, linear 8*16366Skarels * search on a double-linked list. A time is kept with each 9*16366Skarels * entry so that overly old invitations can be eliminated. 10*16366Skarels * 11*16366Skarels * Consider this a mis-guided attempt at modularity 1216356Skarels */ 13*16366Skarels #include <stdio.h> 14*16366Skarels #include <sys/time.h> 1516356Skarels 1616356Skarels #include "ctl.h" 1716356Skarels 18*16366Skarels #define MAX_ID 16000 /* << 2^15 so I don't have sign troubles */ 1916356Skarels 20*16366Skarels #define NIL ((TABLE_ENTRY *)0) 2116356Skarels 22*16366Skarels extern int debug; 23*16366Skarels struct timeval tp; 24*16366Skarels struct timezone *txp; 2516356Skarels 2616356Skarels typedef struct table_entry TABLE_ENTRY; 2716356Skarels 2816356Skarels struct table_entry { 29*16366Skarels CTL_MSG request; 30*16366Skarels long time; 31*16366Skarels TABLE_ENTRY *next; 32*16366Skarels TABLE_ENTRY *last; 3316356Skarels }; 3416356Skarels 35*16366Skarels TABLE_ENTRY *table = NIL; 3616356Skarels CTL_MSG *find_request(); 3716356Skarels CTL_MSG *find_match(); 38*16366Skarels char *malloc(); 3916356Skarels 40*16366Skarels /* 41*16366Skarels * Look in the table for an invitation that matches the current 42*16366Skarels * request looking for an invitation 43*16366Skarels */ 44*16366Skarels CTL_MSG * 45*16366Skarels find_match(request) 46*16366Skarels CTL_MSG *request; 4716356Skarels { 48*16366Skarels TABLE_ENTRY *ptr; 49*16366Skarels long current_time; 5016356Skarels 51*16366Skarels gettimeofday(&tp, &txp); 52*16366Skarels current_time = tp.tv_sec; 53*16366Skarels if (debug) { 54*16366Skarels printf("Entering Look-Up with : \n"); 55*16366Skarels print_request(request); 5616356Skarels } 57*16366Skarels for (ptr = table; ptr != NIL; ptr = ptr->next) { 58*16366Skarels if ((ptr->time - current_time) > MAX_LIFE) { 59*16366Skarels /* the entry is too old */ 60*16366Skarels if (debug) 61*16366Skarels printf("Deleting expired entry : \n"); 62*16366Skarels if (debug) 63*16366Skarels print_request(&ptr->request); 64*16366Skarels delete(ptr); 65*16366Skarels continue; 66*16366Skarels } 67*16366Skarels if (debug) 68*16366Skarels print_request(&ptr->request); 69*16366Skarels if (strcmp(request->l_name, ptr->request.r_name) == 0 && 70*16366Skarels strcmp(request->r_name, ptr->request.l_name) == 0 && 71*16366Skarels ptr->request.type == LEAVE_INVITE) 72*16366Skarels return (&ptr->request); 7316356Skarels } 74*16366Skarels return ((CTL_MSG *)0); 7516356Skarels } 7616356Skarels 77*16366Skarels /* 78*16366Skarels * Look for an identical request, as opposed to a complimentary 79*16366Skarels * one as find_match does 80*16366Skarels */ 81*16366Skarels CTL_MSG * 82*16366Skarels find_request(request) 83*16366Skarels CTL_MSG *request; 8416356Skarels { 85*16366Skarels TABLE_ENTRY *ptr; 86*16366Skarels long current_time; 8716356Skarels 88*16366Skarels gettimeofday(&tp, &txp); 89*16366Skarels current_time = tp.tv_sec; 90*16366Skarels /* 91*16366Skarels * See if this is a repeated message, and check for 92*16366Skarels * out of date entries in the table while we are it. 9316356Skarels */ 94*16366Skarels if (debug) { 95*16366Skarels printf("Entering find_request with : \n"); 96*16366Skarels print_request(request); 9716356Skarels } 98*16366Skarels for (ptr = table; ptr != NIL; ptr = ptr->next) { 99*16366Skarels if ((ptr->time - current_time) > MAX_LIFE) { 100*16366Skarels /* the entry is too old */ 101*16366Skarels if (debug) { 102*16366Skarels printf("Deleting expired entry : \n"); 103*16366Skarels print_request(&ptr->request); 104*16366Skarels } 105*16366Skarels delete(ptr); 106*16366Skarels continue; 107*16366Skarels } 108*16366Skarels if (debug) 109*16366Skarels print_request(&ptr->request); 110*16366Skarels if (strcmp(request->r_name, ptr->request.r_name) == 0 && 111*16366Skarels strcmp(request->l_name, ptr->request.l_name) == 0 && 112*16366Skarels request->type == ptr->request.type && 113*16366Skarels request->pid == ptr->request.pid) { 114*16366Skarels /* update the time if we 'touch' it */ 115*16366Skarels ptr->time = current_time; 116*16366Skarels return (&ptr->request); 117*16366Skarels } 11816356Skarels } 119*16366Skarels return ((CTL_MSG *)0); 12016356Skarels } 12116356Skarels 12216356Skarels insert_table(request, response) 123*16366Skarels CTL_MSG *request; 124*16366Skarels CTL_RESPONSE *response; 12516356Skarels { 126*16366Skarels TABLE_ENTRY *ptr; 127*16366Skarels long current_time; 12816356Skarels 129*16366Skarels gettimeofday(&tp, &txp); 130*16366Skarels current_time = tp.tv_sec; 131*16366Skarels response->id_num = request->id_num = new_id(); 13216356Skarels /* insert a new entry into the top of the list */ 133*16366Skarels ptr = (TABLE_ENTRY *)malloc(sizeof(TABLE_ENTRY)); 134*16366Skarels if (ptr == NIL) { 135*16366Skarels fprintf(stderr, "malloc in insert_table"); 136*16366Skarels exit(1); 137*16366Skarels } 138*16366Skarels ptr->time = current_time; 139*16366Skarels ptr->request = *request; 140*16366Skarels ptr->next = table; 141*16366Skarels if (ptr->next != NIL) 142*16366Skarels ptr->next->last = ptr; 143*16366Skarels ptr->last = NIL; 144*16366Skarels table = ptr; 14516356Skarels } 14616356Skarels 147*16366Skarels /* 148*16366Skarels * Generate a unique non-zero sequence number 149*16366Skarels */ 15016356Skarels new_id() 15116356Skarels { 152*16366Skarels static int current_id = 0; 15316356Skarels 154*16366Skarels current_id = (current_id + 1) % MAX_ID; 15516356Skarels /* 0 is reserved, helps to pick up bugs */ 156*16366Skarels if (current_id == 0) 157*16366Skarels current_id = 1; 158*16366Skarels return (current_id); 15916356Skarels } 16016356Skarels 161*16366Skarels /* 162*16366Skarels * Delete the invitation with id 'id_num' 163*16366Skarels */ 16416356Skarels delete_invite(id_num) 165*16366Skarels int id_num; 16616356Skarels { 167*16366Skarels TABLE_ENTRY *ptr; 16816356Skarels 169*16366Skarels ptr = table; 17016356Skarels 171*16366Skarels if (debug) 172*16366Skarels printf("Entering delete_invite with %d\n", id_num); 173*16366Skarels for (ptr = table; ptr != NIL; ptr = ptr->next) { 174*16366Skarels if (ptr->request.id_num == id_num) 175*16366Skarels break; 176*16366Skarels if (debug) 177*16366Skarels print_request(&ptr->request); 178*16366Skarels } 179*16366Skarels if (ptr != NIL) { 180*16366Skarels delete(ptr); 181*16366Skarels return (SUCCESS); 182*16366Skarels } 183*16366Skarels return (NOT_HERE); 18416356Skarels } 18516356Skarels 186*16366Skarels /* 187*16366Skarels * Classic delete from a double-linked list 188*16366Skarels */ 18916356Skarels delete(ptr) 190*16366Skarels TABLE_ENTRY *ptr; 19116356Skarels { 19216356Skarels 193*16366Skarels if (debug) { 194*16366Skarels printf("Deleting : "); 195*16366Skarels print_request(&ptr->request); 196*16366Skarels } 197*16366Skarels if (table == ptr) 198*16366Skarels table = ptr->next; 199*16366Skarels else if (ptr->last != NIL) 200*16366Skarels ptr->last->next = ptr->next; 201*16366Skarels if (ptr->next != NIL) 202*16366Skarels ptr->next->last = ptr->last; 203*16366Skarels free((char *)ptr); 20416356Skarels } 205