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