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