X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilcclient%2Fclient.c;h=620e3de07318002e6e9c3306e56d27dedf613d00;hp=b1099389aad451abc0a181d53476476256349c72;hb=386c883d8774999c6e74d7c6c37e52e4163a4cb1;hpb=9a3e485d73ab5455dd6e2d0f76e684a70f847d8b diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index b1099389..620e3de0 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -374,8 +374,10 @@ static void silc_client_start_key_exchange_cb(SilcSocketConnection sock, SILC_LOG_DEBUG(("Start")); - if (!conn->sock->hostname) - conn->sock->hostname = strdup(conn->remote_host); + /* XXX We should most likely use the resolved host name instead of the + one user provided for us. */ + silc_free(conn->sock->hostname); + conn->sock->hostname = strdup(conn->remote_host); if (!conn->sock->ip) conn->sock->ip = strdup(conn->remote_host); conn->sock->port = conn->remote_port; @@ -455,6 +457,8 @@ SILC_TASK_CALLBACK(silc_client_connect_failure) SilcClient client = (SilcClient)ctx->client; client->internal->ops->connect(client, ctx->sock->user_data, FALSE); + if (ctx->packet) + silc_packet_context_free(ctx->packet); silc_free(ctx); } @@ -607,8 +611,7 @@ void silc_client_resolve_auth_method(bool success, proto_ctx->auth_meth = auth_meth; if (auth_data && auth_data_len) { - proto_ctx->auth_data = silc_calloc(auth_data_len, sizeof(*auth_data)); - memcpy(proto_ctx->auth_data, auth_data, auth_data_len); + proto_ctx->auth_data = silc_memdup(auth_data, auth_data_len); proto_ctx->auth_data_len = auth_data_len; } @@ -1056,7 +1059,8 @@ void silc_client_packet_parse_type(SilcClient client, if (proto_ctx->packet) silc_packet_context_free(proto_ctx->packet); - + if (proto_ctx->dest_id) + silc_free(proto_ctx->dest_id); proto_ctx->packet = silc_packet_context_dup(packet); proto_ctx->dest_id_type = packet->src_id_type; proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len, @@ -1365,13 +1369,14 @@ void silc_client_close_connection(SilcClient client, /* Clear ID caches */ if (conn->client_cache) - silc_idcache_del_all(conn->client_cache); + silc_idcache_free(conn->client_cache); if (conn->channel_cache) - silc_idcache_del_all(conn->channel_cache); + silc_idcache_free(conn->channel_cache); if (conn->server_cache) - silc_idcache_del_all(conn->server_cache); + silc_idcache_free(conn->server_cache); - /* Free data (my ID is freed in above silc_client_del_client) */ + /* Free data (my ID is freed in above silc_client_del_client). + conn->nickname is freed when freeing the local_entry->nickname. */ if (conn->remote_host) silc_free(conn->remote_host); if (conn->local_id_data) @@ -1432,8 +1437,7 @@ void silc_client_disconnected_by_server(SilcClient client, SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock)); - msg = silc_calloc(message->len + 1, sizeof(char)); - memcpy(msg, message->data, message->len); + msg = silc_memdup(message->data, message->len); client->internal->ops->say(client, sock->user_data, SILC_CLIENT_MESSAGE_AUDIT, msg); silc_free(msg); @@ -1456,13 +1460,24 @@ void silc_client_error_by_server(SilcClient client, { char *msg; - msg = silc_calloc(message->len + 1, sizeof(char)); - memcpy(msg, message->data, message->len); + msg = silc_memdup(message->data, message->len); client->internal->ops->say(client, sock->user_data, SILC_CLIENT_MESSAGE_AUDIT, msg); silc_free(msg); } +/* Auto-nicking callback to send NICK command to server. */ + +SILC_TASK_CALLBACK(silc_client_send_auto_nick) +{ + SilcClientConnection conn = (SilcClientConnection)context; + SilcClient client = conn->client; + + silc_client_command_send(client, conn, SILC_COMMAND_NICK, + ++conn->cmd_ident, 1, 1, + client->nickname, strlen(client->nickname)); +} + /* Processes the received new Client ID from server. Old Client ID is deleted from cache and new one is added. */ @@ -1507,21 +1522,27 @@ void silc_client_receive_new_id(SilcClient client, conn->local_entry->username = strdup(client->username); if (!conn->local_entry->hostname) conn->local_entry->hostname = strdup(client->hostname); - conn->local_entry->server = strdup(conn->remote_host); + if (!conn->local_entry->server) + conn->local_entry->server = strdup(conn->remote_host); conn->local_entry->id = conn->local_id; conn->local_entry->valid = TRUE; - + if (!conn->local_entry->channels) + conn->local_entry->channels = silc_hash_table_alloc(1, silc_hash_ptr, + NULL, NULL, + NULL, NULL, NULL, + TRUE); + /* Put it to the ID cache */ silc_idcache_add(conn->client_cache, strdup(conn->nickname), conn->local_id, (void *)conn->local_entry, 0, NULL); if (connecting) { /* Send NICK command if the nickname was set by the application (and is - not same as the username). */ + not same as the username). Send this with little timeout. */ if (client->nickname && strcmp(client->nickname, client->username)) - silc_client_command_send(client, conn, SILC_COMMAND_NICK, - ++conn->cmd_ident, 1, 1, - client->nickname, strlen(client->nickname)); + silc_schedule_task_add(client->schedule, 0, + silc_client_send_auto_nick, conn, + 1, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); /* Issue INFO command to fetch the real server name and server information and other stuff. */ @@ -1539,73 +1560,23 @@ void silc_client_receive_new_id(SilcClient client, } } -/* Processed received Channel ID for a channel. This is called when client - joins to channel and server replies with channel ID. The ID is cached. - Returns the created channel entry. This is also called when received - channel ID in for example USERS command reply that we do not have. */ - -SilcChannelEntry silc_client_new_channel_id(SilcClient client, - SilcSocketConnection sock, - char *channel_name, - uint32 mode, - SilcIDPayload idp) -{ - SilcClientConnection conn = (SilcClientConnection)sock->user_data; - SilcChannelEntry channel; - - SILC_LOG_DEBUG(("New channel ID")); - - channel = silc_calloc(1, sizeof(*channel)); - channel->channel_name = channel_name; - channel->id = silc_id_payload_get_id(idp); - channel->mode = mode; - silc_list_init(channel->clients, struct SilcChannelUserStruct, next); - - /* Put it to the ID cache */ - silc_idcache_add(conn->channel_cache, channel->channel_name, - (void *)channel->id, (void *)channel, 0, NULL); - - return channel; -} - -/* Removes a client entry from all channel it has joined. This really is - a performance killer (client_entry should have pointers to channel - entry list). */ +/* Removes a client entry from all channels it has joined. */ void silc_client_remove_from_channels(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry) { - SilcIDCacheEntry id_cache; - SilcIDCacheList list; - SilcChannelEntry channel; + SilcHashTableList htl; SilcChannelUser chu; - if (!silc_idcache_get_all(conn->channel_cache, &list)) - return; - - silc_idcache_list_first(list, &id_cache); - channel = (SilcChannelEntry)id_cache->context; - - while (channel) { - - /* Remove client from channel */ - silc_list_start(channel->clients); - while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) { - if (chu->client == client_entry) { - silc_list_del(channel->clients, chu); - silc_free(chu); - break; - } - } - - if (!silc_idcache_list_next(list, &id_cache)) - break; - - channel = (SilcChannelEntry)id_cache->context; + silc_hash_table_list(client_entry->channels, &htl); + while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { + silc_hash_table_del(chu->client->channels, chu->channel); + silc_hash_table_del(chu->channel->user_list, chu->client); + silc_free(chu); } - silc_idcache_list_free(list); + silc_hash_table_list_reset(&htl); } /* Replaces `old' client entries from all channels to `new' client entry. @@ -1618,35 +1589,20 @@ void silc_client_replace_from_channels(SilcClient client, SilcClientEntry old, SilcClientEntry new) { - SilcIDCacheEntry id_cache; - SilcIDCacheList list; - SilcChannelEntry channel; + SilcHashTableList htl; SilcChannelUser chu; - if (!silc_idcache_get_all(conn->channel_cache, &list)) - return; - - silc_idcache_list_first(list, &id_cache); - channel = (SilcChannelEntry)id_cache->context; - - while (channel) { - + silc_hash_table_list(old->channels, &htl); + while (silc_hash_table_get(&htl, NULL, (void *)&chu)) { /* Replace client entry */ - silc_list_start(channel->clients); - while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) { - if (chu->client == old) { - chu->client = new; - break; - } - } - - if (!silc_idcache_list_next(list, &id_cache)) - break; + silc_hash_table_del(chu->client->channels, chu->channel); + silc_hash_table_del(chu->channel->user_list, chu->client); - channel = (SilcChannelEntry)id_cache->context; + chu->client = new; + silc_hash_table_add(chu->channel->user_list, chu->client, chu); + silc_hash_table_add(chu->client->channels, chu->channel, chu); } - - silc_idcache_list_free(list); + silc_hash_table_list_reset(&htl); } /* Registers failure timeout to process the received failure packet