SilcClientCommand cmd;
cmd = silc_calloc(1, sizeof(*cmd));
+ if (!cmd)
+ return FALSE;
cmd->cmd = command;
cmd->command = command_func;
cmd->reply = command_reply_func;
- cmd->name = name ? strdup(name) : NULL;
cmd->max_args = max_args;
+ cmd->name = name ? strdup(name) : NULL;
+ if (!cmd->name) {
+ silc_free(cmd);
+ return FALSE;
+ }
silc_list_add(client->internal->commands, cmd);
return NULL;
}
-/* Free command context and its internals */
-
-static void silc_client_command_free(SilcClientCommandContext cmd)
-{
- int i;
-
- for (i = 0; i < cmd->argc; i++)
- silc_free(cmd->argv[i]);
- silc_free(cmd->argv);
- silc_free(cmd->argv_lens);
- silc_free(cmd->argv_types);
- silc_free(cmd);
-}
-
/* Command thread destructor */
static void silc_client_command_destructor(SilcFSMThread thread,
/****************************** Command API *********************************/
+/* Free command context and its internals */
+
+void silc_client_command_free(SilcClientCommandContext cmd)
+{
+ SilcClientCommandReplyCallback cb;
+ int i;
+
+ for (i = 0; i < cmd->argc; i++)
+ silc_free(cmd->argv[i]);
+ silc_free(cmd->argv);
+ silc_free(cmd->argv_lens);
+ silc_free(cmd->argv_types);
+
+ silc_list_start(cmd->reply_callbacks);
+ while ((cb = silc_list_get(cmd->reply_callbacks)))
+ silc_free(cb);
+
+ silc_free(cmd);
+}
+
/* Executes a command */
SilcUInt16 silc_client_command_call(SilcClient client,
argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) * (argc + 1));
argv_types = silc_realloc(argv_types, sizeof(*argv_types) * (argc + 1));
if (!argv || !argv_lens || !argv_types)
- return FALSE;
+ return 0;
argv[argc] = silc_memdup(arg, strlen(arg));
if (!argv[argc])
- return FALSE;
+ return 0;
argv_lens[argc] = strlen(arg);
argv_types[argc] = argc;
argc++;
cmd->cmd_ident = silc_client_cmd_ident(conn);
cmd->called = TRUE;
cmd->verbose = TRUE;
+ silc_list_init(cmd->reply_callbacks,
+ struct SilcClientCommandReplyCallbackStruct, next);
/*** Call command */
SILC_LOG_DEBUG(("Calling %s command", silc_get_command_name(cmd->cmd)));
return 0;
cmd->conn = conn;
cmd->cmd = command;
+ silc_list_init(cmd->reply_callbacks,
+ struct SilcClientCommandReplyCallbackStruct, next);
/* Send the command */
va_start(ap, argc);
/* Given without arguments fetches client's own information */
if (cmd->argc < 2) {
- silc_client_command_send(conn->client, conn, SILC_COMMAND_WHOIS,
- NULL, NULL, 1, 4,
- silc_buffer_datalen(conn->internal->local_idp));
- goto out;
+ silc_client_command_send_va(conn, cmd, cmd->cmd, NULL, NULL, 1, 4,
+ silc_buffer_data(conn->internal->local_idp),
+ silc_buffer_len(conn->internal->local_idp));
+
+ /* Notify application */
+ COMMAND(SILC_STATUS_OK);
+
+ /** Wait for command reply */
+ silc_fsm_next(fsm, silc_client_command_reply_wait);
+ return SILC_FSM_CONTINUE;
}
for (i = 1; i < cmd->argc; i++) {
SilcClientCommandContext cmd = fsm_context;
SilcClientConnection conn = cmd->conn;
- if (cmd->argc < 2) {
- COMMAND_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
- return SILC_FSM_FINISH;
- }
-
/* Send the command */
silc_client_command_send_va(conn, cmd, cmd->cmd, NULL, NULL, 1,
1, silc_buffer_datalen(conn->internal->
/* Check whether user requested server */
server_entry = silc_client_get_server(client, conn, cmd->argv[1]);
if (!server_entry) {
+ if (cmd->resolved) {
+ /* Resolving didn't find anything. We should never get here as
+ errors are handled in the resolving callback. */
+ COMMAND_ERROR(SILC_STATUS_ERR_NO_SUCH_NICK);
+ COMMAND_ERROR(SILC_STATUS_ERR_NO_SUCH_SERVER);
+ return SILC_FSM_FINISH;
+ }
+
/* No client or server exist with this name, query for both. */
+ cmd->resolved = TRUE;
SILC_FSM_CALL(silc_client_command_send(client, conn,
SILC_COMMAND_IDENTIFY,
silc_client_command_continue,
strlen(cmd->argv[1]),
2, cmd->argv[1],
strlen(cmd->argv[1])));
+ /* NOT REACHED */
}
idp = silc_id_payload_encode(&server_entry->id, SILC_ID_SERVER);
+ silc_client_unref_server(client, conn, server_entry);
} else {
client_entry = silc_dlist_get(clients);
idp = silc_id_payload_encode(&client_entry->id, SILC_ID_CLIENT);