156576Sbostic /* 256576Sbostic * Copyright (c) 1983 Regents of the University of California. 356576Sbostic * All rights reserved. The Berkeley software License Agreement 456576Sbostic * specifies the terms and conditions for redistribution. 556576Sbostic */ 656576Sbostic 756576Sbostic #ifndef lint 856576Sbostic static char sccsid[] = "@(#)table.c 5.1 (Berkeley) 6/6/85"; 956576Sbostic #endif not lint 1056576Sbostic 1156576Sbostic /* 1256576Sbostic * Routines to handle insertion, deletion, etc on the table 1356576Sbostic * of requests kept by the daemon. Nothing fancy here, linear 1456576Sbostic * search on a double-linked list. A time is kept with each 1556576Sbostic * entry so that overly old invitations can be eliminated. 1656576Sbostic * 1756576Sbostic * Consider this a mis-guided attempt at modularity 1856576Sbostic */ 1956576Sbostic #include <stdio.h> 2056576Sbostic #include <sys/time.h> 2156576Sbostic 2256576Sbostic #include "ctl.h" 2356576Sbostic 2456576Sbostic #define MAX_ID 16000 /* << 2^15 so I don't have sign troubles */ 2556576Sbostic 2656576Sbostic #define NIL ((TABLE_ENTRY *)0) 2756576Sbostic 2856576Sbostic extern int debug; 2956576Sbostic struct timeval tp; 30*56579Sbostic struct timezone txp; 3156576Sbostic 3256576Sbostic typedef struct table_entry TABLE_ENTRY; 3356576Sbostic 3456576Sbostic struct table_entry { 3556576Sbostic CTL_MSG request; 3656576Sbostic long time; 3756576Sbostic TABLE_ENTRY *next; 3856576Sbostic TABLE_ENTRY *last; 3956576Sbostic }; 4056576Sbostic 4156576Sbostic TABLE_ENTRY *table = NIL; 4256576Sbostic CTL_MSG *find_request(); 4356576Sbostic CTL_MSG *find_match(); 4456576Sbostic char *malloc(); 4556576Sbostic 4656576Sbostic /* 4756576Sbostic * Look in the table for an invitation that matches the current 4856576Sbostic * request looking for an invitation 4956576Sbostic */ 5056576Sbostic CTL_MSG * 5156576Sbostic find_match(request) 5256576Sbostic CTL_MSG *request; 5356576Sbostic { 5456576Sbostic TABLE_ENTRY *ptr; 5556576Sbostic extern FILE *debugout; 5656576Sbostic long current_time; 5756576Sbostic 5856576Sbostic gettimeofday(&tp, &txp); 5956576Sbostic current_time = tp.tv_sec; 6056576Sbostic if (debug) { 6156576Sbostic fprintf(debugout, "Entering Look-Up with : \n"); 6256576Sbostic print_request(request); 6356576Sbostic } 6456576Sbostic for (ptr = table; ptr != NIL; ptr = ptr->next) { 6556576Sbostic if ((ptr->time - current_time) > MAX_LIFE) { 6656576Sbostic /* the entry is too old */ 6756576Sbostic if (debug) { 6856576Sbostic fprintf(debugout 6956576Sbostic ,"Deleting expired entry : \n"); 7056576Sbostic print_request(&ptr->request); 7156576Sbostic } 7256576Sbostic delete(ptr); 7356576Sbostic continue; 7456576Sbostic } 7556576Sbostic if (debug) 7656576Sbostic print_request(&ptr->request); 7756576Sbostic if (strcmp(request->l_name, ptr->request.r_name) == 0 && 7856576Sbostic strcmp(request->r_name, ptr->request.l_name) == 0 && 7956576Sbostic ptr->request.type == LEAVE_INVITE) 8056576Sbostic return (&ptr->request); 8156576Sbostic } 8256576Sbostic return ((CTL_MSG *)0); 8356576Sbostic } 8456576Sbostic 8556576Sbostic /* 8656576Sbostic * Look for an identical request, as opposed to a complimentary 8756576Sbostic * one as find_match does 8856576Sbostic */ 8956576Sbostic CTL_MSG * 9056576Sbostic find_request(request) 9156576Sbostic CTL_MSG *request; 9256576Sbostic { 9356576Sbostic TABLE_ENTRY *ptr; 9456576Sbostic extern FILE *debugout; 9556576Sbostic long current_time; 9656576Sbostic 9756576Sbostic gettimeofday(&tp, &txp); 9856576Sbostic current_time = tp.tv_sec; 9956576Sbostic /* 10056576Sbostic * See if this is a repeated message, and check for 10156576Sbostic * out of date entries in the table while we are it. 10256576Sbostic */ 10356576Sbostic if (debug) { 10456576Sbostic fprintf(debugout, "Entering find_request with : \n"); 10556576Sbostic print_request(request); 10656576Sbostic } 10756576Sbostic for (ptr = table; ptr != NIL; ptr = ptr->next) { 10856576Sbostic if ((ptr->time - current_time) > MAX_LIFE) { 10956576Sbostic /* the entry is too old */ 11056576Sbostic if (debug) { 11156576Sbostic fprintf(debugout 11256576Sbostic , "Deleting expired entry : \n"); 11356576Sbostic print_request(&ptr->request); 11456576Sbostic } 11556576Sbostic delete(ptr); 11656576Sbostic continue; 11756576Sbostic } 11856576Sbostic if (debug) 11956576Sbostic print_request(&ptr->request); 12056576Sbostic if (strcmp(request->r_name, ptr->request.r_name) == 0 && 12156576Sbostic strcmp(request->l_name, ptr->request.l_name) == 0 && 12256576Sbostic request->type == ptr->request.type && 12356576Sbostic request->pid == ptr->request.pid) { 12456576Sbostic /* update the time if we 'touch' it */ 12556576Sbostic ptr->time = current_time; 12656576Sbostic return (&ptr->request); 12756576Sbostic } 12856576Sbostic } 12956576Sbostic return ((CTL_MSG *)0); 13056576Sbostic } 13156576Sbostic 13256576Sbostic insert_table(request, response) 13356576Sbostic CTL_MSG *request; 13456576Sbostic CTL_RESPONSE *response; 13556576Sbostic { 13656576Sbostic TABLE_ENTRY *ptr; 13756576Sbostic long current_time; 13856576Sbostic 13956576Sbostic gettimeofday(&tp, &txp); 14056576Sbostic current_time = tp.tv_sec; 14156576Sbostic response->id_num = request->id_num = new_id(); 14256576Sbostic /* insert a new entry into the top of the list */ 14356576Sbostic ptr = (TABLE_ENTRY *)malloc(sizeof(TABLE_ENTRY)); 14456576Sbostic if (ptr == NIL) { 14556576Sbostic fprintf(stderr, "malloc in insert_table"); 14656576Sbostic exit(1); 14756576Sbostic } 14856576Sbostic ptr->time = current_time; 14956576Sbostic ptr->request = *request; 15056576Sbostic ptr->next = table; 15156576Sbostic if (ptr->next != NIL) 15256576Sbostic ptr->next->last = ptr; 15356576Sbostic ptr->last = NIL; 15456576Sbostic table = ptr; 15556576Sbostic } 15656576Sbostic 15756576Sbostic /* 15856576Sbostic * Generate a unique non-zero sequence number 15956576Sbostic */ 16056576Sbostic new_id() 16156576Sbostic { 16256576Sbostic static int current_id = 0; 16356576Sbostic 16456576Sbostic current_id = (current_id + 1) % MAX_ID; 16556576Sbostic /* 0 is reserved, helps to pick up bugs */ 16656576Sbostic if (current_id == 0) 16756576Sbostic current_id = 1; 16856576Sbostic return (current_id); 16956576Sbostic } 17056576Sbostic 17156576Sbostic /* 17256576Sbostic * Delete the invitation with id 'id_num' 17356576Sbostic */ 17456576Sbostic delete_invite(id_num) 17556576Sbostic int id_num; 17656576Sbostic { 17756576Sbostic TABLE_ENTRY *ptr; 17856576Sbostic extern FILE *debugout; 17956576Sbostic 18056576Sbostic ptr = table; 18156576Sbostic 18256576Sbostic if (debug) 18356576Sbostic fprintf(debugout,"Entering delete_invite with %d\n", id_num); 18456576Sbostic for (ptr = table; ptr != NIL; ptr = ptr->next) { 18556576Sbostic if (ptr->request.id_num == id_num) 18656576Sbostic break; 18756576Sbostic if (debug) 18856576Sbostic print_request(&ptr->request); 18956576Sbostic } 19056576Sbostic if (ptr != NIL) { 19156576Sbostic delete(ptr); 19256576Sbostic return (SUCCESS); 19356576Sbostic } 19456576Sbostic return (NOT_HERE); 19556576Sbostic } 19656576Sbostic 19756576Sbostic /* 19856576Sbostic * Classic delete from a double-linked list 19956576Sbostic */ 20056576Sbostic delete(ptr) 20156576Sbostic TABLE_ENTRY *ptr; 20256576Sbostic { 20356576Sbostic extern FILE *debugout; 20456576Sbostic 20556576Sbostic if (debug) { 20656576Sbostic fprintf(debugout, "Deleting : "); 20756576Sbostic print_request(&ptr->request); 20856576Sbostic } 20956576Sbostic if (table == ptr) 21056576Sbostic table = ptr->next; 21156576Sbostic else if (ptr->last != NIL) 21256576Sbostic ptr->last->next = ptr->next; 21356576Sbostic if (ptr->next != NIL) 21456576Sbostic ptr->next->last = ptr->last; 21556576Sbostic free((char *)ptr); 21656576Sbostic } 217