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