Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2006 Pekka Riikonen
+ Copyright (C) 1997 - 2007 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
if (status != SILC_STATUS_OK)
silc_fsm_next(&cmd->thread, silc_client_command_continue_error);
- if (clients)
- silc_dlist_uninit(clients);
-
/* Continue with the command */
SILC_FSM_CALL_CONTINUE(&cmd->thread);
}
void *fsm_context,
void *destructor_context)
{
- silc_client_command_free(fsm_context);
+ SilcClientCommandContext cmd = fsm_context;
+ SilcClientConnection conn = cmd->conn;
+
+ /* Removes commands that aren't waiting for reply but are waiting
+ for something. They may not have been removed yet. */
+ silc_list_del(conn->internal->pending_commands, cmd);
+
+ silc_client_command_free(cmd);
}
/* Add a command pending a command reply. Used internally by the library. */
SILC_LOG_DEBUG(("Send command %s", silc_get_command_name(command)));
+ if (conn->internal->disconnected)
+ return 0;
+
if (!cmd->cmd_ident)
cmd->cmd_ident = silc_client_cmd_ident(conn);
SILC_LOG_DEBUG(("Send command %s", silc_get_command_name(command)));
+ if (conn->internal->disconnected)
+ return 0;
+
if (!cmd->cmd_ident)
cmd->cmd_ident = silc_client_cmd_ident(conn);
SilcClientCommandReplyCallback cb;
int i;
- /* If command is running, finish it. Destructor will free the context. */
- if (silc_fsm_is_started(&cmd->thread)) {
- silc_fsm_finish(&cmd->thread);
- return;
- }
-
for (i = 0; i < cmd->argc; i++)
silc_free(cmd->argv[i]);
silc_free(cmd->argv);
{
SilcClientCommandContext cmd = fsm_context;
SilcClientConnection conn = cmd->conn;
- SilcChannelEntry channel;
+ SilcClient client = conn->client;
+ SilcChannelEntry channel = NULL;
SilcBuffer idp = NULL;
if (cmd->argc == 2) {
1, 1, silc_buffer_datalen(idp));
silc_buffer_free(idp);
+ silc_client_unref_channel(client, conn, channel);
/* Notify application */
COMMAND(SILC_STATUS_OK);
{
SilcClientCommandContext cmd = fsm_context;
SilcClientConnection conn = cmd->conn;
+ SilcClient client = conn->client;
SilcChannelEntry channel;
SilcBuffer idp;
char *name;
1, silc_buffer_datalen(idp));
silc_buffer_free(idp);
+ silc_client_unref_channel(client, conn, channel);
/* Notify application */
COMMAND(SILC_STATUS_OK);
SilcClientConnection conn = cmd->conn;
SilcClient client = conn->client;
SilcClientEntry client_entry = NULL;
- SilcChannelEntry channel;
+ SilcChannelEntry channel = NULL;
SilcBuffer clidp, chidp, args = NULL;
SilcPublicKey pubkey = NULL;
SilcDList clients = NULL;
}
channel = conn->current_channel;
+ silc_client_ref_channel(client, conn, channel);
} else {
name = cmd->argv[1];
/* Parse the typed nickname. */
if (cmd->argc == 3) {
if (cmd->argv[2][0] != '+' && cmd->argv[2][0] != '-') {
- if (client->internal->params->nickname_parse)
- client->internal->params->nickname_parse(cmd->argv[2], &nickname);
- else
- nickname = strdup(cmd->argv[2]);
+ silc_client_nickname_parse(client, conn, cmd->argv[2], &nickname);
/* Find client entry */
clients = silc_client_get_clients_local(client, conn, nickname,
silc_buffer_free(args);
silc_free(nickname);
silc_client_list_free(client, conn, clients);
+ silc_client_unref_channel(client, conn, channel);
/* Notify application */
COMMAND(SILC_STATUS_OK);
SilcClientConnection conn = cmd->conn;
SilcClient client = conn->client;
+ SILC_LOG_DEBUG(("Quitting"));
+
/* Notify application */
COMMAND(SILC_STATUS_OK);
/* Call connection callback */
- conn->callback(client, conn, SILC_CLIENT_CONN_DISCONNECTED,
- 0, NULL, conn->callback_context);
+ if (!conn->internal->callback_called)
+ conn->callback(client, conn, SILC_CLIENT_CONN_DISCONNECTED,
+ 0, NULL, conn->callback_context);
+ conn->internal->callback_called = TRUE;
/* Signal to close connection */
if (!conn->internal->disconnected) {
conn->internal->disconnected = TRUE;
- SILC_FSM_SEMA_POST(&conn->internal->wait_event);
+ SILC_FSM_EVENT_SIGNAL(&conn->internal->wait_event);
}
return SILC_FSM_FINISH;
}
/* Parse the typed nickname. */
- if (client->internal->params->nickname_parse)
- client->internal->params->nickname_parse(cmd->argv[1], &nickname);
- else
- nickname = strdup(cmd->argv[1]);
- if (!nickname)
+ if (!silc_client_nickname_parse(client, conn, cmd->argv[1], &nickname))
return SILC_FSM_FINISH;
/* Get the target client */
{
SilcClientCommandContext cmd = fsm_context;
SilcClientConnection conn = cmd->conn;
- SilcChannelEntry channel;
+ SilcClient client = conn->client;
+ SilcChannelEntry channel = NULL;
SilcBuffer auth = NULL, cauth = NULL;
char *name, *passphrase = NULL, *pu8, *cipher = NULL, *hmac = NULL;
int i, passphrase_len = 0;
if (passphrase)
memset(passphrase, 0, strlen(passphrase));
silc_free(passphrase);
+ silc_client_unref_channel(client, conn, channel);
/* Notify application */
COMMAND(SILC_STATUS_OK);
return SILC_FSM_CONTINUE;
out:
+ silc_client_unref_channel(client, conn, channel);
return SILC_FSM_FINISH;
}
SilcClientCommandContext cmd = fsm_context;
SilcClientConnection conn = cmd->conn;
SilcClient client = conn->client;
- SilcChannelEntry channel;
+ SilcChannelEntry channel = NULL;
SilcBuffer chidp, auth = NULL, pk = NULL;
unsigned char *name, *cp, modebuf[4], tmp[4], *arg = NULL;
SilcUInt32 mode, add, type, len, arg_len = 0;
}
channel = conn->current_channel;
+ silc_client_ref_channel(client, conn, channel);
} else {
name = cmd->argv[1];
silc_buffer_free(chidp);
silc_buffer_free(auth);
silc_buffer_free(pk);
+ silc_client_unref_channel(client, conn, channel);
/* Notify application */
COMMAND(SILC_STATUS_OK);
return SILC_FSM_CONTINUE;
out:
+ silc_client_unref_channel(client, conn, channel);
return SILC_FSM_FINISH;
}
SilcClientCommandContext cmd = fsm_context;
SilcClientConnection conn = cmd->conn;
SilcClient client = conn->client;
- SilcChannelEntry channel;
+ SilcChannelEntry channel = NULL;
SilcChannelUser chu;
SilcClientEntry client_entry;
SilcBuffer clidp, chidp, auth = NULL;
}
channel = conn->current_channel;
+ silc_client_ref_channel(client, conn, channel);
} else {
name = cmd->argv[1];
}
/* Parse the typed nickname. */
- if (client->internal->params->nickname_parse)
- client->internal->params->nickname_parse(cmd->argv[3], &nickname);
- else
- nickname = strdup(cmd->argv[3]);
+ silc_client_nickname_parse(client, conn, cmd->argv[3], &nickname);
/* Find client entry */
clients = silc_client_get_clients_local(client, conn, nickname,
silc_buffer_free(auth);
silc_free(nickname);
silc_client_list_free(client, conn, clients);
+ silc_client_unref_channel(client, conn, channel);
/* Notify application */
COMMAND(SILC_STATUS_OK);
return SILC_FSM_CONTINUE;
out:
+ silc_client_unref_channel(client, conn, channel);
silc_client_list_free(client, conn, clients);
silc_free(nickname);
return SILC_FSM_FINISH;
SilcClientCommandContext cmd = fsm_context;
SilcClientConnection conn = cmd->conn;
SilcClient client = conn->client;
- SilcChannelEntry channel;
+ SilcChannelEntry channel = NULL;
SilcBuffer idp, idp2;
SilcClientEntry target;
SilcDList clients = NULL;
}
/* Parse the typed nickname. */
- if (client->internal->params->nickname_parse)
- client->internal->params->nickname_parse(cmd->argv[2], &nickname);
- else
- nickname = strdup(cmd->argv[2]);
+ silc_client_nickname_parse(client, conn, cmd->argv[2], &nickname);
/* Get the target client */
clients = silc_client_get_clients_local(client, conn, nickname,
silc_buffer_free(idp2);
silc_free(nickname);
silc_client_list_free(client, conn, clients);
+ silc_client_unref_channel(client, conn, channel);
/* Notify application */
COMMAND(SILC_STATUS_OK);
return SILC_FSM_CONTINUE;
out:
+ silc_client_unref_channel(client, conn, channel);
silc_free(nickname);
return SILC_FSM_FINISH;
}
{
SilcClientCommandContext cmd = fsm_context;
SilcClientConnection conn = cmd->conn;
+ SilcClient client = conn->client;
SilcChannelEntry channel;
SilcBuffer chidp, args = NULL;
char *name, *ban = NULL;
}
channel = conn->current_channel;
+ silc_client_ref_channel(client, conn, channel);
} else {
name = cmd->argv[1];
silc_buffer_free(chidp);
silc_buffer_free(args);
+ silc_client_unref_channel(client, conn, channel);
/* Notify application */
COMMAND(SILC_STATUS_OK);
{
SilcClientCommandContext cmd = fsm_context;
SilcClientConnection conn = cmd->conn;
+ SilcClient client = conn->client;
SilcChannelEntry channel;
SilcBuffer idp;
char *name;
if (conn->current_channel == channel)
conn->current_channel = NULL;
+ silc_client_unref_channel(client, conn, channel);
+
/** Wait for command reply */
silc_fsm_next(fsm, silc_client_command_reply_wait);
return SILC_FSM_CONTINUE;
}
/* Parse the typed nickname. */
- if (client->internal->params->nickname_parse)
- client->internal->params->nickname_parse(cmd->argv[1], &nickname);
- else
- nickname = strdup(cmd->argv[1]);
- if (!nickname) {
+ if (!silc_client_nickname_parse(client, conn, cmd->argv[1], &nickname)) {
COMMAND_ERROR(SILC_STATUS_ERR_RESOURCE_LIMIT);
return SILC_FSM_FINISH;
}
case SILC_COMMAND_WHOIS:
/* Ignore everything if requested by application */
- if (client->internal->params->ignore_requested_attributes)
+ if (conn->internal->params.ignore_requested_attributes)
break;
silc_client_command_process_whois(client, conn, payload, args);