Updates.
authorPekka Riikonen <priikone@silcnet.org>
Mon, 29 Jan 2001 23:27:12 +0000 (23:27 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 29 Jan 2001 23:27:12 +0000 (23:27 +0000)
12 files changed:
CHANGES
apps/silc/client_ops.c
apps/silcd/command.c
apps/silcd/command.h
apps/silcd/command_reply.c
apps/silcd/command_reply.h
doc/draft-riikonen-silc-spec-01.nroff
lib/silcclient/command.c
lib/silcclient/command.h
lib/silcclient/command_reply.c
lib/silcclient/command_reply.h
lib/silccore/silccommand.h

diff --git a/CHANGES b/CHANGES
index e2e5fb620f89db6133810f00a9a1ef9e55ba9925..076bb2584d47a4bd2457d81b6f08f27a8dedc368 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,25 @@
+Tue Jan 30 00:05:05 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+       * Renames NAMES command to USERS command.  The NAMES was named that
+         due to historical reasons.  Now it is renamed.  Also, rewrote
+         parts of the USERS command.  The nickname list is not sent anymore
+         by the server.  Only Client ID and mode lists are sent in the USERS
+         command.  Changed this also to the protocol specification.
+
+         The client now resolves the names and stuff after it receives
+         the USERS list from the server when joining to the channel.
+
+       * WHOIS and IDENTIFY commands has been changed to support multiple
+         Client ID's per command.  One can now search for multiple users
+         in the network by sending only one WHOIS or IDENTIFY command.
+         Changed the code and the protocol specifications.
+
+       * Remove silc_server_command_identify_parse and changed that IDENTIFY
+         uses silc_server_command_whois_parse to parse the request. */
+
+       * If normal server, do not parse the WHOIS and IDENTIFY requests
+         before sending it to the router.  Saves some time.
+
 Sun Jan 28 16:19:49 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * Fixed JOIN command on client library.  Wrong number of arguments
index 3a2342dbe660ec1f7b994c124934b847aadfecce..511b20c4e500342c656909e3bdcbc7a2c5a82fac 100644 (file)
@@ -318,7 +318,7 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
       }
       break;
 
-    case SILC_COMMAND_NAMES:
+    case SILC_COMMAND_USERS:
       silc_list_start(conn->current_channel->clients);
       while ((chu = silc_list_get(conn->current_channel->clients)) 
             != SILC_LIST_END) {
index a5137efbc618ff3e8e8b8a61d61eef764ff80672..b7f9f680b60ad734945b42ed05a6d2c460e35744 100644 (file)
@@ -38,7 +38,7 @@ silc_server_command_send_status_data(SilcServerCommandContext cmd,
                                     unsigned char *arg,
                                     unsigned int arg_len);
 static void silc_server_command_free(SilcServerCommandContext cmd);
-void silc_server_command_send_names(SilcServer server,
+void silc_server_command_send_users(SilcServer server,
                                    SilcSocketConnection sock,
                                    SilcChannelEntry channel);
 
@@ -73,7 +73,7 @@ SilcServerCommand silc_command_list[] =
   SILC_SERVER_CMD(silcoper, SILCOPER,
                  SILC_CF_LAG | SILC_CF_REG | SILC_CF_SILC_OPER),
   SILC_SERVER_CMD(leave, LEAVE, SILC_CF_LAG | SILC_CF_REG),
-  SILC_SERVER_CMD(names, NAMES, SILC_CF_LAG | SILC_CF_REG),
+  SILC_SERVER_CMD(users, USERS, SILC_CF_LAG | SILC_CF_REG),
 
   { NULL, 0 },
 };
@@ -312,14 +312,17 @@ silc_server_command_send_status_data(SilcServerCommandContext cmd,
 
 static int
 silc_server_command_whois_parse(SilcServerCommandContext cmd,
-                               SilcClientID **client_id,
+                               SilcClientID ***client_id,
+                               unsigned int *client_id_count,
                                char **nickname,
                                char **server_name,
-                               int *count)
+                               int *count,
+                               SilcCommand command)
 {
   unsigned char *tmp;
   unsigned int len;
   unsigned int argc = silc_argument_get_arg_num(cmd->args);
+  int i, k;
 
   /* If client ID is in the command it must be used instead of nickname */
   tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
@@ -337,30 +340,40 @@ silc_server_command_whois_parse(SilcServerCommandContext cmd,
        *nickname = strdup(tmp);
       }
     } else {
-      silc_server_command_send_status_reply(cmd, SILC_COMMAND_WHOIS,
+      silc_server_command_send_status_reply(cmd, command,
                                            SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
       return FALSE;
     }
   } else {
+    /* Command includes ID, we must use that.  Also check whether the command
+       has more than one ID set - take them all. */
+
+    *client_id = silc_calloc(1, sizeof(**client_id));
+    (*client_id)[0] = silc_id_payload_parse_id(tmp, len);
+    *client_id_count = 1;
+
+    /* Take all ID's from the command packet */
+    if (argc > 3) {
+      for (k = 1, i = 4; i < argc; i++) {
+       tmp = silc_argument_get_arg_type(cmd->args, i, &len);
+       if (tmp) {
+         *client_id = silc_realloc(*client_id, sizeof(**client_id) *
+                                   (*client_id_count + 1));
+         (*client_id)[k++] = silc_id_payload_parse_id(tmp, len);
+         (*client_id_count)++;
+       }
+      }
+    }
+
     /* Command includes ID, use that */
-    *client_id = silc_id_payload_parse_id(tmp, len);
   }
 
   /* Get the max count of reply messages allowed */
-  if (argc == 3) {
-    tmp = silc_argument_get_arg_type(cmd->args, 3, NULL);
-    if (!tmp) {
-      silc_server_command_send_status_reply(cmd, SILC_COMMAND_WHOIS,
-                                           SILC_STATUS_ERR_TOO_MANY_PARAMS);
-      if (*nickname)
-       silc_free(*nickname);
-      if (*server_name)
-       silc_free(*server_name);
-
-      return FALSE;
-    }
+  tmp = silc_argument_get_arg_type(cmd->args, 2, NULL);
+  if (tmp)
     *count = atoi(tmp);
-  }
+  else
+    *count = 0;
 
   return TRUE;
 }
@@ -501,15 +514,11 @@ silc_server_command_whois_from_client(SilcServerCommandContext cmd)
 {
   SilcServer server = cmd->server;
   char *nick = NULL, *server_name = NULL;
-  int count = 0, clients_count;
-  SilcClientID *client_id = NULL;
+  int count = 0, clients_count = 0;
   SilcClientEntry *clients = NULL, entry;
-  int ret = 0;
-
-  /* Parse the whois request */
-  if (!silc_server_command_whois_parse(cmd, &client_id, &nick, 
-                                      &server_name, &count))
-    return 0;
+  SilcClientID **client_id = NULL;
+  unsigned int client_id_count = 0;
+  int i, ret = 0;
 
   /* Protocol dictates that we must always send the received WHOIS request
      to our router if we are normal server, so let's do it now unless we
@@ -546,13 +555,23 @@ silc_server_command_whois_from_client(SilcServerCommandContext cmd)
   /* We are ready to process the command request. Let's search for the
      requested client and send reply to the requesting client. */
 
+  /* Parse the whois request */
+  if (!silc_server_command_whois_parse(cmd, &client_id, &client_id_count, 
+                                      &nick, &server_name, &count,
+                                      SILC_COMMAND_WHOIS))
+    return 0;
+
   /* Get all clients matching that ID or nickname from local list */
-  if (client_id) {
-    entry = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
-    if (entry) {
-      clients = silc_calloc(1, sizeof(*clients));
-      clients[0] = entry;
-      clients_count = 1;
+  if (client_id_count) {
+    /* Check all Client ID's received in the command packet */
+    for (i = 0; i < client_id_count; i++) {
+      entry = silc_idlist_find_client_by_id(server->local_list, 
+                                           client_id[i], NULL);
+      if (entry) {
+       clients = silc_realloc(clients, sizeof(*clients) * 
+                              (clients_count + 1));
+       clients[clients_count++] = entry;
+      }
     }
   } else {
     clients = silc_idlist_get_clients_by_nickname(server->local_list, 
@@ -562,13 +581,16 @@ silc_server_command_whois_from_client(SilcServerCommandContext cmd)
   
   /* Check global list as well */
   if (!clients) {
-    if (client_id) {
-      entry = silc_idlist_find_client_by_id(server->global_list, 
-                                           client_id, NULL);
-      if (entry) {
-       clients = silc_calloc(1, sizeof(*clients));
-       clients[0] = entry;
-       clients_count = 1;
+    if (client_id_count) {
+      /* Check all Client ID's received in the command packet */
+      for (i = 0; i < client_id_count; i++) {
+       entry = silc_idlist_find_client_by_id(server->global_list, 
+                                             client_id[i], NULL);
+       if (entry) {
+         clients = silc_realloc(clients, sizeof(*clients) * 
+                                (clients_count + 1));
+         clients[clients_count++] = entry;
+       }
       }
     } else {
       clients = silc_idlist_get_clients_by_nickname(server->global_list, 
@@ -578,10 +600,18 @@ silc_server_command_whois_from_client(SilcServerCommandContext cmd)
   }
   
   if (!clients) {
-    /* Such a client really does not exist in the SILC network. */
-    silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOIS,
-                                        SILC_STATUS_ERR_NO_SUCH_NICK,
-                                        3, nick, strlen(nick));
+    /* Such client(s) really does not exist in the SILC network. */
+    if (!client_id_count) {
+      silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOIS,
+                                          SILC_STATUS_ERR_NO_SUCH_NICK,
+                                          3, nick, strlen(nick));
+    } else {
+      SilcBuffer idp = silc_id_payload_encode(client_id[0], SILC_ID_CLIENT);
+      silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOIS,
+                                          SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
+                                          2, idp->data, idp->len);
+      silc_buffer_free(idp);
+    }
     goto out;
   }
 
@@ -600,10 +630,13 @@ silc_server_command_whois_from_client(SilcServerCommandContext cmd)
   silc_server_command_whois_send_reply(cmd, clients, clients_count);
 
  out:
+  if (client_id_count) {
+    for (i = 0; i < client_id_count; i++)
+      silc_free(client_id[i]);
+    silc_free(client_id);
+  }
   if (clients)
     silc_free(clients);
-  if (client_id)
-    silc_free(client_id);
   if (nick)
     silc_free(nick);
   if (server_name)
@@ -617,25 +650,31 @@ silc_server_command_whois_from_server(SilcServerCommandContext cmd)
 {
   SilcServer server = cmd->server;
   char *nick = NULL, *server_name = NULL;
-  int count = 0, clients_count;
-  SilcClientID *client_id = NULL;
+  int count = 0, clients_count = 0;
   SilcClientEntry *clients = NULL, entry;
-  int ret = 0;
+  SilcClientID **client_id = NULL;
+  unsigned int client_id_count = 0;
+  int i, ret = 0;
 
   /* Parse the whois request */
-  if (!silc_server_command_whois_parse(cmd, &client_id, &nick, 
-                                      &server_name, &count))
+  if (!silc_server_command_whois_parse(cmd, &client_id, &client_id_count, 
+                                      &nick, &server_name, &count,
+                                      SILC_COMMAND_WHOIS))
     return 0;
 
   /* Process the command request. Let's search for the requested client and
      send reply to the requesting server. */
 
-  if (client_id) {
-    entry = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
-    if (entry) {
-      clients = silc_calloc(1, sizeof(*clients));
-      clients[0] = entry;
-      clients_count = 1;
+  if (client_id_count) {
+    /* Check all Client ID's received in the command packet */
+    for (i = 0; i < client_id_count; i++) {
+      entry = silc_idlist_find_client_by_id(server->local_list, 
+                                           client_id[i], NULL);
+      if (entry) {
+       clients = silc_realloc(clients, sizeof(*clients) * 
+                              (clients_count + 1));
+       clients[clients_count++] = entry;
+      }
     }
   } else {
     clients = silc_idlist_get_clients_by_nickname(server->local_list, 
@@ -649,13 +688,16 @@ silc_server_command_whois_from_server(SilcServerCommandContext cmd)
   
   /* If we are router we will check our global list as well. */
   if (!clients && server->server_type == SILC_ROUTER) {
-    if (client_id) {
-      entry = silc_idlist_find_client_by_id(server->global_list, 
-                                           client_id, NULL);
-      if (entry) {
-       clients = silc_calloc(1, sizeof(*clients));
-       clients[0] = entry;
-       clients_count = 1;
+    if (client_id_count) {
+      /* Check all Client ID's received in the command packet */
+      for (i = 0; i < client_id_count; i++) {
+       entry = silc_idlist_find_client_by_id(server->global_list, 
+                                             client_id[i], NULL);
+       if (entry) {
+         clients = silc_realloc(clients, sizeof(*clients) * 
+                                (clients_count + 1));
+         clients[clients_count++] = entry;
+       }
       }
     } else {
       clients = silc_idlist_get_clients_by_nickname(server->global_list, 
@@ -670,12 +712,12 @@ silc_server_command_whois_from_server(SilcServerCommandContext cmd)
 
   if (!clients) {
     /* Such a client really does not exist in the SILC network. */
-    if (!client_id) {
+    if (!client_id_count) {
       silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOIS,
                                           SILC_STATUS_ERR_NO_SUCH_NICK,
                                           3, nick, strlen(nick));
     } else {
-      SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
+      SilcBuffer idp = silc_id_payload_encode(client_id[0], SILC_ID_CLIENT);
       silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOIS,
                                           SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
                                           2, idp->data, idp->len);
@@ -699,10 +741,13 @@ silc_server_command_whois_from_server(SilcServerCommandContext cmd)
   silc_server_command_whois_send_reply(cmd, clients, clients_count);
 
  out:
+  if (client_id_count) {
+    for (i = 0; i < client_id_count; i++)
+      silc_free(client_id[i]);
+    silc_free(client_id);
+  }
   if (clients)
     silc_free(clients);
-  if (client_id)
-    silc_free(client_id);
   if (nick)
     silc_free(nick);
   if (server_name)
@@ -740,61 +785,6 @@ SILC_SERVER_CMD_FUNC(whowas)
 
 ******************************************************************************/
 
-static int
-silc_server_command_identify_parse(SilcServerCommandContext cmd,
-                                  SilcClientID **client_id,
-                                  char **nickname,
-                                  char **server_name,
-                                  int *count)
-{
-  unsigned char *tmp;
-  unsigned int len;
-  unsigned int argc = silc_argument_get_arg_num(cmd->args);
-
-  /* If client ID is in the command it must be used instead of nickname */
-  tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
-  if (!tmp) {
-    /* No ID, get the nickname@server string and parse it. */
-    tmp = silc_argument_get_arg_type(cmd->args, 1, NULL);
-    if (tmp) {
-      if (strchr(tmp, '@')) {
-       len = strcspn(tmp, "@");
-       *nickname = silc_calloc(len + 1, sizeof(char));
-       memcpy(*nickname, tmp, len);
-       *server_name = silc_calloc(strlen(tmp) - len, sizeof(char));
-       memcpy(*server_name, tmp + len + 1, strlen(tmp) - len - 1);
-      } else {
-       *nickname = strdup(tmp);
-      }
-    } else {
-      silc_server_command_send_status_reply(cmd, SILC_COMMAND_IDENTIFY,
-                                           SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
-      return FALSE;
-    }
-  } else {
-    /* Command includes ID, use that */
-    *client_id = silc_id_payload_parse_id(tmp, len);
-  }
-
-  /* Get the max count of reply messages allowed */
-  if (argc == 3) {
-    tmp = silc_argument_get_arg_type(cmd->args, 3, NULL);
-    if (!tmp) {
-      silc_server_command_send_status_reply(cmd, SILC_COMMAND_IDENTIFY,
-                                           SILC_STATUS_ERR_TOO_MANY_PARAMS);
-      if (*nickname)
-       silc_free(*nickname);
-      if (*server_name)
-       silc_free(*server_name);
-
-      return FALSE;
-    }
-    *count = atoi(tmp);
-  }
-
-  return TRUE;
-}
-
 /* Checks that all mandatory fields are present. If not then send WHOIS 
    request to the server who owns the client. We use WHOIS because we want
    to get as much information as possible at once. */
@@ -929,15 +919,11 @@ silc_server_command_identify_from_client(SilcServerCommandContext cmd)
 {
   SilcServer server = cmd->server;
   char *nick = NULL, *server_name = NULL;
-  int count = 0, clients_count;
-  SilcClientID *client_id = NULL;
+  int count = 0, clients_count; 
   SilcClientEntry *clients = NULL, entry;
-  int ret = 0;
-
-  /* Parse the IDENTIFY request */
-  if (!silc_server_command_identify_parse(cmd, &client_id, &nick, 
-                                         &server_name, &count))
-    return 0;
+  SilcClientID **client_id = NULL;
+  unsigned int client_id_count = 0;
+  int i, ret = 0;
 
   /* Protocol dictates that we must always send the received IDENTIFY request
      to our router if we are normal server, so let's do it now unless we
@@ -974,13 +960,23 @@ silc_server_command_identify_from_client(SilcServerCommandContext cmd)
   /* We are ready to process the command request. Let's search for the
      requested client and send reply to the requesting client. */
 
+  /* Parse the IDENTIFY request */
+  if (!silc_server_command_whois_parse(cmd, &client_id, &client_id_count,
+                                      &nick, &server_name, &count,
+                                      SILC_COMMAND_IDENTIFY))
+    return 0;
+
   /* Get all clients matching that ID or nickname from local list */
-  if (client_id) {
-    entry = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
-    if (entry) {
-      clients = silc_calloc(1, sizeof(*clients));
-      clients[0] = entry;
-      clients_count = 1;
+  if (client_id_count) { 
+    /* Check all Client ID's received in the command packet */
+    for (i = 0; i < client_id_count; i++) {
+      entry = silc_idlist_find_client_by_id(server->local_list, 
+                                           client_id[i], NULL);
+      if (entry) {
+       clients = silc_realloc(clients, sizeof(*clients) * 
+                              (clients_count + 1));
+       clients[clients_count++] = entry;
+      }
     }
   } else {
     clients = silc_idlist_get_clients_by_nickname(server->local_list, 
@@ -990,13 +986,16 @@ silc_server_command_identify_from_client(SilcServerCommandContext cmd)
   
   /* Check global list as well */
   if (!clients) {
-    if (client_id) {
-      entry = silc_idlist_find_client_by_id(server->global_list, 
-                                           client_id, NULL);
-      if (entry) {
-       clients = silc_calloc(1, sizeof(*clients));
-       clients[0] = entry;
-       clients_count = 1;
+    if (client_id_count) {
+      /* Check all Client ID's received in the command packet */
+      for (i = 0; i < client_id_count; i++) {
+       entry = silc_idlist_find_client_by_id(server->global_list, 
+                                             client_id[i], NULL);
+       if (entry) {
+         clients = silc_realloc(clients, sizeof(*clients) * 
+                                (clients_count + 1));
+         clients[clients_count++] = entry;
+       }
       }
     } else {
       clients = silc_idlist_get_clients_by_nickname(server->global_list, 
@@ -1007,12 +1006,12 @@ silc_server_command_identify_from_client(SilcServerCommandContext cmd)
   
   if (!clients) {
     /* Such a client really does not exist in the SILC network. */
-    if (!client_id) {
+    if (!client_id_count) {
       silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY,
                                           SILC_STATUS_ERR_NO_SUCH_NICK,
                                           3, nick, strlen(nick));
     } else {
-      SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
+      SilcBuffer idp = silc_id_payload_encode(client_id[0], SILC_ID_CLIENT);
       silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY,
                                           SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
                                           2, idp->data, idp->len);
@@ -1033,10 +1032,13 @@ silc_server_command_identify_from_client(SilcServerCommandContext cmd)
   silc_server_command_identify_send_reply(cmd, clients, clients_count);
 
  out:
+  if (client_id_count) {
+    for (i = 0; i < client_id_count; i++)
+      silc_free(client_id[i]);
+    silc_free(client_id);
+  }
   if (clients)
     silc_free(clients);
-  if (client_id)
-    silc_free(client_id);
   if (nick)
     silc_free(nick);
   if (server_name)
@@ -1051,24 +1053,30 @@ silc_server_command_identify_from_server(SilcServerCommandContext cmd)
   SilcServer server = cmd->server;
   char *nick = NULL, *server_name = NULL;
   int count = 0, clients_count;
-  SilcClientID *client_id = NULL;
   SilcClientEntry *clients = NULL, entry;
-  int ret = 0;
+  SilcClientID **client_id = NULL;
+  unsigned int client_id_count = 0;
+  int i, ret = 0;
 
   /* Parse the IDENTIFY request */
-  if (!silc_server_command_identify_parse(cmd, &client_id, &nick, 
-                                         &server_name, &count))
+  if (!silc_server_command_whois_parse(cmd, &client_id, &client_id_count,
+                                      &nick, &server_name, &count,
+                                      SILC_COMMAND_IDENTIFY))
     return 0;
 
   /* Process the command request. Let's search for the requested client and
      send reply to the requesting server. */
 
-  if (client_id) {
-    entry = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
-    if (entry) {
-      clients = silc_calloc(1, sizeof(*clients));
-      clients[0] = entry;
-      clients_count = 1;
+  if (client_id_count) {
+    /* Check all Client ID's received in the command packet */
+    for (i = 0; i < client_id_count; i++) {
+      entry = silc_idlist_find_client_by_id(server->local_list, 
+                                           client_id[i], NULL);
+      if (entry) {
+       clients = silc_realloc(clients, sizeof(*clients) * 
+                              (clients_count + 1));
+       clients[clients_count++] = entry;
+      }
     }
   } else {
     clients = silc_idlist_get_clients_by_nickname(server->local_list, 
@@ -1082,13 +1090,16 @@ silc_server_command_identify_from_server(SilcServerCommandContext cmd)
   
   /* If we are router we will check our global list as well. */
   if (!clients && server->server_type == SILC_ROUTER) {
-    if (client_id) {
-      entry = silc_idlist_find_client_by_id(server->global_list, 
-                                           client_id, NULL);
-      if (entry) {
-       clients = silc_calloc(1, sizeof(*clients));
-       clients[0] = entry;
-       clients_count = 1;
+    if (client_id_count) {
+      /* Check all Client ID's received in the command packet */
+      for (i = 0; i < client_id_count; i++) {
+       entry = silc_idlist_find_client_by_id(server->global_list, 
+                                             client_id[i], NULL);
+       if (entry) {
+         clients = silc_realloc(clients, sizeof(*clients) * 
+                                (clients_count + 1));
+         clients[clients_count++] = entry;
+       }
       }
     } else {
       clients = silc_idlist_get_clients_by_nickname(server->global_list, 
@@ -1121,10 +1132,13 @@ silc_server_command_identify_from_server(SilcServerCommandContext cmd)
   silc_server_command_identify_send_reply(cmd, clients, clients_count);
 
  out:
+  if (client_id_count) {
+    for (i = 0; i < client_id_count; i++)
+      silc_free(client_id[i]);
+    silc_free(client_id);
+  }
   if (clients)
     silc_free(clients);
-  if (client_id)
-    silc_free(client_id);
   if (nick)
     silc_free(nick);
   if (server_name)
@@ -1436,7 +1450,7 @@ SILC_SERVER_CMD_FUNC(invite)
 
   /* Check whether the requested client is already on the channel. */
   /* XXX if we are normal server we don't know about global clients on
-     the channel thus we must request it (NAMES command), check from
+     the channel thus we must request it (USERS command), check from
      local cache as well. */
   if (silc_server_client_on_channel(dest, channel)) {
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
@@ -1636,9 +1650,9 @@ SILC_TASK_CALLBACK(silc_server_command_join_notify)
                                      client->id, SILC_ID_CLIENT_LEN);
 #endif
 
-    /* Send NAMES command reply to the joined channel so the user sees who
+    /* Send USERS command reply to the joined channel so the user sees who
        is currently on the channel. */
-    silc_server_command_send_names(ctx->server, ctx->client->connection, 
+    silc_server_command_send_users(ctx->server, ctx->client->connection, 
                                   ctx->channel);
 
     silc_buffer_free(clidp);
@@ -1650,11 +1664,11 @@ SILC_TASK_CALLBACK(silc_server_command_join_notify)
   }
 }
 
-/* Assembles NAMES command and executes it. This is called when client
-   joins to a channel and we wan't to send NAMES command reply to the 
+/* Assembles USERS command and executes it. This is called when client
+   joins to a channel and we wan't to send USERS command reply to the 
    client. */
 
-void silc_server_command_send_names(SilcServer server,
+void silc_server_command_send_users(SilcServer server,
                                    SilcSocketConnection sock,
                                    SilcChannelEntry channel)
 {
@@ -1663,7 +1677,7 @@ void silc_server_command_send_names(SilcServer server,
   SilcPacketContext *packet = silc_packet_context_alloc();
 
   idp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
-  buffer = silc_command_payload_encode_va(SILC_COMMAND_NAMES, 0, 1,
+  buffer = silc_command_payload_encode_va(SILC_COMMAND_USERS, 0, 1,
                                          1, idp->data, idp->len);
 
   packet->buffer = silc_buffer_copy(buffer);
@@ -1678,7 +1692,7 @@ void silc_server_command_send_names(SilcServer server,
   cmd->packet = silc_packet_context_dup(packet);
   cmd->pending = FALSE;
 
-  silc_server_command_names((void *)cmd);
+  silc_server_command_users((void *)cmd);
 
   silc_free(buffer);
   silc_free(idp);
@@ -1897,18 +1911,18 @@ static void silc_server_command_join_channel(SilcServer server,
                                      channel->id, SILC_ID_CHANNEL_LEN,
                                      client->id, SILC_ID_CLIENT_LEN);
 
-  /* Send NAMES command reply to the joined channel so the user sees who
+  /* Send USERS command reply to the joined channel so the user sees who
      is currently on the channel. */
-  silc_server_command_send_names(server, sock, channel);
+  silc_server_command_send_users(server, sock, channel);
 
   /*
 
     FAQ:
 
-   * Kuinka NAMES komento händlätään serverissä kun router lähettää sen
+   * Kuinka USERS komento händlätään serverissä kun router lähettää sen
    serverille joka on lähettäny sille clientin puolesta JOIN komennon?
    
-   R: Serverin pitää ymmärtää NAMES comman replyjä.
+   R: Serverin pitää ymmärtää USERS comman replyjä.
 
   */
 
@@ -2820,11 +2834,11 @@ SILC_SERVER_CMD_FUNC(leave)
   silc_server_command_free(cmd);
 }
 
-/* Server side of command NAMES. Resolves clients and their names currently
-   joined on the requested channel. The name list is sent back to the
-   client. */
+/* Server side of command USERS. Resolves clients and their USERS currently
+   joined on the requested channel. The list of Client ID's and their modes
+   on the channel is sent back. */
 
-SILC_SERVER_CMD_FUNC(names)
+SILC_SERVER_CMD_FUNC(users)
 {
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
   SilcServer server = cmd->server;
@@ -2832,56 +2846,58 @@ SILC_SERVER_CMD_FUNC(names)
   SilcChannelClientEntry chl;
   SilcChannelID *id;
   SilcBuffer packet;
-  unsigned int i, len, len2, tmp_len;
   unsigned char *tmp;
-  char *name_list = NULL, *n;
+  unsigned int tmp_len;
   SilcBuffer client_id_list;
   SilcBuffer client_mode_list;
   SilcBuffer idp;
   unsigned short ident = silc_command_get_ident(cmd->payload);
 
-  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_NAMES, cmd, 1, 2);
+  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_USERS, cmd, 1, 2);
 
   /* Get Channel ID */
   tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
   if (!tmp) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_NAMES,
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
                                          SILC_STATUS_ERR_NO_CHANNEL_ID);
     goto out;
   }
   id = silc_id_payload_parse_id(tmp, tmp_len);
 
-  if (server->server_type == SILC_SERVER && !server->standalone &&
-      !cmd->pending) {
-    SilcBuffer tmpbuf;
-    
-    silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
-    tmpbuf = silc_command_payload_encode_payload(cmd->payload);
-    
-    /* Send NAMES command */
-    silc_server_packet_send(server, server->router->connection,
-                           SILC_PACKET_COMMAND, cmd->packet->flags,
-                           tmpbuf->data, tmpbuf->len, TRUE);
-    
-    /* Reprocess this packet after received reply */
-    silc_server_command_pending(server, SILC_COMMAND_NAMES, 
-                               silc_command_get_ident(cmd->payload),
-                               silc_server_command_names, (void *)cmd);
-    cmd->pending = TRUE;
-    silc_command_set_ident(cmd->payload, ident);
-    
-    silc_buffer_free(tmpbuf);
-    silc_free(id);
-    return;
-  }
-
-  /* Get the channel entry */
+  /* If we are server and we don't know about this channel we will send
+     the command to our router. If we know about the channel then we also
+     have the list of users already. */
   channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
   if (!channel) {
+    if (server->server_type == SILC_SERVER && !server->standalone &&
+       !cmd->pending) {
+      SilcBuffer tmpbuf;
+      
+      silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
+      tmpbuf = silc_command_payload_encode_payload(cmd->payload);
+      
+      /* Send USERS command */
+      silc_server_packet_send(server, server->router->connection,
+                             SILC_PACKET_COMMAND, cmd->packet->flags,
+                             tmpbuf->data, tmpbuf->len, TRUE);
+      
+      /* Reprocess this packet after received reply */
+      silc_server_command_pending(server, SILC_COMMAND_USERS, 
+                                 silc_command_get_ident(cmd->payload),
+                                 silc_server_command_users, (void *)cmd);
+      cmd->pending = TRUE;
+      silc_command_set_ident(cmd->payload, ident);
+      
+      silc_buffer_free(tmpbuf);
+      silc_free(id);
+      return;
+    }
+
+    /* We are router and we will check the global list as well. */
     channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
     if (!channel) {
       /* Channel really does not exist */
-      silc_server_command_send_status_reply(cmd, SILC_COMMAND_NAMES,
+      silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
                                            SILC_STATUS_ERR_NO_SUCH_CHANNEL);
       goto out;
     }
@@ -2889,8 +2905,6 @@ SILC_SERVER_CMD_FUNC(names)
 
   /* Assemble the lists now */
 
-  name_list = NULL;
-  len = i = 0;
   client_id_list = silc_buffer_alloc((SILC_ID_CLIENT_LEN + 4) * 
                                     silc_list_count(channel->user_list));
   silc_buffer_pull_tail(client_id_list, SILC_BUFFER_END(client_id_list));
@@ -2900,22 +2914,6 @@ SILC_SERVER_CMD_FUNC(names)
 
   silc_list_start(channel->user_list);
   while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
-    /* Nickname */
-    n = chl->client->nickname;
-    if (n) {
-      len2 = strlen(n);
-      len += len2;
-      name_list = silc_realloc(name_list, sizeof(*name_list) * (len + 1));
-      memcpy(name_list + (len - len2), n, len2);
-      name_list[len] = 0;
-
-      if (i == silc_list_count(channel->user_list) - 1)
-       break;
-      memcpy(name_list + len, ",", 1);
-      len++;
-      i++;
-    }
-
     /* Client ID */
     idp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
     silc_buffer_put(client_id_list, idp->data, idp->len);
@@ -2930,24 +2928,19 @@ SILC_SERVER_CMD_FUNC(names)
                   client_id_list->data - client_id_list->head);
   silc_buffer_push(client_mode_list, 
                   client_mode_list->data - client_mode_list->head);
-  if (!name_list)
-    name_list = "";
 
   /* Send reply */
-  packet = silc_command_reply_payload_encode_va(SILC_COMMAND_NAMES,
+  packet = silc_command_reply_payload_encode_va(SILC_COMMAND_USERS,
                                                SILC_STATUS_OK, 0, 4,
                                                2, tmp, tmp_len,
-                                               3, name_list, 
-                                               strlen(name_list),
-                                               4, client_id_list->data,
+                                               3, client_id_list->data,
                                                client_id_list->len,
-                                               5, client_mode_list->data,
+                                               4, client_mode_list->data,
                                                client_mode_list->len);
   silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, 
                          packet->data, packet->len, FALSE);
     
   silc_buffer_free(packet);
-  silc_free(name_list);
   silc_buffer_free(client_id_list);
   silc_buffer_free(client_mode_list);
   silc_free(id);
index 72ada8b30df493d80b10ea52d317a6a0496b8962..5e6858a43f48d96807e371df86fbb5d5fde0eb60 100644 (file)
@@ -133,6 +133,6 @@ SILC_SERVER_CMD_FUNC(close);
 SILC_SERVER_CMD_FUNC(die);
 SILC_SERVER_CMD_FUNC(silcoper);
 SILC_SERVER_CMD_FUNC(leave);
-SILC_SERVER_CMD_FUNC(names);
+SILC_SERVER_CMD_FUNC(users);
 
 #endif
index 4b69ce9af2accddc206a56f3d523882197bd2e0a..073bf822477dc3332e990347004644c83f8ef499 100644 (file)
@@ -53,7 +53,7 @@ SilcServerCommandReply silc_command_reply_list[] =
   SILC_SERVER_CMD_REPLY(join, JOIN),
   SILC_SERVER_CMD_REPLY(whois, WHOIS),
   SILC_SERVER_CMD_REPLY(identify, IDENTIFY),
-  SILC_SERVER_CMD_REPLY(names, NAMES),
+  SILC_SERVER_CMD_REPLY(users, USERS),
 
   { NULL, 0 },
 };
@@ -484,7 +484,7 @@ SILC_SERVER_CMD_REPLY_FUNC(join)
   silc_server_command_reply_free(cmd);
 }
 
-SILC_SERVER_CMD_REPLY_FUNC(names)
+SILC_SERVER_CMD_REPLY_FUNC(users)
 {
   SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
   SilcServer server = cmd->server;
@@ -494,39 +494,40 @@ SILC_SERVER_CMD_REPLY_FUNC(names)
   SilcBuffer client_id_list;
   SilcBuffer client_mode_list;
   unsigned char *tmp;
-  char *name_list, *cp;
-  int i, len1, len2, list_count = 0;
+  unsigned int tmp_len;
+  unsigned int list_count, i;
 
   COMMAND_CHECK_STATUS;
 
   /* Get channel ID */
-  tmp = silc_argument_get_arg_type(cmd->args, 2, &len1);
+  tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
   if (!tmp)
     goto out;
-  channel_id = silc_id_payload_parse_id(tmp, len1);
+  channel_id = silc_id_payload_parse_id(tmp, tmp_len);
 
-  /* Get the name list of the channel */
-  name_list = silc_argument_get_arg_type(cmd->args, 3, &len1);
-  if (!name_list)
+  /* Get the list count */
+  tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
+  if (!tmp)
     goto out;
+  SILC_GET32_MSB(list_count, tmp);
 
   /* Get Client ID list */
-  tmp = silc_argument_get_arg_type(cmd->args, 4, &len2);
+  tmp = silc_argument_get_arg_type(cmd->args, 4, &tmp_len);
   if (!tmp)
     goto out;
 
-  client_id_list = silc_buffer_alloc(len2);
-  silc_buffer_pull_tail(client_id_list, len2);
-  silc_buffer_put(client_id_list, tmp, len2);
+  client_id_list = silc_buffer_alloc(tmp_len);
+  silc_buffer_pull_tail(client_id_list, tmp_len);
+  silc_buffer_put(client_id_list, tmp, tmp_len);
 
   /* Get client mode list */
-  tmp = silc_argument_get_arg_type(cmd->args, 5, &len2);
+  tmp = silc_argument_get_arg_type(cmd->args, 5, &tmp_len);
   if (!tmp)
     goto out;
 
-  client_mode_list = silc_buffer_alloc(len2);
-  silc_buffer_pull_tail(client_mode_list, len2);
-  silc_buffer_put(client_mode_list, tmp, len2);
+  client_mode_list = silc_buffer_alloc(tmp_len);
+  silc_buffer_pull_tail(client_mode_list, tmp_len);
+  silc_buffer_put(client_mode_list, tmp, tmp_len);
 
   /* Get channel entry */
   channel = silc_idlist_find_channel_by_id(server->local_list, 
@@ -538,32 +539,18 @@ SILC_SERVER_CMD_REPLY_FUNC(names)
       goto out;
   }
 
-  /* Remove commas from list */
-  for (i = 0; i < len1; i++)
-    if (name_list[i] == ',') {
-      name_list[i] = ' ';
-      list_count++;
-    }
-  list_count++;
-
-  /* Cache the received name list, client ID's and modes. This cache expires
+  /* Cache the received Client ID's and modes. This cache expires
      whenever server sends notify message to channel. It means two things;
      some user has joined or leaved the channel. XXX! */
-  cp = name_list;
   for (i = 0; i < list_count; i++) {
-    int nick_len = strcspn(name_list, " ");
     unsigned short idp_len;
     unsigned int mode;
-    char *nick, *nickname = silc_calloc(nick_len + 1, sizeof(*nickname));
     SilcClientID *client_id;
     SilcClientEntry client;
 
-    /* Nickname */
-    memcpy(nickname, name_list, nick_len);
+    /* Client ID */
     SILC_GET16_MSB(idp_len, client_id_list->data + 2);
     idp_len += 4;
-
-    /* Client ID */
     client_id = silc_id_payload_parse_id(client_id_list->data, idp_len);
     silc_buffer_pull(client_id_list, idp_len);
     
@@ -583,35 +570,22 @@ SILC_SERVER_CMD_REPLY_FUNC(names)
       if (server->server_type == SILC_ROUTER)
        goto out;
 
-      /* Take hostname out of nick string if it includes it. */
-      if (strchr(nickname, '@')) {
-       int len = strcspn(nickname, "@");
-       nick = silc_calloc(len + 1, sizeof(char));
-       memcpy(nick, nickname, len);
-      } else {
-       nick = strdup(nickname);
-      }
-      
       /* We don't have that client anywhere, add it. The client is added
         to global list since server didn't have it in the lists so it must be 
         global. */
-      silc_idlist_add_client(server->global_list, nick, NULL, NULL,
+      silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
                             client_id, NULL, NULL);
     } else {
       /* We have the client already. */
       silc_free(client_id);
     }
-
-    silc_free(nickname);
-
-    name_list += nick_len + 1;
   }
 
   silc_buffer_free(client_id_list);
   silc_buffer_free(client_mode_list);
 
   /* Execute any pending commands */
-  SILC_SERVER_COMMAND_EXEC_PENDING(cmd, SILC_COMMAND_NAMES);
+  SILC_SERVER_COMMAND_EXEC_PENDING(cmd, SILC_COMMAND_USERS);
 
  out:
   if (channel_id)
index 599623df97144a123bbc886f34ef7fb5b00a9aca..9e0eb531b1e456c5a1dade73fb87bdd350da964f 100644 (file)
@@ -60,6 +60,6 @@ void silc_server_command_reply_process(SilcServer server,
 SILC_SERVER_CMD_REPLY_FUNC(join);
 SILC_SERVER_CMD_REPLY_FUNC(whois);
 SILC_SERVER_CMD_REPLY_FUNC(identify);
-SILC_SERVER_CMD_REPLY_FUNC(names);
+SILC_SERVER_CMD_REPLY_FUNC(users);
 
 #endif
index 1064e9db6cbe08a93eb472939894644ce4e24ecf..7428a40e4baf413a31c6e7f39627f3d5b005407c 100644 (file)
@@ -1446,9 +1446,9 @@ message communication thereafter.  Client also receives the key for the
 channel in the command reply.
 
 If client wants to know the other clients currently on the channel
-the client must send SILC_COMMAND_NAMES command to receive a list of
+the client must send SILC_COMMAND_USERS command to receive a list of
 channel users.  Server implementation, however, may send command reply
-packet to SILC_COMMAND_NAMES command after client has joined to the
+packet to SILC_COMMAND_USERS command after client has joined to the
 channel even if the client has not sent the command.  Server should also
 send SILC_NOTIFY_TYPE_JOIN to all clients on the channel about a new
 client on the channel.
@@ -1721,9 +1721,9 @@ List of all defined commands in SILC follows.
 
    1    SILC_COMMAND_WHOIS
 
-        Max Arguments:  3
-            Arguments:  (1) [<nickname>[@<server>]]  (2) [<Client ID>]
-                        (3) [<count>]
+        Max Arguments:  3328
+            Arguments:  (1) [<nickname>[@<server>]]  (2) [<count>]
+                        (3) [<Client ID>]            (n) [...]
 
         Whois command is used to query various information about specific
         user.  The user maybe requested by their nickname and server name.
@@ -1735,7 +1735,11 @@ List of all defined commands in SILC follows.
 
         It is also possible to search the user by Client ID.  If <Client ID>
         is provided server must use it as the search value instead of
-        the <nickname>.  One of the arguments must be given.
+        the <nickname>.  One of the arguments must be given.  It is also
+        possible to define multiple Client ID's to search multiple users
+        sending only one WHOIS command.  In this case the Client ID's are
+        appended as normal arguments.  The server replies in this case
+        with only one reply message for all requested users.
 
         To prevent miss-use of this service wildcards in the nickname
         or in the servername are not permitted.  It is not allowed
@@ -1837,9 +1841,9 @@ List of all defined commands in SILC follows.
 
    3    SILC_COMMAND_IDENTIFY
 
-        Max Arguments:  2
-            Arguments:  (1) [<nickname>[@<server>]]  (2) [<Client ID>]
-                        (3) [<count>]
+        Max Arguments:  3328
+            Arguments:  (1) [<nickname>[@<server>]]  (2) [<count>]
+                        (3) [<Client ID>]            (n) [...]
 
         Identify.  Identify command is almost analogous to WHOIS command,
         except that it does not return as much information.  Only relevant
@@ -1855,7 +1859,11 @@ List of all defined commands in SILC follows.
 
         It is also possible to search the user by Client ID.  If <Client ID>
         is provided server must use it as the search value instead of
-        the <nickname>.
+        the <nickname>.  One of the arguments must be given.  It is also
+        possible to define multiple Client ID's to search multiple users
+        sending only one IDENTIFY command.  In this case the Client ID's are
+        appended as normal arguments.  The server replies in this case
+        with only one reply message for all requested users.
 
         To prevent miss-use of this service wildcards in the nickname
         or in the servername are not permitted.  It is not allowed
@@ -2849,7 +2857,7 @@ List of all defined commands in SILC follows.
             SILC_STATUS_ERR_NO_CHANNEL_ID
 
 
-   25   SILC_COMMAND_NAMES
+   25   SILC_COMMAND_USERS
 
         Max Arguments:  1
             Arguments:  (1) <Channel ID>
@@ -2871,19 +2879,17 @@ List of all defined commands in SILC follows.
 
         Max Arguments:  5
             Arguments:  (1) <Status Payload>  (2) <Channel ID>
-                        (3) <name list>       (4) <Client ID list>
+                        (3) <list count>      (4) <Client ID list>
                         (5) <client mode list>
 
-        This command replies with the Channel ID of the requested channel,
-        comma separated list of users on the channel and Client ID list
-        of the users on the list.  The Client ID list has Client ID's
-        of all users in the list.  First Client ID in the list must be
-        the Client ID of the first user in <name list>.  The <Client ID
-        list> is formed by adding Client ID's each after each.  Note that
-        the Client ID list is binary data and the length of each ID must
-        be snooped from the data.  The <client mode list> is formed by
-        adding client's user modes on the channel each after each (4 bytes 
-        each).
+        This command replies with the Channel ID of the requested channel
+        Client ID list of the users on the channel and list of their modes.
+        The Client ID list has Client ID's of all users in the list.  The 
+        <Client ID list> is formed by adding Client ID's one after another.
+        The <client mode list> is formed by adding client's user modes on
+        the channel one after another (4 bytes (32 bits) each).  The <list 
+        count> of length of 4 bytes (32 bits), tells the number of entries
+        in the lists.  Both lists must have equal number of entries.
 
         Status messages:
 
@@ -2986,7 +2992,7 @@ List of all defined command status messages following.
         reply is the last of the list.  There won't be other replies
         belonging to this list after this one.
 
-   3 - 9
+   4 - 9
 
         Currently undefined and has been reserved for the future.
 
index 590ae71c004f997f8b97bbd1ae54d0d8e6e9c5f7..2dc94102d549572c3871fb06a17439c8f678f24f 100644 (file)
@@ -56,7 +56,7 @@ SilcClientCommand silc_command_list[] =
   SILC_CLIENT_CMD(silcoper, SILCOPER, "SILOPER",
                  SILC_CF_LAG | SILC_CF_REG | SILC_CF_SILC_OPER, 2),
   SILC_CLIENT_CMD(leave, LEAVE, "LEAVE", SILC_CF_LAG | SILC_CF_REG, 2),
-  SILC_CLIENT_CMD(names, NAMES, "NAMES", SILC_CF_LAG | SILC_CF_REG, 2),
+  SILC_CLIENT_CMD(users, USERS, "USERS", SILC_CF_LAG | SILC_CF_REG, 2),
 
   { NULL, 0, NULL, 0, 0 },
 };
@@ -1164,10 +1164,10 @@ SILC_CLIENT_CMD_FUNC(leave)
   silc_client_command_free(cmd);
 }
 
-/* Command NAMES. Requests the names of the clients joined on requested
+/* Command USERS. Requests the USERS of the clients joined on requested
    channel. */
 
-SILC_CLIENT_CMD_FUNC(names)
+SILC_CLIENT_CMD_FUNC(users)
 {
   SilcClientCommandContext cmd = (SilcClientCommandContext)context;
   SilcClientConnection conn = cmd->conn;
@@ -1182,7 +1182,7 @@ SILC_CLIENT_CMD_FUNC(names)
   }
 
   if (cmd->argc != 2) {
-    cmd->client->ops->say(cmd->client, conn, "Usage: /NAMES <channel>");
+    cmd->client->ops->say(cmd->client, conn, "Usage: /USERS <channel>");
     COMMAND_ERROR;
     goto out;
   }
@@ -1213,9 +1213,9 @@ SILC_CLIENT_CMD_FUNC(names)
     goto out;
   }
 
-  /* Send NAMES command to the server */
+  /* Send USERS command to the server */
   idp = silc_id_payload_encode(id_cache->id, SILC_ID_CHANNEL);
-  buffer = silc_command_payload_encode_va(SILC_COMMAND_NAMES, 0, 1, 
+  buffer = silc_command_payload_encode_va(SILC_COMMAND_USERS, 0, 1, 
                                          1, idp->data, idp->len);
   silc_client_packet_send(cmd->client, conn->sock, SILC_PACKET_COMMAND, NULL, 
                          0, NULL, NULL, buffer->data, buffer->len, TRUE);
@@ -1230,8 +1230,8 @@ SILC_CLIENT_CMD_FUNC(names)
   /* XXX this is kludge and should be removed after pending command reply 
      support is added. Currently only commands may be pending not command
      replies. */
-  silc_client_command_pending(SILC_COMMAND_NAMES, 
-                             silc_client_command_names, NULL);
+  silc_client_command_pending(SILC_COMMAND_USERS, 
+                             silc_client_command_users, NULL);
 
   /* Notify application */
   COMMAND;
index 11163ac4b2ba52220dcbf9ca31f89c4fa3803229..7e7db0e9a32b2b8ef90dc8e7078fffbde90ccf7d 100644 (file)
@@ -159,6 +159,6 @@ SILC_CLIENT_CMD_FUNC(close);
 SILC_CLIENT_CMD_FUNC(die);
 SILC_CLIENT_CMD_FUNC(silcoper);
 SILC_CLIENT_CMD_FUNC(leave);
-SILC_CLIENT_CMD_FUNC(names);
+SILC_CLIENT_CMD_FUNC(users);
 
 #endif
index 4570a027310978a5d49ce192a19dc84b2615bc26..a4e98d55d8180d51fdb9c1bb4cb5498abbecf177 100644 (file)
@@ -62,7 +62,7 @@ SilcClientCommandReply silc_command_reply_list[] =
   SILC_CLIENT_CMD_REPLY(die, DIE),
   SILC_CLIENT_CMD_REPLY(silcoper, SILCOPER),
   SILC_CLIENT_CMD_REPLY(leave, LEAVE),
-  SILC_CLIENT_CMD_REPLY(names, NAMES),
+  SILC_CLIENT_CMD_REPLY(users, USERS),
 
   { NULL, 0 },
 };
@@ -967,10 +967,10 @@ SILC_CLIENT_CMD_REPLY_FUNC(leave)
   silc_client_command_reply_free(cmd);
 }
 
-/* Reply to NAMES command. Received list of client names on the channel 
-   we requested. */
+/* Reply to USERS command. Received list of client ID's and theirs modes
+   on the channel we requested. */
 
-SILC_CLIENT_CMD_REPLY_FUNC(names)
+SILC_CLIENT_CMD_REPLY_FUNC(users)
 {
   SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
   SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
@@ -982,8 +982,11 @@ SILC_CLIENT_CMD_REPLY_FUNC(names)
   SilcBuffer client_id_list;
   SilcBuffer client_mode_list;
   unsigned char *tmp;
+  unsigned int tmp_len;
+  int i, k, len1, len2, list_count;
+  unsigned char **res_argv = NULL;
+  unsigned int *res_argv_lens = NULL, *res_argv_types = NULL, res_argc = 0;
   char *name_list, *cp;
-  int i, k, len1, len2, list_count = 0;
 
   SILC_LOG_DEBUG(("Start"));
 
@@ -997,67 +1000,43 @@ SILC_CLIENT_CMD_REPLY_FUNC(names)
   }
 
   /* Get channel ID */
-  tmp = silc_argument_get_arg_type(cmd->args, 2, &len1);
-  if (!tmp) {
-    cmd->client->ops->say(cmd->client, conn, 
-                         "Cannot Channel ID: Bad reply packet");
-    COMMAND_REPLY_ERROR;
+  tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
+  if (!tmp)
     goto out;
-  }
-  channel_id = silc_id_payload_parse_id(tmp, len1);
+  channel_id = silc_id_payload_parse_id(tmp, tmp_len);
 
-  /* Get the name list of the channel */
-  name_list = silc_argument_get_arg_type(cmd->args, 3, &len1);
-  if (!name_list) {
-    cmd->client->ops->say(cmd->client, conn, 
-                         "Cannot get user list: Bad reply packet");
-    COMMAND_REPLY_ERROR;
+  /* Get the list count */
+  tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
+  if (!tmp)
     goto out;
-  }
+  SILC_GET32_MSB(list_count, tmp);
 
   /* Get Client ID list */
-  tmp = silc_argument_get_arg_type(cmd->args, 4, &len2);
-  if (!tmp) {
-    cmd->client->ops->say(cmd->client, conn, 
-                         "Cannot get user list: Bad reply packet");
-    COMMAND_REPLY_ERROR;
+  tmp = silc_argument_get_arg_type(cmd->args, 4, &tmp_len);
+  if (!tmp)
     goto out;
-  }
 
-  client_id_list = silc_buffer_alloc(len2);
-  silc_buffer_pull_tail(client_id_list, len2);
-  silc_buffer_put(client_id_list, tmp, len2);
+  client_id_list = silc_buffer_alloc(tmp_len);
+  silc_buffer_pull_tail(client_id_list, tmp_len);
+  silc_buffer_put(client_id_list, tmp, tmp_len);
 
   /* Get client mode list */
-  tmp = silc_argument_get_arg_type(cmd->args, 5, &len2);
-  if (!tmp) {
-    cmd->client->ops->say(cmd->client, conn, 
-                         "Cannot get user list: Bad reply packet");
-    COMMAND_REPLY_ERROR;
+  tmp = silc_argument_get_arg_type(cmd->args, 5, &tmp_len);
+  if (!tmp)
     goto out;
-  }
 
-  client_mode_list = silc_buffer_alloc(len2);
-  silc_buffer_pull_tail(client_mode_list, len2);
-  silc_buffer_put(client_mode_list, tmp, len2);
+  client_mode_list = silc_buffer_alloc(tmp_len);
+  silc_buffer_pull_tail(client_mode_list, tmp_len);
+  silc_buffer_put(client_mode_list, tmp, tmp_len);
 
-  /* Get the channel name */
+  /* Get channel entry */
   if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id,
-                                  SILC_ID_CHANNEL, &id_cache)) {
+                                   SILC_ID_CHANNEL, &id_cache)) {
     COMMAND_REPLY_ERROR;
     goto out;
   }
-  
   channel = (SilcChannelEntry)id_cache->context;
 
-  /* Remove commas from list */
-  for (i = 0; i < len1; i++)
-    if (name_list[i] == ',') {
-      name_list[i] = ' ';
-      list_count++;
-    }
-  list_count++;
-
   /* Remove old client list from channel. */
   silc_list_start(channel->clients);
   while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
@@ -1065,52 +1044,67 @@ SILC_CLIENT_CMD_REPLY_FUNC(names)
     silc_free(chu);
   }
 
-  /* Cache the received name list, client ID's and modes. This cache expires
+  /* Cache the received Client ID's and modes. This cache expires
      whenever server sends notify message to channel. It means two things;
-     some user has joined or leaved the channel. */
-  cp = name_list;
+     some user has joined or leaved the channel. XXX! */
   for (i = 0; i < list_count; i++) {
-    int nick_len = strcspn(name_list, " ");
     unsigned short idp_len;
     unsigned int mode;
-    char *nickname = silc_calloc(nick_len + 1, sizeof(*nickname));
     SilcClientID *client_id;
     SilcClientEntry client;
 
-    memcpy(nickname, name_list, nick_len);
+    /* Client ID */
     SILC_GET16_MSB(idp_len, client_id_list->data + 2);
     idp_len += 4;
     client_id = silc_id_payload_parse_id(client_id_list->data, idp_len);
     silc_buffer_pull(client_id_list, idp_len);
-    
+
+    /* Mode */
     SILC_GET32_MSB(mode, client_mode_list->data);
     silc_buffer_pull(client_mode_list, 4);
 
     /* Check if we have this client cached already. */
     if (!silc_idcache_find_by_id_one(conn->client_cache, (void *)client_id,
                                     SILC_ID_CLIENT, &id_cache)) {
-      client = silc_calloc(1, sizeof(*client));
-      client->id = client_id;
-      silc_parse_nickname(nickname, &client->nickname, &client->server, 
-                         &client->num);
-      silc_free(nickname);
-
-      /* Add client to cache */
-      silc_idcache_add(conn->client_cache, client->nickname, SILC_ID_CLIENT,
-                      client_id, (void *)client, TRUE);
+      /* No we don't have it, query it from the server. Assemble argument
+        table that will be sent fr the IDENTIFY command later. */
+      res_argv = silc_realloc(res_argv, sizeof(*res_argv) *
+                             (res_argc + 1));
+      res_argv_lens = silc_realloc(res_argv_lens, sizeof(*res_argv_lens) *
+                                  (res_argc + 1));
+      res_argv_types = silc_realloc(res_argv_types, sizeof(*res_argv_types) *
+                                   (res_argc + 1));
+      res_argv[res_argc] = client_id_list->data;
+      res_argv_lens[res_argc] = idp_len;
+      res_argv_types[res_argc] = res_argc + 3;
+      res_argc++;
     } else {
+      /* Found the client, join it to the channel */
       client = (SilcClientEntry)id_cache->context;
+      chu = silc_calloc(1, sizeof(*chu));
+      chu->client = client;
+      chu->mode = mode;
+      silc_list_add(channel->clients, chu);
+
       silc_free(client_id);
-      silc_free(nickname);
       id_cache = NULL;
     }
+  }
 
-    chu = silc_calloc(1, sizeof(*chu));
-    chu->client = client;
-    chu->mode = mode;
-    silc_list_add(channel->clients, chu);
-
-    name_list += nick_len + 1;
+  /* Query the client information from server if the list included clients
+     that we don't know about. */
+  if (res_argc) {
+#if 0
+    SilcBuffer res_cmd;
+
+    res_cmd = silc_command_payload_encode(SILC_COMMAND_IDENTIFY,
+                                         res_argc, res_argv, res_argv_lens,
+                                         res_argv_types, 0);
+    silc_client_packet_send(cmd->client, cmd->conn->sock,
+                           SILC_PACKET_COMMAND, NULL, 0, NULL, NULL,
+                           buffer->data, buffer->len, TRUE);
+    goto out;
+#endif
   }
 
   name_list = cp;
index 76bddc1a0a8afa8c4fa0693189d8448d43e6baa1..2b7acf7f346ee42578a4d2cceec007f2a1899350 100644 (file)
@@ -102,6 +102,6 @@ SILC_CLIENT_CMD_REPLY_FUNC(close);
 SILC_CLIENT_CMD_REPLY_FUNC(die);
 SILC_CLIENT_CMD_REPLY_FUNC(silcoper);
 SILC_CLIENT_CMD_REPLY_FUNC(leave);
-SILC_CLIENT_CMD_REPLY_FUNC(names);
+SILC_CLIENT_CMD_REPLY_FUNC(users);
 
 #endif
index 1890b769066620aadeb491e683c59a5d09618a1d..adf99a5875e3db1154b5e5b687ff68886907210a 100644 (file)
@@ -79,7 +79,7 @@ typedef enum {
 #define        SILC_COMMAND_DIE                22
 #define SILC_COMMAND_SILCOPER          23
 #define SILC_COMMAND_LEAVE             24
-#define SILC_COMMAND_NAMES             25
+#define SILC_COMMAND_USERS             25
 
 /* Reserved */
 #define SILC_COMMAND_RESERVED           255