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