xref: /csrg-svn/libexec/talkd/table.c (revision 16366)
1*16366Skarels #ifndef lint
2*16366Skarels static char sccsid[] = "@(#)table.c	1.2 (Berkeley) 04/11/84";
3*16366Skarels #endif
416356Skarels 
5*16366Skarels /*
6*16366Skarels  * Routines to handle insertion, deletion, etc on the table
7*16366Skarels  * of requests kept by the daemon. Nothing fancy here, linear
8*16366Skarels  * search on a double-linked list. A time is kept with each
9*16366Skarels  * entry so that overly old invitations can be eliminated.
10*16366Skarels  *
11*16366Skarels  * Consider this a mis-guided attempt at modularity
1216356Skarels  */
13*16366Skarels #include <stdio.h>
14*16366Skarels #include <sys/time.h>
1516356Skarels 
1616356Skarels #include "ctl.h"
1716356Skarels 
18*16366Skarels #define MAX_ID 16000	/* << 2^15 so I don't have sign troubles */
1916356Skarels 
20*16366Skarels #define NIL ((TABLE_ENTRY *)0)
2116356Skarels 
22*16366Skarels extern	int debug;
23*16366Skarels struct	timeval tp;
24*16366Skarels struct	timezone *txp;
2516356Skarels 
2616356Skarels typedef struct table_entry TABLE_ENTRY;
2716356Skarels 
2816356Skarels struct table_entry {
29*16366Skarels 	CTL_MSG request;
30*16366Skarels 	long	time;
31*16366Skarels 	TABLE_ENTRY *next;
32*16366Skarels 	TABLE_ENTRY *last;
3316356Skarels };
3416356Skarels 
35*16366Skarels TABLE_ENTRY	*table = NIL;
3616356Skarels CTL_MSG *find_request();
3716356Skarels CTL_MSG *find_match();
38*16366Skarels char	*malloc();
3916356Skarels 
40*16366Skarels /*
41*16366Skarels  * Look in the table for an invitation that matches the current
42*16366Skarels  * request looking for an invitation
43*16366Skarels  */
44*16366Skarels CTL_MSG *
45*16366Skarels find_match(request)
46*16366Skarels 	CTL_MSG *request;
4716356Skarels {
48*16366Skarels 	TABLE_ENTRY *ptr;
49*16366Skarels 	long current_time;
5016356Skarels 
51*16366Skarels 	gettimeofday(&tp, &txp);
52*16366Skarels 	current_time = tp.tv_sec;
53*16366Skarels 	if (debug) {
54*16366Skarels 		printf("Entering Look-Up with : \n");
55*16366Skarels 		print_request(request);
5616356Skarels 	}
57*16366Skarels 	for (ptr = table; ptr != NIL; ptr = ptr->next) {
58*16366Skarels 		if ((ptr->time - current_time) > MAX_LIFE) {
59*16366Skarels 			/* the entry is too old */
60*16366Skarels 			if (debug)
61*16366Skarels 				printf("Deleting expired entry : \n");
62*16366Skarels 			if (debug)
63*16366Skarels 				print_request(&ptr->request);
64*16366Skarels 			delete(ptr);
65*16366Skarels 			continue;
66*16366Skarels 		}
67*16366Skarels 		if (debug)
68*16366Skarels 			print_request(&ptr->request);
69*16366Skarels 		if (strcmp(request->l_name, ptr->request.r_name) == 0 &&
70*16366Skarels 		    strcmp(request->r_name, ptr->request.l_name) == 0 &&
71*16366Skarels 		     ptr->request.type == LEAVE_INVITE)
72*16366Skarels 			return (&ptr->request);
7316356Skarels 	}
74*16366Skarels 	return ((CTL_MSG *)0);
7516356Skarels }
7616356Skarels 
77*16366Skarels /*
78*16366Skarels  * Look for an identical request, as opposed to a complimentary
79*16366Skarels  * one as find_match does
80*16366Skarels  */
81*16366Skarels CTL_MSG *
82*16366Skarels find_request(request)
83*16366Skarels 	CTL_MSG *request;
8416356Skarels {
85*16366Skarels 	TABLE_ENTRY *ptr;
86*16366Skarels 	long current_time;
8716356Skarels 
88*16366Skarels 	gettimeofday(&tp, &txp);
89*16366Skarels 	current_time = tp.tv_sec;
90*16366Skarels 	/*
91*16366Skarels 	 * See if this is a repeated message, and check for
92*16366Skarels 	 * out of date entries in the table while we are it.
9316356Skarels 	 */
94*16366Skarels 	if (debug) {
95*16366Skarels 		printf("Entering find_request with : \n");
96*16366Skarels 		print_request(request);
9716356Skarels 	}
98*16366Skarels 	for (ptr = table; ptr != NIL; ptr = ptr->next) {
99*16366Skarels 		if ((ptr->time - current_time) > MAX_LIFE) {
100*16366Skarels 			/* the entry is too old */
101*16366Skarels 			if (debug) {
102*16366Skarels 				printf("Deleting expired entry : \n");
103*16366Skarels 				print_request(&ptr->request);
104*16366Skarels 			}
105*16366Skarels 			delete(ptr);
106*16366Skarels 			continue;
107*16366Skarels 		}
108*16366Skarels 		if (debug)
109*16366Skarels 			print_request(&ptr->request);
110*16366Skarels 		if (strcmp(request->r_name, ptr->request.r_name) == 0 &&
111*16366Skarels 		    strcmp(request->l_name, ptr->request.l_name) == 0 &&
112*16366Skarels 		    request->type == ptr->request.type &&
113*16366Skarels 		    request->pid == ptr->request.pid) {
114*16366Skarels 			/* update the time if we 'touch' it */
115*16366Skarels 			ptr->time = current_time;
116*16366Skarels 			return (&ptr->request);
117*16366Skarels 		}
11816356Skarels 	}
119*16366Skarels 	return ((CTL_MSG *)0);
12016356Skarels }
12116356Skarels 
12216356Skarels insert_table(request, response)
123*16366Skarels 	CTL_MSG *request;
124*16366Skarels 	CTL_RESPONSE *response;
12516356Skarels {
126*16366Skarels 	TABLE_ENTRY *ptr;
127*16366Skarels 	long current_time;
12816356Skarels 
129*16366Skarels 	gettimeofday(&tp, &txp);
130*16366Skarels 	current_time = tp.tv_sec;
131*16366Skarels 	response->id_num = request->id_num = new_id();
13216356Skarels 	/* insert a new entry into the top of the list */
133*16366Skarels 	ptr = (TABLE_ENTRY *)malloc(sizeof(TABLE_ENTRY));
134*16366Skarels 	if (ptr == NIL) {
135*16366Skarels 		fprintf(stderr, "malloc in insert_table");
136*16366Skarels 		exit(1);
137*16366Skarels 	}
138*16366Skarels 	ptr->time = current_time;
139*16366Skarels 	ptr->request = *request;
140*16366Skarels 	ptr->next = table;
141*16366Skarels 	if (ptr->next != NIL)
142*16366Skarels 		ptr->next->last = ptr;
143*16366Skarels 	ptr->last = NIL;
144*16366Skarels 	table = ptr;
14516356Skarels }
14616356Skarels 
147*16366Skarels /*
148*16366Skarels  * Generate a unique non-zero sequence number
149*16366Skarels  */
15016356Skarels new_id()
15116356Skarels {
152*16366Skarels 	static int current_id = 0;
15316356Skarels 
154*16366Skarels 	current_id = (current_id + 1) % MAX_ID;
15516356Skarels 	/* 0 is reserved, helps to pick up bugs */
156*16366Skarels 	if (current_id == 0)
157*16366Skarels 		current_id = 1;
158*16366Skarels 	return (current_id);
15916356Skarels }
16016356Skarels 
161*16366Skarels /*
162*16366Skarels  * Delete the invitation with id 'id_num'
163*16366Skarels  */
16416356Skarels delete_invite(id_num)
165*16366Skarels 	int id_num;
16616356Skarels {
167*16366Skarels 	TABLE_ENTRY *ptr;
16816356Skarels 
169*16366Skarels 	ptr = table;
17016356Skarels 
171*16366Skarels 	if (debug)
172*16366Skarels 		printf("Entering delete_invite with %d\n", id_num);
173*16366Skarels 	for (ptr = table; ptr != NIL; ptr = ptr->next) {
174*16366Skarels 		if (ptr->request.id_num == id_num)
175*16366Skarels 			break;
176*16366Skarels 		if (debug)
177*16366Skarels 			print_request(&ptr->request);
178*16366Skarels 	}
179*16366Skarels 	if (ptr != NIL) {
180*16366Skarels 		delete(ptr);
181*16366Skarels 		return (SUCCESS);
182*16366Skarels 	}
183*16366Skarels 	return (NOT_HERE);
18416356Skarels }
18516356Skarels 
186*16366Skarels /*
187*16366Skarels  * Classic delete from a double-linked list
188*16366Skarels  */
18916356Skarels delete(ptr)
190*16366Skarels 	TABLE_ENTRY *ptr;
19116356Skarels {
19216356Skarels 
193*16366Skarels 	if (debug) {
194*16366Skarels 		printf("Deleting : ");
195*16366Skarels 		print_request(&ptr->request);
196*16366Skarels 	}
197*16366Skarels 	if (table == ptr)
198*16366Skarels 		table = ptr->next;
199*16366Skarels 	else if (ptr->last != NIL)
200*16366Skarels 		ptr->last->next = ptr->next;
201*16366Skarels 	if (ptr->next != NIL)
202*16366Skarels 		ptr->next->last = ptr->last;
203*16366Skarels 	free((char *)ptr);
20416356Skarels }
205