updates.
[silc.git] / apps / irssi / src / silc / core / client_ops.c
index 6324f3dff1e9842bfd4fb910cfcaca61eeb67eaf..f6dac8aec0db84efb94381362710eabde81fb464 100644 (file)
@@ -84,6 +84,8 @@ void silc_channel_message(SilcClient client, SilcClientConnection conn,
   SILC_NICK_REC *nick;
   SILC_CHANNEL_REC *chanrec;
   
+  SILC_LOG_DEBUG(("Start"));
+
   server = conn == NULL ? NULL : conn->context;
   chanrec = silc_channel_find_entry(server, channel);
   if (!chanrec)
@@ -128,6 +130,8 @@ void silc_private_message(SilcClient client, SilcClientConnection conn,
   SILC_SERVER_REC *server;
   char userhost[256];
   
+  SILC_LOG_DEBUG(("Start"));
+
   server = conn == NULL ? NULL : conn->context;
   memset(userhost, 0, sizeof(userhost));
   if (sender->username)
@@ -177,6 +181,8 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
   SILC_SERVER_REC *server;
   va_list va;
   
+  SILC_LOG_DEBUG(("Start"));
+
   server = conn == NULL ? NULL : conn->context;
   va_start(va, type);
   
@@ -199,7 +205,7 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
 
 /* Called to indicate that connection was either successfully established
    or connecting failed.  This is also the first time application receives
-   the SilcClientConnection objecet which it should save somewhere. */
+   the SilcClientConnection object which it should save somewhere. */
 
 void silc_connect(SilcClient client, SilcClientConnection conn, int success)
 {
@@ -226,6 +232,8 @@ void silc_disconnect(SilcClient client, SilcClientConnection conn)
 {
   SILC_SERVER_REC *server = conn->context;
 
+  SILC_LOG_DEBUG(("Start"));
+
   if (server->conn) {
     nicklist_rename_unique(SERVER(server),
                           server->conn->local_entry, server->nick,
@@ -255,6 +263,8 @@ void silc_command(SilcClient client, SilcClientConnection conn,
 {
   SILC_SERVER_REC *server = conn->context;
 
+  SILC_LOG_DEBUG(("Start"));
+
   if (!success)
     return;
 
@@ -385,24 +395,44 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
 
   va_start(vp, status);
 
+  SILC_LOG_DEBUG(("Start"));
+
   switch(command) {
   case SILC_COMMAND_WHOIS:
     {
       char buf[1024], *nickname, *username, *realname, *nick;
+      unsigned char *fingerprint;
       uint32 idle, mode;
       SilcBuffer channels;
       SilcClientEntry client_entry;
       
-      if (status == SILC_STATUS_ERR_NO_SUCH_NICK ||
-         status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
-       char *tmp;
-       tmp = silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
-                                        3, NULL);
+      if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
+       /* Print the unknown nick for user */
+       unsigned char *tmp =
+         silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
+                                    3, NULL);
        if (tmp)
          silc_say_error("%s: %s", tmp, 
                         silc_client_command_status_message(status));
-       else
-         silc_say_error("%s", silc_client_command_status_message(status));
+       break;
+      } else if (status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
+       /* Try to find the entry for the unknown client ID, since we
+          might have, and print the nickname of it for user. */
+       uint32 tmp_len;
+       unsigned char *tmp =
+         silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
+                                    2, &tmp_len);
+       if (tmp) {
+         SilcClientID *client_id = silc_id_payload_parse_id(tmp, tmp_len);
+         if (client_id) {
+           client_entry = silc_client_get_client_by_id(client, conn,
+                                                       client_id);
+           if (client_entry && client_entry->nickname)
+             silc_say_error("%s: %s", client_entry->nickname,
+                            silc_client_command_status_message(status));
+           silc_free(client_id);
+         }
+       }
        break;
       }
       
@@ -416,6 +446,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       channels = va_arg(vp, SilcBuffer);
       mode = va_arg(vp, uint32);
       idle = va_arg(vp, uint32);
+      fingerprint = va_arg(vp, unsigned char *);
       
       silc_parse_userfqdn(nickname, &nick, NULL);
       printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
@@ -427,7 +458,8 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       silc_free(nick);
 
       if (channels) {
-       SilcDList list = silc_channel_payload_parse_list(channels);
+       SilcDList list = silc_channel_payload_parse_list(channels->data,
+                                                        channels->len);
        if (list) {
          SilcChannelPayload entry;
          memset(buf, 0, sizeof(buf));
@@ -476,9 +508,53 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
        printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
                           SILCTXT_WHOIS_IDLE, buf);
       }
+
+      if (fingerprint) {
+       fingerprint = silc_fingerprint(fingerprint, 20);
+       printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
+                          SILCTXT_WHOIS_FINGERPRINT, fingerprint);
+       silc_free(fingerprint);
+      }
     }
     break;
     
+  case SILC_COMMAND_IDENTIFY:
+    {
+      SilcClientEntry client_entry;
+      
+      if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
+       /* Print the unknown nick for user */
+       unsigned char *tmp =
+         silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
+                                    3, NULL);
+       if (tmp)
+         silc_say_error("%s: %s", tmp, 
+                        silc_client_command_status_message(status));
+       break;
+      } else if (status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
+       /* Try to find the entry for the unknown client ID, since we
+          might have, and print the nickname of it for user. */
+       uint32 tmp_len;
+       unsigned char *tmp =
+         silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
+                                    2, &tmp_len);
+       if (tmp) {
+         SilcClientID *client_id = silc_id_payload_parse_id(tmp, tmp_len);
+         if (client_id) {
+           client_entry = silc_client_get_client_by_id(client, conn,
+                                                       client_id);
+           if (client_entry && client_entry->nickname)
+             silc_say_error("%s: %s", client_entry->nickname,
+                            silc_client_command_status_message(status));
+           silc_free(client_id);
+         }
+       }
+       break;
+      }
+
+      break;
+    }
+
   case SILC_COMMAND_WHOWAS:
     {
       char *nickname, *username, *realname;
@@ -491,8 +567,6 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
        if (tmp)
          silc_say_error("%s: %s", tmp, 
                         silc_client_command_status_message(status));
-       else
-         silc_say_error("%s", silc_client_command_status_message(status));
        break;
       }
       
@@ -625,7 +699,10 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
        printformat_module("fe-common/silc", server, NULL,
                           MSGLEVEL_CRAP, SILCTXT_LIST_HEADER);
 
-      snprintf(users, sizeof(users) - 1, "%d", usercount);
+      if (!usercount)
+       snprintf(users, sizeof(users) - 1, "N/A");
+      else
+       snprintf(users, sizeof(users) - 1, "%d", usercount);
       printformat_module("fe-common/silc", server, NULL,
                         MSGLEVEL_CRAP, SILCTXT_LIST,
                         name, users, topic ? topic : "");
@@ -641,13 +718,17 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       
       mode = va_arg(vp, uint32);
       
-      if (mode & SILC_UMODE_SERVER_OPERATOR)
+      if (mode & SILC_UMODE_SERVER_OPERATOR &&
+         !(server->umode & SILC_UMODE_SERVER_OPERATOR))
        printformat_module("fe-common/silc", server, NULL,
                           MSGLEVEL_CRAP, SILCTXT_SERVER_OPER);
 
-      if (mode & SILC_UMODE_ROUTER_OPERATOR)
+      if (mode & SILC_UMODE_ROUTER_OPERATOR &&
+         !(server->umode & SILC_UMODE_ROUTER_OPERATOR))
        printformat_module("fe-common/silc", server, NULL,
                           MSGLEVEL_CRAP, SILCTXT_ROUTER_OPER);
+
+      server->umode = mode;
     }
     break;
     
@@ -771,6 +852,27 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       }
     }
     break;
+
+  case SILC_COMMAND_INFO:
+    {
+      SilcServerEntry server_entry;
+      char *server_name;
+      char *server_info;
+
+      if (!success)
+       return;
+      
+      server_entry = va_arg(vp, SilcServerEntry);
+      server_name = va_arg(vp, char *);
+      server_info = va_arg(vp, char *);
+
+      if (server_name && server_info )
+       {
+         printtext(server, NULL, MSGLEVEL_CRAP, "Server: %s", server_name);
+         printtext(server, NULL, MSGLEVEL_CRAP, "%s", server_info);
+       }
+    }
+    break;
     
   case SILC_COMMAND_TOPIC:
     {
@@ -855,7 +957,7 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
                                SilcVerifyPublicKey completion, void *context)
 {
   int i;
-  char file[256], filename[256], *fingerprint, *format;
+  char file[256], filename[256], *fingerprint, *babbleprint, *format;
   struct passwd *pw;
   struct stat st;
   char *entity = ((conn_type == SILC_SOCKET_TYPE_SERVER ||
@@ -885,7 +987,7 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
   if (conn_type == SILC_SOCKET_TYPE_SERVER ||
       conn_type == SILC_SOCKET_TYPE_ROUTER) {
     snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity, 
-            conn->sock->hostname, conn->sock->port);
+            conn->sock->ip, conn->sock->port);
     snprintf(filename, sizeof(filename) - 1, "%s/.silc/%skeys/%s", 
             pw->pw_dir, entity, file);
   } else {
@@ -903,6 +1005,7 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
 
   /* Take fingerprint of the public key */
   fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
+  babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
 
   verify = silc_calloc(1, sizeof(*verify));
   verify->client = client;
@@ -924,6 +1027,8 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
                       SILCTXT_PUBKEY_RECEIVED, entity);
     printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, 
                       SILCTXT_PUBKEY_FINGERPRINT, entity, fingerprint);
+    printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, 
+                      SILCTXT_PUBKEY_BABBLEPRINT, babbleprint);
     format = format_get_text("fe-common/silc", NULL, NULL, NULL,
                             SILCTXT_PUBKEY_ACCEPT);
     keyboard_entry_redirect((SIGNAL_FUNC)verify_public_key_completion,
@@ -946,6 +1051,8 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
                           SILCTXT_PUBKEY_RECEIVED, entity);
        printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, 
                           SILCTXT_PUBKEY_FINGERPRINT, entity, fingerprint);
+       printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, 
+                          SILCTXT_PUBKEY_BABBLEPRINT, babbleprint);
        printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, 
                           SILCTXT_PUBKEY_COULD_NOT_LOAD, entity);
        format = format_get_text("fe-common/silc", NULL, NULL, NULL,
@@ -964,6 +1071,8 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
                         SILCTXT_PUBKEY_RECEIVED, entity);
       printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, 
                         SILCTXT_PUBKEY_FINGERPRINT, entity, fingerprint);
+      printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, 
+                        SILCTXT_PUBKEY_BABBLEPRINT, babbleprint);
       printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, 
                         SILCTXT_PUBKEY_MALFORMED, entity);
       format = format_get_text("fe-common/silc", NULL, NULL, NULL,
@@ -981,6 +1090,8 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
                         SILCTXT_PUBKEY_RECEIVED, entity);
       printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, 
                         SILCTXT_PUBKEY_FINGERPRINT, entity, fingerprint);
+      printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, 
+                        SILCTXT_PUBKEY_BABBLEPRINT, babbleprint);
       printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, 
                         SILCTXT_PUBKEY_NO_MATCH, entity);
       printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, 
@@ -1063,6 +1174,8 @@ static void silc_get_auth_method_callback(SilcClient client,
 {
   InternalGetAuthMethod internal = (InternalGetAuthMethod)context;
 
+  SILC_LOG_DEBUG(("Start"));
+
   switch (auth_meth) {
   case SILC_AUTH_NONE:
     /* No authentication required. */
@@ -1097,6 +1210,8 @@ void silc_get_auth_method(SilcClient client, SilcClientConnection conn,
 {
   InternalGetAuthMethod internal;
 
+  SILC_LOG_DEBUG(("Start"));
+
   /* XXX must resolve from configuration whether this connection has
      any specific authentication data */
 
@@ -1122,6 +1237,8 @@ void silc_get_auth_method(SilcClient client, SilcClientConnection conn,
 void silc_failure(SilcClient client, SilcClientConnection conn, 
                  SilcProtocol protocol, void *failure)
 {
+  SILC_LOG_DEBUG(("Start"));
+
   if (protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
     SilcSKEStatus status = (SilcSKEStatus)failure;
     
@@ -1171,13 +1288,14 @@ void silc_failure(SilcClient client, SilcClientConnection conn,
    silc_client_perform_key_agreement). */
 
 int silc_key_agreement(SilcClient client, SilcClientConnection conn,
-                      SilcClientEntry client_entry, char *hostname,
-                      int port,
-                      SilcKeyAgreementCallback *completion,
+                      SilcClientEntry client_entry, const char *hostname,
+                      uint16 port, SilcKeyAgreementCallback *completion,
                       void **context)
 {
   char portstr[12];
 
+  SILC_LOG_DEBUG(("Start"));
+
   /* We will just display the info on the screen and return FALSE and user
      will have to start the key agreement with a command. */
 
@@ -1185,10 +1303,10 @@ int silc_key_agreement(SilcClient client, SilcClientConnection conn,
     snprintf(portstr, sizeof(portstr) - 1, "%d", port);
 
   if (!hostname)
-    printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_NOTICES,
+    printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
                       SILCTXT_KEY_AGREEMENT_REQUEST, client_entry->nickname);
   else
-    printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_NOTICES,
+    printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
                       SILCTXT_KEY_AGREEMENT_REQUEST_HOST, 
                       client_entry->nickname, hostname, portstr);
 
@@ -1198,6 +1316,37 @@ int silc_key_agreement(SilcClient client, SilcClientConnection conn,
   return FALSE;
 }
 
+void silc_ftp(SilcClient client, SilcClientConnection conn,
+             SilcClientEntry client_entry, uint32 session_id,
+             const char *hostname, uint16 port)
+{
+  SILC_SERVER_REC *server;
+  char portstr[12];
+  FtpSession ftp = silc_calloc(1, sizeof(*ftp));
+
+  SILC_LOG_DEBUG(("Start"));
+
+  server = conn->context;
+
+  ftp->client_entry = client_entry;
+  ftp->session_id = session_id;
+  ftp->send = FALSE;
+  ftp->conn = conn;
+  silc_dlist_add(server->ftp_sessions, ftp);
+  server->current_session = ftp;
+
+  if (hostname) 
+    snprintf(portstr, sizeof(portstr) - 1, "%d", port);
+
+  if (!hostname)
+    printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
+                      SILCTXT_FILE_REQUEST, client_entry->nickname);
+  else
+    printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
+                      SILCTXT_FILE_REQUEST_HOST, 
+                      client_entry->nickname, hostname, portstr);
+}
+
 /* SILC client operations */
 SilcClientOperations ops = {
   silc_say,
@@ -1213,4 +1362,5 @@ SilcClientOperations ops = {
   silc_ask_passphrase,
   silc_failure,
   silc_key_agreement,
+  silc_ftp,
 };