Fixed a bug in disconnecting in irssi.
[silc.git] / apps / irssi / src / silc / core / client_ops.c
index 664d625a3718de1750a8b42e62e44bca4680bf0a..5c83a211be2e3eb2ffe39a20e626f8074f6d26c4 100644 (file)
@@ -47,6 +47,40 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
                                SilcSKEPKType pk_type,
                                SilcVerifyPublicKey completion, void *context);
 
+static void silc_get_umode_string(SilcUInt32 mode, char *buf, 
+                                 SilcUInt32 buf_size)
+{
+  if ((mode & SILC_UMODE_SERVER_OPERATOR) ||
+      (mode & SILC_UMODE_ROUTER_OPERATOR)) {
+    strcat(buf, (mode & SILC_UMODE_SERVER_OPERATOR) ?
+          "[server operator]" :
+          (mode & SILC_UMODE_ROUTER_OPERATOR) ?
+          "[SILC operator]" : "[unknown mode]");
+  }
+  if (mode & SILC_UMODE_GONE)
+    strcat(buf, " [away]");
+  if (mode & SILC_UMODE_INDISPOSED)
+    strcat(buf, " [indisposed]");
+  if (mode & SILC_UMODE_BUSY)
+    strcat(buf, " [busy]");
+  if (mode & SILC_UMODE_PAGE)
+    strcat(buf, " [page to reach]");
+  if (mode & SILC_UMODE_HYPER)
+    strcat(buf, " [hyper active]");
+  if (mode & SILC_UMODE_ROBOT)
+    strcat(buf, " [robot]");
+  if (mode & SILC_UMODE_ANONYMOUS)
+    strcat(buf, " [anonymous]");
+  if (mode & SILC_UMODE_BLOCK_PRIVMSG)
+    strcat(buf, " [blocks private messages]");
+  if (mode & SILC_UMODE_DETACHED)
+    strcat(buf, " [detached]");
+  if (mode & SILC_UMODE_REJECT_WATCHING)
+    strcat(buf, " [rejects watching]");
+  if (mode & SILC_UMODE_BLOCK_INVITE)
+    strcat(buf, " [blocks invites]");
+}
+
 void silc_say(SilcClient client, SilcClientConnection conn,
              SilcClientMessageType type, char *msg, ...)
 {
@@ -106,6 +140,32 @@ void silc_channel_message(SilcClient client, SilcClientConnection conn,
       nick = silc_nicklist_insert(chanrec, chu, FALSE);
   }
 
+  if (flags & SILC_MESSAGE_FLAG_DATA) {
+    /* MIME object received, try to display it as well as we can */
+    char type[128];
+    unsigned char *data;
+
+    memset(type, 0, sizeof(type));
+    if (!silc_mime_parse(message, message_len, NULL, 0, type, sizeof(type) - 1,
+                        NULL, 0, &data, NULL))
+      return;
+
+    /* Then figure out what we can display */
+    if (strstr(type, "text/") && !strstr(type, "text/t140") &&
+       !strstr(type, "text/vnd")) {
+      /* It is something textual, display it */
+      message = (const unsigned char *)data;
+    } else {
+      printformat_module("fe-common/silc", server, channel->channel_name,
+                        MSGLEVEL_CRAP, SILCTXT_MESSAGE_DATA,
+                        nick == NULL ? "[<unknown>]" : nick->nick, type);
+      message = NULL;
+    }
+  }
+
+  if (!message)
+    return;
+
   if (flags & SILC_MESSAGE_FLAG_ACTION)
     printformat_module("fe-common/silc", server, channel->channel_name,
                       MSGLEVEL_ACTIONS, SILCTXT_CHANNEL_ACTION, 
@@ -114,11 +174,32 @@ void silc_channel_message(SilcClient client, SilcClientConnection conn,
     printformat_module("fe-common/silc", server, channel->channel_name,
                       MSGLEVEL_NOTICES, SILCTXT_CHANNEL_NOTICE, 
                        nick == NULL ? "[<unknown>]" : nick->nick, message);
-  else
+  else {
+    if (flags & SILC_MESSAGE_FLAG_UTF8 && !silc_term_utf8()) {
+      char tmp[256], *cp, *dm = NULL;
+
+      memset(tmp, 0, sizeof(tmp));
+      cp = tmp;
+      if (message_len > sizeof(tmp) - 1) {
+       dm = silc_calloc(message_len + 1, sizeof(*dm));
+       cp = dm;
+      }
+
+      silc_utf8_decode(message, message_len, SILC_STRING_ASCII,
+                      cp, message_len);
+      signal_emit("message public", 6, server, cp,
+                 nick == NULL ? "[<unknown>]" : nick->nick,
+                 nick == NULL ? "" : nick->host == NULL ? "" : nick->host,
+                 chanrec->name, nick);
+      silc_free(dm);
+      return;
+    }
+
     signal_emit("message public", 6, server, message,
                nick == NULL ? "[<unknown>]" : nick->nick,
                nick == NULL ? "" : nick->host == NULL ? "" : nick->host,
                chanrec->name, nick);
+  }
 }
 
 /* Private message to the client. The `sender' is the nickname of the
@@ -139,6 +220,53 @@ void silc_private_message(SilcClient client, SilcClientConnection conn,
   if (sender->username)
     snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
             sender->username, sender->hostname);
+
+  if (flags & SILC_MESSAGE_FLAG_DATA) {
+    /* MIME object received, try to display it as well as we can */
+    char type[128];
+    unsigned char *data;
+
+    memset(type, 0, sizeof(type));
+    if (!silc_mime_parse(message, message_len, NULL, 0, type, sizeof(type) - 1,
+                        NULL, 0, &data, NULL))
+      return;
+
+    /* Then figure out what we can display */
+    if (strstr(type, "text/") && !strstr(type, "text/t140") &&
+       !strstr(type, "text/vnd")) {
+      /* It is something textual, display it */
+      message = (const unsigned char *)data;
+    } else {
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_MESSAGE_DATA,
+                        sender->nickname ? sender->nickname : "[<unknown>]",
+                        type);
+      message = NULL;
+    }
+  }
+
+  if (!message)
+    return;
+
+  if (flags & SILC_MESSAGE_FLAG_UTF8 && !silc_term_utf8()) {
+    char tmp[256], *cp, *dm = NULL;
+
+    memset(tmp, 0, sizeof(tmp));
+    cp = tmp;
+    if (message_len > sizeof(tmp) - 1) {
+      dm = silc_calloc(message_len + 1, sizeof(*dm));
+      cp = dm;
+    }
+
+    silc_utf8_decode(message, message_len, SILC_STRING_ASCII,
+                    cp, message_len);
+    signal_emit("message private", 4, server, cp,
+               sender->nickname ? sender->nickname : "[<unknown>]",
+               sender->username ? userhost : NULL);
+    silc_free(dm);
+    return;
+  }
+
   signal_emit("message private", 4, server, message,
              sender->nickname ? sender->nickname : "[<unknown>]",
              sender->username ? userhost : NULL);
@@ -165,7 +293,7 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
   SilcIdType idtype;
   void *entry;
   SilcUInt32 mode;
-  char userhost[512];
+  char buf[512];
   char *name, *tmp;
   GSList *list1, *list_tmp;
 
@@ -192,11 +320,11 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
     name = va_arg(va, char *);
     client_entry = va_arg(va, SilcClientEntry);
 
-    memset(userhost, 0, sizeof(userhost));
-    snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
+    memset(buf, 0, sizeof(buf));
+    snprintf(buf, sizeof(buf) - 1, "%s@%s",
             client_entry->username, client_entry->hostname);
     signal_emit("message invite", 4, server, channel ? channel->channel_name :
-               name, client_entry->nickname, userhost);
+               name, client_entry->nickname, buf);
     break;
 
   case SILC_NOTIFY_TYPE_JOIN:
@@ -223,13 +351,13 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
       }
     }
     
-    memset(userhost, 0, sizeof(userhost));
+    memset(buf, 0, sizeof(buf));
     if (client_entry->username)
-    snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
+    snprintf(buf, sizeof(buf) - 1, "%s@%s",
             client_entry->username, client_entry->hostname);
     signal_emit("message join", 4, server, channel->channel_name,
                client_entry->nickname,
-               client_entry->username == NULL ? "" : userhost);
+               client_entry->username == NULL ? "" : buf);
     break;
 
   case SILC_NOTIFY_TYPE_LEAVE:
@@ -242,13 +370,13 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
     client_entry = va_arg(va, SilcClientEntry);
     channel = va_arg(va, SilcChannelEntry);
     
-    memset(userhost, 0, sizeof(userhost));
+    memset(buf, 0, sizeof(buf));
     if (client_entry->username)
-      snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
+      snprintf(buf, sizeof(buf) - 1, "%s@%s",
               client_entry->username, client_entry->hostname);
     signal_emit("message part", 5, server, channel->channel_name,
                client_entry->nickname,  client_entry->username ? 
-               userhost : "", client_entry->nickname);
+               buf : "", client_entry->nickname);
     
     chanrec = silc_channel_find_entry(server, channel);
     if (chanrec != NULL) {
@@ -270,12 +398,12 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
     
     silc_server_free_ftp(server, client_entry);
     
-    memset(userhost, 0, sizeof(userhost));
+    memset(buf, 0, sizeof(buf));
     if (client_entry->username)
-      snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
+      snprintf(buf, sizeof(buf) - 1, "%s@%s",
               client_entry->username, client_entry->hostname);
     signal_emit("message quit", 4, server, client_entry->nickname,
-               client_entry->username ? userhost : "", 
+               client_entry->username ? buf : "", 
                tmp ? tmp : "");
     
     list1 = nicklist_get_same_unique(SERVER(server), client_entry);
@@ -309,11 +437,11 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
     
     if (idtype == SILC_ID_CLIENT) {
       client_entry = (SilcClientEntry)entry;
-      memset(userhost, 0, sizeof(userhost));
-      snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
+      memset(buf, 0, sizeof(buf));
+      snprintf(buf, sizeof(buf) - 1, "%s@%s",
               client_entry->username, client_entry->hostname);
       signal_emit("message topic", 5, server, channel->channel_name,
-                 tmp, client_entry->nickname, userhost);
+                 tmp, client_entry->nickname, buf);
     } else if (idtype == SILC_ID_SERVER) {
       server_entry = (SilcServerEntry)entry;
       signal_emit("message topic", 5, server, channel->channel_name,
@@ -339,14 +467,14 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
     if (!strcmp(client_entry->nickname, client_entry2->nickname))
       break;
     
-    memset(userhost, 0, sizeof(userhost));
-    snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
+    memset(buf, 0, sizeof(buf));
+    snprintf(buf, sizeof(buf) - 1, "%s@%s",
             client_entry2->username, client_entry2->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, userhost);
+               client_entry->nickname, buf);
     break;
 
   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
@@ -457,6 +585,11 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
                         SILCTXT_CHANNEL_FOUNDER,
                         channel->channel_name, client_entry2->nickname);
 
+    if (mode & SILC_CHANNEL_UMODE_QUIET && conn->local_entry == client_entry2)
+      printformat_module("fe-common/silc", 
+                        server, channel->channel_name, MSGLEVEL_CRAP,
+                        SILCTXT_CHANNEL_QUIETED, channel->channel_name);
+
     silc_free(tmp);
     break;
 
@@ -593,12 +726,12 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
       clients_count = va_arg(va, SilcUInt32);
   
       for (i = 0; i < clients_count; i++) {
-       memset(userhost, 0, sizeof(userhost));
+       memset(buf, 0, sizeof(buf));
        if (clients[i]->username)
-         snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
+         snprintf(buf, sizeof(buf) - 1, "%s@%s",
                   clients[i]->username, clients[i]->hostname);
        signal_emit("message quit", 4, server, clients[i]->nickname,
-                   clients[i]->username ? userhost : "", 
+                   clients[i]->username ? buf : "", 
                    "server signoff");
 
        silc_server_free_ftp(server, clients[i]);
@@ -614,6 +747,73 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
     }
     break;
 
+  case SILC_NOTIFY_TYPE_ERROR:
+    {
+      SilcStatus error = va_arg(va, int);
+
+      silc_say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
+               "%s", silc_get_status_message(error));
+    }
+    break;
+
+  case SILC_NOTIFY_TYPE_WATCH:
+    {
+      SilcNotifyType notify;
+
+      client_entry = va_arg(va, SilcClientEntry);
+      name = va_arg(va, char *);          /* Maybe NULL */
+      mode = va_arg(va, SilcUInt32);
+      notify = va_arg(va, int);
+
+      if (notify == SILC_NOTIFY_TYPE_NICK_CHANGE) {
+       if (name)
+         printformat_module("fe-common/silc", server, NULL,
+                            MSGLEVEL_CRAP, SILCTXT_WATCH_NICK_CHANGE,
+                            client_entry->nickname, name);
+       else
+         printformat_module("fe-common/silc", server, NULL,
+                            MSGLEVEL_CRAP, SILCTXT_WATCH_PRESENT,
+                            client_entry->nickname);
+      } else if (notify == SILC_NOTIFY_TYPE_UMODE_CHANGE) {
+       /* See if client was away and is now present */
+       if (!(mode & (SILC_UMODE_GONE | SILC_UMODE_INDISPOSED |
+                     SILC_UMODE_BUSY | SILC_UMODE_PAGE |
+                     SILC_UMODE_DETACHED)) &&
+           (client_entry->mode & SILC_UMODE_GONE ||
+            client_entry->mode & SILC_UMODE_INDISPOSED ||
+            client_entry->mode & SILC_UMODE_BUSY ||
+            client_entry->mode & SILC_UMODE_PAGE ||
+            client_entry->mode & SILC_UMODE_DETACHED)) {
+         printformat_module("fe-common/silc", server, NULL,
+                            MSGLEVEL_CRAP, SILCTXT_WATCH_PRESENT,
+                            client_entry->nickname);
+       }
+
+       if (mode) {
+         memset(buf, 0, sizeof(buf));
+         silc_get_umode_string(mode, buf, sizeof(buf) - 1);
+         printformat_module("fe-common/silc", server, NULL,
+                            MSGLEVEL_CRAP, SILCTXT_WATCH_UMODE_CHANGE,
+                            client_entry->nickname, buf);
+       }
+      } else if (notify == SILC_NOTIFY_TYPE_KILLED) {
+       printformat_module("fe-common/silc", server, NULL,
+                          MSGLEVEL_CRAP, SILCTXT_WATCH_KILLED,
+                          client_entry->nickname);
+      } else if (notify == SILC_NOTIFY_TYPE_SIGNOFF ||
+                notify == SILC_NOTIFY_TYPE_SERVER_SIGNOFF) {
+       printformat_module("fe-common/silc", server, NULL,
+                          MSGLEVEL_CRAP, SILCTXT_WATCH_SIGNOFF,
+                          client_entry->nickname);
+      } else if (notify == SILC_NOTIFY_TYPE_NONE) {
+       /* Client logged in to the network */
+       printformat_module("fe-common/silc", server, NULL,
+                          MSGLEVEL_CRAP, SILCTXT_WATCH_PRESENT,
+                          client_entry->nickname);
+      }
+    }
+    break;
+
   default:
     /* Unknown notify */
     printformat_module("fe-common/silc", server, NULL,
@@ -633,7 +833,7 @@ void silc_connect(SilcClient client, SilcClientConnection conn,
 {
   SILC_SERVER_REC *server = conn->context;
 
-  if (!server && status == SILC_CLIENT_CONN_ERROR) {
+  if (!server || server->disconnected) {
     silc_client_close_connection(client, conn);
     return;
   }
@@ -708,17 +908,19 @@ void silc_disconnect(SilcClient client, SilcClientConnection conn)
    that the command really was processed. */
 
 void silc_command(SilcClient client, SilcClientConnection conn, 
-                 SilcClientCommandContext cmd_context, int success,
-                 SilcCommand command)
+                 SilcClientCommandContext cmd_context, bool success,
+                 SilcCommand command, SilcStatus status)
 {
   SILC_SERVER_REC *server = conn->context;
 
   SILC_LOG_DEBUG(("Start"));
 
-  if (!success)
+  if (!success) {
+    silc_say_error("%s", silc_get_status_message(status));
     return;
+  }
 
-  switch(command) {
+  switch (command) {
   case SILC_COMMAND_INVITE:
     printformat_module("fe-common/silc", server, NULL,
                       MSGLEVEL_CRAP, SILCTXT_CHANNEL_INVITING,
@@ -749,6 +951,9 @@ static void silc_client_join_get_users(SilcClient client,
   SilcClientEntry founder = NULL;
   NICK_REC *ownnick;
 
+  SILC_LOG_DEBUG(("Start, channel %s, %d users", channel->channel_name,
+                 silc_hash_table_count(channel->user_list)));
+
   if (!clients)
     return;
 
@@ -838,8 +1043,8 @@ void silc_getkey_cb(bool success, void *context)
 
 void 
 silc_command_reply(SilcClient client, SilcClientConnection conn,
-                  SilcCommandPayload cmd_payload, int success,
-                  SilcCommand command, SilcCommandStatus status, ...)
+                  SilcCommandPayload cmd_payload, bool success,
+                  SilcCommand command, SilcStatus status, ...)
 
 {
   SILC_SERVER_REC *server = conn->context;
@@ -856,7 +1061,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       char buf[1024], *nickname, *username, *realname, *nick;
       unsigned char *fingerprint;
       SilcUInt32 idle, mode;
-      SilcBuffer channels;
+      SilcBuffer channels, user_modes;
       SilcClientEntry client_entry;
       
       if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
@@ -866,7 +1071,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
                                     3, NULL);
        if (tmp)
          silc_say_error("%s: %s", tmp, 
-                        silc_client_command_status_message(status));
+                        silc_get_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
@@ -883,7 +1088,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
                                                        client_id);
            if (client_entry && client_entry->nickname)
              silc_say_error("%s: %s", client_entry->nickname,
-                            silc_client_command_status_message(status));
+                            silc_get_status_message(status));
            silc_free(client_id);
          }
        }
@@ -901,6 +1106,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       mode = va_arg(vp, SilcUInt32);
       idle = va_arg(vp, SilcUInt32);
       fingerprint = va_arg(vp, unsigned char *);
+      user_modes = va_arg(vp, SilcBuffer);
       
       silc_parse_userfqdn(nickname, &nick, NULL);
       printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
@@ -911,16 +1117,20 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
                         SILCTXT_WHOIS_REALNAME, realname);
       silc_free(nick);
 
-      if (channels) {
+      if (channels && user_modes) {
+       SilcUInt32 *umodes;
        SilcDList list = silc_channel_payload_parse_list(channels->data,
                                                         channels->len);
-       if (list) {
+       if (list && silc_get_mode_list(user_modes, silc_dlist_count(list),
+                                      &umodes)) {
          SilcChannelPayload entry;
+         int i = 0;
+
          memset(buf, 0, sizeof(buf));
          silc_dlist_start(list);
          while ((entry = silc_dlist_get(list)) != SILC_LIST_END) {
-           char *m = silc_client_chumode_char(silc_channel_get_mode(entry));
            SilcUInt32 name_len;
+           char *m = silc_client_chumode_char(umodes[i++]);
            char *name = silc_channel_get_name(entry, &name_len);
            
            if (m)
@@ -933,38 +1143,13 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
          printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
                             SILCTXT_WHOIS_CHANNELS, buf);
          silc_channel_payload_list_free(list);
+         silc_free(umodes);
        }
       }
       
       if (mode) {
        memset(buf, 0, sizeof(buf));
-
-       if ((mode & SILC_UMODE_SERVER_OPERATOR) ||
-           (mode & SILC_UMODE_ROUTER_OPERATOR)) {
-         strcat(buf, (mode & SILC_UMODE_SERVER_OPERATOR) ?
-                "Server Operator" :
-                (mode & SILC_UMODE_ROUTER_OPERATOR) ?
-                "SILC Operator" : "[Unknown mode]");
-       }
-       if (mode & SILC_UMODE_GONE)
-         strcat(buf, " [away]");
-       if (mode & SILC_UMODE_INDISPOSED)
-         strcat(buf, " [indisposed]");
-       if (mode & SILC_UMODE_BUSY)
-         strcat(buf, " [busy]");
-       if (mode & SILC_UMODE_PAGE)
-         strcat(buf, " [page to reach]");
-       if (mode & SILC_UMODE_HYPER)
-         strcat(buf, " [hyper active]");
-       if (mode & SILC_UMODE_ROBOT)
-         strcat(buf, " [robot]");
-       if (mode & SILC_UMODE_ANONYMOUS)
-         strcat(buf, " [anonymous]");
-       if (mode & SILC_UMODE_BLOCK_PRIVMSG)
-         strcat(buf, " [blocks private messages]");
-       if (mode & SILC_UMODE_DETACHED)
-         strcat(buf, " [detached]");
-
+       silc_get_umode_string(mode, buf, sizeof(buf - 1));
        printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
                           SILCTXT_WHOIS_MODES, buf);
       }
@@ -999,7 +1184,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
                                     3, NULL);
        if (tmp)
          silc_say_error("%s: %s", tmp, 
-                        silc_client_command_status_message(status));
+                        silc_get_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
@@ -1016,7 +1201,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
                                                        client_id);
            if (client_entry && client_entry->nickname)
              silc_say_error("%s: %s", client_entry->nickname,
-                            silc_client_command_status_message(status));
+                            silc_get_status_message(status));
            silc_free(client_id);
          }
        }
@@ -1037,7 +1222,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
                                         3, NULL);
        if (tmp)
          silc_say_error("%s: %s", tmp, 
-                        silc_client_command_status_message(status));
+                        silc_get_status_message(status));
        break;
       }
       
@@ -1135,8 +1320,8 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
 
   case SILC_COMMAND_NICK: 
     {
-      SilcClientEntry client = va_arg(vp, SilcClientEntry);
       char *old;
+      SilcClientEntry client = va_arg(vp, SilcClientEntry);
       
       if (!success)
        return;
@@ -1400,6 +1585,8 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
     }
     break;
 
+  case SILC_COMMAND_WATCH:
+    break;
   }
 
   va_end(vp);
@@ -1678,6 +1865,8 @@ typedef struct {
 void ask_passphrase_completion(const char *passphrase, void *context)
 {
   AskPassphrase p = (AskPassphrase)context;
+  if (passphrase && passphrase[0] == '\0')
+    passphrase = NULL;
   p->completion((unsigned char *)passphrase, 
                passphrase ? strlen(passphrase) : 0, p->context);
   silc_free(p);