116366Skarels #ifndef lint 2*16466Slayer static char sccsid[] = "@(#)table.c 1.3 (Berkeley) 05/11/84"; 316366Skarels #endif 416356Skarels 516366Skarels /* 616366Skarels * Routines to handle insertion, deletion, etc on the table 716366Skarels * of requests kept by the daemon. Nothing fancy here, linear 816366Skarels * search on a double-linked list. A time is kept with each 916366Skarels * entry so that overly old invitations can be eliminated. 1016366Skarels * 1116366Skarels * Consider this a mis-guided attempt at modularity 1216356Skarels */ 1316366Skarels #include <stdio.h> 1416366Skarels #include <sys/time.h> 1516356Skarels 1616356Skarels #include "ctl.h" 1716356Skarels 1816366Skarels #define MAX_ID 16000 /* << 2^15 so I don't have sign troubles */ 1916356Skarels 2016366Skarels #define NIL ((TABLE_ENTRY *)0) 2116356Skarels 2216366Skarels extern int debug; 2316366Skarels struct timeval tp; 2416366Skarels struct timezone *txp; 2516356Skarels 2616356Skarels typedef struct table_entry TABLE_ENTRY; 2716356Skarels 2816356Skarels struct table_entry { 2916366Skarels CTL_MSG request; 3016366Skarels long time; 3116366Skarels TABLE_ENTRY *next; 3216366Skarels TABLE_ENTRY *last; 3316356Skarels }; 3416356Skarels 3516366Skarels TABLE_ENTRY *table = NIL; 3616356Skarels CTL_MSG *find_request(); 3716356Skarels CTL_MSG *find_match(); 3816366Skarels char *malloc(); 3916356Skarels 4016366Skarels /* 4116366Skarels * Look in the table for an invitation that matches the current 4216366Skarels * request looking for an invitation 4316366Skarels */ 4416366Skarels CTL_MSG * 4516366Skarels find_match(request) 4616366Skarels CTL_MSG *request; 4716356Skarels { 4816366Skarels TABLE_ENTRY *ptr; 49*16466Slayer extern FILE *debugout; 5016366Skarels long current_time; 5116356Skarels 5216366Skarels gettimeofday(&tp, &txp); 5316366Skarels current_time = tp.tv_sec; 5416366Skarels if (debug) { 55*16466Slayer fprintf(debugout, "Entering Look-Up with : \n"); 5616366Skarels print_request(request); 5716356Skarels } 5816366Skarels for (ptr = table; ptr != NIL; ptr = ptr->next) { 5916366Skarels if ((ptr->time - current_time) > MAX_LIFE) { 6016366Skarels /* the entry is too old */ 61*16466Slayer if (debug) { 62*16466Slayer fprintf(debugout 63*16466Slayer ,"Deleting expired entry : \n"); 6416366Skarels print_request(&ptr->request); 65*16466Slayer } 6616366Skarels delete(ptr); 6716366Skarels continue; 6816366Skarels } 6916366Skarels if (debug) 7016366Skarels print_request(&ptr->request); 7116366Skarels if (strcmp(request->l_name, ptr->request.r_name) == 0 && 7216366Skarels strcmp(request->r_name, ptr->request.l_name) == 0 && 7316366Skarels ptr->request.type == LEAVE_INVITE) 7416366Skarels return (&ptr->request); 7516356Skarels } 7616366Skarels return ((CTL_MSG *)0); 7716356Skarels } 7816356Skarels 7916366Skarels /* 8016366Skarels * Look for an identical request, as opposed to a complimentary 8116366Skarels * one as find_match does 8216366Skarels */ 8316366Skarels CTL_MSG * 8416366Skarels find_request(request) 8516366Skarels CTL_MSG *request; 8616356Skarels { 8716366Skarels TABLE_ENTRY *ptr; 88*16466Slayer extern FILE *debugout; 8916366Skarels long current_time; 9016356Skarels 9116366Skarels gettimeofday(&tp, &txp); 9216366Skarels current_time = tp.tv_sec; 9316366Skarels /* 9416366Skarels * See if this is a repeated message, and check for 9516366Skarels * out of date entries in the table while we are it. 9616356Skarels */ 9716366Skarels if (debug) { 98*16466Slayer fprintf(debugout, "Entering find_request with : \n"); 9916366Skarels print_request(request); 10016356Skarels } 10116366Skarels for (ptr = table; ptr != NIL; ptr = ptr->next) { 10216366Skarels if ((ptr->time - current_time) > MAX_LIFE) { 10316366Skarels /* the entry is too old */ 10416366Skarels if (debug) { 105*16466Slayer fprintf(debugout 106*16466Slayer , "Deleting expired entry : \n"); 10716366Skarels print_request(&ptr->request); 10816366Skarels } 10916366Skarels delete(ptr); 11016366Skarels continue; 11116366Skarels } 11216366Skarels if (debug) 11316366Skarels print_request(&ptr->request); 11416366Skarels if (strcmp(request->r_name, ptr->request.r_name) == 0 && 11516366Skarels strcmp(request->l_name, ptr->request.l_name) == 0 && 11616366Skarels request->type == ptr->request.type && 11716366Skarels request->pid == ptr->request.pid) { 11816366Skarels /* update the time if we 'touch' it */ 11916366Skarels ptr->time = current_time; 12016366Skarels return (&ptr->request); 12116366Skarels } 12216356Skarels } 12316366Skarels return ((CTL_MSG *)0); 12416356Skarels } 12516356Skarels 12616356Skarels insert_table(request, response) 12716366Skarels CTL_MSG *request; 12816366Skarels CTL_RESPONSE *response; 12916356Skarels { 13016366Skarels TABLE_ENTRY *ptr; 13116366Skarels long current_time; 13216356Skarels 13316366Skarels gettimeofday(&tp, &txp); 13416366Skarels current_time = tp.tv_sec; 13516366Skarels response->id_num = request->id_num = new_id(); 13616356Skarels /* insert a new entry into the top of the list */ 13716366Skarels ptr = (TABLE_ENTRY *)malloc(sizeof(TABLE_ENTRY)); 13816366Skarels if (ptr == NIL) { 13916366Skarels fprintf(stderr, "malloc in insert_table"); 14016366Skarels exit(1); 14116366Skarels } 14216366Skarels ptr->time = current_time; 14316366Skarels ptr->request = *request; 14416366Skarels ptr->next = table; 14516366Skarels if (ptr->next != NIL) 14616366Skarels ptr->next->last = ptr; 14716366Skarels ptr->last = NIL; 14816366Skarels table = ptr; 14916356Skarels } 15016356Skarels 15116366Skarels /* 15216366Skarels * Generate a unique non-zero sequence number 15316366Skarels */ 15416356Skarels new_id() 15516356Skarels { 15616366Skarels static int current_id = 0; 15716356Skarels 15816366Skarels current_id = (current_id + 1) % MAX_ID; 15916356Skarels /* 0 is reserved, helps to pick up bugs */ 16016366Skarels if (current_id == 0) 16116366Skarels current_id = 1; 16216366Skarels return (current_id); 16316356Skarels } 16416356Skarels 16516366Skarels /* 16616366Skarels * Delete the invitation with id 'id_num' 16716366Skarels */ 16816356Skarels delete_invite(id_num) 16916366Skarels int id_num; 17016356Skarels { 17116366Skarels TABLE_ENTRY *ptr; 172*16466Slayer extern FILE *debugout; 17316356Skarels 17416366Skarels ptr = table; 17516356Skarels 17616366Skarels if (debug) 177*16466Slayer fprintf(debugout,"Entering delete_invite with %d\n", id_num); 17816366Skarels for (ptr = table; ptr != NIL; ptr = ptr->next) { 17916366Skarels if (ptr->request.id_num == id_num) 18016366Skarels break; 18116366Skarels if (debug) 18216366Skarels print_request(&ptr->request); 18316366Skarels } 18416366Skarels if (ptr != NIL) { 18516366Skarels delete(ptr); 18616366Skarels return (SUCCESS); 18716366Skarels } 18816366Skarels return (NOT_HERE); 18916356Skarels } 19016356Skarels 19116366Skarels /* 19216366Skarels * Classic delete from a double-linked list 19316366Skarels */ 19416356Skarels delete(ptr) 19516366Skarels TABLE_ENTRY *ptr; 19616356Skarels { 197*16466Slayer extern FILE *debugout; 19816356Skarels 19916366Skarels if (debug) { 200*16466Slayer fprintf(debugout, "Deleting : "); 20116366Skarels print_request(&ptr->request); 20216366Skarels } 20316366Skarels if (table == ptr) 20416366Skarels table = ptr->next; 20516366Skarels else if (ptr->last != NIL) 20616366Skarels ptr->last->next = ptr->next; 20716366Skarels if (ptr->next != NIL) 20816366Skarels ptr->next->last = ptr->last; 20916366Skarels free((char *)ptr); 21016356Skarels } 211