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