1*22399Sdist /* 2*22399Sdist * Copyright (c) 1983 Regents of the University of California. 3*22399Sdist * All rights reserved. The Berkeley software License Agreement 4*22399Sdist * specifies the terms and conditions for redistribution. 5*22399Sdist */ 6*22399Sdist 716366Skarels #ifndef lint 8*22399Sdist static char sccsid[] = "@(#)table.c 5.1 (Berkeley) 06/06/85"; 9*22399Sdist #endif not lint 1016356Skarels 1116366Skarels /* 1216366Skarels * Routines to handle insertion, deletion, etc on the table 1316366Skarels * of requests kept by the daemon. Nothing fancy here, linear 1416366Skarels * search on a double-linked list. A time is kept with each 1516366Skarels * entry so that overly old invitations can be eliminated. 1616366Skarels * 1716366Skarels * Consider this a mis-guided attempt at modularity 1816356Skarels */ 1916366Skarels #include <stdio.h> 2016366Skarels #include <sys/time.h> 2116356Skarels 2216356Skarels #include "ctl.h" 2316356Skarels 2416366Skarels #define MAX_ID 16000 /* << 2^15 so I don't have sign troubles */ 2516356Skarels 2616366Skarels #define NIL ((TABLE_ENTRY *)0) 2716356Skarels 2816366Skarels extern int debug; 2916366Skarels struct timeval tp; 3016366Skarels struct timezone *txp; 3116356Skarels 3216356Skarels typedef struct table_entry TABLE_ENTRY; 3316356Skarels 3416356Skarels struct table_entry { 3516366Skarels CTL_MSG request; 3616366Skarels long time; 3716366Skarels TABLE_ENTRY *next; 3816366Skarels TABLE_ENTRY *last; 3916356Skarels }; 4016356Skarels 4116366Skarels TABLE_ENTRY *table = NIL; 4216356Skarels CTL_MSG *find_request(); 4316356Skarels CTL_MSG *find_match(); 4416366Skarels char *malloc(); 4516356Skarels 4616366Skarels /* 4716366Skarels * Look in the table for an invitation that matches the current 4816366Skarels * request looking for an invitation 4916366Skarels */ 5016366Skarels CTL_MSG * 5116366Skarels find_match(request) 5216366Skarels CTL_MSG *request; 5316356Skarels { 5416366Skarels TABLE_ENTRY *ptr; 5516466Slayer extern FILE *debugout; 5616366Skarels long current_time; 5716356Skarels 5816366Skarels gettimeofday(&tp, &txp); 5916366Skarels current_time = tp.tv_sec; 6016366Skarels if (debug) { 6116466Slayer fprintf(debugout, "Entering Look-Up with : \n"); 6216366Skarels print_request(request); 6316356Skarels } 6416366Skarels for (ptr = table; ptr != NIL; ptr = ptr->next) { 6516366Skarels if ((ptr->time - current_time) > MAX_LIFE) { 6616366Skarels /* the entry is too old */ 6716466Slayer if (debug) { 6816466Slayer fprintf(debugout 6916466Slayer ,"Deleting expired entry : \n"); 7016366Skarels print_request(&ptr->request); 7116466Slayer } 7216366Skarels delete(ptr); 7316366Skarels continue; 7416366Skarels } 7516366Skarels if (debug) 7616366Skarels print_request(&ptr->request); 7716366Skarels if (strcmp(request->l_name, ptr->request.r_name) == 0 && 7816366Skarels strcmp(request->r_name, ptr->request.l_name) == 0 && 7916366Skarels ptr->request.type == LEAVE_INVITE) 8016366Skarels return (&ptr->request); 8116356Skarels } 8216366Skarels return ((CTL_MSG *)0); 8316356Skarels } 8416356Skarels 8516366Skarels /* 8616366Skarels * Look for an identical request, as opposed to a complimentary 8716366Skarels * one as find_match does 8816366Skarels */ 8916366Skarels CTL_MSG * 9016366Skarels find_request(request) 9116366Skarels CTL_MSG *request; 9216356Skarels { 9316366Skarels TABLE_ENTRY *ptr; 9416466Slayer extern FILE *debugout; 9516366Skarels long current_time; 9616356Skarels 9716366Skarels gettimeofday(&tp, &txp); 9816366Skarels current_time = tp.tv_sec; 9916366Skarels /* 10016366Skarels * See if this is a repeated message, and check for 10116366Skarels * out of date entries in the table while we are it. 10216356Skarels */ 10316366Skarels if (debug) { 10416466Slayer fprintf(debugout, "Entering find_request with : \n"); 10516366Skarels print_request(request); 10616356Skarels } 10716366Skarels for (ptr = table; ptr != NIL; ptr = ptr->next) { 10816366Skarels if ((ptr->time - current_time) > MAX_LIFE) { 10916366Skarels /* the entry is too old */ 11016366Skarels if (debug) { 11116466Slayer fprintf(debugout 11216466Slayer , "Deleting expired entry : \n"); 11316366Skarels print_request(&ptr->request); 11416366Skarels } 11516366Skarels delete(ptr); 11616366Skarels continue; 11716366Skarels } 11816366Skarels if (debug) 11916366Skarels print_request(&ptr->request); 12016366Skarels if (strcmp(request->r_name, ptr->request.r_name) == 0 && 12116366Skarels strcmp(request->l_name, ptr->request.l_name) == 0 && 12216366Skarels request->type == ptr->request.type && 12316366Skarels request->pid == ptr->request.pid) { 12416366Skarels /* update the time if we 'touch' it */ 12516366Skarels ptr->time = current_time; 12616366Skarels return (&ptr->request); 12716366Skarels } 12816356Skarels } 12916366Skarels return ((CTL_MSG *)0); 13016356Skarels } 13116356Skarels 13216356Skarels insert_table(request, response) 13316366Skarels CTL_MSG *request; 13416366Skarels CTL_RESPONSE *response; 13516356Skarels { 13616366Skarels TABLE_ENTRY *ptr; 13716366Skarels long current_time; 13816356Skarels 13916366Skarels gettimeofday(&tp, &txp); 14016366Skarels current_time = tp.tv_sec; 14116366Skarels response->id_num = request->id_num = new_id(); 14216356Skarels /* insert a new entry into the top of the list */ 14316366Skarels ptr = (TABLE_ENTRY *)malloc(sizeof(TABLE_ENTRY)); 14416366Skarels if (ptr == NIL) { 14516366Skarels fprintf(stderr, "malloc in insert_table"); 14616366Skarels exit(1); 14716366Skarels } 14816366Skarels ptr->time = current_time; 14916366Skarels ptr->request = *request; 15016366Skarels ptr->next = table; 15116366Skarels if (ptr->next != NIL) 15216366Skarels ptr->next->last = ptr; 15316366Skarels ptr->last = NIL; 15416366Skarels table = ptr; 15516356Skarels } 15616356Skarels 15716366Skarels /* 15816366Skarels * Generate a unique non-zero sequence number 15916366Skarels */ 16016356Skarels new_id() 16116356Skarels { 16216366Skarels static int current_id = 0; 16316356Skarels 16416366Skarels current_id = (current_id + 1) % MAX_ID; 16516356Skarels /* 0 is reserved, helps to pick up bugs */ 16616366Skarels if (current_id == 0) 16716366Skarels current_id = 1; 16816366Skarels return (current_id); 16916356Skarels } 17016356Skarels 17116366Skarels /* 17216366Skarels * Delete the invitation with id 'id_num' 17316366Skarels */ 17416356Skarels delete_invite(id_num) 17516366Skarels int id_num; 17616356Skarels { 17716366Skarels TABLE_ENTRY *ptr; 17816466Slayer extern FILE *debugout; 17916356Skarels 18016366Skarels ptr = table; 18116356Skarels 18216366Skarels if (debug) 18316466Slayer fprintf(debugout,"Entering delete_invite with %d\n", id_num); 18416366Skarels for (ptr = table; ptr != NIL; ptr = ptr->next) { 18516366Skarels if (ptr->request.id_num == id_num) 18616366Skarels break; 18716366Skarels if (debug) 18816366Skarels print_request(&ptr->request); 18916366Skarels } 19016366Skarels if (ptr != NIL) { 19116366Skarels delete(ptr); 19216366Skarels return (SUCCESS); 19316366Skarels } 19416366Skarels return (NOT_HERE); 19516356Skarels } 19616356Skarels 19716366Skarels /* 19816366Skarels * Classic delete from a double-linked list 19916366Skarels */ 20016356Skarels delete(ptr) 20116366Skarels TABLE_ENTRY *ptr; 20216356Skarels { 20316466Slayer extern FILE *debugout; 20416356Skarels 20516366Skarels if (debug) { 20616466Slayer fprintf(debugout, "Deleting : "); 20716366Skarels print_request(&ptr->request); 20816366Skarels } 20916366Skarels if (table == ptr) 21016366Skarels table = ptr->next; 21116366Skarels else if (ptr->last != NIL) 21216366Skarels ptr->last->next = ptr->next; 21316366Skarels if (ptr->next != NIL) 21416366Skarels ptr->next->last = ptr->last; 21516366Skarels free((char *)ptr); 21616356Skarels } 217