updates
[silc.git] / apps / silcd / server_util.c
1 /*
2
3   server_util.c 
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2002 Pekka Riikonen
8
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; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19 /* $Id$ */
20
21 #include "serverincludes.h"
22 #include "server_internal.h"
23
24 extern char *server_version;
25
26 /* Removes the client from channels and possibly removes the channels
27    as well.  After removing those channels that exist, their channel
28    keys are regnerated. This is called only by the function
29    silc_server_remove_clients_by_server. */
30
31 static void silc_server_remove_clients_channels(SilcServer server, 
32                                                 SilcSocketConnection sock,
33                                                 SilcClientEntry client,
34                                                 SilcHashTable channels)
35 {
36   SilcChannelEntry channel;
37   SilcChannelClientEntry chl;
38   SilcHashTableList htl;
39   SilcBuffer clidp;
40
41   SILC_LOG_DEBUG(("Start"));
42
43   if (!client || !client->id)
44     return;
45
46   clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
47
48   /* Remove the client from all channels. The client is removed from
49      the channels' user list. */
50   silc_hash_table_list(client->channels, &htl);
51   while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
52     channel = chl->channel;
53
54     /* Remove channel if this is last client leaving the channel, unless
55        the channel is permanent. */
56     if (server->server_type == SILC_ROUTER &&
57         silc_hash_table_count(channel->user_list) < 2) {
58       if (silc_hash_table_find(channels, channel, NULL, NULL))
59         silc_hash_table_del(channels, channel);
60       silc_schedule_task_del_by_context(server->schedule, channel->rekey);
61       silc_server_channel_delete(server, channel);
62       continue;
63     }
64
65     silc_hash_table_del(client->channels, channel);
66     silc_hash_table_del(channel->user_list, chl->client);
67     channel->user_count--;
68
69     /* If there is no global users on the channel anymore mark the channel
70        as local channel. Do not check if the removed client is local client. */
71     if (server->server_type != SILC_ROUTER && channel->global_users && 
72         chl->client->router && !silc_server_channel_has_global(channel))
73       channel->global_users = FALSE;
74
75     silc_free(chl);
76     server->stat.my_chanclients--;
77
78     /* If there is not at least one local user on the channel then we don't
79        need the channel entry anymore, we can remove it safely, unless the
80        channel is permanent channel */
81     if (server->server_type != SILC_ROUTER &&
82         !silc_server_channel_has_local(channel)) {
83       if (silc_hash_table_find(channels, channel, NULL, NULL))
84         silc_hash_table_del(channels, channel);
85       silc_schedule_task_del_by_context(server->schedule, channel->rekey);
86       silc_server_channel_delete(server, channel);
87       continue;
88     }
89
90     /* Add the channel to the the channels list to regenerate the 
91        channel key */
92     if (!silc_hash_table_find(channels, channel, NULL, NULL))
93       silc_hash_table_add(channels, channel, channel);
94   }
95   silc_hash_table_list_reset(&htl);
96   silc_buffer_free(clidp);
97 }
98
99 /* This function is used to remove all client entries by the server `entry'.
100    This is called when the connection is lost to the server. In this case
101    we must invalidate all the client entries owned by the server `entry'. 
102    If the `server_signoff' is TRUE then the SERVER_SIGNOFF notify is
103    distributed to our local clients. */
104
105 bool silc_server_remove_clients_by_server(SilcServer server, 
106                                           SilcServerEntry entry,
107                                           bool server_signoff)
108 {
109   SilcIDCacheList list = NULL;
110   SilcIDCacheEntry id_cache = NULL;
111   SilcClientEntry client = NULL;
112   SilcBuffer idp;
113   SilcClientEntry *clients = NULL;
114   SilcUInt32 clients_c = 0;
115   unsigned char **argv = NULL;
116   SilcUInt32 *argv_lens = NULL, *argv_types = NULL, argc = 0;
117   SilcHashTableList htl;
118   SilcChannelEntry channel;
119   SilcHashTable channels;
120   int i;
121
122   SILC_LOG_DEBUG(("Start"));
123
124   /* Allocate the hash table that holds the channels that require
125      channel key re-generation after we've removed this server's clients
126      from the channels. */
127   channels = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
128                                    NULL, NULL, TRUE);
129
130   if (server_signoff) {
131     idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
132     argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
133     argv_lens = silc_realloc(argv_lens,  sizeof(*argv_lens) * (argc + 1));
134     argv_types = silc_realloc(argv_types, sizeof(*argv_types) * (argc + 1));
135     argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
136     memcpy(argv[argc], idp->data, idp->len);
137     argv_lens[argc] = idp->len;
138     argv_types[argc] = argc + 1;
139     argc++;
140     silc_buffer_free(idp);
141   }
142
143   if (silc_idcache_get_all(server->local_list->clients, &list)) {
144
145     if (silc_idcache_list_first(list, &id_cache)) {
146       while (id_cache) {
147         client = (SilcClientEntry)id_cache->context;
148         if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
149           if (!silc_idcache_list_next(list, &id_cache))
150             break;
151           else
152             continue;
153         }
154
155         if (client->router != entry) {
156           if (server_signoff) {
157             clients = silc_realloc(clients, 
158                                    sizeof(*clients) * (clients_c + 1));
159             clients[clients_c] = client;
160             clients_c++;
161           }
162
163           if (!silc_idcache_list_next(list, &id_cache))
164             break;
165           else
166             continue;
167         }
168
169         if (server_signoff) {
170           idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
171           argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
172           argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
173                                    (argc + 1));
174           argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
175                                     (argc + 1));
176           argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
177           memcpy(argv[argc], idp->data, idp->len);
178           argv_lens[argc] = idp->len;
179           argv_types[argc] = argc + 1;
180           argc++;
181           silc_buffer_free(idp);
182         }
183
184         /* Update statistics */
185         server->stat.clients--;
186         if (server->stat.cell_clients)
187           server->stat.cell_clients--;
188         SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
189         SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
190
191         /* Remove the client entry */
192         silc_server_remove_clients_channels(server, NULL, client, channels);
193         if (!server_signoff) {
194           client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
195           id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
196         } else {
197           /* Remove this client from watcher list if it is */
198           silc_server_del_from_watcher_list(server, client);
199           silc_idlist_del_client(server->local_list, client);
200         }
201
202         if (!silc_idcache_list_next(list, &id_cache))
203           break;
204       }
205     }
206     silc_idcache_list_free(list);
207   }
208   
209   if (silc_idcache_get_all(server->global_list->clients, &list)) {
210
211     if (silc_idcache_list_first(list, &id_cache)) {
212       while (id_cache) {
213         client = (SilcClientEntry)id_cache->context;
214         if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
215           if (!silc_idcache_list_next(list, &id_cache))
216             break;
217           else
218             continue;
219         }
220         
221         if (client->router != entry) {
222           if (server_signoff && client->connection) {
223             clients = silc_realloc(clients, 
224                                    sizeof(*clients) * (clients_c + 1));
225             clients[clients_c] = client;
226             clients_c++;
227           }
228
229           if (!silc_idcache_list_next(list, &id_cache))
230             break;
231           else
232             continue;
233         }
234
235         if (server_signoff) {
236           idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
237           argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
238           argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
239                                    (argc + 1));
240           argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
241                                     (argc + 1));
242           argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
243           memcpy(argv[argc], idp->data, idp->len);
244           argv_lens[argc] = idp->len;
245           argv_types[argc] = argc + 1;
246           argc++;
247           silc_buffer_free(idp);
248         }
249
250         /* Update statistics */
251         server->stat.clients--;
252         if (server->stat.cell_clients)
253           server->stat.cell_clients--;
254         SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
255         SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
256
257         /* Remove the client entry */
258         silc_server_remove_clients_channels(server, NULL, client, channels);
259         if (!server_signoff) {
260           client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
261           id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
262         } else {
263           silc_idlist_del_client(server->global_list, client);
264         }
265
266         if (!silc_idcache_list_next(list, &id_cache))
267           break;
268       }
269     }
270     silc_idcache_list_free(list);
271   }
272
273   /* Send the SERVER_SIGNOFF notify */
274   if (server_signoff) {
275     SilcBuffer args, not;
276
277     /* Send SERVER_SIGNOFF notify to our primary router */
278     if (!server->standalone && server->router &&
279         server->router != entry) {
280       args = silc_argument_payload_encode(1, argv, argv_lens,
281                                           argv_types);
282       silc_server_send_notify_args(server, 
283                                    server->router->connection,
284                                    server->server_type == SILC_SERVER ? 
285                                    FALSE : TRUE, 
286                                    SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
287                                    argc, args);
288       silc_buffer_free(args);
289     }
290
291     /* Send to local clients. We also send the list of client ID's that
292        is to be removed for those servers that would like to use that list. */
293     args = silc_argument_payload_encode(argc, argv, argv_lens,
294                                         argv_types);
295     not = silc_notify_payload_encode_args(SILC_NOTIFY_TYPE_SERVER_SIGNOFF, 
296                                           argc, args);
297     silc_server_packet_send_clients(server, clients, clients_c,
298                                     SILC_PACKET_NOTIFY, 0, FALSE,
299                                     not->data, not->len, FALSE);
300
301     silc_free(clients);
302     silc_buffer_free(args);
303     silc_buffer_free(not);
304     for (i = 0; i < argc; i++)
305       silc_free(argv[i]);
306     silc_free(argv);
307     silc_free(argv_lens);
308     silc_free(argv_types);
309   }
310
311   /* We must now re-generate the channel key for all channels that had
312      this server's client(s) on the channel. As they left the channel we
313      must re-generate the channel key. */
314   silc_hash_table_list(channels, &htl);
315   while (silc_hash_table_get(&htl, NULL, (void **)&channel)) {
316     if (!silc_server_create_channel_key(server, channel, 0)) {
317       silc_hash_table_list_reset(&htl);
318       silc_hash_table_free(channels);
319       return FALSE;
320     }
321
322     /* Do not send the channel key if private channel key mode is set */
323     if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
324       continue;
325
326     silc_server_send_channel_key(server, NULL, channel, 
327                                  server->server_type == SILC_ROUTER ? 
328                                  FALSE : !server->standalone);
329   }
330   silc_hash_table_list_reset(&htl);
331   silc_hash_table_free(channels);
332
333   return TRUE;
334 }
335
336 static SilcServerEntry
337 silc_server_update_clients_by_real_server(SilcServer server,
338                                           SilcServerEntry from,
339                                           SilcClientEntry client,
340                                           bool local,
341                                           SilcIDCacheEntry client_cache)
342 {
343   SilcServerEntry server_entry;
344   SilcIDCacheEntry id_cache = NULL;
345   SilcIDCacheList list;
346
347   if (!silc_idcache_get_all(server->local_list->servers, &list))
348     return NULL;
349
350   if (silc_idcache_list_first(list, &id_cache)) {
351     while (id_cache) {
352       server_entry = (SilcServerEntry)id_cache->context;
353       if (server_entry != from &&
354           SILC_ID_COMPARE(server_entry->id, client->id, 
355                           client->id->ip.data_len)) {
356         SILC_LOG_DEBUG(("Found (local) %s",
357                         silc_id_render(server_entry->id, SILC_ID_SERVER)));
358
359         if (!server_entry->data.send_key && server_entry->router) {
360           SILC_LOG_DEBUG(("Server not locally connected, use its router"));
361           /* If the client is not marked as local then move it to local list
362              since the server is local. */
363           if (!local) {
364             SILC_LOG_DEBUG(("Moving client to local list"));
365             silc_idcache_add(server->local_list->clients, client_cache->name,
366                              client_cache->id, client_cache->context,
367                              client_cache->expire, NULL);
368             silc_idcache_del_by_context(server->global_list->clients, client);
369           }
370           server_entry = server_entry->router;
371         } else {
372           /* If the client is not marked as local then move it to local list
373              since the server is local. */
374           if (server_entry->server_type != SILC_BACKUP_ROUTER && !local) {
375             SILC_LOG_DEBUG(("Moving client to local list"));
376             silc_idcache_add(server->local_list->clients, client_cache->name,
377                              client_cache->id, client_cache->context,
378                              client_cache->expire, NULL);
379             silc_idcache_del_by_context(server->global_list->clients, client);
380           }
381         }
382
383         silc_idcache_list_free(list);
384         return server_entry;
385       }
386
387       if (!silc_idcache_list_next(list, &id_cache))
388         break;
389     }
390   }
391
392   silc_idcache_list_free(list);
393
394   if (!silc_idcache_get_all(server->global_list->servers, &list))
395     return NULL;
396
397   if (silc_idcache_list_first(list, &id_cache)) {
398     while (id_cache) {
399       server_entry = (SilcServerEntry)id_cache->context;
400       if (server_entry != from &&
401           SILC_ID_COMPARE(server_entry->id, client->id, 
402                           client->id->ip.data_len)) {
403         SILC_LOG_DEBUG(("Found (global) %s",
404                         silc_id_render(server_entry->id, SILC_ID_SERVER)));
405
406         if (!server_entry->data.send_key && server_entry->router) {
407           SILC_LOG_DEBUG(("Server not locally connected, use its router"));
408           /* If the client is marked as local then move it to global list
409              since the server is global. */
410           if (local) {
411             SILC_LOG_DEBUG(("Moving client to global list"));
412             silc_idcache_add(server->global_list->clients, client_cache->name,
413                              client_cache->id, client_cache->context,
414                              client_cache->expire, NULL);
415             silc_idcache_del_by_context(server->local_list->clients, client);
416           }
417           server_entry = server_entry->router;
418         } else {
419           /* If the client is marked as local then move it to global list
420              since the server is global. */
421           if (server_entry->server_type != SILC_BACKUP_ROUTER && local) {
422             SILC_LOG_DEBUG(("Moving client to global list"));
423             silc_idcache_add(server->global_list->clients, client_cache->name,
424                              client_cache->id, client_cache->context,
425                              client_cache->expire, NULL);
426             silc_idcache_del_by_context(server->local_list->clients, client);
427           }
428         }
429
430         silc_idcache_list_free(list);
431         return server_entry;
432       }
433
434       if (!silc_idcache_list_next(list, &id_cache))
435         break;
436     }
437   }
438
439   silc_idcache_list_free(list);
440
441   return NULL;
442 }
443
444 /* Updates the clients that are originated from the `from' to be originated
445    from the `to'. If the `resolve_real_server' is TRUE then this will
446    attempt to figure out which clients really are originated from the
447    `from' and which are originated from a server that we have connection
448    to, when we've acting as backup router. If it is FALSE the `to' will
449    be the new source. This function also removes the clients that are
450    *really* originated from `from' if `remove_from' is TRUE. These are
451    clients that the `from' owns, and not just clients that are behind
452    the `from'. */
453
454 void silc_server_update_clients_by_server(SilcServer server, 
455                                           SilcServerEntry from,
456                                           SilcServerEntry to,
457                                           bool resolve_real_server,
458                                           bool remove_from)
459 {
460   SilcIDCacheList list = NULL;
461   SilcIDCacheEntry id_cache = NULL;
462   SilcClientEntry client = NULL;
463   bool local;
464
465   SILC_LOG_DEBUG(("Start"));
466
467   SILC_LOG_DEBUG(("Updating %s", silc_id_render(from->id,
468                                                 SILC_ID_SERVER)));
469   SILC_LOG_DEBUG(("to %s", silc_id_render(to->id,
470                                           SILC_ID_SERVER)));
471
472
473   local = FALSE;
474   if (silc_idcache_get_all(server->global_list->clients, &list)) {
475     if (silc_idcache_list_first(list, &id_cache)) {
476       while (id_cache) {
477         client = (SilcClientEntry)id_cache->context;
478         if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
479           if (!silc_idcache_list_next(list, &id_cache))
480             break;
481           else
482             continue;
483         }
484
485         SILC_LOG_DEBUG(("Client (global) %s", 
486                         silc_id_render(client->id, SILC_ID_CLIENT)));
487         if (client->router)
488           SILC_LOG_DEBUG(("Client->router (global) %s", 
489                           silc_id_render(client->router->id, SILC_ID_SERVER)));
490
491         if (client->router == from) {
492           /* Skip clients that are *really* owned by the `from' */
493           if (remove_from && SILC_ID_COMPARE(from->id, client->id, 
494                                              client->id->ip.data_len)) {
495             SILC_LOG_DEBUG(("Found really owned client, skip it"));
496             if (!silc_idcache_list_next(list, &id_cache))
497               break;
498             else
499               continue;
500           }
501
502           if (resolve_real_server) {
503             client->router = 
504               silc_server_update_clients_by_real_server(server, from, client,
505                                                         local, id_cache);
506             if (!client->router)
507               client->router = to;
508           } else {
509             client->router = to;
510           }
511         }
512
513         if (!silc_idcache_list_next(list, &id_cache))
514           break;
515       }
516     }
517     silc_idcache_list_free(list);
518   }
519
520   local = TRUE;
521   if (silc_idcache_get_all(server->local_list->clients, &list)) {
522     if (silc_idcache_list_first(list, &id_cache)) {
523       while (id_cache) {
524         client = (SilcClientEntry)id_cache->context;
525         if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
526           if (!silc_idcache_list_next(list, &id_cache))
527             break;
528           else
529             continue;
530         }
531
532         SILC_LOG_DEBUG(("Client (local) %s", 
533                         silc_id_render(client->id, SILC_ID_CLIENT)));
534         if (client->router)
535           SILC_LOG_DEBUG(("Client->router (local) %s", 
536                           silc_id_render(client->router->id, SILC_ID_SERVER)));
537
538         if (client->router == from) {
539           /* Skip clients that are *really* owned by the `from' */
540           if (remove_from && SILC_ID_COMPARE(from->id, client->id, 
541                                              client->id->ip.data_len)) {
542             SILC_LOG_DEBUG(("Found really owned client, skip it"));
543             if (!silc_idcache_list_next(list, &id_cache))
544               break;
545             else
546               continue;
547           }
548
549           if (resolve_real_server) {
550             client->router = 
551               silc_server_update_clients_by_real_server(server, from, client,
552                                                         local, id_cache);
553             if (!client->router)
554               client->router = from; /* on local list put old from */
555           } else {
556             client->router = to;
557           }
558         }
559
560         if (!silc_idcache_list_next(list, &id_cache))
561           break;
562       }
563     }
564     silc_idcache_list_free(list);
565   }
566
567   if (remove_from)
568     /* Now remove the clients that are still marked as orignated from the
569        `from'. These are the clients that really was owned by the `from' and
570        not just exist behind the `from'. */
571     silc_server_remove_clients_by_server(server, from, TRUE);
572 }
573
574 /* Updates servers that are from `from' to be originated from `to'.  This
575    will also update the server's connection to `to's connection. */
576
577 void silc_server_update_servers_by_server(SilcServer server, 
578                                           SilcServerEntry from,
579                                           SilcServerEntry to)
580 {
581   SilcIDCacheList list = NULL;
582   SilcIDCacheEntry id_cache = NULL;
583   SilcServerEntry server_entry = NULL;
584
585   SILC_LOG_DEBUG(("Start"));
586
587   if (silc_idcache_get_all(server->local_list->servers, &list)) {
588     if (silc_idcache_list_first(list, &id_cache)) {
589       while (id_cache) {
590         server_entry = (SilcServerEntry)id_cache->context;
591         if (server_entry->router == from) {
592           server_entry->router = to;
593           server_entry->connection = to->connection;
594         }
595         if (!silc_idcache_list_next(list, &id_cache))
596           break;
597       }
598     }
599     silc_idcache_list_free(list);
600   }
601
602   if (silc_idcache_get_all(server->global_list->servers, &list)) {
603     if (silc_idcache_list_first(list, &id_cache)) {
604       while (id_cache) {
605         server_entry = (SilcServerEntry)id_cache->context;
606         if (server_entry->router == from) {
607           server_entry->router = to;
608           server_entry->connection = to->connection;
609         }
610         if (!silc_idcache_list_next(list, &id_cache))
611           break;
612       }
613     }
614     silc_idcache_list_free(list);
615   }
616 }
617
618 /* Removes channels that are from `from. */
619
620 void silc_server_remove_channels_by_server(SilcServer server, 
621                                            SilcServerEntry from)
622 {
623   SilcIDCacheList list = NULL;
624   SilcIDCacheEntry id_cache = NULL;
625   SilcChannelEntry channel = NULL;
626
627   SILC_LOG_DEBUG(("Removing channels by server"));
628
629   if (silc_idcache_get_all(server->global_list->channels, &list)) {
630     if (silc_idcache_list_first(list, &id_cache)) {
631       while (id_cache) {
632         channel = (SilcChannelEntry)id_cache->context;
633         if (channel->router == from)
634           silc_idlist_del_channel(server->global_list, channel);
635         if (!silc_idcache_list_next(list, &id_cache))
636           break;
637       }
638     }
639     silc_idcache_list_free(list);
640   }
641 }
642
643 /* Updates channels that are from `from' to be originated from `to'.  */
644
645 void silc_server_update_channels_by_server(SilcServer server, 
646                                            SilcServerEntry from,
647                                            SilcServerEntry to)
648 {
649   SilcIDCacheList list = NULL;
650   SilcIDCacheEntry id_cache = NULL;
651   SilcChannelEntry channel = NULL;
652
653   SILC_LOG_DEBUG(("Updating channels by server"));
654
655   if (silc_idcache_get_all(server->global_list->channels, &list)) {
656     if (silc_idcache_list_first(list, &id_cache)) {
657       while (id_cache) {
658         channel = (SilcChannelEntry)id_cache->context;
659         if (channel->router == from)
660           channel->router = to;
661         if (!silc_idcache_list_next(list, &id_cache))
662           break;
663       }
664     }
665     silc_idcache_list_free(list);
666   }
667 }
668
669 /* Checks whether given channel has global users.  If it does this returns
670    TRUE and FALSE if there is only locally connected clients on the channel. */
671
672 bool silc_server_channel_has_global(SilcChannelEntry channel)
673 {
674   SilcChannelClientEntry chl;
675   SilcHashTableList htl;
676
677   silc_hash_table_list(channel->user_list, &htl);
678   while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
679     if (chl->client->router) {
680       silc_hash_table_list_reset(&htl);
681       return TRUE;
682     }
683   }
684   silc_hash_table_list_reset(&htl);
685
686   return FALSE;
687 }
688
689 /* Checks whether given channel has locally connected users.  If it does this
690    returns TRUE and FALSE if there is not one locally connected client. */
691
692 bool silc_server_channel_has_local(SilcChannelEntry channel)
693 {
694   SilcChannelClientEntry chl;
695   SilcHashTableList htl;
696
697   silc_hash_table_list(channel->user_list, &htl);
698   while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
699     if (!chl->client->router) {
700       silc_hash_table_list_reset(&htl);
701       return TRUE;
702     }
703   }
704   silc_hash_table_list_reset(&htl);
705
706   return FALSE;
707 }
708
709 /* This function removes the channel and all users on the channel, unless
710    the channel is permanent.  In this case the channel is disabled but all
711    users are removed from the channel.  Returns TRUE if the channel is
712    destroyed totally, and FALSE if it is permanent and remains. */
713
714 bool silc_server_channel_delete(SilcServer server,
715                                 SilcChannelEntry channel)
716 {
717   SilcChannelClientEntry chl;
718   SilcHashTableList htl;
719   bool delchan = !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH);
720
721   if (delchan) {
722     SILC_LOG_DEBUG(("Deleting %s channel", channel->channel_name));
723
724     /* Totally delete the channel and all users on the channel. The
725        users are deleted automatically in silc_idlist_del_channel. */
726     silc_schedule_task_del_by_context(server->schedule, channel->rekey);
727     if (silc_idlist_del_channel(server->local_list, channel))
728       server->stat.my_channels--;
729     else
730       silc_idlist_del_channel(server->global_list, channel);
731     return FALSE;
732   }
733
734   /* Channel is permanent, do not remove it, remove only users */
735   channel->disabled = TRUE;
736   silc_hash_table_list(channel->user_list, &htl);
737   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
738     silc_hash_table_del(chl->client->channels, channel);
739     silc_hash_table_del(channel->user_list, chl->client);
740     channel->user_count--;
741     silc_free(chl);
742   }
743   silc_hash_table_list_reset(&htl);
744
745   SILC_LOG_DEBUG(("Channel %s remains", channel->channel_name));
746
747   return TRUE;
748 }
749
750 /* Returns TRUE if the given client is on the channel.  FALSE if not. 
751    This works because we assure that the user list on the channel is
752    always in up to date thus we can only check the channel list from 
753    `client' which is faster than checking the user list from `channel'. */
754
755 bool silc_server_client_on_channel(SilcClientEntry client,
756                                    SilcChannelEntry channel,
757                                    SilcChannelClientEntry *chl)
758 {
759   if (!client || !channel)
760     return FALSE;
761
762   return silc_hash_table_find(client->channels, channel, NULL, 
763                               (void **)chl);
764 }
765
766 /* Checks string for bad characters and returns TRUE if they are found. */
767
768 bool silc_server_name_bad_chars(const char *name, SilcUInt32 name_len)
769 {
770   int i;
771
772   for (i = 0; i < name_len; i++) {
773     if (!isascii(name[i]))
774       return TRUE;
775     if (name[i] <= 32) return TRUE;
776     if (name[i] == ' ') return TRUE;
777     if (name[i] == '*') return TRUE;
778     if (name[i] == '?') return TRUE;
779     if (name[i] == ',') return TRUE;
780   }
781
782   return FALSE;
783 }
784
785 /* Modifies the `name' if it includes bad characters and returns new
786    allocated name that does not include bad characters. */
787
788 char *silc_server_name_modify_bad(const char *name, SilcUInt32 name_len)
789 {
790   int i;
791   char *newname = strdup(name);
792
793   for (i = 0; i < name_len; i++) {
794     if (!isascii(newname[i])) newname[i] = '_';
795     if (newname[i] <= 32) newname[i] = '_';
796     if (newname[i] == ' ') newname[i] = '_';
797     if (newname[i] == '*') newname[i] = '_';
798     if (newname[i] == '?') newname[i] = '_';
799     if (newname[i] == ',') newname[i] = '_';
800   }
801
802   return newname;
803 }
804
805 /* Find number of sockets by IP address indicated by `ip'. Returns 0 if
806    socket connections with the IP address does not exist. */
807
808 SilcUInt32 silc_server_num_sockets_by_ip(SilcServer server, const char *ip,
809                                          SilcSocketType type)
810 {
811   int i, count;
812
813   for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
814     if (server->sockets[i] && !strcmp(server->sockets[i]->ip, ip) &&
815         server->sockets[i]->type == type)
816       count++;
817   }
818
819   return count;
820 }
821
822 /* Find number of sockets by IP address indicated by remote host, indicatd
823    by `ip' or `hostname', `port', and `type'.  Returns 0 if socket connections
824    does not exist. If `ip' is provided then `hostname' is ignored. */
825
826 SilcUInt32 silc_server_num_sockets_by_remote(SilcServer server, 
827                                              const char *ip,
828                                              const char *hostname,
829                                              SilcUInt16 port,
830                                              SilcSocketType type)
831 {
832   int i, count;
833
834   if (!ip && !hostname)
835     return 0;
836
837   for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
838     if (server->sockets[i] && 
839         ((ip && !strcmp(server->sockets[i]->ip, ip)) ||
840          (hostname && !strcmp(server->sockets[i]->hostname, hostname))) &&
841         server->sockets[i]->port == port &&
842         server->sockets[i]->type == type)
843       count++;
844   }
845
846   return count;
847 }
848
849 /* Finds locally cached public key by the public key received in the SKE. 
850    If we have it locally cached then we trust it and will use it in the
851    authentication protocol.  Returns the locally cached public key or NULL
852    if we do not find the public key.  */
853
854 SilcPublicKey silc_server_find_public_key(SilcServer server, 
855                                           SilcHashTable local_public_keys,
856                                           SilcPublicKey remote_public_key)
857 {
858   SilcPublicKey cached_key;
859
860   SILC_LOG_DEBUG(("Find remote public key (%d keys in local cache)",
861                   silc_hash_table_count(local_public_keys)));
862
863   if (!silc_hash_table_find_ext(local_public_keys, remote_public_key,
864                                 (void **)&cached_key, NULL, 
865                                 silc_hash_public_key, NULL,
866                                 silc_hash_public_key_compare, NULL)) {
867     SILC_LOG_ERROR(("Public key not found"));
868     return NULL;
869   }
870
871   SILC_LOG_DEBUG(("Found public key"));
872
873   return cached_key;
874 }
875
876 /* This returns the first public key from the table of public keys.  This
877    is used only in cases where single public key exists in the table and
878    we want to get a pointer to it.  For public key tables that has multiple
879    keys in it the silc_server_find_public_key must be used. */
880
881 SilcPublicKey silc_server_get_public_key(SilcServer server,
882                                          SilcHashTable local_public_keys)
883 {
884   SilcPublicKey cached_key;
885   SilcHashTableList htl;
886
887   SILC_LOG_DEBUG(("Start"));
888
889   assert(silc_hash_table_count(local_public_keys) < 2);
890
891   silc_hash_table_list(local_public_keys, &htl);
892   if (!silc_hash_table_get(&htl, NULL, (void **)&cached_key))
893     return NULL;
894   silc_hash_table_list_reset(&htl);
895
896   return cached_key;
897 }
898
899 /* Check whether the connection `sock' is allowed to connect to us.  This
900    checks for example whether there is too much connections for this host,
901    and required version for the host etc. */
902
903 bool silc_server_connection_allowed(SilcServer server, 
904                                     SilcSocketConnection sock,
905                                     SilcSocketType type,
906                                     SilcServerConfigConnParams *global,
907                                     SilcServerConfigConnParams *params,
908                                     SilcSKE ske)
909 {
910   SilcUInt32 conn_number = (type == SILC_SOCKET_TYPE_CLIENT ?
911                             server->stat.my_clients :
912                             type == SILC_SOCKET_TYPE_SERVER ?
913                             server->stat.my_servers :
914                             server->stat.my_routers);
915   SilcUInt32 num_sockets, max_hosts, max_per_host;
916   SilcUInt32 r_protocol_version, l_protocol_version;
917   SilcUInt32 r_software_version, l_software_version;
918   char *r_vendor_version = NULL, *l_vendor_version;
919
920   /* Check version */
921
922   l_protocol_version = 
923     silc_version_to_num(params && params->version_protocol ? 
924                         params->version_protocol : 
925                         global->version_protocol);
926   l_software_version = 
927     silc_version_to_num(params && params->version_software ? 
928                         params->version_software : 
929                         global->version_software);
930   l_vendor_version = (params && params->version_software_vendor ? 
931                       params->version_software_vendor : 
932                       global->version_software_vendor);
933   
934   if (ske && silc_ske_parse_version(ske, &r_protocol_version, NULL,
935                                     &r_software_version, NULL,
936                                     &r_vendor_version)) {
937     sock->version = r_protocol_version;
938
939     /* Match protocol version */
940     if (l_protocol_version && r_protocol_version &&
941         r_protocol_version < l_protocol_version) {
942       SILC_LOG_INFO(("Connection %s (%s) is too old version",
943                      sock->hostname, sock->ip));
944       silc_server_disconnect_remote(server, sock, 
945                                     SILC_STATUS_ERR_BAD_VERSION,
946                                     "You support too old protocol version");
947       return FALSE;
948     }
949
950     /* Math software version */
951     if (l_software_version && r_software_version &&
952         r_software_version < l_software_version) {
953       SILC_LOG_INFO(("Connection %s (%s) is too old version",
954                      sock->hostname, sock->ip));
955       silc_server_disconnect_remote(server, sock, 
956                                     SILC_STATUS_ERR_BAD_VERSION,
957                                     "You support too old software version");
958       return FALSE;
959     }
960
961     /* Regex match vendor version */
962     if (l_vendor_version && r_vendor_version && 
963         !silc_string_match(l_vendor_version, r_vendor_version)) {
964       SILC_LOG_INFO(("Connection %s (%s) is unsupported version",
965                      sock->hostname, sock->ip));
966       silc_server_disconnect_remote(server, sock, 
967                                     SILC_STATUS_ERR_BAD_VERSION,
968                                     "Your software is not supported");
969       return FALSE;
970     }
971   }
972   silc_free(r_vendor_version);
973
974   /* Check for maximum connections limit */
975
976   num_sockets = silc_server_num_sockets_by_ip(server, sock->ip, type);
977   max_hosts = (params ? params->connections_max : global->connections_max);
978   max_per_host = (params ? params->connections_max_per_host :
979                   global->connections_max_per_host);
980
981   if (max_hosts && conn_number >= max_hosts) {
982     SILC_LOG_INFO(("Server is full, closing %s (%s) connection",
983                    sock->hostname, sock->ip));
984     silc_server_disconnect_remote(server, sock, 
985                                   SILC_STATUS_ERR_RESOURCE_LIMIT,
986                                   "Server is full, try again later");
987     return FALSE;
988   }
989
990   if (num_sockets >= max_per_host) {
991     SILC_LOG_INFO(("Too many connections from %s (%s), closing connection",
992                    sock->hostname, sock->ip));
993     silc_server_disconnect_remote(server, sock, 
994                                   SILC_STATUS_ERR_RESOURCE_LIMIT,
995                                   "Too many connections from your host");
996     return FALSE;
997   }
998
999   return TRUE;
1000 }
1001
1002 /* Checks that client has rights to add or remove channel modes. If any
1003    of the checks fails FALSE is returned. */
1004
1005 bool silc_server_check_cmode_rights(SilcServer server,
1006                                     SilcChannelEntry channel,
1007                                     SilcChannelClientEntry client,
1008                                     SilcUInt32 mode)
1009 {
1010   bool is_op = client->mode & SILC_CHANNEL_UMODE_CHANOP;
1011   bool is_fo = client->mode & SILC_CHANNEL_UMODE_CHANFO;
1012
1013   /* Check whether has rights to change anything */
1014   if (!is_op && !is_fo)
1015     return FALSE;
1016
1017   /* Check whether has rights to change everything */
1018   if (is_op && is_fo)
1019     return TRUE;
1020
1021   /* Founder implies operator */
1022   if (is_fo)
1023     is_op = TRUE;
1024
1025   /* We know that client is channel operator, check that they are not
1026      changing anything that requires channel founder rights. Rest of the
1027      modes are available automatically for channel operator. */
1028
1029   if (mode & SILC_CHANNEL_MODE_PRIVKEY) {
1030     if (is_op && !is_fo)
1031       return FALSE;
1032   } else {
1033     if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
1034       if (is_op && !is_fo)
1035         return FALSE;
1036     }
1037   }
1038   
1039   if (mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1040     if (is_op && !is_fo)
1041       return FALSE;
1042   } else {
1043     if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1044       if (is_op && !is_fo)
1045         return FALSE;
1046     }
1047   }
1048
1049   if (mode & SILC_CHANNEL_MODE_CIPHER) {
1050     if (is_op && !is_fo)
1051       return FALSE;
1052   } else {
1053     if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
1054       if (is_op && !is_fo)
1055         return FALSE;
1056     }
1057   }
1058   
1059   if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1060     if (is_op && !is_fo)
1061       return FALSE;
1062   } else {
1063     if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1064       if (is_op && !is_fo)
1065         return FALSE;
1066     }
1067   }
1068   
1069   if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1070     if (is_op && !is_fo)
1071       return FALSE;
1072   } else {
1073     if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1074       if (is_op && !is_fo)
1075         return FALSE;
1076     }
1077   }
1078   
1079   if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1080     if (is_op && !is_fo)
1081       return FALSE;
1082   } else {
1083     if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1084       if (is_op && !is_fo)
1085         return FALSE;
1086     }
1087   }
1088   
1089   return TRUE;
1090 }
1091
1092 /* Check that the client has rights to change its user mode.  Returns
1093    FALSE if setting some mode is not allowed. */
1094
1095 bool silc_server_check_umode_rights(SilcServer server,
1096                                     SilcClientEntry client,
1097                                     SilcUInt32 mode)
1098 {
1099   bool server_op = FALSE, router_op = FALSE;
1100
1101   if (mode & SILC_UMODE_SERVER_OPERATOR) {
1102     /* Cannot set server operator mode (must use OPER command) */
1103     if (!(client->mode & SILC_UMODE_SERVER_OPERATOR))
1104       return FALSE;
1105   } else {
1106     /* Remove the server operator rights */
1107     if (client->mode & SILC_UMODE_SERVER_OPERATOR)
1108       server_op = TRUE;
1109   }
1110
1111   if (mode & SILC_UMODE_ROUTER_OPERATOR) {
1112     /* Cannot set router operator mode (must use SILCOPER command) */
1113     if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1114       return FALSE;
1115   } else {
1116     /* Remove the router operator rights */
1117     if (client->mode & SILC_UMODE_ROUTER_OPERATOR)
1118       router_op = TRUE;
1119   }
1120
1121   if (server_op)
1122     SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1123   if (router_op)
1124     SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1125
1126   return TRUE;
1127 }
1128
1129 /* This function is used to send the notify packets and motd to the
1130    incoming client connection. */
1131
1132 void silc_server_send_connect_notifys(SilcServer server,
1133                                       SilcSocketConnection sock,
1134                                       SilcClientEntry client)
1135 {
1136   SilcIDListData idata = (SilcIDListData)client;
1137
1138   /* Send some nice info to the client */
1139   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1140                           ("Welcome to the SILC Network %s",
1141                            client->username));
1142   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1143                           ("Your host is %s, running version %s",
1144                            server->server_name, server_version));
1145
1146   if (server->stat.clients && server->stat.servers + 1)
1147     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1148                             ("There are %d clients on %d servers in SILC "
1149                              "Network", server->stat.clients,
1150                              server->stat.servers + 1));
1151   if (server->stat.cell_clients && server->stat.cell_servers + 1)
1152     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1153                             ("There are %d clients on %d server in our cell",
1154                              server->stat.cell_clients,
1155                              server->stat.cell_servers + 1));
1156   if (server->server_type == SILC_ROUTER) {
1157     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1158                             ("I have %d clients, %d channels, %d servers and "
1159                              "%d routers",
1160                              server->stat.my_clients, 
1161                              server->stat.my_channels,
1162                              server->stat.my_servers,
1163                              server->stat.my_routers));
1164   } else {
1165     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1166                             ("I have %d clients and %d channels formed",
1167                              server->stat.my_clients,
1168                              server->stat.my_channels));
1169   }
1170
1171   if (server->stat.server_ops || server->stat.router_ops)
1172     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1173                             ("There are %d server operators and %d router "
1174                              "operators online",
1175                              server->stat.server_ops,
1176                              server->stat.router_ops));
1177   if (server->stat.my_router_ops + server->stat.my_server_ops)
1178     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1179                             ("I have %d operators online",
1180                              server->stat.my_router_ops +
1181                              server->stat.my_server_ops));
1182
1183   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1184                           ("Your connection is secured with %s cipher, "
1185                            "key length %d bits",
1186                            idata->send_key->cipher->name,
1187                            idata->send_key->cipher->key_len));
1188   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1189                           ("Your current nickname is %s",
1190                            client->nickname));
1191
1192   /* Send motd */
1193   silc_server_send_motd(server, sock);
1194 }
1195
1196 /* Kill the client indicated by `remote_client' sending KILLED notify
1197    to the client, to all channels client has joined and to primary
1198    router if needed.  The killed client is also removed from all channels. */
1199
1200 void silc_server_kill_client(SilcServer server,
1201                              SilcClientEntry remote_client,
1202                              const char *comment,
1203                              void *killer_id,
1204                              SilcIdType killer_id_type)
1205 {
1206   SilcBuffer killed, killer;
1207
1208   SILC_LOG_DEBUG(("Killing client %s", 
1209                   silc_id_render(remote_client->id, SILC_ID_CLIENT)));
1210
1211   /* Send the KILL notify packets. First send it to the channel, then
1212      to our primary router and then directly to the client who is being
1213      killed right now. */
1214
1215   killed = silc_id_payload_encode(remote_client->id, SILC_ID_CLIENT);
1216   killer = silc_id_payload_encode(killer_id, killer_id_type);
1217
1218   /* Send KILLED notify to the channels. It is not sent to the client
1219      as it will be sent differently destined directly to the client and not
1220      to the channel. */
1221   silc_server_send_notify_on_channels(server, remote_client, 
1222                                       remote_client, SILC_NOTIFY_TYPE_KILLED,
1223                                       3, killed->data, killed->len,
1224                                       comment, comment ? strlen(comment) : 0,
1225                                       killer->data, killer->len);
1226
1227   /* Send KILLED notify to primary route */
1228   if (!server->standalone)
1229     silc_server_send_notify_killed(server, server->router->connection, TRUE,
1230                                    remote_client->id, comment, 
1231                                    killer_id, killer_id_type);
1232
1233   /* Send KILLED notify to the client directly */
1234   if (remote_client->connection || remote_client->router)
1235     silc_server_send_notify_killed(server, remote_client->connection ? 
1236                                    remote_client->connection : 
1237                                    remote_client->router->connection, FALSE,
1238                                    remote_client->id, comment, 
1239                                    killer_id, killer_id_type);
1240
1241   /* Remove the client from all channels. This generates new keys to the
1242      channels as well. */
1243   silc_server_remove_from_channels(server, NULL, remote_client, FALSE, 
1244                                    NULL, TRUE);
1245
1246   /* Remove the client entry, If it is locally connected then we will also
1247      disconnect the client here */
1248   if (remote_client->connection) {
1249     /* Remove locally conneted client */
1250     SilcSocketConnection sock = remote_client->connection;
1251     silc_server_free_client_data(server, sock, remote_client, FALSE, NULL);
1252     silc_server_close_connection(server, sock);
1253   } else {
1254     /* Update statistics */
1255     server->stat.clients--;
1256     server->stat.my_clients--;
1257     if (server->stat.cell_clients)
1258       server->stat.cell_clients--;
1259     SILC_OPER_STATS_UPDATE(remote_client, server, SILC_UMODE_SERVER_OPERATOR);
1260     SILC_OPER_STATS_UPDATE(remote_client, router, SILC_UMODE_ROUTER_OPERATOR);
1261
1262     /* Remove remote client */
1263     if (!silc_idlist_del_client(server->global_list, remote_client)) {
1264       /* Remove this client from watcher list if it is */
1265       silc_server_del_from_watcher_list(server, remote_client);
1266       silc_idlist_del_client(server->local_list, remote_client);  
1267     }
1268   }
1269
1270   silc_buffer_free(killer);
1271   silc_buffer_free(killed);
1272 }
1273
1274 typedef struct {
1275   SilcServer server;
1276   SilcClientEntry client;
1277   SilcNotifyType notify;
1278   const char *new_nick;
1279 } WatcherNotifyContext;
1280
1281 static void 
1282 silc_server_check_watcher_list_foreach(void *key, void *context, 
1283                                        void *user_context)
1284 {
1285   WatcherNotifyContext *notify = user_context;
1286   SilcClientEntry entry = context;
1287   SilcSocketConnection sock;
1288
1289   if (entry == notify->client)
1290     return;
1291
1292   sock = silc_server_get_client_route(notify->server, NULL, 0, entry->id,
1293                                       NULL, NULL);
1294   if (sock) {
1295     SILC_LOG_DEBUG(("Sending WATCH notify to %s",
1296                     silc_id_render(entry->id, SILC_ID_CLIENT)));
1297
1298     /* Send the WATCH notify */
1299     silc_server_send_notify_watch(notify->server, sock, entry, 
1300                                   notify->client, 
1301                                   notify->new_nick ? notify->new_nick :
1302                                   (const char *)notify->client->nickname, 
1303                                   notify->notify);
1304   }
1305 }
1306
1307 /* This function checks whether the `client' nickname is being watched
1308    by someone, and notifies the watcher of the notify change of notify
1309    type indicated by `notify'. */
1310
1311 bool silc_server_check_watcher_list(SilcServer server,
1312                                     SilcClientEntry client,
1313                                     const char *new_nick,
1314                                     SilcNotifyType notify)
1315 {
1316   unsigned char hash[16];
1317   WatcherNotifyContext n;
1318
1319   SILC_LOG_DEBUG(("Start"));
1320
1321   /* If the watching is rejected by the client do nothing */
1322   if (client->mode & SILC_UMODE_REJECT_WATCHING)
1323     return FALSE;
1324
1325   /* Make hash from the nick, or take it from Client ID */
1326   if (client->nickname) {
1327     char nick[128 + 1];
1328     memset(nick, 0, sizeof(nick));
1329     silc_to_lower(client->nickname, nick, sizeof(nick) - 1);
1330     silc_hash_make(server->md5hash, nick, strlen(nick), hash);
1331   } else {
1332     memset(hash, 0, sizeof(hash));
1333     memcpy(hash, client->id->hash, sizeof(client->id->hash));
1334   }
1335
1336   n.server = server;
1337   n.client = client;
1338   n.new_nick = new_nick;
1339   n.notify = notify;
1340
1341   /* Send notify to all watchers */
1342   silc_hash_table_find_foreach(server->watcher_list, hash,
1343                                silc_server_check_watcher_list_foreach, &n);
1344
1345   return TRUE;
1346 }
1347
1348 /* Remove the `client' from watcher list. After calling this the `client'
1349    is not watching any nicknames. */
1350
1351 bool silc_server_del_from_watcher_list(SilcServer server,
1352                                        SilcClientEntry client)
1353 {
1354   SilcHashTableList htl;
1355   void *key;
1356   SilcClientEntry entry;
1357   bool found = FALSE;
1358
1359   silc_hash_table_list(server->watcher_list, &htl);
1360   while (silc_hash_table_get(&htl, &key, (void **)&entry)) {
1361     if (entry == client) {
1362       silc_hash_table_del_by_context(server->watcher_list, key, client);
1363
1364       SILC_LOG_DEBUG(("Removing %s from WATCH list",
1365                       silc_id_render(client->id, SILC_ID_CLIENT)));
1366
1367       /* Now check whether there still exists entries with this key, if not
1368          then free the key to not leak memory. */
1369       if (!silc_hash_table_find(server->watcher_list, key, NULL, NULL))
1370         silc_free(key);
1371
1372       found = TRUE;
1373     }
1374   }
1375   silc_hash_table_list_reset(&htl);
1376
1377   return found;
1378 }
1379
1380 /* Force the client indicated by `chl' to change the channel user mode
1381    on channel indicated by `channel' to `forced_mode'. */
1382
1383 bool silc_server_force_cumode_change(SilcServer server,
1384                                      SilcSocketConnection sock,
1385                                      SilcChannelEntry channel,
1386                                      SilcChannelClientEntry chl,
1387                                      SilcUInt32 forced_mode)
1388 {
1389   SilcBuffer idp1, idp2;
1390   unsigned char cumode[4];
1391
1392   SILC_LOG_DEBUG(("Start"));
1393
1394   silc_server_send_notify_cumode(server, sock, FALSE, channel, forced_mode,
1395                                  server->id, SILC_ID_SERVER,
1396                                  chl->client->id, NULL);
1397
1398   idp1 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
1399   idp2 = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
1400   SILC_PUT32_MSB(forced_mode, cumode);
1401   silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1402                                      SILC_NOTIFY_TYPE_CUMODE_CHANGE,
1403                                      3, idp1->data, idp1->len,
1404                                      cumode, sizeof(cumode),
1405                                      idp2->data, idp2->len);
1406   silc_buffer_free(idp1);
1407   silc_buffer_free(idp2);
1408
1409   return TRUE;
1410 }