Fixed NOTIFY_TYPE_JOIN handling (new Toolkit API change).
[silc.git] / apps / irssi / src / silc / core / client_ops.c
index bf0a1881ea53fdb29fdee4e1ad1055143624c218..854334203fe91b4d1ccaff3e50b26b7542a5eddd 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2001 - 2006 Pekka Riikonen
+  Copyright (C) 2001 - 2007 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
@@ -895,19 +895,18 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
     SILC_LOG_DEBUG(("Notify: NICK_CHANGE"));
 
     client_entry = va_arg(va, SilcClientEntry);
-    client_entry2 = va_arg(va, SilcClientEntry);
+    name = va_arg(va, char *);                /* old nickname */
 
-    if (!strcmp(client_entry->nickname, client_entry2->nickname))
+    if (!strcmp(client_entry->nickname, name))
       break;
 
     memset(buf, 0, sizeof(buf));
     snprintf(buf, sizeof(buf) - 1, "%s@%s",
-            client_entry2->username, client_entry2->hostname);
+            client_entry->username, client_entry->hostname);
     nicklist_rename_unique(SERVER(server),
-                          client_entry, client_entry->nickname,
-                          client_entry2, client_entry2->nickname);
-    signal_emit("message nick", 4, server, client_entry2->nickname,
-               client_entry->nickname, buf);
+                          client_entry, name,
+                          client_entry, client_entry->nickname);
+    signal_emit("message nick", 4, server, client_entry->nickname, name, buf);
     break;
 
   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
@@ -1276,7 +1275,7 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
    after application has called the command. Just to tell application
    that the command really was processed. */
 
-static bool cmode_list_chpks = FALSE;
+static SilcBool cmode_list_chpks = FALSE;
 
 void silc_command(SilcClient client, SilcClientConnection conn,
                  SilcBool success, SilcCommand command, SilcStatus status,
@@ -1736,21 +1735,21 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
 
       nicks = nicklist_get_same(SERVER(server), client_entry->nickname);
       if ((nicks != NULL) &&
-        (strcmp(SERVER(server)->nick, client_entry->nickname))) {
+         (strcmp(SERVER(server)->nick, client_entry->nickname))) {
        char buf[512];
        SilcClientEntry collider, old;
 
        old = ((SILC_NICK_REC *)(nicks->next->data))->silc_user->client;
        collider = silc_client_get_client_by_id(client, conn, &old->id);
        if (collider != client_entry) {
-          memset(buf, 0, sizeof(buf));
-          snprintf(buf, sizeof(buf) - 1, "%s@%s",
-                  collider->username, collider->hostname);
+         memset(buf, 0, sizeof(buf));
+         snprintf(buf, sizeof(buf) - 1, "%s@%s",
+                  collider->username, collider->hostname);
          nicklist_rename_unique(SERVER(server),
-                                old, old->nickname,
-                                collider, collider->nickname);
+                                old, old->nickname,
+                                collider, collider->nickname);
          silc_print_nick_change(server, collider->nickname,
-                                client_entry->nickname, buf);
+                                client_entry->nickname, buf);
        }
        silc_client_unref_client(client, conn, collider);
       }
@@ -2196,11 +2195,52 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
 
   case SILC_COMMAND_LEAVE:
     {
-      /* we might be cycling, so disable queueing again */
+      if (SILC_STATUS_IS_ERROR(status))
+       return;
+
+      /* We might be cycling, so disable queueing again */
       silc_queue_disable(conn);
     }
     break;
 
+  case SILC_COMMAND_DETACH:
+    {
+      /* Save the detachment data to file. */
+      char *file;
+      SilcBuffer detach;
+
+      if (SILC_STATUS_IS_ERROR(status))
+       return;
+
+      detach = va_arg(vp, SilcBuffer);
+      file = silc_get_session_filename(server);
+      silc_file_writefile(file, silc_buffer_data(detach),
+                         silc_buffer_len(detach));
+      silc_free(file);
+    }
+    break;
+
+  case SILC_COMMAND_KILL:
+    {
+      SilcClientEntry client_entry;
+
+      if (SILC_STATUS_IS_ERROR(status)) {
+       silc_say_error("KILL: %s", silc_get_status_message(status));
+       return;
+      }
+
+      client_entry = va_arg(vp, SilcClientEntry);
+      if (!client_entry || !client_entry->nickname[0])
+       break;
+
+      /* Print this only if the killed client isn't joined on channels.
+        If it is, we receive KILLED notify and we'll print this there. */
+      if (!silc_hash_table_count(client_entry->channels))
+       printformat_module("fe-common/silc", server, NULL,
+                          MSGLEVEL_CRAP, SILCTXT_CHANNEL_KILLED,
+                          client_entry->nickname,
+                          conn->local_entry->nickname, "");
+    }
   }
 }
 
@@ -2506,82 +2546,60 @@ void silc_ask_passphrase(SilcClient client, SilcClientConnection conn,
 typedef struct {
   SilcGetAuthMeth completion;
   void *context;
-} *InternalGetAuthMethod;
-
-/* Callback called when we've received the authentication method information
-   from the server after we've requested it. This will get the authentication
-   data from the user if needed. */
+} *GetAuthMethod;
 
-static void silc_get_auth_method_callback(SilcClient client,
-                                         SilcClientConnection conn,
-                                         SilcAuthMethod auth_meth,
-                                         void *context)
+static void silc_get_auth_ask_passphrase(unsigned char *passphrase,
+                                        SilcUInt32 passphrase_len,
+                                        void *context)
 {
-  InternalGetAuthMethod internal = (InternalGetAuthMethod)context;
-
-  SILC_LOG_DEBUG(("Start"));
-
-  switch (auth_meth) {
-  case SILC_AUTH_NONE:
-    /* No authentication required. */
-    (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);
-    break;
-  case SILC_AUTH_PASSWORD:
-    {
-      /* Check whether we find the password for this server in our
-        configuration.  If not, then don't provide so library will ask
-        it from the user. */
-      SERVER_SETUP_REC *setup = server_setup_find_port(conn->remote_host,
-                                                      conn->remote_port);
-      if (!setup || !setup->password) {
-       (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);
-       break;
-      }
-
-      (*internal->completion)(TRUE, auth_meth, setup->password,
-                             strlen(setup->password), internal->context);
-    }
-    break;
-  case SILC_AUTH_PUBLIC_KEY:
-    /* Do not get the authentication data now, the library will generate
-       it using our default key, if we do not provide it here. */
-    /* XXX In the future when we support multiple local keys and multiple
-       local certificates we will need to ask from user which one to use. */
-    (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);
-    break;
-  }
-
-  silc_free(internal);
+  GetAuthMethod a = context;
+  a->completion(passphrase ? SILC_AUTH_PASSWORD : SILC_AUTH_NONE,
+               passphrase, passphrase_len, a->context);
+  silc_free(a);
 }
 
-/* Find authentication method and authentication data by hostname and
-   port. The hostname may be IP address as well. The found authentication
-   method and authentication data is returned to `auth_meth', `auth_data'
-   and `auth_data_len'. The function returns TRUE if authentication method
-   is found and FALSE if not. `conn' may be NULL. */
+/* Find authentication data by hostname and port. The hostname may be IP
+   address as well.*/
 
 void silc_get_auth_method(SilcClient client, SilcClientConnection conn,
                          char *hostname, SilcUInt16 port,
+                         SilcAuthMethod auth_meth,
                          SilcGetAuthMeth completion, void *context)
 {
-  InternalGetAuthMethod internal;
+  SERVER_SETUP_REC *setup;
 
   SILC_LOG_DEBUG(("Start"));
 
-  /* If we do not have this connection configured by the user in a
-     configuration file then resolve the authentication method from the
-     server for this session. */
-  internal = silc_calloc(1, sizeof(*internal));
-  internal->completion = completion;
-  internal->context = context;
+  if (auth_meth == SILC_AUTH_PUBLIC_KEY) {
+    /* Returning NULL will cause library to use our private key configured
+       for this connection */
+    completion(SILC_AUTH_PUBLIC_KEY, NULL, 0, context);
+    return;
+  }
 
-#if 0
-  silc_client_request_authentication_method(client, conn,
-                                           silc_get_auth_method_callback,
-                                           internal);
-#else
-  completion(TRUE, SILC_AUTH_NONE, NULL, 0, context);
-#endif
+  /* Check whether we find the password for this server in our
+     configuration.  If it's set, always send it server. */
+  setup = server_setup_find_port(hostname, port);
+  if (setup && setup->password) {
+    completion(SILC_AUTH_PASSWORD, setup->password, strlen(setup->password),
+              context);
+    return;
+  }
+
+  /* Didn't find password.  If server wants it, ask it from user. */
+  if (auth_meth == SILC_AUTH_PASSWORD) {
+    GetAuthMethod a;
+    a = silc_calloc(1, sizeof(*a));
+    if (a) {
+      a->completion = completion;
+      a->context = context;
+      silc_ask_passphrase(client, conn, silc_get_auth_ask_passphrase, a);
+      return;
+    }
+  }
+
+  /* No authentication */
+  completion(SILC_AUTH_NONE, NULL, 0, context);
 }
 
 /* Asks whether the user would like to perform the key agreement protocol.
@@ -2666,37 +2684,6 @@ void silc_ftp(SilcClient client, SilcClientConnection conn,
                       client_entry->nickname, hostname, portstr);
 }
 
-/* Delivers SILC session detachment data indicated by `detach_data' to the
-   application.  If application has issued SILC_COMMAND_DETACH command
-   the client session in the SILC network is not quit.  The client remains
-   in the network but is detached.  The detachment data may be used later
-   to resume the session in the SILC Network.  The appliation is
-   responsible of saving the `detach_data', to for example in a file.
-
-   The detachment data can be given as argument to the functions
-   silc_client_connect_to_server, or silc_client_add_connection when
-   creating connection to remote server, inside SilcClientConnectionParams
-   structure.  If it is provided the client library will attempt to resume
-   the session in the network.  After the connection is created
-   successfully, the application is responsible of setting the user
-   interface for user into the same state it was before detaching (showing
-   same channels, channel modes, etc).  It can do this by fetching the
-   information (like joined channels) from the client library. */
-
-void
-silc_detach(SilcClient client, SilcClientConnection conn,
-            const unsigned char *detach_data, SilcUInt32 detach_data_len)
-{
-  SILC_SERVER_REC *server = conn->context;
-  char *file;
-
-  /* Save the detachment data to file. */
-
-  file = silc_get_session_filename(server);
-  silc_file_writefile(file, detach_data, detach_data_len);
-  silc_free(file);
-}
-
 /* SILC client operations */
 SilcClientOperations ops = {
   silc_say,
@@ -2710,5 +2697,4 @@ SilcClientOperations ops = {
   silc_ask_passphrase,
   silc_key_agreement,
   silc_ftp,
-  silc_detach,
 };