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