Started implementing protocol version 1.1 and narrowing down
[silc.git] / lib / silcclient / command.c
index 2d4aa6c580d8964319b0bd24a1d8ac4d11c3ed75..7ffc279f4fa165c9b62e24332482fdfb1cd1a968 100644 (file)
@@ -18,7 +18,8 @@
 */
 /* $Id$ */
 
-#include "clientlibincludes.h"
+#include "silcincludes.h"
+#include "silcclient.h"
 #include "client_internal.h"
 
 #define SILC_NOT_CONNECTED(x, c) \
@@ -40,8 +41,8 @@
    encoded into correct form and in correct order. */
 
 void silc_client_command_send(SilcClient client, SilcClientConnection conn,
-                             SilcCommand command, uint16 ident,
-                             uint32 argc, ...)
+                             SilcCommand command, SilcUInt16 ident,
+                             SilcUInt32 argc, ...)
 {
   SilcBuffer packet;
   va_list ap;
@@ -92,7 +93,7 @@ void silc_client_command_call(SilcClientCommand command,
 
 void silc_client_command_pending(SilcClientConnection conn,
                                 SilcCommand reply_cmd,
-                                uint16 ident,
+                                SilcUInt16 ident,
                                 SilcCommandCb callback,
                                 void *context)
 {
@@ -110,7 +111,7 @@ void silc_client_command_pending(SilcClientConnection conn,
 
 void silc_client_command_pending_del(SilcClientConnection conn,
                                     SilcCommand reply_cmd,
-                                    uint16 ident)
+                                    SilcUInt16 ident)
 {
   SilcClientCommandPending *r;
 
@@ -129,7 +130,7 @@ void silc_client_command_pending_del(SilcClientConnection conn,
 int silc_client_command_pending_check(SilcClientConnection conn,
                                      SilcClientCommandReplyContext ctx,
                                      SilcCommand command, 
-                                     uint16 ident)
+                                     SilcUInt16 ident)
 {
   SilcClientCommandPending *r;
 
@@ -321,9 +322,8 @@ SILC_CLIENT_CMD_FUNC(nick_change)
   SilcClientConnection conn = cmd->conn;
   SilcClientCommandReplyContext reply = 
     (SilcClientCommandReplyContext)context2;
-  SilcCommandStatus status;
+  SilcCommandStatus status = silc_command_get_status(reply->payload);
 
-  SILC_GET16_MSB(status, silc_argument_get_arg_type(reply->args, 1, NULL));
   if (status == SILC_STATUS_OK) {
     /* Set the nickname */
     silc_idcache_del_by_context(conn->client_cache, conn->local_entry);
@@ -545,7 +545,7 @@ SILC_CLIENT_CMD_FUNC(invite)
   SilcClientEntry client_entry = NULL;
   SilcChannelEntry channel;
   SilcBuffer buffer, clidp, chidp;
-  uint32 type = 0;
+  SilcUInt32 type = 0;
   char *nickname = NULL, *name;
   char *invite = NULL;
 
@@ -748,9 +748,8 @@ SILC_CLIENT_CMD_FUNC(kill_remove)
   SilcClientCommandContext cmd = (SilcClientCommandContext)context;
   SilcClientCommandReplyContext reply = 
     (SilcClientCommandReplyContext)context2;
-  SilcCommandStatus status;
+  SilcCommandStatus status = silc_command_get_status(reply->payload);
 
-  SILC_GET16_MSB(status, silc_argument_get_arg_type(reply->args, 1, NULL));
   if (status == SILC_STATUS_OK) {
     /* Remove with timeout */
     silc_schedule_task_add(cmd->client->schedule, cmd->conn->sock->sock,
@@ -986,7 +985,7 @@ SILC_CLIENT_CMD_FUNC(join)
       if (!strcasecmp(cmd->argv[i + 1], "-pubkey")) {
        auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
                                                  cmd->client->private_key,
-                                                 conn->hash,
+                                                 cmd->client->rng, conn->hash,
                                                  conn->local_id,
                                                  SILC_ID_CLIENT);
       } else {
@@ -1075,7 +1074,7 @@ SILC_CLIENT_CMD_FUNC(umode)
   SilcClientConnection conn = cmd->conn;
   SilcBuffer buffer, idp;
   unsigned char *cp, modebuf[4];
-  uint32 mode, add, len;
+  SilcUInt32 mode, add, len;
   int i;
 
   if (!cmd->conn) {
@@ -1170,7 +1169,7 @@ SILC_CLIENT_CMD_FUNC(cmode)
   SilcChannelEntry channel;
   SilcBuffer buffer, chidp, auth = NULL;
   unsigned char *name, *cp, modebuf[4], tmp[4], *arg = NULL;
-  uint32 mode, add, type, len, arg_len = 0;
+  SilcUInt32 mode, add, type, len, arg_len = 0;
   int i;
 
   if (!cmd->conn) {
@@ -1253,6 +1252,18 @@ SILC_CLIENT_CMD_FUNC(cmode)
       else
        mode &= ~SILC_CHANNEL_MODE_TOPIC;
       break;
+    case 'm':
+      if (add)
+       mode |= SILC_CHANNEL_MODE_SILENCE_USERS;
+      else
+       mode &= ~SILC_CHANNEL_MODE_SILENCE_USERS;
+      break;
+    case 'M':
+      if (add)
+       mode |= SILC_CHANNEL_MODE_SILENCE_OPERS;
+      else
+       mode &= ~SILC_CHANNEL_MODE_SILENCE_OPERS;
+      break;
     case 'l':
       if (add) {
        int ll;
@@ -1335,6 +1346,7 @@ SILC_CLIENT_CMD_FUNC(cmode)
        if (!strcasecmp(cmd->argv[3], "-pubkey")) {
          auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
                                                    cmd->client->private_key,
+                                                   cmd->client->rng, 
                                                    conn->hash,
                                                    conn->local_id,
                                                    SILC_ID_CLIENT);
@@ -1400,7 +1412,7 @@ SILC_CLIENT_CMD_FUNC(cumode)
   SilcClientEntry client_entry;
   SilcBuffer buffer, clidp, chidp, auth = NULL;
   unsigned char *name, *cp, modebuf[4];
-  uint32 mode = 0, add, len;
+  SilcUInt32 mode = 0, add, len;
   char *nickname = NULL;
   int i;
 
@@ -1493,6 +1505,7 @@ SILC_CLIENT_CMD_FUNC(cumode)
          if (!strcasecmp(cmd->argv[4], "-pubkey")) {
            auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
                                                      cmd->client->private_key,
+                                                     cmd->client->rng,
                                                      conn->hash,
                                                      conn->local_id,
                                                      SILC_ID_CLIENT);
@@ -1649,7 +1662,7 @@ SILC_CLIENT_CMD_FUNC(kick)
 }
 
 static void silc_client_command_oper_send(unsigned char *data,
-                                         uint32 data_len, void *context)
+                                         SilcUInt32 data_len, void *context)
 {
   SilcClientCommandContext cmd = (SilcClientCommandContext)context;
   SilcClientConnection conn = cmd->conn;
@@ -1659,7 +1672,7 @@ static void silc_client_command_oper_send(unsigned char *data,
     /* Encode the public key authentication payload */
     auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
                                              cmd->client->private_key,
-                                             conn->hash,
+                                             cmd->client->rng, conn->hash,
                                              conn->local_id,
                                              SILC_ID_CLIENT);
   } else {
@@ -1717,7 +1730,7 @@ SILC_CLIENT_CMD_FUNC(oper)
 }
 
 static void silc_client_command_silcoper_send(unsigned char *data,
-                                             uint32 data_len, void *context)
+                                             SilcUInt32 data_len, void *context)
 {
   SilcClientCommandContext cmd = (SilcClientCommandContext)context;
   SilcClientConnection conn = cmd->conn;
@@ -1727,7 +1740,7 @@ static void silc_client_command_silcoper_send(unsigned char *data,
     /* Encode the public key authentication payload */
     auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
                                              cmd->client->private_key,
-                                             conn->hash,
+                                             cmd->client->rng, conn->hash,
                                              conn->local_id,
                                              SILC_ID_CLIENT);
   } else {
@@ -1784,54 +1797,6 @@ SILC_CLIENT_CMD_FUNC(silcoper)
   silc_client_command_free(cmd);
 }
 
-/* CONNECT command. Connects the server to another server. */
-
-SILC_CLIENT_CMD_FUNC(connect)
-{
-  SilcClientCommandContext cmd = (SilcClientCommandContext)context;
-  SilcClientConnection conn = cmd->conn;
-  SilcBuffer buffer;
-  unsigned char port[4];
-  uint32 tmp;
-
-  if (!cmd->conn) {
-    SILC_NOT_CONNECTED(cmd->client, cmd->conn);
-    COMMAND_ERROR;
-    goto out;
-  }
-
-  if (cmd->argc < 2) {
-    SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO, 
-       "Usage: /CONNECT <server> [<port>]");
-    COMMAND_ERROR;
-    goto out;
-  }
-
-  if (cmd->argc == 3) {
-    tmp = atoi(cmd->argv[2]);
-    SILC_PUT32_MSB(tmp, port);
-  }
-
-  if (cmd->argc == 3)
-    buffer = silc_command_payload_encode_va(SILC_COMMAND_CONNECT, 0, 2, 
-                                           1, cmd->argv[1], 
-                                           strlen(cmd->argv[1]),
-                                           2, port, 4);
-  else
-    buffer = silc_command_payload_encode_va(SILC_COMMAND_CONNECT, 0, 1,
-                                           1, cmd->argv[1], 
-                                           strlen(cmd->argv[1]));
-  silc_client_packet_send(cmd->client, conn->sock, SILC_PACKET_COMMAND, NULL,
-                         0, NULL, NULL, buffer->data, buffer->len, TRUE);
-  silc_buffer_free(buffer);
-
-  /* Notify application */
-  COMMAND;
-
- out:
-  silc_client_command_free(cmd);
-}
-
 /* Command BAN. This is used to manage the ban list of the channel. */
 
 SILC_CLIENT_CMD_FUNC(ban)
@@ -1911,77 +1876,6 @@ SILC_CLIENT_CMD_FUNC(ban)
   silc_client_command_free(cmd);
 }
 
-/* CLOSE command. Close server connection to the remote server */
-SILC_CLIENT_CMD_FUNC(close)
-{
-  SilcClientCommandContext cmd = (SilcClientCommandContext)context;
-  SilcClientConnection conn = cmd->conn;
-  SilcBuffer buffer;
-  unsigned char port[4];
-  uint32 tmp;
-
-  if (!cmd->conn) {
-    SILC_NOT_CONNECTED(cmd->client, cmd->conn);
-    COMMAND_ERROR;
-    goto out;
-  }
-
-  if (cmd->argc < 2) {
-    SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO, 
-       "Usage: /CLOSE <server> [<port>]");
-    COMMAND_ERROR;
-    goto out;
-  }
-
-  if (cmd->argc == 3) {
-    tmp = atoi(cmd->argv[2]);
-    SILC_PUT32_MSB(tmp, port);
-  }
-
-  if (cmd->argc == 3)
-    buffer = silc_command_payload_encode_va(SILC_COMMAND_CLOSE, 0, 2, 
-                                           1, cmd->argv[1], 
-                                           strlen(cmd->argv[1]),
-                                           2, port, 4);
-  else
-    buffer = silc_command_payload_encode_va(SILC_COMMAND_CLOSE, 0, 1,
-                                           1, cmd->argv[1], 
-                                           strlen(cmd->argv[1]));
-  silc_client_packet_send(cmd->client, conn->sock, SILC_PACKET_COMMAND, NULL,
-                         0, NULL, NULL, buffer->data, buffer->len, TRUE);
-  silc_buffer_free(buffer);
-
-  /* Notify application */
-  COMMAND;
-
- out:
-  silc_client_command_free(cmd);
-}
-/* SHUTDOWN command. Shutdowns the server. */
-
-SILC_CLIENT_CMD_FUNC(shutdown)
-{
-  SilcClientCommandContext cmd = (SilcClientCommandContext)context;
-
-  if (!cmd->conn) {
-    SILC_NOT_CONNECTED(cmd->client, cmd->conn);
-    COMMAND_ERROR;
-    goto out;
-  }
-
-  /* Send the command */
-  silc_client_command_send(cmd->client, cmd->conn, 
-                          SILC_COMMAND_SHUTDOWN, 0, 0);
-
-  /* Notify application */
-  COMMAND;
-
- out:
-  silc_client_command_free(cmd);
-}
-
 /* LEAVE command. Leaves a channel. Client removes itself from a channel. */
 
 SILC_CLIENT_CMD_FUNC(leave)
@@ -2164,9 +2058,7 @@ SILC_CLIENT_CMD_FUNC(getkey)
       } else {
        SilcClientCommandReplyContext reply = 
          (SilcClientCommandReplyContext)context2;
-       SilcCommandStatus status;
-       unsigned char *tmp = silc_argument_get_arg_type(reply->args, 1, NULL);
-       SILC_GET16_MSB(status, tmp);
+       SilcCommandStatus status = silc_command_get_status(reply->payload);
        
        /* If nickname was not found, then resolve the server. */
        if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
@@ -2239,8 +2131,8 @@ bool silc_client_command_register(SilcClient client,
                                  const char *name,
                                  SilcCommandCb command_function,
                                  SilcCommandCb command_reply_function,
-                                 uint8 max_args,
-                                 uint16 ident)
+                                 SilcUInt8 max_args,
+                                 SilcUInt16 ident)
 {
   SilcClientCommand cmd;
 
@@ -2265,7 +2157,7 @@ bool silc_client_command_unregister(SilcClient client,
                                    SilcCommand command,
                                    SilcCommandCb command_function,
                                    SilcCommandCb command_reply_function,
-                                   uint16 ident)
+                                   SilcUInt16 ident)
 {
   SilcClientCommand cmd;
 
@@ -2283,6 +2175,129 @@ bool silc_client_command_unregister(SilcClient client,
   return FALSE;
 }
 
+/* Private range commands, specific to this implementation (and compatible
+   with SILC Server). */
+
+/* CONNECT command. Connects the server to another server. */
+
+SILC_CLIENT_CMD_FUNC(connect)
+{
+  SilcClientCommandContext cmd = (SilcClientCommandContext)context;
+  SilcClientConnection conn = cmd->conn;
+  SilcBuffer buffer;
+  unsigned char port[4];
+  SilcUInt32 tmp;
+
+  if (!cmd->conn) {
+    SILC_NOT_CONNECTED(cmd->client, cmd->conn);
+    COMMAND_ERROR;
+    goto out;
+  }
+
+  if (cmd->argc < 2) {
+    SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO, 
+       "Usage: /CONNECT <server> [<port>]");
+    COMMAND_ERROR;
+    goto out;
+  }
+
+  if (cmd->argc == 3) {
+    tmp = atoi(cmd->argv[2]);
+    SILC_PUT32_MSB(tmp, port);
+  }
+
+  if (cmd->argc == 3)
+    buffer = silc_command_payload_encode_va(SILC_COMMAND_PRIV_CONNECT, 0, 2, 
+                                           1, cmd->argv[1], 
+                                           strlen(cmd->argv[1]),
+                                           2, port, 4);
+  else
+    buffer = silc_command_payload_encode_va(SILC_COMMAND_PRIV_CONNECT, 0, 1,
+                                           1, cmd->argv[1], 
+                                           strlen(cmd->argv[1]));
+  silc_client_packet_send(cmd->client, conn->sock, SILC_PACKET_COMMAND, NULL,
+                         0, NULL, NULL, buffer->data, buffer->len, TRUE);
+  silc_buffer_free(buffer);
+
+  /* Notify application */
+  COMMAND;
+
+ out:
+  silc_client_command_free(cmd);
+}
+
+
+/* CLOSE command. Close server connection to the remote server */
+SILC_CLIENT_CMD_FUNC(close)
+{
+  SilcClientCommandContext cmd = (SilcClientCommandContext)context;
+  SilcClientConnection conn = cmd->conn;
+  SilcBuffer buffer;
+  unsigned char port[4];
+  SilcUInt32 tmp;
+
+  if (!cmd->conn) {
+    SILC_NOT_CONNECTED(cmd->client, cmd->conn);
+    COMMAND_ERROR;
+    goto out;
+  }
+
+  if (cmd->argc < 2) {
+    SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO, 
+       "Usage: /CLOSE <server> [<port>]");
+    COMMAND_ERROR;
+    goto out;
+  }
+
+  if (cmd->argc == 3) {
+    tmp = atoi(cmd->argv[2]);
+    SILC_PUT32_MSB(tmp, port);
+  }
+
+  if (cmd->argc == 3)
+    buffer = silc_command_payload_encode_va(SILC_COMMAND_PRIV_CLOSE, 0, 2, 
+                                           1, cmd->argv[1], 
+                                           strlen(cmd->argv[1]),
+                                           2, port, 4);
+  else
+    buffer = silc_command_payload_encode_va(SILC_COMMAND_PRIV_CLOSE, 0, 1,
+                                           1, cmd->argv[1], 
+                                           strlen(cmd->argv[1]));
+  silc_client_packet_send(cmd->client, conn->sock, SILC_PACKET_COMMAND, NULL,
+                         0, NULL, NULL, buffer->data, buffer->len, TRUE);
+  silc_buffer_free(buffer);
+
+  /* Notify application */
+  COMMAND;
+
+ out:
+  silc_client_command_free(cmd);
+}
+/* SHUTDOWN command. Shutdowns the server. */
+
+SILC_CLIENT_CMD_FUNC(shutdown)
+{
+  SilcClientCommandContext cmd = (SilcClientCommandContext)context;
+
+  if (!cmd->conn) {
+    SILC_NOT_CONNECTED(cmd->client, cmd->conn);
+    COMMAND_ERROR;
+    goto out;
+  }
+
+  /* Send the command */
+  silc_client_command_send(cmd->client, cmd->conn, 
+                          SILC_COMMAND_PRIV_SHUTDOWN, 0, 0);
+
+  /* Notify application */
+  COMMAND;
+
+ out:
+  silc_client_command_free(cmd);
+}
+
 /* Register all default commands provided by the client library for the
    application. */
 
@@ -2301,7 +2316,6 @@ void silc_client_commands_register(SilcClient client)
   SILC_CLIENT_CMD(quit, QUIT, "QUIT", 2);
   SILC_CLIENT_CMD(kill, KILL, "KILL", 3);
   SILC_CLIENT_CMD(info, INFO, "INFO", 2);
-  SILC_CLIENT_CMD(connect, CONNECT, "CONNECT", 3);
   SILC_CLIENT_CMD(ping, PING, "PING", 2);
   SILC_CLIENT_CMD(oper, OPER, "OPER", 3);
   SILC_CLIENT_CMD(join, JOIN, "JOIN", 9);
@@ -2311,12 +2325,14 @@ void silc_client_commands_register(SilcClient client)
   SILC_CLIENT_CMD(cumode, CUMODE, "CUMODE", 5);
   SILC_CLIENT_CMD(kick, KICK, "KICK", 4);
   SILC_CLIENT_CMD(ban, BAN, "BAN", 3);
-  SILC_CLIENT_CMD(close, CLOSE, "CLOSE", 3);
-  SILC_CLIENT_CMD(shutdown, SHUTDOWN, "SHUTDOWN", 1);
   SILC_CLIENT_CMD(silcoper, SILCOPER, "SILCOPER", 3);
   SILC_CLIENT_CMD(leave, LEAVE, "LEAVE", 2);
   SILC_CLIENT_CMD(users, USERS, "USERS", 2);
   SILC_CLIENT_CMD(getkey, GETKEY, "GETKEY", 2);
+
+  SILC_CLIENT_CMD(connect, PRIV_CONNECT, "CONNECT", 3);
+  SILC_CLIENT_CMD(close, PRIV_CLOSE, "CLOSE", 3);
+  SILC_CLIENT_CMD(shutdown, PRIV_SHUTDOWN, "SHUTDOWN", 1);
 }
 
 /* Unregister all commands. */
@@ -2333,7 +2349,6 @@ void silc_client_commands_unregister(SilcClient client)
   SILC_CLIENT_CMDU(quit, QUIT, "QUIT");
   SILC_CLIENT_CMDU(kill, KILL, "KILL");
   SILC_CLIENT_CMDU(info, INFO, "INFO");
-  SILC_CLIENT_CMDU(connect, CONNECT, "CONNECT");
   SILC_CLIENT_CMDU(ping, PING, "PING");
   SILC_CLIENT_CMDU(oper, OPER, "OPER");
   SILC_CLIENT_CMDU(join, JOIN, "JOIN");
@@ -2343,10 +2358,12 @@ void silc_client_commands_unregister(SilcClient client)
   SILC_CLIENT_CMDU(cumode, CUMODE, "CUMODE");
   SILC_CLIENT_CMDU(kick, KICK, "KICK");
   SILC_CLIENT_CMDU(ban, BAN, "BAN");
-  SILC_CLIENT_CMDU(close, CLOSE, "CLOSE");
-  SILC_CLIENT_CMDU(shutdown, SHUTDOWN, "SHUTDOWN");
   SILC_CLIENT_CMDU(silcoper, SILCOPER, "SILCOPER");
   SILC_CLIENT_CMDU(leave, LEAVE, "LEAVE");
   SILC_CLIENT_CMDU(users, USERS, "USERS");
   SILC_CLIENT_CMDU(getkey, GETKEY, "GETKEY");
+
+  SILC_CLIENT_CMDU(connect, PRIV_CONNECT, "CONNECT");
+  SILC_CLIENT_CMDU(close, PRIV_CLOSE, "CLOSE");
+  SILC_CLIENT_CMDU(shutdown, PRIV_SHUTDOWN, "SHUTDOWN");
 }