xref: /csrg-svn/old/talk/talkd/table.c (revision 56579)
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