X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilcclient%2Fidlist.c;h=dfdfc6f3e5d4420367acfcd94dd0e74d5939cea7;hp=82a2e05120b6b4c654c4347827b06a5f66986895;hb=413da0f8686910f5e627393157566ae729ca99c4;hpb=5d90b0684f07a8a51d5dff5cd108a328ec82ffa9 diff --git a/lib/silcclient/idlist.c b/lib/silcclient/idlist.c index 82a2e051..dfdfc6f3 100644 --- a/lib/silcclient/idlist.c +++ b/lib/silcclient/idlist.c @@ -1,10 +1,10 @@ /* - idlist.c + idlist.c Author: Pekka Riikonen - Copyright (C) 2001 - 2002 Pekka Riikonen + Copyright (C) 2001 - 2003 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 @@ -49,8 +49,13 @@ SilcClientEntry *silc_client_get_clients_local(SilcClient client, int i = 0; bool found = FALSE; + assert(client && conn); + if (!nickname) + return NULL; + /* Find ID from cache */ - if (!silc_idcache_find_by_name(conn->client_cache, (char *)nickname, &list)) + if (!silc_idcache_find_by_name(conn->internal->client_cache, + (char *)nickname, &list)) return NULL; if (!silc_idcache_list_count(list)) { @@ -82,7 +87,7 @@ SilcClientEntry *silc_client_get_clients_local(SilcClient client, continue; } } - + clients[i++] = id_cache->context; found = TRUE; if (!silc_idcache_list_next(list, &id_cache)) @@ -141,7 +146,7 @@ SILC_CLIENT_CMD_FUNC(get_client_callback) silc_free(i); } -/* Finds client entry or entries by the `nickname' and `server'. The +/* Finds client entry or entries by the `nickname' and `server'. The completion callback will be called when the client entries has been found. Note: this function is always asynchronous and resolves the client @@ -158,8 +163,11 @@ void silc_client_get_clients(SilcClient client, void *context) { GetClientInternal i; + int len; char *userhost; + assert(client && conn); + if (!nickname) return; @@ -172,13 +180,13 @@ void silc_client_get_clients(SilcClient client, i->context = context; if (nickname && server) { - userhost = silc_calloc(strlen(nickname) + strlen(server) + 2, - sizeof(*userhost)); - strncat(userhost, nickname, strlen(nickname)); - strncat(userhost, "@", 1); - strncat(userhost, server, strlen(server)); + len = strlen(nickname) + strlen(server) + 3; + userhost = silc_calloc(len, sizeof(*userhost)); + silc_strncat(userhost, len, nickname, strlen(nickname)); + silc_strncat(userhost, len, "@", 1); + silc_strncat(userhost, len, server, strlen(server)); } else { - userhost = strdup(nickname); + userhost = silc_memdup(nickname, strlen(nickname)); } /* Register our own command reply for this command */ @@ -187,13 +195,13 @@ void silc_client_get_clients(SilcClient client, ++conn->cmd_ident); /* Send the command */ - silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY, - conn->cmd_ident, 1, 1, userhost, + silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY, + conn->cmd_ident, 1, 1, userhost, strlen(userhost)); /* Add pending callback */ silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY, conn->cmd_ident, - silc_client_command_get_client_callback, + silc_client_command_get_client_callback, (void *)i); silc_free(userhost); @@ -218,20 +226,20 @@ SilcClientEntry silc_idlist_get_client(SilcClient client, SILC_LOG_DEBUG(("Start")); /* Find ID from cache */ - if (!silc_idcache_find_by_name(conn->client_cache, (char *)nickname, - &list)) { + if (!silc_idcache_find_by_name(conn->internal->client_cache, + (char *)nickname, &list)) { identify: if (query) { SILC_LOG_DEBUG(("Requesting Client ID from server")); - + /* Register our own command reply for this command */ silc_client_command_register(client, SILC_COMMAND_IDENTIFY, NULL, NULL, silc_client_command_reply_identify_i, 0, ++conn->cmd_ident); /* Send the command */ - silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY, + silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY, conn->cmd_ident, 1, 1, nickname, strlen(nickname)); @@ -279,7 +287,6 @@ SilcClientEntry silc_idlist_get_client(SilcClient client, return entry; } - typedef struct { SilcClient client; SilcClientConnection conn; @@ -310,6 +317,8 @@ SILC_CLIENT_CMD_FUNC(get_clients_list_callback) SILC_LOG_DEBUG(("Resolved all clients")); + clients = silc_calloc(i->list_count, sizeof(*clients)); + for (c = 0; c < i->list_count; c++) { SilcUInt16 idp_len; SilcClientID *client_id; @@ -324,13 +333,11 @@ SILC_CLIENT_CMD_FUNC(get_clients_list_callback) } /* Get the client entry */ - if (silc_idcache_find_by_id_one_ext(i->conn->client_cache, - (void *)client_id, - NULL, NULL, + if (silc_idcache_find_by_id_one_ext(i->conn->internal->client_cache, + (void *)client_id, + NULL, NULL, silc_hash_client_id_compare, NULL, &id_cache)) { - clients = silc_realloc(clients, sizeof(*clients) * - (clients_count + 1)); clients[clients_count] = (SilcClientEntry)id_cache->context; clients_count++; found = TRUE; @@ -373,6 +380,8 @@ void silc_client_get_clients_by_list(SilcClient client, GetClientsByListInternal in; bool wait_res = FALSE; + assert(client && conn && client_id_list); + SILC_LOG_DEBUG(("Start")); in = silc_calloc(1, sizeof(*in)); @@ -400,8 +409,8 @@ void silc_client_get_clients_by_list(SilcClient client, /* Check if we have this client cached already. */ ret = - silc_idcache_find_by_id_one_ext(conn->client_cache, (void *)client_id, - NULL, NULL, + silc_idcache_find_by_id_one_ext(conn->internal->client_cache, + (void *)client_id, NULL, NULL, silc_hash_client_id_compare, NULL, &id_cache); @@ -414,9 +423,9 @@ void silc_client_get_clients_by_list(SilcClient client, if (entry->status & SILC_CLIENT_STATUS_RESOLVING) { /* Attach to this resolving and wait until it finishes */ silc_client_command_pending( - conn, SILC_COMMAND_NONE, + conn, SILC_COMMAND_NONE, entry->resolve_cmd_ident, - silc_client_command_get_clients_list_callback, + silc_client_command_get_clients_list_callback, (void *)in); wait_res = TRUE; in->res_count++; @@ -448,7 +457,7 @@ void silc_client_get_clients_by_list(SilcClient client, silc_buffer_pull(client_id_list, idp_len); } - silc_buffer_push(client_id_list, client_id_list->data - + silc_buffer_push(client_id_list, client_id_list->data - client_id_list->head); /* Query the client information from server if the list included clients @@ -460,7 +469,7 @@ void silc_client_get_clients_by_list(SilcClient client, res_cmd = silc_command_payload_encode(SILC_COMMAND_IDENTIFY, res_argc, res_argv, res_argv_lens, res_argv_types, ++conn->cmd_ident); - silc_client_packet_send(client, conn->sock, SILC_PACKET_COMMAND, + silc_client_packet_send(client, conn->sock, SILC_PACKET_COMMAND, NULL, 0, NULL, NULL, res_cmd->data, res_cmd->len, TRUE); @@ -471,7 +480,7 @@ void silc_client_get_clients_by_list(SilcClient client, /* Process the applications request after reply has been received */ silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY, conn->cmd_ident, - silc_client_command_get_clients_list_callback, + silc_client_command_get_clients_list_callback, (void *)in); in->res_count++; @@ -489,6 +498,169 @@ void silc_client_get_clients_by_list(SilcClient client, silc_client_command_get_clients_list_callback((void *)in, NULL); } +typedef struct { + SilcClient client; + SilcClientConnection conn; + SilcChannelID channel_id; + SilcGetClientCallback completion; + void *context; + int res_count; +} *GetClientsByChannelInternal; + +SILC_CLIENT_CMD_FUNC(get_clients_by_channel_cb) +{ + GetClientsByChannelInternal i = context; + SilcClientEntry *clients = NULL; + SilcUInt32 clients_count = 0; + bool found = FALSE; + SilcChannelEntry channel; + SilcHashTableList htl; + SilcChannelUser chu; + + channel = silc_client_get_channel_by_id(i->client, i->conn, &i->channel_id); + if (channel && !silc_hash_table_count(channel->user_list)) { + clients = silc_calloc(silc_hash_table_count(channel->user_list), + sizeof(*clients)); + silc_hash_table_list(channel->user_list, &htl); + while (silc_hash_table_get(&htl, NULL, (void **)&chu)) + clients[clients_count++] = chu->client; + silc_hash_table_list_reset(&htl); + found = TRUE; + } + + if (found) { + i->completion(i->client, i->conn, clients, clients_count, i->context); + silc_free(clients); + } else { + i->completion(i->client, i->conn, NULL, 0, i->context); + } + + silc_free(i); +} + +/* Gets client entries by the channel entry indicated by `channel'. Thus, + it resolves the clients currently on that channel. */ + +void silc_client_get_clients_by_channel(SilcClient client, + SilcClientConnection conn, + SilcChannelEntry channel, + SilcGetClientCallback completion, + void *context) +{ + GetClientsByChannelInternal in; + SilcHashTableList htl; + SilcChannelUser chu; + SilcClientEntry entry; + unsigned char **res_argv = NULL; + SilcUInt32 *res_argv_lens = NULL, *res_argv_types = NULL, res_argc = 0; + SilcBuffer idp; + bool wait_res = FALSE; + + assert(client && conn && channel); + + SILC_LOG_DEBUG(("Start")); + + in = silc_calloc(1, sizeof(*in)); + in->client = client; + in->conn = conn; + in->channel_id = *channel->id; + in->completion = completion; + in->context = context; + + /* If user list does not exist, send USERS command. */ + if (!channel->user_list || !silc_hash_table_count(channel->user_list)) { + SILC_LOG_DEBUG(("Sending USERS")); + silc_client_command_register(client, SILC_COMMAND_USERS, NULL, NULL, + silc_client_command_reply_users_i, 0, + ++conn->cmd_ident); + silc_client_command_send(client, conn, SILC_COMMAND_USERS, + conn->cmd_ident, 1, 2, channel->channel_name, + strlen(channel->channel_name)); + silc_client_command_pending(conn, SILC_COMMAND_USERS, conn->cmd_ident, + silc_client_command_get_clients_by_channel_cb, + in); + return; + } + + silc_hash_table_list(channel->user_list, &htl); + while (silc_hash_table_get(&htl, NULL, (void **)&chu)) { + entry = chu->client; + + /* If the entry has incomplete info, then resolve it from the server. */ + if (!entry->nickname || !entry->realname) { + if (entry->status & SILC_CLIENT_STATUS_RESOLVING) { + /* Attach to this resolving and wait until it finishes */ + silc_client_command_pending( + conn, SILC_COMMAND_NONE, + entry->resolve_cmd_ident, + silc_client_command_get_clients_by_channel_cb, + (void *)in); + wait_res = TRUE; + in->res_count++; + continue; + } + entry->status |= SILC_CLIENT_STATUS_RESOLVING; + entry->resolve_cmd_ident = conn->cmd_ident + 1; + + idp = silc_id_payload_encode(entry->id, SILC_ID_CLIENT); + + /* No we don't have it, query it from the server. Assemble argument + table that will be sent for the WHOIS command later. */ + res_argv = silc_realloc(res_argv, sizeof(*res_argv) * + (res_argc + 1)); + res_argv_lens = silc_realloc(res_argv_lens, sizeof(*res_argv_lens) * + (res_argc + 1)); + res_argv_types = silc_realloc(res_argv_types, sizeof(*res_argv_types) * + (res_argc + 1)); + res_argv[res_argc] = silc_memdup(idp->data, idp->len); + res_argv_lens[res_argc] = idp->len; + res_argv_types[res_argc] = res_argc + 4; + res_argc++; + + silc_buffer_free(idp); + } + } + silc_hash_table_list_reset(&htl); + + /* Query the client information from server if the list included clients + that we don't know about. */ + if (res_argc) { + SilcBuffer res_cmd; + + /* Send the WHOIS command to server */ + res_cmd = silc_command_payload_encode(SILC_COMMAND_WHOIS, + res_argc, res_argv, res_argv_lens, + res_argv_types, ++conn->cmd_ident); + silc_client_packet_send(client, conn->sock, SILC_PACKET_COMMAND, + NULL, 0, NULL, NULL, res_cmd->data, res_cmd->len, + TRUE); + + /* Register our own command reply for this command */ + silc_client_command_register(client, SILC_COMMAND_WHOIS, NULL, NULL, + silc_client_command_reply_whois_i, 0, + conn->cmd_ident); + + /* Process the applications request after reply has been received */ + silc_client_command_pending( + conn, SILC_COMMAND_WHOIS, conn->cmd_ident, + silc_client_command_get_clients_by_channel_cb, + (void *)in); + in->res_count++; + + silc_buffer_free(res_cmd); + silc_free(res_argv); + silc_free(res_argv_lens); + silc_free(res_argv_types); + return; + } + + if (wait_res) + return; + + /* We have the clients in cache, get them and call the completion */ + silc_client_command_get_clients_by_channel_cb((void *)in, NULL); +} + /* Finds entry for client by the client's ID. Returns the entry or NULL if the entry was not found. */ @@ -498,12 +670,16 @@ SilcClientEntry silc_client_get_client_by_id(SilcClient client, { SilcIDCacheEntry id_cache; - SILC_LOG_DEBUG(("Finding client by ID (%s)", + assert(client && conn); + if (!client_id) + return NULL; + + SILC_LOG_DEBUG(("Finding client by ID (%s)", silc_id_render(client_id, SILC_ID_CLIENT))); /* Find ID from cache */ - if (!silc_idcache_find_by_id_one_ext(conn->client_cache, (void *)client_id, - NULL, NULL, + if (!silc_idcache_find_by_id_one_ext(conn->internal->client_cache, + (void *)client_id, NULL, NULL, silc_hash_client_id_compare, NULL, &id_cache)) return NULL; @@ -554,6 +730,8 @@ void silc_client_get_client_by_id_resolve(SilcClient client, SilcBuffer idp; GetClientByIDInternal i = silc_calloc(1, sizeof(*i)); + assert(client && conn && client_id); + SILC_LOG_DEBUG(("Start")); i->client = client; @@ -561,7 +739,7 @@ void silc_client_get_client_by_id_resolve(SilcClient client, i->client_id = silc_id_dup(client_id, SILC_ID_CLIENT); i->completion = completion; i->context = context; - + /* Register our own command reply for this command */ silc_client_command_register(client, SILC_COMMAND_WHOIS, NULL, NULL, silc_client_command_reply_whois_i, 0, @@ -577,7 +755,7 @@ void silc_client_get_client_by_id_resolve(SilcClient client, /* Add pending callback */ silc_client_command_pending(conn, SILC_COMMAND_WHOIS, conn->cmd_ident, - silc_client_command_get_client_by_id_callback, + silc_client_command_get_client_by_id_callback, (void *)i); } @@ -594,7 +772,7 @@ void silc_client_get_client_by_id_resolve(SilcClient client, SilcClientEntry silc_client_add_client(SilcClient client, SilcClientConnection conn, - char *nickname, char *username, + char *nickname, char *username, char *userinfo, SilcClientID *id, SilcUInt32 mode) { SilcClientEntry client_entry; @@ -607,7 +785,7 @@ silc_client_add_client(SilcClient client, SilcClientConnection conn, client_entry->id = id; client_entry->valid = TRUE; silc_parse_userfqdn(nickname, &nick, &client_entry->server); - silc_parse_userfqdn(username, &client_entry->username, + silc_parse_userfqdn(username, &client_entry->username, &client_entry->hostname); if (userinfo) client_entry->realname = strdup(userinfo); @@ -619,9 +797,9 @@ silc_client_add_client(SilcClient client, SilcClientConnection conn, /* Format the nickname */ silc_client_nickname_format(client, conn, client_entry); - + /* Add client to cache, the non-formatted nickname is saved to cache */ - if (!silc_idcache_add(conn->client_cache, nick, client_entry->id, + if (!silc_idcache_add(conn->internal->client_cache, nick, client_entry->id, (void *)client_entry, 0, NULL)) { silc_free(client_entry->nickname); silc_free(client_entry->username); @@ -668,15 +846,15 @@ void silc_client_update_client(SilcClient client, if (nick) { /* Remove the old cache entry and create a new one */ - silc_idcache_del_by_context(conn->client_cache, client_entry); - silc_idcache_add(conn->client_cache, nick, client_entry->id, + silc_idcache_del_by_context(conn->internal->client_cache, client_entry); + silc_idcache_add(conn->internal->client_cache, nick, client_entry->id, client_entry, 0, NULL); } } /* Deletes the client entry and frees all memory. */ -void silc_client_del_client_entry(SilcClient client, +void silc_client_del_client_entry(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry) { @@ -706,13 +884,16 @@ void silc_client_del_client_entry(SilcClient client, bool silc_client_del_client(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry) { - bool ret = silc_idcache_del_by_context(conn->client_cache, client_entry); + bool ret = silc_idcache_del_by_context(conn->internal->client_cache, + client_entry); - /* Remove from channels */ - silc_client_remove_from_channels(client, conn, client_entry); + if (ret) { + /* Remove from channels */ + silc_client_remove_from_channels(client, conn, client_entry); - /* Free the client entry data */ - silc_client_del_client_entry(client, conn, client_entry); + /* Free the client entry data */ + silc_client_del_client_entry(client, conn, client_entry); + } return ret; } @@ -722,7 +903,7 @@ bool silc_client_del_client(SilcClient client, SilcClientConnection conn, SilcChannelEntry silc_client_add_channel(SilcClient client, SilcClientConnection conn, const char *channel_name, - SilcUInt32 mode, + SilcUInt32 mode, SilcChannelID *channel_id) { SilcChannelEntry channel; @@ -737,7 +918,7 @@ SilcChannelEntry silc_client_add_channel(SilcClient client, NULL, NULL, NULL, TRUE); /* Put it to the ID cache */ - if (!silc_idcache_add(conn->channel_cache, channel->channel_name, + if (!silc_idcache_add(conn->internal->channel_cache, channel->channel_name, (void *)channel->id, (void *)channel, 0, NULL)) { silc_free(channel->channel_name); silc_hash_table_free(channel->user_list); @@ -769,12 +950,13 @@ static void silc_client_del_channel_foreach(void *key, void *context, bool silc_client_del_channel(SilcClient client, SilcClientConnection conn, SilcChannelEntry channel) { - bool ret = silc_idcache_del_by_context(conn->channel_cache, channel); + bool ret = silc_idcache_del_by_context(conn->internal->channel_cache, + channel); SILC_LOG_DEBUG(("Start")); /* Free all client entrys from the users list. The silc_hash_table_free - will free all the entries so they are not freed at the foreach + will free all the entries so they are not freed at the foreach callback. */ silc_hash_table_foreach(channel->user_list, silc_client_del_channel_foreach, NULL); @@ -787,12 +969,20 @@ bool silc_client_del_channel(SilcClient client, SilcClientConnection conn, silc_cipher_free(channel->channel_key); if (channel->hmac) silc_hmac_free(channel->hmac); - if (channel->old_channel_key) - silc_cipher_free(channel->old_channel_key); - if (channel->old_hmac) - silc_hmac_free(channel->old_hmac); - if (channel->rekey_task) - silc_schedule_task_del(conn->client->schedule, channel->rekey_task); + if (channel->old_channel_keys) { + SilcCipher key; + silc_dlist_start(channel->old_channel_keys); + while ((key = silc_dlist_get(channel->old_channel_keys)) != SILC_LIST_END) + silc_cipher_free(key); + silc_dlist_uninit(channel->old_channel_keys); + } + if (channel->old_hmacs) { + SilcHmac hmac; + silc_dlist_start(channel->old_hmacs); + while ((hmac = silc_dlist_get(channel->old_hmacs)) != SILC_LIST_END) + silc_hmac_free(hmac); + silc_dlist_uninit(channel->old_hmacs); + } silc_client_del_channel_private_keys(client, conn, channel); silc_free(channel); return ret; @@ -809,15 +999,16 @@ bool silc_client_replace_channel_id(SilcClient client, if (!new_id) return FALSE; - SILC_LOG_DEBUG(("Old Channel ID id(%s)", + SILC_LOG_DEBUG(("Old Channel ID id(%s)", silc_id_render(channel->id, SILC_ID_CHANNEL))); - SILC_LOG_DEBUG(("New Channel ID id(%s)", + SILC_LOG_DEBUG(("New Channel ID id(%s)", silc_id_render(new_id, SILC_ID_CHANNEL))); - silc_idcache_del_by_id(conn->channel_cache, channel->id); + silc_idcache_del_by_id(conn->internal->channel_cache, channel->id); silc_free(channel->id); channel->id = new_id; - return silc_idcache_add(conn->channel_cache, channel->channel_name, + return silc_idcache_add(conn->internal->channel_cache, + channel->channel_name, (void *)channel->id, (void *)channel, 0, NULL); } @@ -833,9 +1024,13 @@ SilcChannelEntry silc_client_get_channel(SilcClient client, SilcIDCacheEntry id_cache; SilcChannelEntry entry; + assert(client && conn); + if (!channel) + return NULL; + SILC_LOG_DEBUG(("Start")); - if (!silc_idcache_find_by_name_one(conn->channel_cache, channel, + if (!silc_idcache_find_by_name_one(conn->internal->channel_cache, channel, &id_cache)) return NULL; @@ -857,9 +1052,13 @@ SilcChannelEntry silc_client_get_channel_by_id(SilcClient client, SilcIDCacheEntry id_cache; SilcChannelEntry entry; + assert(client && conn); + if (!channel_id) + return NULL; + SILC_LOG_DEBUG(("Start")); - if (!silc_idcache_find_by_id_one(conn->channel_cache, channel_id, + if (!silc_idcache_find_by_id_one(conn->internal->channel_cache, channel_id, &id_cache)) return NULL; @@ -873,27 +1072,85 @@ SilcChannelEntry silc_client_get_channel_by_id(SilcClient client, typedef struct { SilcClient client; SilcClientConnection conn; - SilcChannelID *channel_id; + union { + SilcChannelID *channel_id; + char *channel_name; + } u; SilcGetChannelCallback completion; void *context; -} *GetChannelByIDInternal; +} *GetChannelInternal; + +SILC_CLIENT_CMD_FUNC(get_channel_resolve_callback) +{ + GetChannelInternal i = (GetChannelInternal)context; + SilcChannelEntry entry; + + SILC_LOG_DEBUG(("Start")); + + /* Get the channel */ + entry = silc_client_get_channel(i->client, i->conn, i->u.channel_name); + if (entry) { + i->completion(i->client, i->conn, &entry, 1, i->context); + } else { + i->completion(i->client, i->conn, NULL, 0, i->context); + } + + silc_free(i->u.channel_name); + silc_free(i); +} + +/* Resolves channel entry from the server by the channel name. */ + +void silc_client_get_channel_resolve(SilcClient client, + SilcClientConnection conn, + char *channel_name, + SilcGetChannelCallback completion, + void *context) +{ + GetChannelInternal i = silc_calloc(1, sizeof(*i)); + + assert(client && conn && channel_name); + + SILC_LOG_DEBUG(("Start")); + + i->client = client; + i->conn = conn; + i->u.channel_name = strdup(channel_name); + i->completion = completion; + i->context = context; + + /* Register our own command reply for this command */ + silc_client_command_register(client, SILC_COMMAND_IDENTIFY, NULL, NULL, + silc_client_command_reply_identify_i, 0, + ++conn->cmd_ident); + + /* Send the command */ + silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY, + conn->cmd_ident, + 1, 3, channel_name, strlen(channel_name)); + + /* Add pending callback */ + silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY, conn->cmd_ident, + silc_client_command_get_channel_resolve_callback, + (void *)i); +} SILC_CLIENT_CMD_FUNC(get_channel_by_id_callback) { - GetChannelByIDInternal i = (GetChannelByIDInternal)context; + GetChannelInternal i = (GetChannelInternal)context; SilcChannelEntry entry; SILC_LOG_DEBUG(("Start")); /* Get the channel */ - entry = silc_client_get_channel_by_id(i->client, i->conn, i->channel_id); + entry = silc_client_get_channel_by_id(i->client, i->conn, i->u.channel_id); if (entry) { i->completion(i->client, i->conn, &entry, 1, i->context); } else { i->completion(i->client, i->conn, NULL, 0, i->context); } - silc_free(i->channel_id); + silc_free(i->u.channel_id); silc_free(i); } @@ -906,16 +1163,18 @@ void silc_client_get_channel_by_id_resolve(SilcClient client, void *context) { SilcBuffer idp; - GetChannelByIDInternal i = silc_calloc(1, sizeof(*i)); + GetChannelInternal i = silc_calloc(1, sizeof(*i)); + + assert(client && conn && channel_id); SILC_LOG_DEBUG(("Start")); i->client = client; i->conn = conn; - i->channel_id = silc_id_dup(channel_id, SILC_ID_CHANNEL); + i->u.channel_id = silc_id_dup(channel_id, SILC_ID_CHANNEL); i->completion = completion; i->context = context; - + /* Register our own command reply for this command */ silc_client_command_register(client, SILC_COMMAND_IDENTIFY, NULL, NULL, silc_client_command_reply_identify_i, 0, @@ -923,14 +1182,14 @@ void silc_client_get_channel_by_id_resolve(SilcClient client, /* Send the command */ idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL); - silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY, + silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY, conn->cmd_ident, 1, 5, idp->data, idp->len); silc_buffer_free(idp); /* Add pending callback */ silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY, conn->cmd_ident, - silc_client_command_get_channel_by_id_callback, + silc_client_command_get_channel_by_id_callback, (void *)i); } @@ -943,10 +1202,14 @@ SilcServerEntry silc_client_get_server(SilcClient client, SilcIDCacheEntry id_cache; SilcServerEntry entry; + assert(client && conn); + if (!server_name) + return NULL; + SILC_LOG_DEBUG(("Start")); - if (!silc_idcache_find_by_name_one(conn->server_cache, server_name, - &id_cache)) + if (!silc_idcache_find_by_name_one(conn->internal->server_cache, + server_name, &id_cache)) return NULL; entry = (SilcServerEntry)id_cache->context; @@ -963,10 +1226,14 @@ SilcServerEntry silc_client_get_server_by_id(SilcClient client, SilcIDCacheEntry id_cache; SilcServerEntry entry; + assert(client && conn); + if (!server_id) + return NULL; + SILC_LOG_DEBUG(("Start")); - if (!silc_idcache_find_by_id_one(conn->server_cache, (void *)server_id, - &id_cache)) + if (!silc_idcache_find_by_id_one(conn->internal->server_cache, + (void *)server_id, &id_cache)) return NULL; entry = (SilcServerEntry)id_cache->context; @@ -997,7 +1264,8 @@ SilcServerEntry silc_client_add_server(SilcClient client, server_entry->server_info = strdup(server_info); /* Add server to cache */ - if (!silc_idcache_add(conn->server_cache, server_entry->server_name, + if (!silc_idcache_add(conn->internal->server_cache, + server_entry->server_name, server_entry->server_id, server_entry, 0, NULL)) { silc_free(server_entry->server_id); silc_free(server_entry->server_name); @@ -1014,7 +1282,7 @@ SilcServerEntry silc_client_add_server(SilcClient client, bool silc_client_del_server(SilcClient client, SilcClientConnection conn, SilcServerEntry server) { - bool ret = silc_idcache_del_by_context(conn->server_cache, server); + bool ret = silc_idcache_del_by_context(conn->internal->server_cache, server); silc_free(server->server_name); silc_free(server->server_info); silc_free(server->server_id); @@ -1035,10 +1303,10 @@ void silc_client_update_server(SilcClient client, if (server_name && (!server_entry->server_name || strcmp(server_entry->server_name, server_name))) { - silc_idcache_del_by_context(conn->server_cache, server_entry); + silc_idcache_del_by_context(conn->internal->server_cache, server_entry); silc_free(server_entry->server_name); server_entry->server_name = strdup(server_name); - silc_idcache_add(conn->server_cache, server_entry->server_name, + silc_idcache_add(conn->internal->server_cache, server_entry->server_name, server_entry->server_id, server_entry, 0, NULL); } @@ -1055,7 +1323,7 @@ void silc_client_update_server(SilcClient client, nickname and replace the old nickname in the client entry. If the format string is not specified then this function has no effect. */ -void silc_client_nickname_format(SilcClient client, +void silc_client_nickname_format(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry) { @@ -1096,6 +1364,20 @@ void silc_client_nickname_format(SilcClient client, if (!len || freebase) return; + if (clients_count == 1) + unformatted = clients[0]; + else + for (i = 0; i < clients_count; i++) + if (!strncasecmp(clients[i]->nickname, client_entry->nickname, + strlen(clients[i]->nickname))) + unformatted = clients[i]; + + /* If we are changing nickname of our local entry we'll enforce + that we will always get the unformatted nickname. Give our + format number to the one that is not formatted now. */ + if (unformatted && client_entry == conn->local_entry) + client_entry = unformatted; + cp = client->internal->params->nickname_format; while (*cp) { if (*cp == '%') { @@ -1158,15 +1440,10 @@ void silc_client_nickname_format(SilcClient client, char tmp[6]; int num, max = 1; - if (clients_count == 1) { - unformatted = clients[0]; + if (clients_count == 1) break; - } for (i = 0; i < clients_count; i++) { - if (!strncasecmp(clients[i]->nickname, client_entry->nickname, - strlen(clients[i]->nickname))) - unformatted = clients[i]; if (strncasecmp(clients[i]->nickname, newnick, off)) continue; if (strlen(clients[i]->nickname) <= off) @@ -1198,12 +1475,6 @@ void silc_client_nickname_format(SilcClient client, newnick = silc_realloc(newnick, sizeof(*newnick) * (off + 1)); newnick[off] = 0; - /* If we are changing nickname of our local entry we'll enforce - that we will always get the unformatted nickname. Give our - format number to the one that is not formatted now. */ - if (unformatted && client_entry == conn->local_entry) - client_entry = unformatted; - silc_free(client_entry->nickname); client_entry->nickname = newnick; silc_free(clients);