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