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