Commit | Line | Data |
---|---|---|
578bbb04 KB |
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; | |
36435c9e | 30 | struct timezone txp; |
578bbb04 KB |
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 | } |