X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcclient%2Fcommand.c;h=85e33fe38217f0fe7b17c6c70a97270b1d3e2aca;hb=52e57c880aba9c5e89f59d962eb9af75670b76e0;hp=91f35f3275c194e51d47a2d46491bde70d96ce8b;hpb=8a6279964422ae932dcf5af1a32616cfcbde5a19;p=silc.git diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index 91f35f32..85e33fe3 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -68,7 +68,7 @@ static SilcUInt16 silc_client_cmd_ident(SilcClientConnection conn) SILC_FSM_STATE(silc_client_command_continue_error) { /* Destructor will free all resources */ - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /* Command reply callback to continue with the execution of a command. @@ -123,6 +123,32 @@ static void silc_client_command_resolve_continue(SilcClient client, SILC_FSM_CALL_CONTINUE(&cmd->thread); } +/* Dummy command callback. Nothing interesting to do here. Use this when + you just send command but don't care about reply. */ + +SilcBool silc_client_command_called_dummy(SilcClient client, + SilcClientConnection conn, + SilcCommand command, + SilcStatus status, + SilcStatus error, + void *context, + va_list ap) +{ + return FALSE; +} + +/* Dummy resolving callback. Nothing interesting to do here. Use this + when you just resolve entires but don't care about reply. */ + +void silc_client_command_resolve_dummy(SilcClient client, + SilcClientConnection conn, + SilcStatus status, + SilcDList clients, + void *context) +{ + /* Nothing */ +} + /* Register command to client */ static SilcBool @@ -390,7 +416,7 @@ SilcUInt16 silc_client_command_call(SilcClient client, char *arg; if (!conn) { - client->internal->ops->say(client, NULL, SILC_CLIENT_MESSAGE_ERROR, + client->internal->ops->say(client, NULL, SILC_CLIENT_MESSAGE_COMMAND_ERROR, "You are not connected to a server, please connect to server"); return 0; } @@ -610,6 +636,7 @@ SILC_FSM_STATE(silc_client_command_whois) unsigned char count[4], *tmp = NULL; SilcBool details = FALSE, nick = FALSE; unsigned char *pubkey = NULL; + char *nickname = NULL; int i; /* Given without arguments fetches client's own information */ @@ -623,7 +650,7 @@ SILC_FSM_STATE(silc_client_command_whois) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } for (i = 1; i < cmd->argc; i++) { @@ -670,7 +697,7 @@ SILC_FSM_STATE(silc_client_command_whois) SilcPublicKey pk; if (!silc_pkcs_load_public_key(pubkey, &pk)) { - SAY(client, conn, SILC_CLIENT_MESSAGE_ERROR, + SAY(client, conn, SILC_CLIENT_MESSAGE_COMMAND_ERROR, "Could not load public key %s, check the filename", pubkey); COMMAND_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); @@ -700,24 +727,32 @@ SILC_FSM_STATE(silc_client_command_whois) SILC_ATTRIBUTE_USER_PUBLIC_KEY, SILC_ATTRIBUTE_FLAG_VALID, &obj, sizeof(obj)); + silc_free(obj.data); + } + + if (nick) { + silc_client_nickname_parse(client, conn, cmd->argv[1], &nickname); + if (!nickname) + nickname = strdup(cmd->argv[1]); } /* Send command */ silc_client_command_send_va(conn, cmd, cmd->cmd, NULL, NULL, - 3, 1, nick ? cmd->argv[1] : NULL, - nick ? cmd->argv_lens[1] : 0, + 3, 1, nick ? nickname : NULL, + nick ? strlen(nickname) : 0, 2, tmp ? tmp : NULL, tmp ? 4 : 0, 3, silc_buffer_datalen(attrs)); + silc_free(nickname); /* Notify application */ COMMAND(SILC_STATUS_OK); /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; out: - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /******************************** WHOWAS ************************************/ @@ -737,7 +772,7 @@ SILC_FSM_STATE(silc_client_command_whowas) "Usage: /WHOWAS [@] []"); COMMAND_ERROR((cmd->argc < 2 ? SILC_STATUS_ERR_NOT_ENOUGH_PARAMS : SILC_STATUS_ERR_TOO_MANY_PARAMS)); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } if (cmd->argc == 2) { @@ -756,7 +791,7 @@ SILC_FSM_STATE(silc_client_command_whowas) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /******************************** IDENTIFY **********************************/ @@ -772,7 +807,7 @@ SILC_FSM_STATE(silc_client_command_identify) int c; if (cmd->argc < 2 || cmd->argc > 3) - SILC_FSM_FINISH; + return SILC_FSM_FINISH; if (cmd->argc == 2) { silc_client_command_send_va(conn, cmd, cmd->cmd, NULL, NULL, @@ -787,7 +822,7 @@ SILC_FSM_STATE(silc_client_command_identify) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /********************************** NICK ************************************/ @@ -797,7 +832,7 @@ SILC_FSM_STATE(silc_client_command_identify) SILC_FSM_STATE(silc_client_command_nick) { - SilcClientCommandContext cmd = fsm_context; + SilcClientCommandContext cmd2, cmd = fsm_context; SilcClientConnection conn = cmd->conn; if (cmd->argc < 2) { @@ -825,6 +860,19 @@ SILC_FSM_STATE(silc_client_command_nick) goto out; } + /* If JOIN command is active, wait for it to finish before sending NICK. + To avoid problems locally with changing IDs while joining, we do this. */ + silc_mutex_lock(conn->internal->lock); + silc_list_start(conn->internal->pending_commands); + while ((cmd2 = silc_list_get(conn->internal->pending_commands))) { + if (cmd2->cmd == SILC_COMMAND_JOIN) { + silc_mutex_unlock(conn->internal->lock); + silc_fsm_next_later(fsm, silc_client_command_nick, 0, 300000); + return SILC_FSM_WAIT; + } + } + silc_mutex_unlock(conn->internal->lock); + if (cmd->argv_lens[1] > 128) cmd->argv_lens[1] = 128; @@ -837,10 +885,10 @@ SILC_FSM_STATE(silc_client_command_nick) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; out: - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /********************************** LIST ************************************/ @@ -876,7 +924,7 @@ SILC_FSM_STATE(silc_client_command_list) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /********************************** TOPIC ***********************************/ @@ -890,7 +938,7 @@ SILC_FSM_STATE(silc_client_command_topic) SilcClient client = conn->client; SilcChannelEntry channel; SilcBuffer idp; - char *name; + char *name, tmp[512]; if (cmd->argc < 2 || cmd->argc > 3) { SAY(conn->client, conn, SILC_CLIENT_MESSAGE_INFO, @@ -905,7 +953,15 @@ SILC_FSM_STATE(silc_client_command_topic) COMMAND_ERROR(SILC_STATUS_ERR_NOT_ON_CHANNEL); goto out; } - name = conn->current_channel->channel_name; + + if (client->internal->params->full_channel_names) + silc_snprintf(tmp, sizeof(tmp), conn->current_channel->channel_name); + else + silc_snprintf(tmp, sizeof(tmp), "%s%s%s", + conn->current_channel->channel_name, + conn->current_channel->server[0] ? "@" : "", + conn->current_channel->server); + name = tmp; } else { name = cmd->argv[1]; } @@ -941,10 +997,10 @@ SILC_FSM_STATE(silc_client_command_topic) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; out: - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /********************************* INVITE ***********************************/ @@ -998,13 +1054,12 @@ SILC_FSM_STATE(silc_client_command_invite) silc_client_nickname_parse(client, conn, cmd->argv[2], &nickname); /* Find client entry */ - clients = silc_client_get_clients_local(client, conn, nickname, - cmd->argv[2]); + clients = silc_client_get_clients_local(client, conn, cmd->argv[2], + FALSE); if (!clients) /* Resolve client information */ SILC_FSM_CALL(silc_client_get_clients( - client, conn, nickname, - cmd->argv[2], + client, conn, nickname, NULL, silc_client_command_resolve_continue, cmd)); @@ -1067,11 +1122,11 @@ SILC_FSM_STATE(silc_client_command_invite) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; out: silc_free(nickname); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /********************************** QUIT ************************************/ @@ -1082,26 +1137,20 @@ SILC_FSM_STATE(silc_client_command_quit_final) { SilcClientCommandContext cmd = fsm_context; SilcClientConnection conn = cmd->conn; - SilcClient client = conn->client; SILC_LOG_DEBUG(("Quitting")); /* Notify application */ COMMAND(SILC_STATUS_OK); - /* Call connection callback */ - 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 */ + conn->internal->status = SILC_CLIENT_CONN_DISCONNECTED; if (!conn->internal->disconnected) { conn->internal->disconnected = TRUE; SILC_FSM_EVENT_SIGNAL(&conn->internal->wait_event); } - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /* Command QUIT. Closes connection with current server. */ @@ -1122,12 +1171,11 @@ SILC_FSM_STATE(silc_client_command_quit) /* We close the connection with a little timeout */ silc_fsm_next_later(fsm, silc_client_command_quit_final, 2, 0); - SILC_FSM_WAIT; + return SILC_FSM_WAIT; } /********************************** KILL ************************************/ - /* Command KILL. Router operator can use this command to remove an client fromthe SILC Network. */ @@ -1145,20 +1193,18 @@ SILC_FSM_STATE(silc_client_command_kill) SAY(conn->client, conn, SILC_CLIENT_MESSAGE_INFO, "Usage: /KILL [] [-pubkey]"); COMMAND_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /* Parse the typed nickname. */ if (!silc_client_nickname_parse(client, conn, cmd->argv[1], &nickname)) - SILC_FSM_FINISH; + return SILC_FSM_FINISH; /* Get the target client */ - clients = silc_client_get_clients_local(client, conn, nickname, - cmd->argv[1]); + clients = silc_client_get_clients_local(client, conn, cmd->argv[1], FALSE); if (!clients) /* Resolve client information */ - SILC_FSM_CALL(silc_client_get_clients(client, conn, nickname, - cmd->argv[1], + SILC_FSM_CALL(silc_client_get_clients(client, conn, nickname, NULL, silc_client_command_resolve_continue, cmd)); @@ -1195,7 +1241,7 @@ SILC_FSM_STATE(silc_client_command_kill) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /********************************** INFO ************************************/ @@ -1220,7 +1266,7 @@ SILC_FSM_STATE(silc_client_command_info) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /********************************** STATS ***********************************/ @@ -1242,7 +1288,7 @@ SILC_FSM_STATE(silc_client_command_stats) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /********************************** PING ************************************/ @@ -1256,7 +1302,7 @@ SILC_FSM_STATE(silc_client_command_ping) if (cmd->argc < 2) { COMMAND_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /* Send the command */ @@ -1272,7 +1318,7 @@ SILC_FSM_STATE(silc_client_command_ping) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /********************************** JOIN ************************************/ @@ -1281,7 +1327,7 @@ SILC_FSM_STATE(silc_client_command_ping) SILC_FSM_STATE(silc_client_command_join) { - SilcClientCommandContext cmd = fsm_context; + SilcClientCommandContext cmd2, cmd = fsm_context; SilcClientConnection conn = cmd->conn; SilcClient client = conn->client; SilcChannelEntry channel = NULL; @@ -1299,6 +1345,19 @@ SILC_FSM_STATE(silc_client_command_join) if (channel && silc_client_on_channel(channel, conn->local_entry)) goto out; + /* If NICK command is active, wait for it to finish before sending JOIN. + To avoid problems locally with changing IDs while joining, we do this. */ + silc_mutex_lock(conn->internal->lock); + silc_list_start(conn->internal->pending_commands); + while ((cmd2 = silc_list_get(conn->internal->pending_commands))) { + if (cmd2->cmd == SILC_COMMAND_NICK) { + silc_mutex_unlock(conn->internal->lock); + silc_fsm_next_later(fsm, silc_client_command_join, 0, 300000); + return SILC_FSM_WAIT; + } + } + silc_mutex_unlock(conn->internal->lock); + if (cmd->argv_lens[1] > 256) cmd->argv_lens[1] = 256; @@ -1330,7 +1389,7 @@ SILC_FSM_STATE(silc_client_command_join) } if (!silc_load_key_pair(cmd->argv[i + 1], cmd->argv[i + 2], pass, &pubkey, &privkey)) { - SAY(conn->client, conn, SILC_CLIENT_MESSAGE_ERROR, + SAY(conn->client, conn, SILC_CLIENT_MESSAGE_COMMAND_ERROR, "Could not load key pair, check your arguments"); COMMAND_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); goto out; @@ -1389,11 +1448,11 @@ SILC_FSM_STATE(silc_client_command_join) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; out: silc_client_unref_channel(client, conn, channel); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /********************************** MOTD ************************************/ @@ -1410,7 +1469,7 @@ SILC_FSM_STATE(silc_client_command_motd) "Usage: /MOTD []"); COMMAND_ERROR((cmd->argc < 1 ? SILC_STATUS_ERR_NOT_ENOUGH_PARAMS : SILC_STATUS_ERR_TOO_MANY_PARAMS)); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /* Send the command */ @@ -1427,7 +1486,7 @@ SILC_FSM_STATE(silc_client_command_motd) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /********************************** UMODE ***********************************/ @@ -1447,7 +1506,7 @@ SILC_FSM_STATE(silc_client_command_umode) SAY(conn->client, conn, SILC_CLIENT_MESSAGE_INFO, "Usage: /UMODE +|-"); COMMAND_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } mode = conn->local_entry->mode; @@ -1548,7 +1607,7 @@ SILC_FSM_STATE(silc_client_command_umode) break; default: COMMAND_ERROR(SILC_STATUS_ERR_UNKNOWN_MODE); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; break; } } @@ -1566,7 +1625,7 @@ SILC_FSM_STATE(silc_client_command_umode) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /********************************** CMODE ***********************************/ @@ -1750,7 +1809,7 @@ SILC_FSM_STATE(silc_client_command_cmode) pass = cmd->argv[5]; if (!silc_load_key_pair(cmd->argv[3], cmd->argv[4], pass, &pubkey, &privkey)) { - SAY(client, conn, SILC_CLIENT_MESSAGE_ERROR, + SAY(client, conn, SILC_CLIENT_MESSAGE_COMMAND_ERROR, "Could not load key pair, check your arguments"); COMMAND_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); goto out; @@ -1785,10 +1844,14 @@ SILC_FSM_STATE(silc_client_command_cmode) NULL, NULL, 1, 1, silc_buffer_datalen(chidp)); silc_buffer_free(chidp); + silc_client_unref_channel(client, conn, channel); /* Notify application */ COMMAND(SILC_STATUS_OK); - goto out; + + /** Wait for command reply */ + silc_fsm_next(fsm, silc_client_command_reply_wait); + return SILC_FSM_CONTINUE; } if (cmd->argc >= 4) { @@ -1802,7 +1865,7 @@ SILC_FSM_STATE(silc_client_command_cmode) if (cmd->argv[k][0] == '+') chadd = TRUE; if (!silc_pkcs_load_public_key(cmd->argv[k] + 1, &chpk)) { - SAY(conn->client, conn, SILC_CLIENT_MESSAGE_ERROR, + SAY(conn->client, conn, SILC_CLIENT_MESSAGE_COMMAND_ERROR, "Could not load public key %s, check the filename", cmd->argv[k]); COMMAND_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); @@ -1861,11 +1924,11 @@ SILC_FSM_STATE(silc_client_command_cmode) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; out: silc_client_unref_channel(client, conn, channel); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /********************************* CUMODE ***********************************/ @@ -1916,11 +1979,10 @@ SILC_FSM_STATE(silc_client_command_cumode) silc_client_nickname_parse(client, conn, cmd->argv[3], &nickname); /* Find client entry */ - clients = silc_client_get_clients_local(client, conn, nickname, - cmd->argv[3]); + clients = silc_client_get_clients_local(client, conn, cmd->argv[3], FALSE); if (!clients) /* Resolve client information */ - SILC_FSM_CALL(silc_client_get_clients(client, conn, nickname, cmd->argv[3], + SILC_FSM_CALL(silc_client_get_clients(client, conn, nickname, NULL, silc_client_command_resolve_continue, cmd)); @@ -1964,7 +2026,7 @@ SILC_FSM_STATE(silc_client_command_cumode) pass = cmd->argv[6]; if (!silc_load_key_pair(cmd->argv[4], cmd->argv[5], pass, &pubkey, &privkey)) { - SAY(conn->client, conn, SILC_CLIENT_MESSAGE_ERROR, + SAY(conn->client, conn, SILC_CLIENT_MESSAGE_COMMAND_ERROR, "Could not load key pair, check your arguments"); COMMAND_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); goto out; @@ -2043,13 +2105,13 @@ SILC_FSM_STATE(silc_client_command_cumode) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; out: silc_client_unref_channel(client, conn, channel); silc_client_list_free(client, conn, clients); silc_free(nickname); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /********************************** KICK ************************************/ @@ -2065,8 +2127,7 @@ SILC_FSM_STATE(silc_client_command_kick) SilcBuffer idp, idp2; SilcClientEntry target; SilcDList clients = NULL; - char *name; - char *nickname = NULL; + char *name, tmp[512]; if (cmd->argc < 3) { SAY(conn->client, conn, SILC_CLIENT_MESSAGE_INFO, @@ -2080,7 +2141,15 @@ SILC_FSM_STATE(silc_client_command_kick) COMMAND_ERROR(SILC_STATUS_ERR_NOT_ON_CHANNEL); goto out; } - name = conn->current_channel->channel_name; + + if (client->internal->params->full_channel_names) + silc_snprintf(tmp, sizeof(tmp), conn->current_channel->channel_name); + else + silc_snprintf(tmp, sizeof(tmp), "%s%s%s", + conn->current_channel->channel_name, + conn->current_channel->server[0] ? "@" : "", + conn->current_channel->server); + name = tmp; } else { name = cmd->argv[1]; } @@ -2097,12 +2166,8 @@ SILC_FSM_STATE(silc_client_command_kick) goto out; } - /* Parse the typed nickname. */ - silc_client_nickname_parse(client, conn, cmd->argv[2], &nickname); - /* Get the target client */ - clients = silc_client_get_clients_local(client, conn, nickname, - cmd->argv[2]); + clients = silc_client_get_clients_local(client, conn, cmd->argv[2], FALSE); if (!clients) { SAY(conn->client, conn, SILC_CLIENT_MESSAGE_INFO, "No such client: %s", cmd->argv[2]); @@ -2126,7 +2191,6 @@ SILC_FSM_STATE(silc_client_command_kick) silc_buffer_free(idp); silc_buffer_free(idp2); - silc_free(nickname); silc_client_list_free(client, conn, clients); silc_client_unref_channel(client, conn, channel); @@ -2135,12 +2199,11 @@ SILC_FSM_STATE(silc_client_command_kick) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; out: silc_client_unref_channel(client, conn, channel); - silc_free(nickname); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /***************************** OPER & SILCOPER ******************************/ @@ -2152,7 +2215,7 @@ typedef struct { /* Ask passphrase callback */ -static void silc_client_command_oper_cb(unsigned char *data, +static void silc_client_command_oper_cb(const unsigned char *data, SilcUInt32 data_len, void *context) { SilcClientCommandContext cmd = context; @@ -2205,7 +2268,7 @@ SILC_FSM_STATE(silc_client_command_oper_send) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /* OPER command. Used to obtain server operator privileges. */ @@ -2220,22 +2283,23 @@ SILC_FSM_STATE(silc_client_command_oper) SAY(conn->client, conn, SILC_CLIENT_MESSAGE_INFO, "Usage: /OPER [-pubkey]"); COMMAND_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } + silc_fsm_next(fsm, silc_client_command_oper_send); + /* Get passphrase */ if (cmd->argc < 3) { oper = silc_calloc(1, sizeof(*oper)); if (!oper) - SILC_FSM_FINISH; + return SILC_FSM_FINISH; cmd->context = oper; SILC_FSM_CALL(conn->client->internal-> ops->ask_passphrase(conn->client, conn, silc_client_command_oper_cb, cmd)); } - silc_fsm_next(fsm, silc_client_command_oper_send); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /* SILCOPER command. Used to obtain router operator privileges. */ @@ -2250,22 +2314,23 @@ SILC_FSM_STATE(silc_client_command_silcoper) SAY(conn->client, conn, SILC_CLIENT_MESSAGE_INFO, "Usage: /SILCOPER [-pubkey]"); COMMAND_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } + silc_fsm_next(fsm, silc_client_command_oper_send); + /* Get passphrase */ if (cmd->argc < 3) { oper = silc_calloc(1, sizeof(*oper)); if (!oper) - SILC_FSM_FINISH; + return SILC_FSM_FINISH; cmd->context = oper; SILC_FSM_CALL(conn->client->internal-> ops->ask_passphrase(conn->client, conn, silc_client_command_oper_cb, cmd)); } - silc_fsm_next(fsm, silc_client_command_oper_send); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /*********************************** BAN ************************************/ @@ -2355,10 +2420,10 @@ SILC_FSM_STATE(silc_client_command_ban) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; out: - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /********************************* DETACH ***********************************/ @@ -2377,7 +2442,7 @@ SILC_FSM_STATE(silc_client_command_detach) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /********************************** WATCH ***********************************/ @@ -2417,7 +2482,7 @@ SILC_FSM_STATE(silc_client_command_watch) SilcBuffer buffer; if (!silc_pkcs_load_public_key(pubkey, &pk)) { - SAY(conn->client, conn, SILC_CLIENT_MESSAGE_ERROR, + SAY(conn->client, conn, SILC_CLIENT_MESSAGE_COMMAND_ERROR, "Could not load public key %s, check the filename", pubkey); COMMAND_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); goto out; @@ -2434,6 +2499,12 @@ SILC_FSM_STATE(silc_client_command_watch) silc_pkcs_public_key_free(pk); } + /* If watching by nickname, resolve all users with that nickname so that + we get their information immediately. */ + if (type == 2) + silc_client_get_clients(conn->client, conn, cmd->argv[2], NULL, + silc_client_command_resolve_dummy, NULL); + /* Send the commmand */ silc_client_command_send_va(conn, cmd, cmd->cmd, NULL, NULL, 2, 1, silc_buffer_datalen(conn->internal-> @@ -2449,10 +2520,10 @@ SILC_FSM_STATE(silc_client_command_watch) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; out: - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /********************************** LEAVE ***********************************/ @@ -2466,7 +2537,7 @@ SILC_FSM_STATE(silc_client_command_leave) SilcClient client = conn->client; SilcChannelEntry channel; SilcBuffer idp; - char *name; + char *name, tmp[512]; if (cmd->argc != 2) { SAY(conn->client, conn, SILC_CLIENT_MESSAGE_INFO, @@ -2480,7 +2551,15 @@ SILC_FSM_STATE(silc_client_command_leave) COMMAND_ERROR(SILC_STATUS_ERR_NOT_ON_CHANNEL); goto out; } - name = conn->current_channel->channel_name; + + if (client->internal->params->full_channel_names) + silc_snprintf(tmp, sizeof(tmp), conn->current_channel->channel_name); + else + silc_snprintf(tmp, sizeof(tmp), "%s%s%s", + conn->current_channel->channel_name, + conn->current_channel->server[0] ? "@" : "", + conn->current_channel->server); + name = tmp; } else { name = cmd->argv[1]; } @@ -2510,10 +2589,10 @@ SILC_FSM_STATE(silc_client_command_leave) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; out: - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /********************************** USERS ***********************************/ @@ -2525,7 +2604,7 @@ SILC_FSM_STATE(silc_client_command_users) { SilcClientCommandContext cmd = fsm_context; SilcClientConnection conn = cmd->conn; - char *name; + char *name, tmp[512]; if (cmd->argc != 2) { SAY(conn->client, conn, SILC_CLIENT_MESSAGE_INFO, @@ -2539,7 +2618,15 @@ SILC_FSM_STATE(silc_client_command_users) COMMAND_ERROR(SILC_STATUS_ERR_NOT_ON_CHANNEL); goto out; } - name = conn->current_channel->channel_name; + + if (conn->client->internal->params->full_channel_names) + silc_snprintf(tmp, sizeof(tmp), conn->current_channel->channel_name); + else + silc_snprintf(tmp, sizeof(tmp), "%s%s%s", + conn->current_channel->channel_name, + conn->current_channel->server[0] ? "@" : "", + conn->current_channel->server); + name = tmp; } else { name = cmd->argv[1]; } @@ -2553,10 +2640,10 @@ SILC_FSM_STATE(silc_client_command_users) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; out: - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /********************************* GETKEY ***********************************/ @@ -2571,25 +2658,17 @@ SILC_FSM_STATE(silc_client_command_getkey) SilcClientEntry client_entry; SilcServerEntry server_entry; SilcDList clients; - char *nickname = NULL; SilcBuffer idp; if (cmd->argc < 2) { client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_INFO, "Usage: /GETKEY "); COMMAND_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); - SILC_FSM_FINISH; - } - - /* Parse the typed nickname. */ - if (!silc_client_nickname_parse(client, conn, cmd->argv[1], &nickname)) { - COMMAND_ERROR(SILC_STATUS_ERR_RESOURCE_LIMIT); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /* Find client entry */ - clients = silc_client_get_clients_local(client, conn, nickname, - cmd->argv[1]); + clients = silc_client_get_clients_local(client, conn, cmd->argv[1], FALSE); if (!clients) { /* Check whether user requested server */ server_entry = silc_client_get_server(client, conn, cmd->argv[1]); @@ -2599,7 +2678,7 @@ SILC_FSM_STATE(silc_client_command_getkey) errors are handled in the resolving callback. */ COMMAND_ERROR(SILC_STATUS_ERR_NO_SUCH_NICK); COMMAND_ERROR(SILC_STATUS_ERR_NO_SUCH_SERVER); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /* No client or server exist with this name, query for both. */ @@ -2627,14 +2706,13 @@ SILC_FSM_STATE(silc_client_command_getkey) 1, silc_buffer_datalen(idp)); silc_buffer_free(idp); - silc_free(nickname); /* Notify application */ COMMAND(SILC_STATUS_OK); /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /********************************* SERVICE **********************************/ @@ -2654,7 +2732,7 @@ SILC_FSM_STATE(silc_client_command_service) SAY(conn->client, conn, SILC_CLIENT_MESSAGE_INFO, "Usage: /SERVICE [] [-pubkey]"); COMMAND_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } name = cmd->argv[1]; @@ -2674,7 +2752,7 @@ SILC_FSM_STATE(silc_client_command_service) /** Wait for command reply */ silc_fsm_next(fsm, silc_client_command_reply_wait); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /* Register all default commands provided by the client library for the @@ -2756,7 +2834,6 @@ static void silc_client_command_process_whois(SilcClient client, SilcCommandPayload payload, SilcArgumentPayload args) { -#if 0 SilcDList attrs; unsigned char *tmp; SilcUInt32 tmp_len; @@ -2780,18 +2857,25 @@ static void silc_client_command_process_whois(SilcClient client, return; } - /* Send the attributes back */ + /* Send the attributes back in COMMAND_REPLY packet */ packet = silc_command_reply_payload_encode_va(SILC_COMMAND_WHOIS, SILC_STATUS_OK, 0, silc_command_get_ident(payload), - 1, 11, buffer->data, buffer->len); - silc_client_packet_send(client, sock, SILC_PACKET_COMMAND_REPLY, - NULL, 0, NULL, NULL, packet->data, - packet->len, TRUE); + 1, 11, buffer->data, + silc_buffer_len(buffer)); + if (!packet) { + silc_buffer_free(buffer); + return; + } + + SILC_LOG_DEBUG(("Sending back requested WHOIS attributes")); + + silc_packet_send(conn->stream, SILC_PACKET_COMMAND_REPLY, 0, + silc_buffer_datalen(packet)); + silc_buffer_free(packet); silc_buffer_free(buffer); -#endif /* 0 */ } /* Client is able to receive some command packets even though they are @@ -2815,7 +2899,7 @@ SILC_FSM_STATE(silc_client_command) silc_buffer_len(&packet->buffer)); if (!payload) { SILC_LOG_DEBUG(("Bad command packet")); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /* Get arguments */ @@ -2838,5 +2922,5 @@ SILC_FSM_STATE(silc_client_command) } silc_command_payload_free(payload); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; }