xref: /csrg-svn/libexec/talkd/table.c (revision 16356)
1*16356Skarels /* $Header: /a/guest/moore/talk/RCS/table.c,v 1.9 83/07/06 00:11:38 moore Exp $ */
2*16356Skarels 
3*16356Skarels /* routines to handle insertion, deletion, etc on the table
4*16356Skarels    of requests kept by the daemon. Nothing fancy here, linear
5*16356Skarels    search on a double-linked list. A time is kept with each
6*16356Skarels    entry so that overly old invitations can be eliminated.
7*16356Skarels 
8*16356Skarels    Consider this a mis-guided attempt at modularity
9*16356Skarels  */
10*16356Skarels 
11*16356Skarels #include "ctl.h"
12*16356Skarels #include <sys/time.h>
13*16356Skarels 
14*16356Skarels #define MAX_ID 16000 /* << 2^15 so I don't have sign troubles */
15*16356Skarels 
16*16356Skarels #define NIL ( (TABLE_ENTRY *) 0)
17*16356Skarels 
18*16356Skarels extern int debug;
19*16356Skarels struct timeval tp;
20*16356Skarels struct timezone *txp;
21*16356Skarels 
22*16356Skarels typedef struct table_entry TABLE_ENTRY;
23*16356Skarels 
24*16356Skarels struct table_entry {
25*16356Skarels     CTL_MSG request;
26*16356Skarels     long time;
27*16356Skarels     TABLE_ENTRY *next;
28*16356Skarels     TABLE_ENTRY *last;
29*16356Skarels };
30*16356Skarels 
31*16356Skarels TABLE_ENTRY *table = NIL;
32*16356Skarels CTL_MSG *find_request();
33*16356Skarels CTL_MSG *find_match();
34*16356Skarels char *malloc();
35*16356Skarels 
36*16356Skarels     /*
37*16356Skarels      * Look in the table for an invitation that matches the current
38*16356Skarels      * request looking for an invitation
39*16356Skarels      */
40*16356Skarels 
41*16356Skarels CTL_MSG *find_match(request)
42*16356Skarels CTL_MSG *request;
43*16356Skarels {
44*16356Skarels     TABLE_ENTRY *ptr;
45*16356Skarels     long current_time;
46*16356Skarels 
47*16356Skarels     gettimeofday(&tp, &txp);
48*16356Skarels     current_time = tp.tv_sec;
49*16356Skarels 
50*16356Skarels     ptr = table;
51*16356Skarels 
52*16356Skarels     if (debug) {
53*16356Skarels 	printf("Entering Look-Up with : \n");
54*16356Skarels 	print_request(request);
55*16356Skarels     }
56*16356Skarels 
57*16356Skarels     while (ptr != NIL) {
58*16356Skarels 
59*16356Skarels 	if ( (ptr->time - current_time) > MAX_LIFE ) {
60*16356Skarels 		/* the entry is too old */
61*16356Skarels 	    if (debug) printf("Deleting expired entry : \n");
62*16356Skarels 	    if (debug) print_request(&ptr->request);
63*16356Skarels 	    delete(ptr);
64*16356Skarels 	    ptr = ptr->next;
65*16356Skarels 	    continue;
66*16356Skarels 	}
67*16356Skarels 
68*16356Skarels 	if (debug) print_request(&ptr->request);
69*16356Skarels 
70*16356Skarels 	if ( strcmp(request->l_name, ptr->request.r_name) == 0 &&
71*16356Skarels 	     strcmp(request->r_name, ptr->request.l_name) == 0 &&
72*16356Skarels 	     ptr->request.type == LEAVE_INVITE ) {
73*16356Skarels 	    return(&ptr->request);
74*16356Skarels 	}
75*16356Skarels 
76*16356Skarels 	ptr = ptr->next;
77*16356Skarels     }
78*16356Skarels 
79*16356Skarels     return((CTL_MSG *) 0);
80*16356Skarels }
81*16356Skarels 
82*16356Skarels     /*
83*16356Skarels      * look for an identical request, as opposed to a complimentary
84*16356Skarels      * one as find_match does
85*16356Skarels      */
86*16356Skarels 
87*16356Skarels CTL_MSG *find_request(request)
88*16356Skarels CTL_MSG *request;
89*16356Skarels {
90*16356Skarels     TABLE_ENTRY *ptr;
91*16356Skarels     long current_time;
92*16356Skarels 
93*16356Skarels     gettimeofday(&tp, &txp);
94*16356Skarels     current_time = tp.tv_sec;
95*16356Skarels 
96*16356Skarels 	/* See if this is a repeated message, and check for
97*16356Skarels 	   out of date entries in the table while we are it.
98*16356Skarels 	 */
99*16356Skarels 
100*16356Skarels     ptr = table;
101*16356Skarels 
102*16356Skarels     if (debug) {
103*16356Skarels 	printf("Entering find_request with : \n");
104*16356Skarels 	print_request(request);
105*16356Skarels     }
106*16356Skarels 
107*16356Skarels     while (ptr != NIL) {
108*16356Skarels 
109*16356Skarels 	if ( (ptr->time - current_time) > MAX_LIFE ) {
110*16356Skarels 		/* the entry is too old */
111*16356Skarels 	    if (debug) printf("Deleting expired entry : \n");
112*16356Skarels 	    if (debug) print_request(&ptr->request);
113*16356Skarels 	    delete(ptr);
114*16356Skarels 	    ptr = ptr->next;
115*16356Skarels 	    continue;
116*16356Skarels 	}
117*16356Skarels 
118*16356Skarels 	if (debug) print_request(&ptr->request);
119*16356Skarels 
120*16356Skarels 	if ( strcmp(request->r_name, ptr->request.r_name) == 0 &&
121*16356Skarels 	     strcmp(request->l_name, ptr->request.l_name) == 0 &&
122*16356Skarels 	     request->type == ptr->request.type &&
123*16356Skarels 	     request->pid == ptr->request.pid) {
124*16356Skarels 
125*16356Skarels 		/* update the time if we 'touch' it */
126*16356Skarels 	    ptr->time = current_time;
127*16356Skarels 	    return(&ptr->request);
128*16356Skarels 	}
129*16356Skarels 
130*16356Skarels 	ptr = ptr->next;
131*16356Skarels     }
132*16356Skarels 
133*16356Skarels     return((CTL_MSG *) 0);
134*16356Skarels }
135*16356Skarels 
136*16356Skarels insert_table(request, response)
137*16356Skarels CTL_MSG *request;
138*16356Skarels CTL_RESPONSE *response;
139*16356Skarels {
140*16356Skarels     TABLE_ENTRY *ptr;
141*16356Skarels     long current_time;
142*16356Skarels 
143*16356Skarels     gettimeofday(&tp, &txp);
144*16356Skarels     current_time = tp.tv_sec;
145*16356Skarels 
146*16356Skarels     response->id_num = request->id_num = new_id();
147*16356Skarels 
148*16356Skarels 	/* insert a new entry into the top of the list */
149*16356Skarels 
150*16356Skarels     ptr = (TABLE_ENTRY *) malloc(sizeof(TABLE_ENTRY));
151*16356Skarels 
152*16356Skarels     if (ptr == NIL) {
153*16356Skarels 	print_error("malloc in insert_table");
154*16356Skarels     }
155*16356Skarels 
156*16356Skarels     ptr->time = current_time;
157*16356Skarels     ptr->request = *request;
158*16356Skarels 
159*16356Skarels     ptr->next = table;
160*16356Skarels     if (ptr->next != NIL) {
161*16356Skarels 	ptr->next->last = ptr;
162*16356Skarels     }
163*16356Skarels     ptr->last = NIL;
164*16356Skarels     table = ptr;
165*16356Skarels }
166*16356Skarels 
167*16356Skarels     /* generate a unique non-zero sequence number */
168*16356Skarels 
169*16356Skarels new_id()
170*16356Skarels {
171*16356Skarels     static int current_id = 0;
172*16356Skarels 
173*16356Skarels     current_id = (current_id + 1) % MAX_ID;
174*16356Skarels 
175*16356Skarels 	/* 0 is reserved, helps to pick up bugs */
176*16356Skarels 
177*16356Skarels     if (current_id == 0) current_id = 1;
178*16356Skarels 
179*16356Skarels     return(current_id);
180*16356Skarels }
181*16356Skarels 
182*16356Skarels     /* delete the invitation with id 'id_num' */
183*16356Skarels 
184*16356Skarels delete_invite(id_num)
185*16356Skarels int id_num;
186*16356Skarels {
187*16356Skarels     TABLE_ENTRY *ptr;
188*16356Skarels 
189*16356Skarels     ptr = table;
190*16356Skarels 
191*16356Skarels     if (debug) printf("Entering delete_invite with %d\n", id_num);
192*16356Skarels 
193*16356Skarels     while (ptr != NIL && ptr->request.id_num != id_num) {
194*16356Skarels 	if (debug) print_request(&ptr->request);
195*16356Skarels 	ptr = ptr->next;
196*16356Skarels     }
197*16356Skarels 
198*16356Skarels     if (ptr != NIL) {
199*16356Skarels 	delete(ptr);
200*16356Skarels 	return(SUCCESS);
201*16356Skarels     }
202*16356Skarels 
203*16356Skarels     return(NOT_HERE);
204*16356Skarels }
205*16356Skarels 
206*16356Skarels     /* classic delete from a double-linked list */
207*16356Skarels 
208*16356Skarels delete(ptr)
209*16356Skarels TABLE_ENTRY *ptr;
210*16356Skarels {
211*16356Skarels     if (debug) printf("Deleting : ");
212*16356Skarels     if (debug) print_request(&ptr->request);
213*16356Skarels 
214*16356Skarels     if (table == ptr) {
215*16356Skarels 	table = ptr->next;
216*16356Skarels     } else if (ptr->last != NIL) {
217*16356Skarels 	ptr->last->next = ptr->next;
218*16356Skarels     }
219*16356Skarels 
220*16356Skarels     if (ptr->next != NIL) {
221*16356Skarels 	ptr->next->last = ptr->last;
222*16356Skarels     }
223*16356Skarels 
224*16356Skarels     free((char *) ptr);
225*16356Skarels }
226