Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2001 - 2007 Pekka Riikonen
+ Copyright (C) 2001 - 2014 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
/* Take all without any further checking */
while ((id_cache = silc_list_get(list))) {
entry = id_cache->context;
+ if (!entry)
+ continue;
if (!get_valid || entry->internal.valid) {
silc_client_ref_client(client, conn, id_cache->context);
silc_dlist_add(clients, id_cache->context);
/* Check multiple cache entries for exact match */
while ((id_cache = silc_list_get(list))) {
entry = id_cache->context;
+ if (!entry)
+ continue;
/* If server was provided, find entries that either have no server
set or have the same server. Ignore those that have different
client_entry->server, sizeof(client_entry->server));
if (nickname && client->internal->params->full_nicknames)
silc_snprintf(client_entry->nickname, sizeof(client_entry->nickname),
- nickname);
+ "%s", nickname);
else if (nickname)
silc_snprintf(client_entry->nickname, sizeof(client_entry->nickname),
- parsed);
+ "%s", parsed);
silc_parse_userfqdn(username, client_entry->username,
sizeof(client_entry->username),
NULL, NULL, NULL, TRUE);
if (!client_entry->channels) {
silc_free(client_entry->realname);
+ silc_atomic_uninit32(&client_entry->internal.deleted);
+ silc_atomic_uninit32(&client_entry->internal.refcnt);
+ silc_rwlock_free(client_entry->internal.lock);
silc_free(client_entry);
return NULL;
}
nick = silc_identifier_check(parsed, strlen(parsed),
SILC_STRING_UTF8, 128, NULL);
if (!nick) {
- silc_free(client_entry->realname);
silc_hash_table_free(client_entry->channels);
+ silc_free(client_entry->realname);
+ silc_atomic_uninit32(&client_entry->internal.deleted);
+ silc_atomic_uninit32(&client_entry->internal.refcnt);
+ silc_rwlock_free(client_entry->internal.lock);
silc_free(client_entry);
return NULL;
}
if (!silc_idcache_add(conn->internal->client_cache, nick,
&client_entry->id, client_entry)) {
silc_free(nick);
- silc_free(client_entry->realname);
silc_hash_table_free(client_entry->channels);
+ silc_free(client_entry->realname);
+ silc_atomic_uninit32(&client_entry->internal.deleted);
+ silc_atomic_uninit32(&client_entry->internal.refcnt);
+ silc_rwlock_free(client_entry->internal.lock);
silc_free(client_entry);
silc_mutex_unlock(conn->internal->lock);
return NULL;
client_entry->server, sizeof(client_entry->server));
if (client->internal->params->full_nicknames)
silc_snprintf(client_entry->nickname, sizeof(client_entry->nickname),
- nickname);
+ "%s", nickname);
else
silc_snprintf(client_entry->nickname, sizeof(client_entry->nickname),
- parsed);
+ "%s", parsed);
/* Normalize nickname */
nick = silc_identifier_check(parsed, strlen(parsed),
if (client_entry->internal.hmac_receive)
silc_hmac_free(client_entry->internal.hmac_receive);
silc_client_ftp_session_free_client(client, client_entry);
+ if (client_entry->internal.op)
+ silc_async_abort(client_entry->internal.op, NULL, NULL);
+ client_entry->internal.op = NULL;
if (client_entry->internal.ke)
silc_client_abort_key_agreement(client, conn, client_entry);
silc_atomic_uninit32(&client_entry->internal.deleted);
if (!client_entry)
return FALSE;
- SILC_LOG_DEBUG(("Marking client entry %p deleted"));
+ SILC_LOG_DEBUG(("Marking client entry %p deleted", client_entry));
if (silc_atomic_sub_int32(&client_entry->internal.deleted, 1) != 0) {
- SILC_LOG_DEBUG(("Client entry %p already marked deleted"));
+ SILC_LOG_DEBUG(("Client entry %p already marked deleted", client_entry));
return FALSE;
}
+ /* Abort ongoing operation */
+ if (client_entry->internal.op) {
+ SILC_LOG_DEBUG(("Aborting ongoing operation %p",
+ client_entry->internal.op));
+ silc_async_abort(client_entry->internal.op, NULL, NULL);
+ client_entry->internal.op = NULL;
+ }
+
silc_client_unref_client(client, conn, client_entry);
return TRUE;
}
return NULL;
silc_snprintf(client_entry->nickname, sizeof(client_entry->nickname),
- cp);
+ "%s", cp);
silc_free(cp);
}
if (!channel->channel_name) {
silc_rwlock_free(channel->internal.lock);
silc_atomic_uninit32(&channel->internal.refcnt);
+ silc_atomic_uninit32(&channel->internal.deleted);
silc_free(channel);
return NULL;
}
if (!channel->user_list) {
silc_rwlock_free(channel->internal.lock);
silc_atomic_uninit32(&channel->internal.refcnt);
+ silc_atomic_uninit32(&channel->internal.deleted);
silc_free(channel->channel_name);
silc_free(channel);
return NULL;
if (!channel_namec) {
silc_rwlock_free(channel->internal.lock);
silc_atomic_uninit32(&channel->internal.refcnt);
+ silc_atomic_uninit32(&channel->internal.deleted);
silc_free(channel->channel_name);
silc_hash_table_free(channel->user_list);
silc_free(channel);
&channel->id, channel)) {
silc_rwlock_free(channel->internal.lock);
silc_atomic_uninit32(&channel->internal.refcnt);
+ silc_atomic_uninit32(&channel->internal.deleted);
silc_free(channel_namec);
silc_free(channel->channel_name);
silc_hash_table_free(channel->user_list);
if (!channel)
return FALSE;
- SILC_LOG_DEBUG(("Marking channel entry %p deleted"));
+ SILC_LOG_DEBUG(("Marking channel entry %p deleted", channel));
if (silc_atomic_sub_int32(&channel->internal.deleted, 1) != 0) {
- SILC_LOG_DEBUG(("Channel entry %p already marked deleted"));
+ SILC_LOG_DEBUG(("Channel entry %p already marked deleted", channel));
return FALSE;
}
silc_rwlock_alloc(&server_entry->internal.lock);
silc_atomic_init32(&server_entry->internal.refcnt, 0);
+ silc_atomic_init32(&server_entry->internal.deleted, 1);
server_entry->id = *server_id;
if (server_name)
server_entry->server_name = strdup(server_name);
if (!server_namec) {
silc_free(server_entry->server_name);
silc_free(server_entry->server_info);
+ silc_atomic_uninit32(&server_entry->internal.deleted);
+ silc_atomic_uninit32(&server_entry->internal.refcnt);
+ silc_rwlock_free(server_entry->internal.lock);
silc_free(server_entry);
return NULL;
}
silc_free(server_namec);
silc_free(server_entry->server_name);
silc_free(server_entry->server_info);
+ silc_atomic_uninit32(&server_entry->internal.deleted);
+ silc_atomic_uninit32(&server_entry->internal.refcnt);
+ silc_rwlock_free(server_entry->internal.lock);
silc_free(server_entry);
silc_mutex_unlock(conn->internal->lock);
return NULL;
return FALSE;
if (silc_atomic_sub_int32(&server->internal.deleted, 1) != 0)
- {
- SILC_LOG_DEBUG(("** WARNING ** Deleting a server twice %p", server));
-// asm("int3");
- return FALSE;
- }
+ return FALSE;
silc_client_unref_server(client, conn, server);
return TRUE;
void silc_client_unref_server(SilcClient client, SilcClientConnection conn,
SilcServerEntry server_entry)
{
- SilcBool ret;
SilcIDCacheEntry id_cache;
char *namec;
if (silc_idcache_find_by_context(conn->internal->server_cache, server_entry,
&id_cache)) {
namec = id_cache->name;
- ret = silc_idcache_del_by_context(conn->internal->server_cache,
- server_entry, NULL);
+ silc_idcache_del_by_context(conn->internal->server_cache,
+ server_entry, NULL);
silc_free(namec);
}
silc_mutex_unlock(conn->internal->lock);
silc_free(server_entry->server_info);
if (server_entry->public_key)
silc_pkcs_public_key_free(server_entry->public_key);
+ silc_atomic_uninit32(&server_entry->internal.deleted);
silc_atomic_uninit32(&server_entry->internal.refcnt);
silc_rwlock_free(server_entry->internal.lock);
silc_free(server_entry);