]> git.saurik.com Git - apple/network_cmds.git/blob - talkd.tproj/table.c
network_cmds-176.2.1.tar.gz
[apple/network_cmds.git] / talkd.tproj / table.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License."
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /*
25 * Copyright (c) 1983, 1993
26 * The Regents of the University of California. All rights reserved.
27 *
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
30 * are met:
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. All advertising materials mentioning features or use of this software
37 * must display the following acknowledgement:
38 * This product includes software developed by the University of
39 * California, Berkeley and its contributors.
40 * 4. Neither the name of the University nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
43 *
44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE.
55 */
56
57 #ifndef lint
58 static char sccsid[] = "@(#)table.c 8.1 (Berkeley) 6/4/93";
59 #endif /* not lint */
60
61 /*
62 * Routines to handle insertion, deletion, etc on the table
63 * of requests kept by the daemon. Nothing fancy here, linear
64 * search on a double-linked list. A time is kept with each
65 * entry so that overly old invitations can be eliminated.
66 *
67 * Consider this a mis-guided attempt at modularity
68 */
69 #include <sys/param.h>
70 #include <sys/time.h>
71 #include <sys/socket.h>
72 #include <protocols/talkd.h>
73 #include <syslog.h>
74 #include <unistd.h>
75 #include <stdio.h>
76 #include <stdlib.h>
77 #include <string.h>
78 #include "talkd.h"
79
80 #define MAX_ID 16000 /* << 2^15 so I don't have sign troubles */
81
82 #define NIL ((TABLE_ENTRY *)0)
83
84 extern int debug;
85 struct timeval tp;
86 struct timezone txp;
87
88 typedef struct table_entry TABLE_ENTRY;
89
90 struct table_entry {
91 CTL_MSG request;
92 long time;
93 TABLE_ENTRY *next;
94 TABLE_ENTRY *last;
95 };
96
97 TABLE_ENTRY *table = NIL;
98 CTL_MSG *find_request();
99 CTL_MSG *find_match();
100
101 void delete __P((TABLE_ENTRY *ptr));
102
103 /*
104 * Look in the table for an invitation that matches the current
105 * request looking for an invitation
106 */
107 CTL_MSG *
108 find_match(request)
109 register CTL_MSG *request;
110 {
111 register TABLE_ENTRY *ptr;
112 time_t current_time;
113
114 gettimeofday(&tp, &txp);
115 current_time = tp.tv_sec;
116 if (debug)
117 print_request("find_match", request);
118 for (ptr = table; ptr != NIL; ptr = ptr->next) {
119 if ((ptr->time - current_time) > MAX_LIFE) {
120 /* the entry is too old */
121 if (debug)
122 print_request("deleting expired entry",
123 &ptr->request);
124 delete(ptr);
125 continue;
126 }
127 if (debug)
128 print_request("", &ptr->request);
129 if (strcmp(request->l_name, ptr->request.r_name) == 0 &&
130 strcmp(request->r_name, ptr->request.l_name) == 0 &&
131 ptr->request.type == LEAVE_INVITE)
132 return (&ptr->request);
133 }
134 return ((CTL_MSG *)0);
135 }
136
137 /*
138 * Look for an identical request, as opposed to a complimentary
139 * one as find_match does
140 */
141 CTL_MSG *
142 find_request(request)
143 register CTL_MSG *request;
144 {
145 register TABLE_ENTRY *ptr;
146 time_t current_time;
147
148 gettimeofday(&tp, &txp);
149 current_time = tp.tv_sec;
150 /*
151 * See if this is a repeated message, and check for
152 * out of date entries in the table while we are it.
153 */
154 if (debug)
155 print_request("find_request", request);
156 for (ptr = table; ptr != NIL; ptr = ptr->next) {
157 if ((ptr->time - current_time) > MAX_LIFE) {
158 /* the entry is too old */
159 if (debug)
160 print_request("deleting expired entry",
161 &ptr->request);
162 delete(ptr);
163 continue;
164 }
165 if (debug)
166 print_request("", &ptr->request);
167 if (strcmp(request->r_name, ptr->request.r_name) == 0 &&
168 strcmp(request->l_name, ptr->request.l_name) == 0 &&
169 request->type == ptr->request.type &&
170 request->pid == ptr->request.pid) {
171 /* update the time if we 'touch' it */
172 ptr->time = current_time;
173 return (&ptr->request);
174 }
175 }
176 return ((CTL_MSG *)0);
177 }
178
179 void
180 insert_table(request, response)
181 CTL_MSG *request;
182 CTL_RESPONSE *response;
183 {
184 register TABLE_ENTRY *ptr;
185 time_t current_time;
186
187 gettimeofday(&tp, &txp);
188 current_time = tp.tv_sec;
189 request->id_num = new_id();
190 response->id_num = htonl(request->id_num);
191 /* insert a new entry into the top of the list */
192 ptr = (TABLE_ENTRY *)malloc(sizeof(TABLE_ENTRY));
193 if (ptr == NIL) {
194 syslog(LOG_ERR, "insert_table: Out of memory");
195 _exit(1);
196 }
197 ptr->time = current_time;
198 ptr->request = *request;
199 ptr->next = table;
200 if (ptr->next != NIL)
201 ptr->next->last = ptr;
202 ptr->last = NIL;
203 table = ptr;
204 }
205
206 /*
207 * Generate a unique non-zero sequence number
208 */
209 int
210 new_id()
211 {
212 static int current_id = 0;
213
214 current_id = (current_id + 1) % MAX_ID;
215 /* 0 is reserved, helps to pick up bugs */
216 if (current_id == 0)
217 current_id = 1;
218 return (current_id);
219 }
220
221 /*
222 * Delete the invitation with id 'id_num'
223 */
224 int
225 delete_invite(id_num)
226 int id_num;
227 {
228 register TABLE_ENTRY *ptr;
229
230 ptr = table;
231 if (debug)
232 syslog(LOG_DEBUG, "delete_invite(%d)", id_num);
233 for (ptr = table; ptr != NIL; ptr = ptr->next) {
234 if (ptr->request.id_num == id_num)
235 break;
236 if (debug)
237 print_request("", &ptr->request);
238 }
239 if (ptr != NIL) {
240 delete(ptr);
241 return (SUCCESS);
242 }
243 return (NOT_HERE);
244 }
245
246 /*
247 * Classic delete from a double-linked list
248 */
249 void
250 delete(ptr)
251 register TABLE_ENTRY *ptr;
252 {
253
254 if (debug)
255 print_request("delete", &ptr->request);
256 if (table == ptr)
257 table = ptr->next;
258 else if (ptr->last != NIL)
259 ptr->last->next = ptr->next;
260 if (ptr->next != NIL)
261 ptr->next->last = ptr->last;
262 free((char *)ptr);
263 }