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