X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilcclient%2Fclient_entry.c;h=0c812de00adbd6bec3672098d5b4565e334c52f3;hp=c59a48fd3e4992008c26ed4a53cea0323688f2b5;hb=52e57c880aba9c5e89f59d962eb9af75670b76e0;hpb=ae1482a76c29db9fdcd6ed6cf63d312a37a5cb01 diff --git a/lib/silcclient/client_entry.c b/lib/silcclient/client_entry.c index c59a48fd..0c812de0 100644 --- a/lib/silcclient/client_entry.c +++ b/lib/silcclient/client_entry.c @@ -72,19 +72,23 @@ SilcDList silc_client_get_clients_local_ext(SilcClient client, SilcList list; SilcDList clients; SilcClientEntry entry; - char *nicknamec, *parsed = NULL, *format = NULL; + char nick[128 + 1], *nicknamec, *parsed = NULL, *format = NULL; + char server[256 + 1]; if (!client || !conn || !nickname) return NULL; + /* Get nickname from nickname@server string */ + silc_parse_userfqdn(nickname, nick, sizeof(nick), server, sizeof(server)); + /* Parse nickname in case it is formatted */ - if (!silc_client_nickname_parse(client, conn, (char *)nickname, &parsed)) + if (!silc_client_nickname_parse(client, conn, (char *)nick, &parsed)) return NULL; if (!get_all && parsed) - format = (char *)nickname; + format = (char *)nick; if (!parsed) { - parsed = silc_memdup(nickname, strlen(nickname)); + parsed = silc_memdup(nick, strlen(nick)); if (!parsed) return NULL; } @@ -133,6 +137,14 @@ SilcDList silc_client_get_clients_local_ext(SilcClient client, /* Check multiple cache entries for exact match */ while ((id_cache = silc_list_get(list))) { entry = id_cache->context; + + /* If server was provided, find entries that either have no server + set or have the same server. Ignore those that have different + server. */ + if (server[0] && entry->server && + !silc_utf8_strcasecmp(entry->server, server)) + continue; + if (silc_utf8_strcasecmp(entry->nickname, format ? format : parsed) && (!get_valid || entry->internal.valid)) { @@ -340,7 +352,7 @@ static SilcUInt16 silc_client_get_clients_i(SilcClient client, /* Parse server name from the nickname if set */ if (silc_parse_userfqdn(nickname, nick, sizeof(nick), - serv, sizeof(serv) == 2)) + serv, sizeof(serv)) == 2) server = (const char *)serv; nickname = (const char *)nick; @@ -769,7 +781,7 @@ SilcClientEntry silc_client_add_client(SilcClient client, SilcUInt32 mode) { SilcClientEntry client_entry; - char *nick = NULL; + char *nick = NULL, parsed[128 + 1]; SILC_LOG_DEBUG(("Adding new client entry")); @@ -783,14 +795,21 @@ SilcClientEntry silc_client_add_client(SilcClient client, client_entry->id = *id; client_entry->mode = mode; client_entry->realname = userinfo ? strdup(userinfo) : NULL; - silc_parse_userfqdn(nickname, client_entry->nickname, - sizeof(client_entry->nickname), - client_entry->server, - sizeof(client_entry->server)); + + silc_parse_userfqdn(nickname, parsed, sizeof(parsed), + client_entry->server, sizeof(client_entry->server)); + if (nickname && client->internal->params->full_nicknames) + silc_snprintf(client_entry->nickname, sizeof(client_entry->nickname), + nickname); + else if (nickname) + silc_snprintf(client_entry->nickname, sizeof(client_entry->nickname), + parsed); + silc_parse_userfqdn(username, client_entry->username, sizeof(client_entry->username), client_entry->hostname, sizeof(client_entry->hostname)); + client_entry->channels = silc_hash_table_alloc(1, silc_hash_ptr, NULL, NULL, NULL, NULL, NULL, TRUE); if (!client_entry->channels) { @@ -801,8 +820,7 @@ SilcClientEntry silc_client_add_client(SilcClient client, /* Normalize nickname */ if (client_entry->nickname[0]) { - nick = silc_identifier_check(client_entry->nickname, - strlen(client_entry->nickname), + nick = silc_identifier_check(parsed, strlen(parsed), SILC_STRING_UTF8, 128, NULL); if (!nick) { silc_free(client_entry->realname); @@ -852,7 +870,7 @@ void silc_client_update_client(SilcClient client, const char *userinfo, SilcUInt32 mode) { - char *nick = NULL; + char *nick = NULL, parsed[128 + 1]; SILC_LOG_DEBUG(("Update client entry")); @@ -860,20 +878,25 @@ void silc_client_update_client(SilcClient client, if (!client_entry->realname && userinfo) client_entry->realname = strdup(userinfo); + if ((!client_entry->username[0] || !client_entry->hostname[0]) && username) silc_parse_userfqdn(username, client_entry->username, sizeof(client_entry->username), client_entry->hostname, sizeof(client_entry->username)); + if (!client_entry->nickname[0] && nickname) { - silc_parse_userfqdn(nickname, client_entry->nickname, - sizeof(client_entry->nickname), - client_entry->server, - sizeof(client_entry->server)); + silc_parse_userfqdn(nickname, parsed, sizeof(parsed), + client_entry->server, sizeof(client_entry->server)); + if (client->internal->params->full_nicknames) + silc_snprintf(client_entry->nickname, sizeof(client_entry->nickname), + nickname); + else + silc_snprintf(client_entry->nickname, sizeof(client_entry->nickname), + parsed); /* Normalize nickname */ - nick = silc_identifier_check(client_entry->nickname, - strlen(client_entry->nickname), + nick = silc_identifier_check(parsed, strlen(parsed), SILC_STRING_UTF8, 128, NULL); if (!nick) { silc_rwlock_unlock(client_entry->internal.lock); @@ -1125,7 +1148,8 @@ SilcClientEntry silc_client_nickname_format(SilcClient client, } /* Is the requested client formatted already */ - if (!silc_utf8_strcasecmp(client_entry->nickname, + if (client_entry->nickname_normalized && + !silc_utf8_strcasecmp(client_entry->nickname, client_entry->nickname_normalized)) formatted = TRUE; @@ -1142,7 +1166,7 @@ SilcClientEntry silc_client_nickname_format(SilcClient client, unformatted = entry; break; } - } + } /* If there are no other unformatted clients and the requested client is unformatted, just return it. */ @@ -1151,7 +1175,7 @@ SilcClientEntry silc_client_nickname_format(SilcClient client, return client_entry; } - /* If priority formatting then the requested client will get the + /* If priority formatting then the requested client will get the unformatted nickname, and the unformatted client will get a new formatted nickname. */ if (priority) { @@ -1161,7 +1185,7 @@ SilcClientEntry silc_client_nickname_format(SilcClient client, &cp)) return NULL; - silc_snprintf(client_entry->nickname, sizeof(client_entry->nickname), + silc_snprintf(client_entry->nickname, sizeof(client_entry->nickname), cp); silc_free(cp); } @@ -1344,32 +1368,66 @@ SilcChannelEntry silc_client_get_channel(SilcClient client, SilcClientConnection conn, char *channel) { + SilcList list; SilcIDCacheEntry id_cache; - SilcChannelEntry entry; + SilcChannelEntry entry = NULL; + char chname[256 + 1], server[256 + 1]; if (!client || !conn || !channel) return NULL; SILC_LOG_DEBUG(("Find channel %s", channel)); + /* Parse server name from channel name */ + silc_parse_userfqdn(channel, chname, sizeof(chname), server, sizeof(server)); + /* Normalize name for search */ - channel = silc_channel_name_check(channel, strlen(channel), SILC_STRING_UTF8, + channel = silc_channel_name_check(chname, strlen(chname), SILC_STRING_UTF8, 256, NULL); if (!channel) return NULL; silc_mutex_lock(conn->internal->lock); - if (!silc_idcache_find_by_name_one(conn->internal->channel_cache, channel, - &id_cache)) { + if (!silc_idcache_find_by_name(conn->internal->channel_cache, channel, + &list)) { silc_mutex_unlock(conn->internal->lock); silc_free(channel); return NULL; } - SILC_LOG_DEBUG(("Found")); + /* If server name was specified with channel name, find the correct + channel entry with the server name. There can only be one channel + with same name on same server. */ + silc_list_start(list); + if (server[0]) { + while ((id_cache = silc_list_get(list))) { + entry = id_cache->context; + if (!entry->server[0]) + continue; + if (silc_utf8_strcasecmp(entry->server, server)) + break; + } + } else { + /* Get first channel without server name specified or one with our + current server connection name */ + while ((id_cache = silc_list_get(list))) { + entry = id_cache->context; + if (!entry->server[0]) + break; + if (silc_utf8_strcasecmp(entry->server, conn->remote_host)) + break; + } + } - entry = id_cache->context; + if (!id_cache) { + silc_mutex_unlock(conn->internal->lock); + silc_free(channel); + return NULL; + } + + SILC_LOG_DEBUG(("Found channel %s%s%s", entry->channel_name, + entry->server[0] ? "@" : "", entry->server)); /* Reference */ silc_client_ref_channel(client, conn, entry); @@ -1558,9 +1616,9 @@ SilcChannelEntry silc_client_add_channel(SilcClient client, SilcChannelID *channel_id) { SilcChannelEntry channel; - char *channel_namec; + char *channel_namec, name[256 + 1]; - SILC_LOG_DEBUG(("Start")); + SILC_LOG_DEBUG(("Adding channel %s", channel_name)); channel = silc_calloc(1, sizeof(*channel)); if (!channel) @@ -1571,8 +1629,16 @@ SilcChannelEntry silc_client_add_channel(SilcClient client, channel->id = *channel_id; channel->mode = mode; - channel->channel_name = strdup(channel_name); + silc_parse_userfqdn(channel_name, name, sizeof(name), + channel->server, sizeof(channel->server)); + if (client->internal->params->full_channel_names) + channel->channel_name = strdup(channel_name); + else + channel->channel_name = strdup(name); + if (!channel->channel_name) { + silc_rwlock_free(channel->internal.lock); + silc_atomic_uninit16(&channel->internal.refcnt); silc_free(channel); return NULL; } @@ -1580,15 +1646,19 @@ SilcChannelEntry silc_client_add_channel(SilcClient client, channel->user_list = silc_hash_table_alloc(1, silc_hash_ptr, NULL, NULL, NULL, NULL, NULL, TRUE); if (!channel->user_list) { + silc_rwlock_free(channel->internal.lock); + silc_atomic_uninit16(&channel->internal.refcnt); silc_free(channel->channel_name); silc_free(channel); return NULL; } /* Normalize channel name */ - channel_namec = silc_channel_name_check(channel_name, strlen(channel_name), + channel_namec = silc_channel_name_check(name, strlen(name), SILC_STRING_UTF8, 256, NULL); if (!channel_namec) { + silc_rwlock_free(channel->internal.lock); + silc_atomic_uninit16(&channel->internal.refcnt); silc_free(channel->channel_name); silc_hash_table_free(channel->user_list); silc_free(channel); @@ -1600,6 +1670,8 @@ SilcChannelEntry silc_client_add_channel(SilcClient client, /* Add channel to cache, the normalized channel name is saved to cache */ if (!silc_idcache_add(conn->internal->channel_cache, channel_namec, &channel->id, channel)) { + silc_rwlock_free(channel->internal.lock); + silc_atomic_uninit16(&channel->internal.refcnt); silc_free(channel_namec); silc_free(channel->channel_name); silc_hash_table_free(channel->user_list); @@ -1622,9 +1694,10 @@ SilcBool silc_client_del_channel(SilcClient client, SilcClientConnection conn, SilcChannelEntry channel) { SilcIDCacheEntry id_cache; - SilcBool ret; + SilcBool ret = TRUE; SilcCipher key; SilcHmac hmac; + char *namec; if (!channel) return FALSE; @@ -1636,10 +1709,12 @@ SilcBool silc_client_del_channel(SilcClient client, SilcClientConnection conn, silc_mutex_lock(conn->internal->lock); if (silc_idcache_find_by_context(conn->internal->channel_cache, channel, - &id_cache)) - silc_free(id_cache->name); - ret = silc_idcache_del_by_context(conn->internal->channel_cache, - channel, NULL); + &id_cache)) { + namec = id_cache->name; + ret = silc_idcache_del_by_context(conn->internal->channel_cache, + channel, NULL); + silc_free(namec); + } silc_mutex_unlock(conn->internal->lock); if (!ret) @@ -2029,7 +2104,8 @@ SilcBool silc_client_del_server(SilcClient client, SilcClientConnection conn, SilcServerEntry server) { SilcIDCacheEntry id_cache; - SilcBool ret; + SilcBool ret = TRUE; + char *namec; if (!server) return FALSE; @@ -2041,10 +2117,12 @@ SilcBool silc_client_del_server(SilcClient client, SilcClientConnection conn, silc_mutex_lock(conn->internal->lock); if (silc_idcache_find_by_context(conn->internal->server_cache, server, - &id_cache)) - silc_free(id_cache->name); - ret = silc_idcache_del_by_context(conn->internal->server_cache, - server, NULL); + &id_cache)) { + namec = id_cache->name; + ret = silc_idcache_del_by_context(conn->internal->server_cache, + server, NULL); + silc_free(namec); + } silc_mutex_unlock(conn->internal->lock); silc_free(server->server_name);