updates.
[silc.git] / apps / irssi / src / silc / core / client_ops.c
index 9247a3c4f484b5305855ee17e89e36c8b34cc047..6324f3dff1e9842bfd4fb910cfcaca61eeb67eaf 100644 (file)
@@ -90,6 +90,18 @@ void silc_channel_message(SilcClient client, SilcClientConnection conn,
     return;
   
   nick = silc_nicklist_find(chanrec, sender);
+  if (!nick) {
+    /* We didn't find client but it clearly exists, add it. */
+    SilcChannelUser chu;
+
+    silc_list_start(channel->clients);
+    while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
+      if (chu->client == sender) {
+       nick = silc_nicklist_insert(chanrec, chu, FALSE);
+       break;
+      }
+    }
+  }
 
   if (flags & SILC_MESSAGE_FLAG_ACTION)
     printformat_module("fe-common/silc", server, channel->channel_name,
@@ -114,11 +126,16 @@ void silc_private_message(SilcClient client, SilcClientConnection conn,
                          char *msg)
 {
   SILC_SERVER_REC *server;
+  char userhost[256];
   
   server = conn == NULL ? NULL : conn->context;
+  memset(userhost, 0, sizeof(userhost));
+  if (sender->username)
+    snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
+            sender->username, sender->hostname);
   signal_emit("message private", 4, server, msg,
              sender->nickname ? sender->nickname : "[<unknown>]",
-             sender->username ? sender->username : NULL);
+             sender->username ? userhost : NULL);
 }
 
 /* Notify message to the client. The notify arguments are sent in the
@@ -209,6 +226,14 @@ void silc_disconnect(SilcClient client, SilcClientConnection conn)
 {
   SILC_SERVER_REC *server = conn->context;
 
+  if (server->conn) {
+    nicklist_rename_unique(SERVER(server),
+                          server->conn->local_entry, server->nick,
+                          server->conn->local_entry, 
+                          silc_client->username);
+    silc_change_nick(server, silc_client->username);
+  }
+
   server->conn->context = NULL;
   server->conn = NULL;
   server->connection_lost = TRUE;
@@ -272,6 +297,8 @@ static void silc_client_join_get_users(SilcClient client,
 
   silc_list_start(channel->clients);
   while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
+    if (!chu->client->nickname)
+      continue;
     if (chu->mode & SILC_CHANNEL_UMODE_CHANFO)
       founder = chu->client;
     silc_nicklist_insert(chanrec, chu, FALSE);
@@ -302,6 +329,34 @@ static void silc_client_join_get_users(SilcClient client,
   }
 }
 
+typedef struct {
+  SilcClient client;
+  SilcClientConnection conn;
+  void *entry;
+  SilcIdType id_type;
+  char *fingerprint;
+} *GetkeyContext;
+
+void silc_getkey_cb(bool success, void *context)
+{
+  GetkeyContext getkey = (GetkeyContext)context;
+  char *entity = (getkey->id_type == SILC_ID_CLIENT ? "user" : "server");
+  char *name = (getkey->id_type == SILC_ID_CLIENT ? 
+               ((SilcClientEntry)getkey->entry)->nickname :
+               ((SilcServerEntry)getkey->entry)->server_name);
+
+  if (success) {
+    printformat_module("fe-common/silc", NULL, NULL,
+                      MSGLEVEL_CRAP, SILCTXT_GETKEY_VERIFIED, entity, name);
+  } else {
+    printformat_module("fe-common/silc", NULL, NULL,
+                      MSGLEVEL_CRAP, SILCTXT_GETKEY_DISCARD, entity, name);
+  }
+
+  silc_free(getkey->fingerprint);
+  silc_free(getkey);
+}
+
 /* Command reply handler. This function is called always in the command reply
    function. If error occurs it will be called as well. Normal scenario
    is that it will be called after the received command data has been parsed
@@ -333,9 +388,10 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
   switch(command) {
   case SILC_COMMAND_WHOIS:
     {
-      char buf[1024], *nickname, *username, *realname;
+      char buf[1024], *nickname, *username, *realname, *nick;
       uint32 idle, mode;
       SilcBuffer channels;
+      SilcClientEntry client_entry;
       
       if (status == SILC_STATUS_ERR_NO_SUCH_NICK ||
          status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
@@ -353,7 +409,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       if (!success)
        return;
       
-      (void)va_arg(vp, SilcClientEntry);
+      client_entry = va_arg(vp, SilcClientEntry);
       nickname = va_arg(vp, char *);
       username = va_arg(vp, char *);
       realname = va_arg(vp, char *);
@@ -361,9 +417,14 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       mode = va_arg(vp, uint32);
       idle = va_arg(vp, uint32);
       
+      silc_parse_userfqdn(nickname, &nick, NULL);
       printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
-                        SILCTXT_WHOIS_USERINFO, nickname, username, 
-                        realname);
+                        SILCTXT_WHOIS_USERINFO, nickname, 
+                        client_entry->username, client_entry->hostname,
+                        nick, client_entry->nickname);
+      printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
+                        SILCTXT_WHOIS_REALNAME, realname);
+      silc_free(nick);
 
       if (channels) {
        SilcDList list = silc_channel_payload_parse_list(channels);
@@ -511,8 +572,10 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       }
 
       mode = silc_client_chmode(modei, 
-                               channel_entry->channel_key->cipher->name,
-                               channel_entry->hmac->hmac->name);
+                               channel_entry->channel_key ? 
+                               channel_entry->channel_key->cipher->name : "",
+                               channel_entry->hmac ? 
+                               silc_hmac_get_name(channel_entry->hmac) : "");
       g_free_not_null(chanrec->mode);
       chanrec->mode = g_strdup(mode == NULL ? "" : mode);
       signal_emit("channel mode changed", 1, chanrec);
@@ -622,6 +685,9 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
        SilcClientEntry e = chu->client;
        char stat[5], *mode;
+
+       if (!e->nickname)
+         continue;
        
        memset(stat, 0, sizeof(stat));
        mode = silc_client_chumode_char(chu->mode);
@@ -634,7 +700,9 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
 
        printformat_module("fe-common/silc", server, channel->channel_name,
                           MSGLEVEL_CRAP, SILCTXT_USERS,
-                          e->nickname, stat, e->username, 
+                          e->nickname, stat, 
+                          e->username ? e->username : "",
+                          e->hostname ? e->hostname : "",
                           e->realname ? e->realname : "");
        if (mode)
          silc_free(mode);
@@ -671,6 +739,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       SilcPublicKey public_key;
       unsigned char *pk;
       uint32 pk_len;
+      GetkeyContext getkey;
       
       if (!success)
        return;
@@ -681,13 +750,20 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
 
       if (public_key) {
        pk = silc_pkcs_public_key_encode(public_key, &pk_len);
+
+       getkey = silc_calloc(1, sizeof(*getkey));
+       getkey->entry = entry;
+       getkey->id_type = id_type;
+       getkey->client = client;
+       getkey->conn = conn;
+       getkey->fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
        
        silc_verify_public_key_internal(client, conn, 
                                        (id_type == SILC_ID_CLIENT ?
                                         SILC_SOCKET_TYPE_CLIENT :
                                         SILC_SOCKET_TYPE_SERVER),
                                        pk, pk_len, SILC_SKE_PK_TYPE_SILC,
-                                       NULL, NULL);
+                                       silc_getkey_cb, getkey);
        silc_free(pk);
       } else {
        printformat_module("fe-common/silc", server, NULL,