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