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(("Start"));
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(("Start"));
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 emplies 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 (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
1031       if (is_op && !is_fo)
1032         return FALSE;
1033   } else {
1034     if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
1035       if (is_op && !is_fo)
1036         return FALSE;
1037     }
1038   }
1039   
1040   if (mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1041     if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE))
1042       if (is_op && !is_fo)
1043         return FALSE;
1044   } else {
1045     if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1046       if (is_op && !is_fo)
1047         return FALSE;
1048     }
1049   }
1050
1051   if (mode & SILC_CHANNEL_MODE_CIPHER) {
1052     if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER))
1053       if (is_op && !is_fo)
1054         return FALSE;
1055   } else {
1056     if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
1057       if (is_op && !is_fo)
1058         return FALSE;
1059     }
1060   }
1061   
1062   if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1063     if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH))
1064       if (is_op && !is_fo)
1065         return FALSE;
1066   } else {
1067     if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1068       if (is_op && !is_fo)
1069         return FALSE;
1070     }
1071   }
1072   
1073   if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1074     if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS))
1075       if (is_op && !is_fo)
1076         return FALSE;
1077   } else {
1078     if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1079       if (is_op && !is_fo)
1080         return FALSE;
1081     }
1082   }
1083   
1084   if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1085     if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS))
1086       if (is_op && !is_fo)
1087         return FALSE;
1088   } else {
1089     if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1090       if (is_op && !is_fo)
1091         return FALSE;
1092     }
1093   }
1094   
1095   return TRUE;
1096 }
1097
1098 /* Check that the client has rights to change its user mode.  Returns
1099    FALSE if setting some mode is not allowed. */
1100
1101 bool silc_server_check_umode_rights(SilcServer server,
1102                                     SilcClientEntry client,
1103                                     SilcUInt32 mode)
1104 {
1105   bool server_op = FALSE, router_op = FALSE;
1106
1107   if (mode & SILC_UMODE_SERVER_OPERATOR) {
1108     /* Cannot set server operator mode (must use OPER command) */
1109     if (!(client->mode & SILC_UMODE_SERVER_OPERATOR))
1110       return FALSE;
1111   } else {
1112     /* Remove the server operator rights */
1113     if (client->mode & SILC_UMODE_SERVER_OPERATOR)
1114       server_op = TRUE;
1115   }
1116
1117   if (mode & SILC_UMODE_ROUTER_OPERATOR) {
1118     /* Cannot set router operator mode (must use SILCOPER command) */
1119     if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1120       return FALSE;
1121   } else {
1122     /* Remove the router operator rights */
1123     if (client->mode & SILC_UMODE_ROUTER_OPERATOR)
1124       router_op = TRUE;
1125   }
1126
1127   if (server_op)
1128     SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1129   if (router_op)
1130     SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1131
1132   return TRUE;
1133 }
1134
1135 /* This function is used to send the notify packets and motd to the
1136    incoming client connection. */
1137
1138 void silc_server_send_connect_notifys(SilcServer server,
1139                                       SilcSocketConnection sock,
1140                                       SilcClientEntry client)
1141 {
1142   SilcIDListData idata = (SilcIDListData)client;
1143
1144   /* Send some nice info to the client */
1145   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1146                           ("Welcome to the SILC Network %s",
1147                            client->username));
1148   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1149                           ("Your host is %s, running version %s",
1150                            server->server_name, server_version));
1151
1152   if (server->stat.clients && server->stat.servers + 1)
1153     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1154                             ("There are %d clients on %d servers in SILC "
1155                              "Network", server->stat.clients,
1156                              server->stat.servers + 1));
1157   if (server->stat.cell_clients && server->stat.cell_servers + 1)
1158     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1159                             ("There are %d clients on %d server in our cell",
1160                              server->stat.cell_clients,
1161                              server->stat.cell_servers + 1));
1162   if (server->server_type == SILC_ROUTER) {
1163     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1164                             ("I have %d clients, %d channels, %d servers and "
1165                              "%d routers",
1166                              server->stat.my_clients, 
1167                              server->stat.my_channels,
1168                              server->stat.my_servers,
1169                              server->stat.my_routers));
1170   } else {
1171     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1172                             ("I have %d clients and %d channels formed",
1173                              server->stat.my_clients,
1174                              server->stat.my_channels));
1175   }
1176
1177   if (server->stat.server_ops || server->stat.router_ops)
1178     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1179                             ("There are %d server operators and %d router "
1180                              "operators online",
1181                              server->stat.server_ops,
1182                              server->stat.router_ops));
1183   if (server->stat.my_router_ops + server->stat.my_server_ops)
1184     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1185                             ("I have %d operators online",
1186                              server->stat.my_router_ops +
1187                              server->stat.my_server_ops));
1188
1189   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1190                           ("Your connection is secured with %s cipher, "
1191                            "key length %d bits",
1192                            idata->send_key->cipher->name,
1193                            idata->send_key->cipher->key_len));
1194   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1195                           ("Your current nickname is %s",
1196                            client->nickname));
1197
1198   /* Send motd */
1199   silc_server_send_motd(server, sock);
1200 }
1201
1202 /* Kill the client indicated by `remote_client' sending KILLED notify
1203    to the client, to all channels client has joined and to primary
1204    router if needed.  The killed client is also removed from all channels. */
1205
1206 void silc_server_kill_client(SilcServer server,
1207                              SilcClientEntry remote_client,
1208                              const char *comment,
1209                              void *killer_id,
1210                              SilcIdType killer_id_type)
1211 {
1212   SilcBuffer killed, killer;
1213
1214   SILC_LOG_DEBUG(("Killing client %s", 
1215                   silc_id_render(remote_client->id, SILC_ID_CLIENT)));
1216
1217   /* Send the KILL notify packets. First send it to the channel, then
1218      to our primary router and then directly to the client who is being
1219      killed right now. */
1220
1221   killed = silc_id_payload_encode(remote_client->id, SILC_ID_CLIENT);
1222   killer = silc_id_payload_encode(killer_id, killer_id_type);
1223
1224   /* Send KILLED notify to the channels. It is not sent to the client
1225      as it will be sent differently destined directly to the client and not
1226      to the channel. */
1227   silc_server_send_notify_on_channels(server, remote_client, 
1228                                       remote_client, SILC_NOTIFY_TYPE_KILLED,
1229                                       3, killed->data, killed->len,
1230                                       comment, comment ? strlen(comment) : 0,
1231                                       killer->data, killer->len);
1232
1233   /* Send KILLED notify to primary route */
1234   if (!server->standalone)
1235     silc_server_send_notify_killed(server, server->router->connection, TRUE,
1236                                    remote_client->id, comment, 
1237                                    killer_id, killer_id_type);
1238
1239   /* Send KILLED notify to the client directly */
1240   if (remote_client->connection || remote_client->router)
1241     silc_server_send_notify_killed(server, remote_client->connection ? 
1242                                    remote_client->connection : 
1243                                    remote_client->router->connection, FALSE,
1244                                    remote_client->id, comment, 
1245                                    killer_id, killer_id_type);
1246
1247   /* Remove the client from all channels. This generates new keys to the
1248      channels as well. */
1249   silc_server_remove_from_channels(server, NULL, remote_client, FALSE, 
1250                                    NULL, TRUE);
1251
1252   /* Remove the client entry, If it is locally connected then we will also
1253      disconnect the client here */
1254   if (remote_client->connection) {
1255     /* Remove locally conneted client */
1256     SilcSocketConnection sock = remote_client->connection;
1257     silc_server_free_client_data(server, sock, remote_client, FALSE, NULL);
1258     silc_server_close_connection(server, sock);
1259   } else {
1260     /* Update statistics */
1261     server->stat.clients--;
1262     server->stat.my_clients--;
1263     if (server->stat.cell_clients)
1264       server->stat.cell_clients--;
1265     SILC_OPER_STATS_UPDATE(remote_client, server, SILC_UMODE_SERVER_OPERATOR);
1266     SILC_OPER_STATS_UPDATE(remote_client, router, SILC_UMODE_ROUTER_OPERATOR);
1267
1268     /* Remove remote client */
1269     if (!silc_idlist_del_client(server->global_list, remote_client)) {
1270       /* Remove this client from watcher list if it is */
1271       silc_server_del_from_watcher_list(server, remote_client);
1272       silc_idlist_del_client(server->local_list, remote_client);  
1273     }
1274   }
1275
1276   silc_buffer_free(killer);
1277   silc_buffer_free(killed);
1278 }
1279
1280 typedef struct {
1281   SilcServer server;
1282   SilcClientEntry client;
1283   SilcNotifyType notify;
1284   const char *new_nick;
1285 } WatcherNotifyContext;
1286
1287 static void 
1288 silc_server_check_watcher_list_foreach(void *key, void *context, 
1289                                        void *user_context)
1290 {
1291   WatcherNotifyContext *notify = user_context;
1292   SilcClientEntry entry = context;
1293   SilcSocketConnection sock;
1294
1295   if (entry == notify->client)
1296     return;
1297
1298   sock = silc_server_get_client_route(notify->server, NULL, 0, entry->id,
1299                                       NULL, NULL);
1300   if (sock) {
1301     SILC_LOG_DEBUG(("Sending WATCH notify to %s",
1302                     silc_id_render(entry->id, SILC_ID_CLIENT)));
1303
1304     /* Send the WATCH notify */
1305     silc_server_send_notify_watch(notify->server, sock, entry, 
1306                                   notify->client, 
1307                                   notify->new_nick ? notify->new_nick :
1308                                   (const char *)notify->client->nickname, 
1309                                   notify->notify);
1310   }
1311 }
1312
1313 /* This function checks whether the `client' nickname is being watched
1314    by someone, and notifies the watcher of the notify change of notify
1315    type indicated by `notify'. */
1316
1317 bool silc_server_check_watcher_list(SilcServer server,
1318                                     SilcClientEntry client,
1319                                     const char *new_nick,
1320                                     SilcNotifyType notify)
1321 {
1322   unsigned char hash[16];
1323   WatcherNotifyContext n;
1324
1325   SILC_LOG_DEBUG(("Start"));
1326
1327   /* If the watching is rejected by the client do nothing */
1328   if (client->mode & SILC_UMODE_REJECT_WATCHING)
1329     return FALSE;
1330
1331   /* Make hash from the nick, or take it from Client ID */
1332   if (client->nickname) {
1333     char nick[128 + 1];
1334     memset(nick, 0, sizeof(nick));
1335     silc_to_lower(client->nickname, nick, sizeof(nick) - 1);
1336     silc_hash_make(server->md5hash, nick, strlen(nick), hash);
1337   } else {
1338     memset(hash, 0, sizeof(hash));
1339     memcpy(hash, client->id->hash, sizeof(client->id->hash));
1340   }
1341
1342   n.server = server;
1343   n.client = client;
1344   n.new_nick = new_nick;
1345   n.notify = notify;
1346
1347   /* Send notify to all watchers */
1348   silc_hash_table_find_foreach(server->watcher_list, hash,
1349                                silc_server_check_watcher_list_foreach, &n);
1350
1351   return TRUE;
1352 }
1353
1354 /* Remove the `client' from watcher list. After calling this the `client'
1355    is not watching any nicknames. */
1356
1357 bool silc_server_del_from_watcher_list(SilcServer server,
1358                                        SilcClientEntry client)
1359 {
1360   SilcHashTableList htl;
1361   void *key;
1362   SilcClientEntry entry;
1363   bool found = FALSE;
1364
1365   silc_hash_table_list(server->watcher_list, &htl);
1366   while (silc_hash_table_get(&htl, &key, (void **)&entry)) {
1367     if (entry == client) {
1368       silc_hash_table_del_by_context(server->watcher_list, key, client);
1369
1370       SILC_LOG_DEBUG(("Removing %s from WATCH list",
1371                       silc_id_render(client->id, SILC_ID_CLIENT)));
1372
1373       /* Now check whether there still exists entries with this key, if not
1374          then free the key to not leak memory. */
1375       if (!silc_hash_table_find(server->watcher_list, key, NULL, NULL))
1376         silc_free(key);
1377
1378       found = TRUE;
1379     }
1380   }
1381   silc_hash_table_list_reset(&htl);
1382
1383   return found;
1384 }
1385
1386 /* Force the client indicated by `chl' to change the channel user mode
1387    on channel indicated by `channel' to `forced_mode'. */
1388
1389 bool silc_server_force_cumode_change(SilcServer server,
1390                                      SilcSocketConnection sock,
1391                                      SilcChannelEntry channel,
1392                                      SilcChannelClientEntry chl,
1393                                      SilcUInt32 forced_mode)
1394 {
1395   SilcBuffer idp1, idp2;
1396   unsigned char cumode[4];
1397
1398   SILC_LOG_DEBUG(("Start"));
1399
1400   silc_server_send_notify_cumode(server, sock, FALSE, channel, forced_mode,
1401                                  server->id, SILC_ID_SERVER,
1402                                  chl->client->id, NULL);
1403
1404   idp1 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
1405   idp2 = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
1406   SILC_PUT32_MSB(forced_mode, cumode);
1407   silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1408                                      SILC_NOTIFY_TYPE_CUMODE_CHANGE,
1409                                      3, idp1->data, idp1->len,
1410                                      cumode, sizeof(cumode),
1411                                      idp2->data, idp2->len);
1412   silc_buffer_free(idp1);
1413   silc_buffer_free(idp2);
1414
1415   return TRUE;
1416 }