silcd: Fixed SIGUSR1 signal handling
[silc.git] / apps / silcd / command.c
index 698b22657ac1c719dbfc455c7ae8e6a45ffb6a7f..0ddc787e951c4ed441d346fe1aaf5683f5a96107 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2008 Pekka Riikonen
+  Copyright (C) 1997 - 2009 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -339,7 +339,7 @@ SILC_TASK_CALLBACK(silc_server_command_pending_timeout)
   SilcBuffer tmpreply;
   int i;
 
-  SILC_LOG_DEBUG(("Timeout pending command"));
+  SILC_LOG_DEBUG(("Timeout pending command %p", reply));
 
   /* Allocate temporary and bogus command reply context */
   cmdr = silc_calloc(1, sizeof(*cmdr));
@@ -2379,7 +2379,7 @@ SILC_SERVER_CMD_FUNC(join)
        channel will be global, based on our router name. */
     if (!serv[0] && !server->config->local_channels) {
       if (!server->standalone) {
-       silc_snprintf(serv, sizeof(serv), server->router->server_name);
+       silc_snprintf(serv, sizeof(serv), "%s", server->router->server_name);
       } else {
        SilcServerConfigRouter *router;
        router = silc_server_config_get_primary_router(server);
@@ -4065,29 +4065,44 @@ SILC_TASK_CALLBACK(silc_server_command_detach_cb)
 {
   SilcServer server = app_context;
   QuitInternal q = (QuitInternal)context;
-  SilcClientID *client_id = (SilcClientID *)q->sock;
-  SilcClientEntry client;
-  SilcPacketStream sock;
+  SilcPacketStream sock = q->sock;
+  SilcClientEntry client = silc_packet_get_context(sock);
+  SilcIDListData idata = (SilcIDListData)client;
 
-  client = silc_idlist_find_client_by_id(server->local_list, client_id,
-                                        TRUE, NULL);
-  if (client && client->connection) {
-    sock = client->connection;
+  if (!client) {
+    silc_packet_stream_unref(sock);
+    silc_free(q);
+    return;
+  }
 
-    /* Close the connection on our side */
-    client->router = NULL;
-    client->connection = NULL;
-    silc_server_close_connection(server, sock);
+  SILC_LOG_DEBUG(("Detaching client %s",
+                 silc_id_render(client->id, SILC_ID_CLIENT)));
 
-    /*
-     * Decrement the user count; we'll increment it if the user resumes on our
-     * server.
-     */
-    SILC_VERIFY(&server->stat.my_clients > 0);
-    server->stat.my_clients--;
+  /* Stop rekey for the client. */
+  silc_server_stop_rekey(server, client);
+
+  /* Abort any active protocol */
+  idata = silc_packet_get_context(sock);
+  if (idata && idata->sconn && idata->sconn->op) {
+    SILC_LOG_DEBUG(("Abort active protocol"));
+    silc_async_abort(idata->sconn->op, NULL, NULL);
+    idata->sconn->op = NULL;
   }
 
-  silc_free(client_id);
+  /* Close the connection on our side */
+  client->router = NULL;
+  client->connection = NULL;
+  silc_server_close_connection(server, sock);
+
+  /* Mark the client as locally detached. */
+  client->local_detached = TRUE;
+
+  /* Decrement the user count; we'll increment it if the user resumes on our
+     server. */
+  SILC_VERIFY(&server->stat.my_clients > 0);
+  server->stat.my_clients--;
+
+  silc_packet_stream_unref(sock);
   silc_free(q);
 }
 
@@ -4154,14 +4169,15 @@ SILC_SERVER_CMD_FUNC(detach)
                                   SILC_NOTIFY_TYPE_UMODE_CHANGE);
 
   q = silc_calloc(1, sizeof(*q));
-  q->sock = silc_id_dup(client->id, SILC_ID_CLIENT);
+  q->sock = cmd->sock;
+  silc_packet_stream_ref(q->sock);
   silc_schedule_task_add_timeout(server->schedule,
                                 silc_server_command_detach_cb,
                                 q, 0, 200000);
 
   if (server->config->detach_timeout) {
     q = silc_calloc(1, sizeof(*q));
-    q->sock = silc_id_dup(client->id, SILC_ID_CLIENT);
+    q->sock = (void *)silc_id_dup(client->id, SILC_ID_CLIENT);
     silc_schedule_task_add_timeout(server->schedule,
                                   silc_server_command_detach_timeout,
                                   q, server->config->detach_timeout * 60, 0);