/*
* $Id$
* $Log$
+ * Revision 1.6 2000/07/06 07:14:36 priikone
+ * Fixes to NAMES command handling.
+ * Fixes when leaving from channel.
+ *
* Revision 1.5 2000/07/05 06:12:05 priikone
* Global cosmetic changes.
*
port = atoi(cmd->argv[1] + 1 + len);
} else {
hostname = cmd->argv[1];
- port = 334;
+ port = 706;
}
/* Connect asynchronously to not to block user interface */
channel_id = silc_id_id2str(id_cache->id, SILC_ID_CHANNEL);
buffer = silc_command_encode_payload_va(SILC_COMMAND_INVITE, 2,
- client_id, SILC_ID_CLIENT_LEN,
- channel_id, SILC_ID_CHANNEL_LEN);
+ 1, client_id, SILC_ID_CLIENT_LEN,
+ 2, channel_id, SILC_ID_CHANNEL_LEN);
silc_client_packet_send(cmd->client, cmd->sock,
SILC_PACKET_COMMAND, NULL, 0, NULL, NULL,
buffer->data, buffer->len, TRUE);
/* Send the command */
buffer = silc_command_encode_payload_va(SILC_COMMAND_PING, 1,
- win->remote_id_data,
+ 1, win->remote_id_data,
SILC_ID_SERVER_LEN);
silc_client_packet_send(cmd->client, cmd->client->current_win->sock,
SILC_PACKET_COMMAND, NULL, 0, NULL, NULL,
win = (SilcClientWindow)cmd->sock->user_data;
- if (cmd->argv[1][0] == '*')
+ if (cmd->argv[1][0] == '*') {
+ if (!win->current_channel) {
+ silc_say(cmd->client, "You are not on any chanenl");
+ goto out;
+ }
name = win->current_channel->channel_name;
- else
+ } else {
name = cmd->argv[1];
+ }
if (!win->current_channel) {
- silc_say(cmd->client, "You are not on that channel", name);
+ silc_say(cmd->client, "You are not on that channel");
goto out;
}
/* Get the Channel ID of the channel */
silc_idcache_find_by_data(CIDC(name[0]), CIDCC(name[0]), name, &id_cache);
if (!id_cache) {
- silc_say(cmd->client, "You are not on that channel", name);
+ silc_say(cmd->client, "You are not on that channel");
goto out;
}
/* Send LEAVE command to the server */
id_string = silc_id_id2str(id_cache->id, SILC_ID_CHANNEL);
buffer = silc_command_encode_payload_va(SILC_COMMAND_LEAVE, 1,
- id_string, SILC_ID_CHANNEL_LEN);
+ 1, id_string, SILC_ID_CHANNEL_LEN);
silc_client_packet_send(cmd->client, cmd->client->current_win->sock,
SILC_PACKET_COMMAND, NULL, 0, NULL, NULL,
buffer->data, buffer->len, TRUE);
/* Send NAMES command to the server */
id_string = silc_id_id2str(id_cache->id, SILC_ID_CHANNEL);
buffer = silc_command_encode_payload_va(SILC_COMMAND_NAMES, 1,
- id_string, SILC_ID_CHANNEL_LEN);
+ 1, id_string, SILC_ID_CHANNEL_LEN);
silc_client_packet_send(cmd->client, cmd->client->current_win->sock,
SILC_PACKET_COMMAND, NULL, 0, NULL, NULL,
buffer->data, buffer->len, TRUE);
silc_buffer_free(buffer);
silc_free(id_string);
+ /* Register dummy pending command that will tell the reply command
+ that user called this command. Server may send reply to this command
+ even if user did not send this command thus we want to handle things
+ differently when user sent the command. This is dummy and won't be
+ execute. */
+ /* XXX this is kludge and should be removed after pending command reply
+ support is added. Currently only commands may be pending not command
+ replies. */
+ silc_client_command_pending(SILC_COMMAND_NAMES, silc_client_command_names,
+ NULL);
+
out:
silc_client_command_free(cmd);
#undef CIDC
/*
* $Id$
* $Log$
+ * Revision 1.5 2000/07/06 07:14:36 priikone
+ * Fixes to NAMES command handling.
+ * Fixes when leaving from channel.
+ *
* Revision 1.4 2000/07/05 06:12:34 priikone
* Tweaked NAMES command reply for better. Should now show users
* joined to a channel.
SILC_GET16_MSB(status, tmp);
if (status != SILC_STATUS_OK) {
if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
- tmp += 2;
- silc_say(cmd->client, "%s: %s", tmp,
- silc_client_command_status_message(status));
+ /* Take nickname which may be provided */
+ tmp = silc_command_get_arg_type(cmd->payload, 3, NULL);
+ if (tmp)
+ silc_say(cmd->client, "%s: %s", tmp,
+ silc_client_command_status_message(status));
+ else
+ silc_say(cmd->client, "%s",
+ silc_client_command_status_message(status));
goto out;
} else {
silc_say(cmd->client, "%s", silc_client_command_status_message(status));
SILC_GET16_MSB(status, tmp);
if (status != SILC_STATUS_OK) {
if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
- tmp += 2;
- silc_say(cmd->client, "%s: %s", tmp,
- silc_client_command_status_message(status));
+ /* Take nickname which may be provided */
+ tmp = silc_command_get_arg_type(cmd->payload, 3, NULL);
+ if (tmp)
+ silc_say(cmd->client, "%s: %s", tmp,
+ silc_client_command_status_message(status));
+ else
+ silc_say(cmd->client, "%s",
+ silc_client_command_status_message(status));
goto out;
} else {
silc_say(cmd->client, "%s", silc_client_command_status_message(status));
/* Get channel name */
tmp = silc_command_get_arg_type(cmd->payload, 2, NULL);
+ if (!tmp) {
+ silc_say(cmd->client, "Cannot join channel: Bad reply packet");
+ goto out;
+ }
channel_name = strdup(tmp);
/* Get Channel ID */
id_string = silc_command_get_arg_type(cmd->payload, 3, NULL);
+ if (!id_string) {
+ silc_say(cmd->client, "Cannot join channel: Bad reply packet");
+ goto out;
+ }
/* Get channel mode */
tmp = silc_command_get_arg_type(cmd->payload, 4, NULL);
- SILC_GET32_MSB(mode, tmp);
+ if (tmp)
+ SILC_GET32_MSB(mode, tmp);
+ else
+ mode = 0;
/* Get topic */
topic = silc_command_get_arg_type(cmd->payload, 5, NULL);
SilcIDCache *id_cache = NULL;
SilcChannelEntry channel;
SilcChannelID *channel_id = NULL;
+ SilcBuffer client_id_list;
unsigned char *tmp;
char *name_list;
- int i, len;
+ int i, len1, len2, list_count = 0;
SILC_LOG_DEBUG(("Start"));
#define CIDC(x) win->channel_id_cache[(x)]
#define CIDCC(x) win->channel_id_cache_count[(x)]
+#define CLC(x) win->client_id_cache[(x) - 32]
+#define CLCC(x) win->client_id_cache_count[(x) - 32]
tmp = silc_command_get_arg_type(cmd->payload, 1, NULL);
SILC_GET16_MSB(status, tmp);
/* Get channel ID */
tmp = silc_command_get_arg_type(cmd->payload, 2, NULL);
- if (!tmp)
+ if (!tmp) {
+ silc_say(cmd->client, "Cannot get user list: Bad reply packet");
goto out;
+ }
channel_id = silc_id_str2id(tmp, SILC_ID_CHANNEL);
/* Get the name list of the channel */
- name_list = silc_command_get_arg_type(cmd->payload, 3, &len);
- if (!name_list)
+ name_list = silc_command_get_arg_type(cmd->payload, 3, &len1);
+ if (!name_list) {
+ silc_say(cmd->client, "Cannot get user list: Bad reply packet");
+ goto out;
+ }
+
+ /* Get Client ID list */
+ tmp = silc_command_get_arg_type(cmd->payload, 4, &len2);
+ if (!tmp) {
+ silc_say(cmd->client, "Cannot get user list: Bad reply packet");
goto out;
+ }
+
+ client_id_list = silc_buffer_alloc(len2);
+ silc_buffer_pull_tail(client_id_list, len2);
+ silc_buffer_put(client_id_list, tmp, len2);
/* Get the channel name */
for (i = 0; i < 96; i++) {
channel = (SilcChannelEntry)id_cache->context;
- /* If there are pending commands set for this command reply we will
- execute them and let them handle the received name list. */
+ /* If there is pending command we know that user has called this command
+ and we will handle the name list differently. */
if (cmd->callback) {
- SILC_CLIENT_COMMAND_EXEC_PENDING(cmd, SILC_COMMAND_WHOIS);
+ /* We will resolve all the necessary information about the people
+ on the channel. Only after that will we display the user list. */
+ for (i = 0; i < len1; i++) {
+ /* XXX */
+
+ }
+ silc_client_command_pending_del(SILC_COMMAND_NAMES);
} else {
/* there is no pending callback it means that this command reply
has been received without calling the command, ie. server has sent
with SILC servers that sends NAMES reply after joining to a channel. */
/* Remove commas from list */
- for (i = 0; i < len; i++)
- if (name_list[i] == ',')
+ for (i = 0; i < len1; i++)
+ if (name_list[i] == ',') {
name_list[i] = ' ';
+ list_count++;
+ }
silc_say(cmd->client, "Users on %s: %s", channel->channel_name, name_list);
}
+ /* Cache the received name list and client ID's. This cache expires
+ whenever server sends notify message to channel. It means to things;
+ some user has joined or leaved the channel. */
+ for (i = 0; i < list_count; i++) {
+ int nick_len = strcspn(name_list, " ");
+ char *nickname = silc_calloc(nick_len, sizeof(*nickname));
+ SilcClientID *client_id;
+ SilcClientEntry client;
+
+ memcpy(nickname, name_list, nick_len);
+ client_id = silc_id_str2id(client_id_list->data, SILC_ID_CLIENT_LEN);
+ silc_buffer_pull(client_id_list, SILC_ID_CLIENT_LEN);
+
+ client = silc_calloc(1, sizeof(*client));
+ client->id = client_id;
+ client->nickname = nickname;
+
+ CLCC(nickname[0]) = silc_idcache_add(&CLC(nickname[0]), CLCC(nickname[0]),
+ nickname, SILC_ID_CLIENT,
+ client_id, (void *)client);
+
+ name_list = name_list + nick_len + 1;
+ }
+
+ silc_buffer_free(client_id_list);
+
out:
if (channel_id)
silc_free(channel_id);
silc_client_command_reply_free(cmd);
#undef CIDC
#undef CIDCC
+#undef CLC
+#undef CLCC
}
/* Private message received. This processes the private message and