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