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