silc_parse_nickname(nickname, &client_entry->nickname,
&client_entry->server, &client_entry->num);
client_entry->username = strdup(username);
+ if (realname)
+ client_entry->realname = strdup(realname);
/* Add client to cache */
silc_idcache_add(conn->client_cache, client_entry->nickname,
SILC_ID_CLIENT, client_id, (void *)client_entry, TRUE);
} else {
client_entry = (SilcClientEntry)id_cache->context;
+ if (client_entry->nickname)
+ silc_free(client_entry->nickname);
+ if (client_entry->server)
+ silc_free(client_entry->server);
+ if (client_entry->username)
+ silc_free(client_entry->username);
+ if (client_entry->realname)
+ silc_free(client_entry->realname);
+
+ silc_parse_nickname(nickname, &client_entry->nickname,
+ &client_entry->server, &client_entry->num);
+ client_entry->username = strdup(username);
+ if (realname)
+ client_entry->realname = strdup(realname);
+
+ id_cache->data = client_entry->nickname;
+
silc_free(client_id);
}
cmd->client->ops->say(cmd->client, conn, "%s", buf);
/* Notify application */
- COMMAND_REPLY((ARGS, client_entry, nickname,
- username, realname, NULL, NULL));
+ COMMAND_REPLY((ARGS, client_entry, nickname, username, realname,
+ NULL, NULL));
}
/* Received reply for WHOIS command. This maybe called several times
SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
SilcClientEntry client_entry;
+ SilcIDCacheEntry id_cache = NULL;
SilcCommandStatus status;
unsigned char *tmp;
unsigned char *id_data;
char *nickname;
char *username;
+ SilcClientID *client_id;
id_data = silc_argument_get_arg_type(cmd->args, 2, &len);
+ if (!id_data)
+ goto out;
+ client_id = silc_id_payload_parse_id(id_data, len);
+
nickname = silc_argument_get_arg_type(cmd->args, 3, NULL);
username = silc_argument_get_arg_type(cmd->args, 4, NULL);
- /* Allocate client entry */
- client_entry = silc_calloc(1, sizeof(*client_entry));
- client_entry->id = silc_id_payload_parse_id(id_data, len);
- if (nickname)
+ if (!silc_idcache_find_by_id_one(conn->client_cache, (void *)client_id,
+ SILC_ID_CLIENT, &id_cache)) {
+ client_entry = silc_calloc(1, sizeof(*client_entry));
+ client_entry->id = client_id;
silc_parse_nickname(nickname, &client_entry->nickname,
&client_entry->server, &client_entry->num);
- if (username)
- client_entry->username = strdup(username);
+ if (username)
+ client_entry->username = strdup(username);
+
+ /* Add client to cache */
+ silc_idcache_add(conn->client_cache, client_entry->nickname,
+ SILC_ID_CLIENT, client_id, (void *)client_entry, TRUE);
+ } else {
+ client_entry = (SilcClientEntry)id_cache->context;
+ if (client_entry->nickname)
+ silc_free(client_entry->nickname);
+ if (client_entry->server)
+ silc_free(client_entry->server);
+ if (username && client_entry->username)
+ silc_free(client_entry->username);
- /* Save received Client ID to ID cache */
- silc_idcache_add(conn->client_cache, client_entry->nickname,
- SILC_ID_CLIENT, client_entry->id, client_entry, TRUE);
+ silc_parse_nickname(nickname, &client_entry->nickname,
+ &client_entry->server, &client_entry->num);
+
+ if (username)
+ client_entry->username = strdup(username);
+
+ id_cache->data = client_entry->nickname;
+
+ silc_free(client_id);
+ }
}
if (status == SILC_STATUS_LIST_START) {
SilcCommandStatus status;
SilcIDCacheEntry id_cache = NULL;
SilcChannelEntry channel;
+ SilcChannelUser chu;
SilcChannelID *channel_id = NULL;
SilcBuffer client_id_list;
SilcBuffer client_mode_list;
channel = (SilcChannelEntry)id_cache->context;
- /* If there is pending command we know that user has called this command
- and we will handle the name list differently. */
- if (cmd->callback) {
- /* 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 */
-
+ /* Remove commas from list */
+ for (i = 0; i < len1; i++)
+ if (name_list[i] == ',') {
+ name_list[i] = ' ';
+ list_count++;
}
- 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
- the reply without getting the command from us first. This happens
- with SILC servers that sends NAMES reply after joining to a channel. */
-
- /* Remove commas from list */
- for (i = 0; i < len1; i++)
- if (name_list[i] == ',') {
- name_list[i] = ' ';
- list_count++;
- }
- list_count++;
- }
+ list_count++;
- /* Remove old client list from channel, if exists */
- if (channel->clients) {
- silc_free(channel->clients);
- channel->clients = NULL;
- channel->clients_count = 0;
+ /* Remove old client list from channel. */
+ silc_list_start(channel->clients);
+ while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
+ silc_list_del(channel->clients, chu);
+ silc_free(chu);
}
- /* Allocate room for clients in the channel */
- channel->clients = silc_calloc(list_count, sizeof(*channel->clients));
-
/* Cache the received name list, client ID's and modes. This cache expires
whenever server sends notify message to channel. It means two things;
some user has joined or leaved the channel. */
id_cache = NULL;
}
- channel->clients[channel->clients_count].client = client;
- channel->clients[channel->clients_count].mode = mode;
- channel->clients_count++;
+ chu = silc_calloc(1, sizeof(*chu));
+ chu->client = client;
+ chu->mode = mode;
+ silc_list_add(channel->clients, chu);
name_list += nick_len + 1;
}
name_list = cp;
for (i = 0; i < list_count; i++) {
- int c;
+ int c = 0;
int nick_len = strcspn(name_list, " ");
char *nickname = silc_calloc(nick_len + 1, sizeof(*nickname));
memcpy(nickname, name_list, nick_len);
- for (c = 0, k = 0; k < channel->clients_count; k++) {
- if (channel->clients[k].client &&
- !strncmp(channel->clients[k].client->nickname,
- nickname, strlen(channel->clients[k].client->nickname))) {
+ silc_list_start(channel->clients);
+ while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
+ if (!strncmp(chu->client->nickname, nickname,
+ strlen(chu->client->nickname))) {
char t[8];
if (!c) {
}
memset(t, 0, sizeof(t));
- channel->clients[k].client->nickname =
- silc_calloc(strlen(nickname) + 8, sizeof(*channel->clients[k].
- client->nickname));
- strncat(channel->clients[k].client->nickname, nickname,
- strlen(nickname));
- snprintf(t, sizeof(t), " [%d]", c++);
- strncat(channel->clients[k].client->nickname, t, strlen(t));
+ chu->client->nickname = silc_calloc(strlen(nickname) + 8, 1);
+ snprintf(t, sizeof(t), "[%d]", c++);
+ strncat(chu->client->nickname, t, strlen(t));
+ strncat(chu->client->nickname, nickname, strlen(nickname));
}
}
silc_free(nickname);
}
- name_list = NULL;
- len1 = 0;
- for (k = 0; k < channel->clients_count; k++) {
- char *n = channel->clients[k].client->nickname;
- len2 = strlen(n);
- len1 += len2;
- name_list = silc_realloc(name_list, sizeof(*name_list) * (len1 + 1));
- memcpy(name_list + (len1 - len2), n, len2);
- name_list[len1] = 0;
+ /* XXX hmm... actually it is applications business to display this
+ information. We should just pass (as we do) the data to application and
+ let it to parse it and display it the way it wants. */
+ if (cmd->callback) {
+ cmd->client->ops->say(cmd->client, conn, "Users on %s",
+ channel->channel_name);
- if (k == channel->clients_count - 1)
- break;
- memcpy(name_list + len1, " ", 1);
- len1++;
+ silc_list_start(channel->clients);
+ while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
+ SilcClientEntry e = chu->client;
+ char *m, tmp[80], line[80];
+
+ memset(line, 0, sizeof(line));
+ memset(tmp, 0, sizeof(tmp));
+ m = silc_client_chumode_char(chu->mode);
+
+ strcat(line, " ");
+ strcat(line, e->nickname);
+ strcat(line, e->server ? "@" : "");
+
+ len1 = 0;
+ if (e->server)
+ len1 = strlen(e->server);
+ strncat(line, e->server ? e->server : "", len1 > 30 ? 30 : len1);
+
+ len1 = strlen(line);
+ if (len1 >= 30) {
+ memset(&line[29], 0, len1 - 29);
+ } else {
+ for (i = 0; i < 30 - len1 - 1; i++)
+ strcat(line, " ");
+ }
+
+ strcat(line, " H");
+ strcat(tmp, m ? m : "");
+ strcat(line, tmp);
+
+ if (strlen(tmp) < 5)
+ for (i = 0; i < 5 - strlen(tmp); i++)
+ strcat(line, " ");
+
+ strcat(line, e->username ? e->username : "");
+
+ cmd->client->ops->say(cmd->client, conn, "%s", line);
+
+ if (m)
+ silc_free(m);
+ }
+
+ } else {
+ name_list = NULL;
+ len1 = 0;
+ k = 0;
+
+ silc_list_start(channel->clients);
+ while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
+ char *m, *n = chu->client->nickname;
+ len2 = strlen(n);
+ len1 += len2;
+
+ name_list = silc_realloc(name_list, sizeof(*name_list) * (len1 + 3));
+
+ m = silc_client_chumode_char(chu->mode);
+ if (m) {
+ memcpy(name_list + (len1 - len2), m, strlen(m));
+ len1 += strlen(m);
+ silc_free(m);
+ }
+
+ memcpy(name_list + (len1 - len2), n, len2);
+ name_list[len1] = 0;
+
+ if (k == silc_list_count(channel->clients) - 1)
+ break;
+ memcpy(name_list + len1, " ", 1);
+ len1++;
+ k++;
+ }
+
+ cmd->client->ops->say(cmd->client, conn, "Users on %s: %s",
+ channel->channel_name, name_list);
+ silc_free(name_list);
}
- cmd->client->ops->say(cmd->client, conn,
- "Users on %s: %s", channel->channel_name, name_list);
+ name_list = silc_argument_get_arg_type(cmd->args, 3, &len1);
/* Notify application */
COMMAND_REPLY((ARGS, channel, name_list, client_id_list->head,
client_mode_list->head));
- silc_free(name_list);
silc_buffer_free(client_id_list);
silc_buffer_free(client_mode_list);