Changed the silc_client_command_call to be simpler for
authorPekka Riikonen <priikone@silcnet.org>
Wed, 6 Nov 2002 15:27:56 +0000 (15:27 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Wed, 6 Nov 2002 15:27:56 +0000 (15:27 +0000)
application.

CHANGES
apps/irssi/src/silc/core/silc-servers.c
lib/silcclient/command.c
lib/silcclient/command.h
lib/silcclient/silcclient.h
tutorial/mybot/mybot.c

diff --git a/CHANGES b/CHANGES
index d6324c73596335888fbf931b066dc2541bb2315e..449e828001c2dc6cbb1a96afc312f668e01df42f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,15 @@
+Wed Nov  6 17:18:13 EET 2002  Pekka Riikonen <priikone@silcnet.org>
+
+       * Fixed manual page installation patch by Ville Räsänen.
+         USERS help page fix patch by Ville Räsänen
+
+       * Changed the silc_client_command_call interface to make
+         the command call simpler for the application.  The library
+         now handles the command line parsing, command finding and
+         execution.  Application only needs to call the function
+         with the command line.  Affected files are 
+         lib/silcclient/silcclient.h, command.[ch].
+
 Mon Nov  4 16:02:59 EET 2002  Pekka Riikonen <priikone@silcnet.org>
 
        * Print notify for server opers when backup router comes
@@ -9,6 +21,10 @@ Mon Nov  4 16:02:59 EET 2002  Pekka Riikonen <priikone@silcnet.org>
        * Fixed MOTD command reply sending.  Affected file
          silcd/command.c.
 
+       * UTF-8 decode the topic in TOPIC command reply and LIST
+         command reply in Irssi SILC client.  Affected file is
+         irssi/src/silc/core/client_ops.c.
+
 Sun Nov  3 17:59:15 EET 2002  Pekka Riikonen <priikone@silcnet.org>
 
        * Fixed the INVITE command to not crash Irssi SILC client
index c72705885798aecbb23ae7ee873220e5619c7737..f6e0403af4169d9ff6b26f5a3784b4ae30939e28 100644 (file)
@@ -448,41 +448,13 @@ char *silc_server_get_channels(SILC_SERVER_REC *server)
 void silc_command_exec(SILC_SERVER_REC *server,
                       const char *command, const char *args)
 {
-  SilcUInt32 argc = 0;
-  unsigned char **argv;
-  SilcUInt32 *argv_lens, *argv_types;
-  char *data, *tmpcmd;
-  SilcClientCommand cmd;
-  SilcClientCommandContext ctx;
-
+  char *data;
   g_return_if_fail(server != NULL);
 
-  tmpcmd = g_strdup(command); 
-  g_strup(tmpcmd);
-  cmd = silc_client_command_find(silc_client, tmpcmd);
-  g_free(tmpcmd);
-  if (cmd == NULL)
-    return;
-  
-  /* Now parse all arguments */
+  /* Call the command */
   data = g_strconcat(command, " ", args, NULL);
-  silc_parse_command_line(data, &argv, &argv_lens,
-                         &argv_types, &argc, cmd->max_args);
+  silc_client_command_call(silc_client, server->conn, data);
   g_free(data);
-
-  /* Allocate command context. This and its internals must be free'd
-     by the command routine receiving it. */
-  ctx = silc_client_command_alloc();
-  ctx->client = silc_client;
-  ctx->conn = server->conn;
-  ctx->command = cmd;
-  ctx->argc = argc;
-  ctx->argv = argv;
-  ctx->argv_lens = argv_lens;
-  ctx->argv_types = argv_types;
-  
-  /* Execute command */
-  silc_client_command_call(cmd, ctx);
 }
 
 /* Generic command function to call any SILC command directly. */
index f1a9ace6308d86d3aea4dc8aa9a1f8aec0ae6894..66e51786d1fce744d30d5e97cb74cb58d01046a3 100644 (file)
@@ -71,24 +71,89 @@ SilcClientCommand silc_client_command_find(SilcClient client,
 
   silc_list_start(client->internal->commands);
   while ((cmd = silc_list_get(client->internal->commands)) != SILC_LIST_END) {
-    if (cmd->name && !strcmp(cmd->name, name))
+    if (cmd->name && !strcasecmp(cmd->name, name))
       return cmd;
   }
 
   return NULL;
 }
 
-/* Calls the command (executes it).  Application can call this after
-   it has allocated the SilcClientCommandContext with the function
-   silc_client_command_alloc and found the command from the client
-   library by calling silc_client_command_find.  This will execute
-   the command. */
+/* Executes a command */
 
-void silc_client_command_call(SilcClientCommand command, 
-                             SilcClientCommandContext cmd)
+bool silc_client_command_call(SilcClient client,
+                             SilcClientConnection conn,
+                             const char *command_line, ...)
 {
-  assert(command);
-  (*command->command)((void *)cmd, NULL);
+  va_list va;
+  SilcUInt32 argc = 0;
+  unsigned char **argv = NULL;
+  SilcUInt32 *argv_lens = NULL, *argv_types = NULL;
+  SilcClientCommand cmd;
+  SilcClientCommandContext ctx;
+  char *arg;
+
+  assert(client);
+
+  /* Parse arguments */
+  va_start(va, command_line);
+  if (command_line) {
+    char *command_name;
+
+    /* Get command name */
+    command_name = silc_memdup(command_line, strcspn(command_line, " "));
+    if (!command_name)
+      return FALSE;
+
+    /* Find command by name */
+    cmd = silc_client_command_find(client, command_name);
+    if (!cmd) {
+      silc_free(command_name);
+      return FALSE;
+    }
+
+    /* Parse command line */
+    silc_parse_command_line((char *)command_line, &argv, &argv_lens,
+                           &argv_types, &argc, cmd->max_args);
+
+    silc_free(command_name);
+  } else {
+    arg = va_arg(va, char *);
+    if (!arg)
+      return FALSE;
+
+    /* Find command by name */
+    cmd = silc_client_command_find(client, arg);
+    if (!cmd)
+      return FALSE;
+
+    while (arg) {
+      argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
+      argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) * (argc + 1));
+      argv_types = silc_realloc(argv_types, sizeof(*argv_types) * (argc + 1));
+      argv[argc] = silc_memdup(arg, strlen(arg));
+      argv_lens[argc] = strlen(arg);
+      argv_types[argc] = argc + 1;
+      argc++;
+      arg = va_arg(va, char *);
+    }
+  }
+
+  /* Allocate command context. */
+  ctx = silc_client_command_alloc();
+  ctx->client = client;
+  ctx->conn = conn;
+  ctx->command = cmd;
+  ctx->argc = argc;
+  ctx->argv = argv;
+  ctx->argv_lens = argv_lens;
+  ctx->argv_types = argv_types;
+  
+  /* Call the command */
+  cmd->command(ctx, NULL);
+
+  va_end(va);
+
+  return TRUE;
 }
 
 /* Add new pending command to be executed when reply to a command has been
index 84663109522fed1265ec71443b0f3325fcdc0e97..de06296d540c22c5b11c6ea349bee9e4da10ee70 100644 (file)
@@ -36,7 +36,7 @@ struct SilcClientCommandStruct {
   SilcCommandCb reply;            /* Command reply callback */
   char *name;                     /* Name of the command (optional) */
   SilcUInt8 max_args;             /* Maximum arguments (optional)  */
-  SilcUInt16 ident;                       /* Identifier for command (optional)  */
+  SilcUInt16 ident;               /* Identifier for command (optional)  */
   struct SilcClientCommandStruct *next;
 };
 
@@ -97,6 +97,11 @@ do {                                                                   \
   silc_client_command_pending_del(ctx->sock->user_data, cmd, ctx->ident); \
 } while(0)
 
+SilcClientCommandContext silc_client_command_alloc(void);
+void silc_client_command_free(SilcClientCommandContext ctx);
+SilcClientCommandContext silc_client_command_dup(SilcClientCommandContext ctx);
+SilcClientCommand silc_client_command_find(SilcClient client,
+                                          const char *name);
 bool silc_client_command_register(SilcClient client,
                                  SilcCommand command,
                                  const char *name,
index 43c1bee9fba8281a3a42da44a02e53e17bd3b8d3..3a5a4e376c7d4b8c9c76b21b7409c79c283ac30f 100644 (file)
@@ -1407,92 +1407,45 @@ SilcChannelUser silc_client_on_channel(SilcChannelEntry channel,
 
 /* Command management (command.c) */
 
-/****f* silcclient/SilcClientAPI/silc_client_command_alloc
- *
- * SYNOPSIS
- *
- *    SilcClientCommandContext silc_client_command_alloc(void);
- *
- * DESCRIPTION
- *
- *    Allocate Command Context. The context is defined in `command.h' file.
- *    The context is used by the library commands and applications should use
- *    it as well. However, application may choose to use some own context
- *    for its local commands. All library commands, however, must use this
- *    context. 
- *
- ***/
-SilcClientCommandContext silc_client_command_alloc(void);
-
-/****f* silcclient/SilcClientAPI/silc_client_command_free
- *
- * SYNOPSIS
- *
- *    void silc_client_command_free(SilcClientCommandContext ctx);
- *
- * DESCRIPTION
- *
- *    Free command context and its internals.  If the contex was duplicated
- *    with silc_client_command_dup this may not actually free the data, 
- *    instead it will decrease the reference counter of the context.  The
- *    context will be freed when the reference counter hits zero.
- *
- ***/
-void silc_client_command_free(SilcClientCommandContext ctx);
-
-/****f* silcclient/SilcClientAPI/silc_client_command_dup
- *
- * SYNOPSIS
- *
- *    SilcClientCommandContext 
- *    silc_client_command_dup(SilcClientCommandContext ctx);
- *
- * DESCRIPTION
- *
- *    Duplicate Command Context by adding reference counter. The context won't
- *    be free'd untill it hits zero. 
- *
- ***/
-SilcClientCommandContext silc_client_command_dup(SilcClientCommandContext ctx);
-
-/****f* silcclient/SilcClientAPI/silc_client_command_find
+/****f* silcclient/SilcClientAPI/silc_client_command_call
  *
  * SYNOPSIS
  *
- *    SilcClientCommand silc_client_command_find(SilcClient client,
- *                                               const char *name);
+ *    void silc_client_command_call(SilcClient client,
+ *                                  SilcClientConnection conn,
+ *                                  const char *command_line, ...);
  *
  * DESCRIPTION
  *
- *    Finds and returns a pointer to the command list. Return NULL if the
- *    command is not found. See the `command.[ch]' for the command list. 
- *    Command names are not case-sensitive.
+ *    Calls and executes the command indicated by the `command_name'.
+ *    The `command_line' is a string which includes the command's name and
+ *    its arguments separated with whitespaces (' ').  If `command_line'
+ *    is non-NULL then all variable arguments are ignored by default.
  *
- ***/
-SilcClientCommand silc_client_command_find(SilcClient client,
-                                          const char *name);
-
-/****f* silcclient/SilcClientAPI/silc_client_command_call
+ *    If `command_line' is NULL, then the variable arguments define the
+ *    command's nameand its arguments.  The variable argument list must
+ *    be terminated with NULL.
  *
- * SYNOPSIS
- *
- *    void silc_client_command_call(SilcClientCommand command);
+ *    Returns FALSE if the command is not known and TRUE after command.
+ *    execution.  The "command" client operation is called when the
+ *    command is executed to indicate whether the command executed
+ *    successfully or not.
  *
- * DESCRIPTION
+ *    The "command_reply" client operation will be called when reply is
+ *    received from the server to the command.  Application may also use
+ *    the silc_client_command_pending to attach to the command reply.
+ *    The command identifier for silc_client_command_pending function after
+ *    this function call is conn->cmd_ident, which application may use.
  *
- *    Calls the command (executes it).  Application can call this after
- *    it has allocated the SilcClientCommandContext with the function
- *    silc_client_command_alloc and found the command from the client
- *    library by calling silc_client_command_find.  This will execute
- *    the command.
+ * EXAMPLE
  *
- *    Application can call the command function directly too if it
- *    wishes to do so.  See the command.h for details of the
- *    SilcClientCommand structure.
+ *    silc_client_command_call(client, NULL, "PING", "silc.silcnet.org", NULL);
+ *    silc_client_command_call(client, "PING silc.silcnet.org");
  *
  ***/
-void silc_client_command_call(SilcClientCommand command,
-                             SilcClientCommandContext cmd);
+bool silc_client_command_call(SilcClient client,
+                             SilcClientConnection conn,
+                             const char *command_line, ...);
 
 /****f* silcclient/SilcClientAPI/silc_client_command_send
  *
index f6297c4481fd2b1672c1e2205d8d411ec7b59ead..8e16c897ec72c7a650ad112a20addef4562bd40e 100644 (file)
@@ -29,7 +29,7 @@
                 v
           silc_get_auth_method
                 v
-          silc_connected -> silc_client_send_command (JOIN)
+          silc_connected -> silc_client_command_call (JOIN)
                 v
           silc_command_reply -> silc_send_channel_message ("hello")
                 v
@@ -331,13 +331,8 @@ silc_connected(SilcClient client, SilcClientConnection conn,
   /* Save the connection context */
   mybot->conn = conn;
 
-  /* Now that we are connected, send the JOIN command to the "mybot"
-     channel */
-  idp = silc_id_payload_encode(conn->local_id, SILC_ID_CLIENT);
-  silc_client_command_send(client, conn, SILC_COMMAND_JOIN, 0, 2,
-                          1, "mybot", strlen("mybot"),
-                          2, idp->data, idp->len);
-  silc_buffer_free(idp);
+  /* Now that we are connected, join to mybot channel with JOIN command. */
+  silc_client_command_call(client, conn, "JOIN mybot");
 }