5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2000 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
23 * Revision 1.4 2000/07/06 07:16:13 priikone
24 * Added SilcPublicKey's
26 * Revision 1.3 2000/07/05 06:14:01 priikone
27 * Global costemic changes.
29 * Revision 1.2 2000/07/03 05:52:11 priikone
30 * Fixed typo and a bug.
32 * Revision 1.1.1.1 2000/06/27 11:36:56 priikone
33 * Imported from internal CVS/Added Log headers.
38 #include "serverincludes.h"
41 /* Adds a new server to the list. The pointer sent as argument is allocated
44 void silc_idlist_add_server(SilcServerList **list,
45 char *server_name, int server_type,
46 SilcServerID *id, SilcServerList *router,
47 SilcCipher send_key, SilcCipher receive_key,
48 SilcPKCS public_key, SilcHmac hmac,
49 SilcServerList **new_idlist)
51 SilcServerList *last, *idlist;
53 SILC_LOG_DEBUG(("Adding new server to id list"));
55 idlist = silc_calloc(1, sizeof(*idlist));
57 SILC_LOG_ERROR(("Could not allocate new server list object"));
62 /* Set the pointers */
63 idlist->server_name = server_name;
64 idlist->server_type = server_type;
66 idlist->router = router;
67 idlist->send_key = send_key;
68 idlist->receive_key = receive_key;
69 idlist->pkcs = public_key;
71 idlist->next = idlist;
72 idlist->prev = idlist;
74 /* First on the list? */
81 /* Add it to the list */
84 (*list)->prev = idlist;
85 idlist->next = (*list);
92 /* Adds a new client to the client list. This is called when new client
93 connection is accepted to the server. This adds all the relevant data
94 about the client and session with it to the list. This list is
95 referenced for example when sending message to the client. */
97 void silc_idlist_add_client(SilcClientList **list, char *nickname,
98 char *username, char *userinfo,
99 SilcClientID *id, SilcServerList *router,
100 SilcCipher send_key, SilcCipher receive_key,
101 SilcPKCS public_key, SilcHmac hmac,
102 SilcClientList **new_idlist)
104 SilcClientList *last, *idlist;
106 SILC_LOG_DEBUG(("Adding new client to id list"));
108 idlist = silc_calloc(1, sizeof(*idlist));
109 if (idlist == NULL) {
110 SILC_LOG_ERROR(("Could not allocate new client list object"));
114 /* Set the pointers */
115 idlist->nickname = nickname;
116 idlist->username = username;
117 idlist->userinfo = userinfo;
119 idlist->router = router;
120 idlist->send_key = send_key;
121 idlist->receive_key = receive_key;
122 idlist->pkcs = public_key;
124 idlist->next = idlist;
125 idlist->prev = idlist;
127 /* First on the list? */
131 *new_idlist = idlist;
135 /* Add it to the list */
136 last = (*list)->prev;
138 (*list)->prev = idlist;
139 idlist->next = *list;
143 *new_idlist = idlist;
146 /* Free client entry. This free's everything. */
148 void silc_idlist_del_client(SilcClientList **list, SilcClientList *entry)
152 silc_free(entry->nickname);
154 silc_free(entry->username);
156 silc_free(entry->userinfo);
158 silc_free(entry->id);
160 silc_cipher_free(entry->send_key);
161 if (entry->receive_key)
162 silc_cipher_free(entry->receive_key);
164 silc_pkcs_free(entry->pkcs);
166 silc_hmac_free(entry->hmac);
167 if (entry->hmac_key) {
168 memset(entry->hmac_key, 0, entry->hmac_key_len);
169 silc_free(entry->hmac_key);
172 /* Last one in list? */
173 if (*list == entry && entry->next == entry) {
179 /* At the start of list? */
180 if (*list == entry && entry->next != entry) {
182 entry->next->prev = entry->prev;
183 entry->prev->next = *list;
188 /* Remove from list */
189 entry->prev->next = entry->next;
190 entry->next->prev = entry->prev;
197 silc_idlist_find_client_by_nickname(SilcClientList *list,
201 SilcClientList *first, *entry;
203 SILC_LOG_DEBUG(("Finding client by nickname"));
208 first = entry = list;
209 if (!strcmp(entry->nickname, nickname)) {
210 SILC_LOG_DEBUG(("Found"));
215 while(entry != first) {
216 if (!strcmp(entry->nickname, nickname)) {
217 SILC_LOG_DEBUG(("Found"));
228 silc_idlist_find_client_by_hash(SilcClientList *list,
229 char *nickname, SilcHash md5hash)
231 SilcClientList *first, *entry;
232 unsigned char hash[16];
234 SILC_LOG_DEBUG(("Finding client by nickname hash"));
239 /* Make hash of the nickname */
240 silc_hash_make(md5hash, nickname, strlen(nickname), hash);
242 first = entry = list;
243 if (entry && !SILC_ID_COMPARE_HASH(entry->id, hash)) {
244 SILC_LOG_DEBUG(("Found"));
249 while(entry != first) {
250 if (entry && !SILC_ID_COMPARE_HASH(entry->id, hash)) {
251 SILC_LOG_DEBUG(("Found"));
262 silc_idlist_find_client_by_id(SilcClientList *list, SilcClientID *id)
264 SilcClientList *first, *entry;
266 SILC_LOG_DEBUG(("Finding client by Client ID"));
271 first = entry = list;
272 if (entry && !SILC_ID_CLIENT_COMPARE(entry->id, id)) {
273 SILC_LOG_DEBUG(("Found"));
278 while(entry != first) {
279 if (entry && !SILC_ID_CLIENT_COMPARE(entry->id, id)) {
280 SILC_LOG_DEBUG(("Found"));
290 /* Adds new channel to the list. */
292 void silc_idlist_add_channel(SilcChannelList **list,
293 char *channel_name, int mode,
294 SilcChannelID *id, SilcServerList *router,
295 SilcCipher channel_key,
296 SilcChannelList **new_idlist)
298 SilcChannelList *last, *idlist;
300 SILC_LOG_DEBUG(("Adding new channel to id list"));
302 idlist = silc_calloc(1, sizeof(*idlist));
303 if (idlist == NULL) {
304 SILC_LOG_ERROR(("Could not allocate new channel list object"));
308 /* Set the pointers */
309 idlist->channel_name = channel_name;
312 idlist->router = router;
313 idlist->channel_key = channel_key;
314 idlist->next = idlist;
315 idlist->prev = idlist;
317 /* First on the list? */
321 *new_idlist = idlist;
325 /* Add it to the list */
326 last = (*list)->prev;
328 (*list)->prev = idlist;
329 idlist->next = (*list);
333 *new_idlist = idlist;
337 silc_idlist_find_channel_by_id(SilcChannelList *list, SilcChannelID *id)
339 SilcChannelList *first, *entry;
341 SILC_LOG_DEBUG(("Finding channel by Channel ID"));
346 first = entry = list;
347 if (entry && !SILC_ID_CHANNEL_COMPARE(entry->id, id)) {
348 SILC_LOG_DEBUG(("Found"));
353 while(entry != first) {
354 if (entry && !SILC_ID_CHANNEL_COMPARE(entry->id, id)) {
355 SILC_LOG_DEBUG(("Found"));
365 /* Free channel entry. This free's everything. */
367 void silc_idlist_del_channel(SilcChannelList **list, SilcChannelList *entry)
370 if (entry->channel_name)
371 silc_free(entry->channel_name);
373 silc_free(entry->id);
375 silc_free(entry->topic);
376 if (entry->channel_key)
377 silc_cipher_free(entry->channel_key);
379 memset(entry->key, 0, entry->key_len / 8);
380 silc_free(entry->key);
382 memset(entry->iv, 0, sizeof(entry->iv));
384 if (entry->user_list_count)
385 silc_free(entry->user_list);
387 /* Last one in list? */
388 if (*list == entry && entry->next == entry) {
394 /* At the start of list? */
395 if (*list == entry && entry->next != entry) {
397 entry->next->prev = entry->prev;
398 entry->prev->next = *list;
403 /* Remove from list */
404 entry->prev->next = entry->next;
405 entry->next->prev = entry->prev;