Commit | Line | Data |
---|---|---|
d0aeaf5a DF |
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 | ||
963ce42e | 7 | #ifndef lint |
595cdd5e | 8 | static char sccsid[] = "@(#)table.c 5.2 (Berkeley) %G%"; |
d0aeaf5a | 9 | #endif not lint |
963ce42e MK |
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 | |
1d0f8542 | 18 | */ |
963ce42e MK |
19 | #include <stdio.h> |
20 | #include <sys/time.h> | |
595cdd5e | 21 | #include <syslog.h> |
1d0f8542 | 22 | |
595cdd5e | 23 | #include <protocols/talkd.h> |
1d0f8542 | 24 | |
963ce42e | 25 | #define MAX_ID 16000 /* << 2^15 so I don't have sign troubles */ |
1d0f8542 | 26 | |
963ce42e | 27 | #define NIL ((TABLE_ENTRY *)0) |
1d0f8542 | 28 | |
963ce42e MK |
29 | extern int debug; |
30 | struct timeval tp; | |
31 | struct timezone *txp; | |
1d0f8542 MK |
32 | |
33 | typedef struct table_entry TABLE_ENTRY; | |
34 | ||
35 | struct table_entry { | |
963ce42e MK |
36 | CTL_MSG request; |
37 | long time; | |
38 | TABLE_ENTRY *next; | |
39 | TABLE_ENTRY *last; | |
1d0f8542 MK |
40 | }; |
41 | ||
595cdd5e | 42 | TABLE_ENTRY *table = NIL; |
1d0f8542 MK |
43 | CTL_MSG *find_request(); |
44 | CTL_MSG *find_match(); | |
963ce42e | 45 | char *malloc(); |
1d0f8542 | 46 | |
963ce42e MK |
47 | /* |
48 | * Look in the table for an invitation that matches the current | |
49 | * request looking for an invitation | |
50 | */ | |
51 | CTL_MSG * | |
52 | find_match(request) | |
595cdd5e | 53 | register CTL_MSG *request; |
1d0f8542 | 54 | { |
595cdd5e | 55 | register TABLE_ENTRY *ptr; |
963ce42e MK |
56 | long current_time; |
57 | ||
58 | gettimeofday(&tp, &txp); | |
59 | current_time = tp.tv_sec; | |
595cdd5e KM |
60 | if (debug) |
61 | print_request("find_match", request); | |
963ce42e MK |
62 | for (ptr = table; ptr != NIL; ptr = ptr->next) { |
63 | if ((ptr->time - current_time) > MAX_LIFE) { | |
64 | /* the entry is too old */ | |
595cdd5e KM |
65 | if (debug) |
66 | print_request("deleting expired entry", | |
67 | &ptr->request); | |
963ce42e MK |
68 | delete(ptr); |
69 | continue; | |
70 | } | |
71 | if (debug) | |
595cdd5e | 72 | print_request("", &ptr->request); |
963ce42e MK |
73 | if (strcmp(request->l_name, ptr->request.r_name) == 0 && |
74 | strcmp(request->r_name, ptr->request.l_name) == 0 && | |
75 | ptr->request.type == LEAVE_INVITE) | |
76 | return (&ptr->request); | |
1d0f8542 | 77 | } |
963ce42e | 78 | return ((CTL_MSG *)0); |
1d0f8542 MK |
79 | } |
80 | ||
963ce42e MK |
81 | /* |
82 | * Look for an identical request, as opposed to a complimentary | |
83 | * one as find_match does | |
84 | */ | |
85 | CTL_MSG * | |
86 | find_request(request) | |
595cdd5e | 87 | register CTL_MSG *request; |
1d0f8542 | 88 | { |
595cdd5e | 89 | register TABLE_ENTRY *ptr; |
963ce42e MK |
90 | long current_time; |
91 | ||
92 | gettimeofday(&tp, &txp); | |
93 | current_time = tp.tv_sec; | |
94 | /* | |
95 | * See if this is a repeated message, and check for | |
96 | * out of date entries in the table while we are it. | |
1d0f8542 | 97 | */ |
595cdd5e KM |
98 | if (debug) |
99 | print_request("find_request", request); | |
963ce42e MK |
100 | for (ptr = table; ptr != NIL; ptr = ptr->next) { |
101 | if ((ptr->time - current_time) > MAX_LIFE) { | |
102 | /* the entry is too old */ | |
595cdd5e KM |
103 | if (debug) |
104 | print_request("deleting expired entry", | |
105 | &ptr->request); | |
963ce42e MK |
106 | delete(ptr); |
107 | continue; | |
108 | } | |
109 | if (debug) | |
595cdd5e | 110 | print_request("", &ptr->request); |
963ce42e MK |
111 | if (strcmp(request->r_name, ptr->request.r_name) == 0 && |
112 | strcmp(request->l_name, ptr->request.l_name) == 0 && | |
113 | request->type == ptr->request.type && | |
114 | request->pid == ptr->request.pid) { | |
115 | /* update the time if we 'touch' it */ | |
116 | ptr->time = current_time; | |
117 | return (&ptr->request); | |
118 | } | |
1d0f8542 | 119 | } |
963ce42e | 120 | return ((CTL_MSG *)0); |
1d0f8542 MK |
121 | } |
122 | ||
123 | insert_table(request, response) | |
963ce42e MK |
124 | CTL_MSG *request; |
125 | CTL_RESPONSE *response; | |
1d0f8542 | 126 | { |
595cdd5e | 127 | register TABLE_ENTRY *ptr; |
963ce42e | 128 | long current_time; |
1d0f8542 | 129 | |
963ce42e MK |
130 | gettimeofday(&tp, &txp); |
131 | current_time = tp.tv_sec; | |
595cdd5e KM |
132 | request->id_num = new_id(); |
133 | response->id_num = htonl(request->id_num); | |
1d0f8542 | 134 | /* insert a new entry into the top of the list */ |
963ce42e MK |
135 | ptr = (TABLE_ENTRY *)malloc(sizeof(TABLE_ENTRY)); |
136 | if (ptr == NIL) { | |
595cdd5e KM |
137 | syslog(LOG_ERR, "insert_table: Out of memory"); |
138 | _exit(1); | |
963ce42e MK |
139 | } |
140 | ptr->time = current_time; | |
141 | ptr->request = *request; | |
142 | ptr->next = table; | |
143 | if (ptr->next != NIL) | |
144 | ptr->next->last = ptr; | |
145 | ptr->last = NIL; | |
146 | table = ptr; | |
1d0f8542 MK |
147 | } |
148 | ||
963ce42e MK |
149 | /* |
150 | * Generate a unique non-zero sequence number | |
151 | */ | |
1d0f8542 MK |
152 | new_id() |
153 | { | |
963ce42e | 154 | static int current_id = 0; |
1d0f8542 | 155 | |
963ce42e | 156 | current_id = (current_id + 1) % MAX_ID; |
1d0f8542 | 157 | /* 0 is reserved, helps to pick up bugs */ |
963ce42e MK |
158 | if (current_id == 0) |
159 | current_id = 1; | |
160 | return (current_id); | |
1d0f8542 MK |
161 | } |
162 | ||
963ce42e MK |
163 | /* |
164 | * Delete the invitation with id 'id_num' | |
165 | */ | |
1d0f8542 | 166 | delete_invite(id_num) |
963ce42e | 167 | int id_num; |
1d0f8542 | 168 | { |
595cdd5e | 169 | register TABLE_ENTRY *ptr; |
1d0f8542 | 170 | |
963ce42e | 171 | ptr = table; |
963ce42e | 172 | if (debug) |
595cdd5e | 173 | syslog(LOG_DEBUG, "delete_invite(%d)", id_num); |
963ce42e MK |
174 | for (ptr = table; ptr != NIL; ptr = ptr->next) { |
175 | if (ptr->request.id_num == id_num) | |
176 | break; | |
177 | if (debug) | |
595cdd5e | 178 | print_request("", &ptr->request); |
963ce42e MK |
179 | } |
180 | if (ptr != NIL) { | |
181 | delete(ptr); | |
182 | return (SUCCESS); | |
183 | } | |
184 | return (NOT_HERE); | |
185 | } | |
186 | ||
187 | /* | |
188 | * Classic delete from a double-linked list | |
189 | */ | |
1d0f8542 | 190 | delete(ptr) |
595cdd5e | 191 | register TABLE_ENTRY *ptr; |
1d0f8542 | 192 | { |
1d0f8542 | 193 | |
595cdd5e KM |
194 | if (debug) |
195 | print_request("delete", &ptr->request); | |
963ce42e MK |
196 | if (table == ptr) |
197 | table = ptr->next; | |
198 | else if (ptr->last != NIL) | |
199 | ptr->last->next = ptr->next; | |
200 | if (ptr->next != NIL) | |
201 | ptr->next->last = ptr->last; | |
202 | free((char *)ptr); | |
1d0f8542 | 203 | } |