void *callback_context,
void *stream_context)
{
- SilcClient client = callback_context;
SilcClientConnection conn = stream_context;
/* Packets we do not handle */
goto out;
/* Create local client entry */
- conn->local_entry = silc_client_add_client(client, conn, (client->nickname ?
- client->nickname :
- client->username),
+ conn->local_entry = silc_client_add_client(client, conn,
+ (client->nickname ?
+ client->nickname :
+ client->username),
client->username,
client->realname,
&id.u.client_id, 0);
}
}
-/* Processes the received new Client ID from server. Old Client ID is
- deleted from cache and new one is added. */
-
-void silc_client_receive_new_id(SilcClient client,
- SilcClientConnection conn,
- SilcIDPayload idp)
-{
- SilcClientConnection conn = (SilcClientConnection)sock->user_data;
- int connecting = FALSE;
- SilcClientID *client_id = silc_id_payload_get_id(idp);
- char *nickname;
-
- if (!conn->local_entry)
- connecting = TRUE;
-
- /* Delete old ID from ID cache */
- if (conn->local_id) {
- /* Check whether they are different */
- if (SILC_ID_CLIENT_COMPARE(conn->local_id, client_id)) {
- silc_free(client_id);
- return;
- }
-
- silc_idcache_del_by_context(conn->internal->client_cache,
- conn->local_entry);
- silc_free(conn->local_id);
- }
-
- /* Save the new ID */
-
- if (conn->local_id_data)
- silc_free(conn->local_id_data);
-
- conn->local_id = client_id;
- conn->local_id_data = silc_id_payload_get_data(idp);
- conn->local_id_data_len = silc_id_payload_get_len(idp);;
-
- if (!conn->local_entry)
- conn->local_entry = silc_calloc(1, sizeof(*conn->local_entry));
-
- conn->local_entry->nickname = conn->nickname;
- if (!conn->local_entry->username)
- conn->local_entry->username = strdup(client->username);
- 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);
-
- /* Normalize nickname */
- nickname = silc_identifier_check(conn->nickname, strlen(conn->nickname),
- SILC_STRING_UTF8, 128, NULL);
- if (!nickname)
- return;
-
- /* Put it to the ID cache */
- silc_idcache_add(conn->internal->client_cache, nickname, conn->local_id,
- (void *)conn->local_entry, 0, NULL);
-
-#if 0
- if (connecting) {
- SilcBuffer sidp;
-
- /* Issue IDENTIFY command for itself to get resolved hostname
- correctly from server. */
- silc_client_command_register(client, SILC_COMMAND_IDENTIFY, NULL, NULL,
- silc_client_command_reply_identify_i, 0,
- ++conn->cmd_ident);
- sidp = silc_id_payload_encode(conn->local_entry->id, SILC_ID_CLIENT);
- silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY,
- conn->cmd_ident, 1, 5, sidp->data, sidp->len);
- silc_buffer_free(sidp);
-
- if (!conn->internal->params.detach_data) {
- /* Send NICK command if the nickname was set by the application (and is
- not same as the username). Send this with little timeout. */
- if (client->nickname &&
- !silc_utf8_strcasecmp(client->nickname, client->username))
- silc_schedule_task_add(client->schedule, 0,
- silc_client_send_auto_nick, conn,
- 1, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
-
- /* Notify application of successful connection. We do it here now that
- we've received the Client ID and are allowed to send traffic. */
- client->internal->ops->connected(client, conn, SILC_CLIENT_CONN_SUCCESS);
-
- /* Issue INFO command to fetch the real server name and server
- information and other stuff. */
- silc_client_command_register(client, SILC_COMMAND_INFO, NULL, NULL,
- silc_client_command_reply_info_i, 0,
- ++conn->cmd_ident);
- sidp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER);
- silc_client_command_send(client, conn, SILC_COMMAND_INFO,
- conn->cmd_ident, 1, 2, sidp->data, sidp->len);
- silc_buffer_free(sidp);
- } else {
- /* We are resuming session. Start resolving informations from the
- server we need to set the client libary in the state before
- detaching the session. The connect client operation is called
- after this is successfully completed */
- silc_client_resume_session(client, conn, silc_client_resume_session_cb,
- NULL);
- }
- }
-#endif /* 0 */
-}
-
/* Removes a client entry from all channels it has joined. */
void silc_client_remove_from_channels(SilcClient client,
/* Get client entry */
client_entry = silc_client_get_client_by_id(client, conn, &id.u.client_id);
- if (client_entry) {
- silc_client_ref_client(client, conn, client_entry);
+ if (client_entry)
silc_dlist_add(clients, client_entry);
- }
if (!silc_buffer_pull(i->client_id_list, idp_len)) {
status = SILC_STATUS_ERR_BAD_CLIENT_ID;
/* Check if we have this client cached already. If we don't have the
entry or it has incomplete info, then resolve it from the server. */
entry = silc_client_get_client_by_id(client, conn, &id.u.client_id);
- if (!entry || !entry->nickname || !entry->username || !entry->realname) {
+ if (!entry || !entry->nickname[0] || !entry->username[0] ||
+ !entry->realname) {
if (!res_argv) {
res_argv = silc_calloc(list_count, sizeof(*res_argv));
res_argv_lens = silc_calloc(list_count, sizeof(*res_argv_lens));
res_argv_types = silc_calloc(list_count, sizeof(*res_argv_types));
- if (!res_argv || !res_argv_lens || !res_argv_types)
+ if (!res_argv || !res_argv_lens || !res_argv_types) {
+ silc_client_unref_client(client, conn, entry);
goto err;
+ }
}
res_argv[res_argc] = client_id_list->data;
res_argv_types[res_argc] = res_argc + 5;
res_argc++;
}
+ silc_client_unref_client(client, conn, entry);
if (!silc_buffer_pull(client_id_list, idp_len))
goto err;
entry = chu->client;
/* If the entry has incomplete info, then resolve it from the server. */
- if (!entry->nickname || !entry->realname) {
+ if (!entry->nickname[0] || !entry->realname) {
if (entry->status & SILC_CLIENT_STATUS_RESOLVING) {
/* Attach to this resolving and wait until it finishes */
silc_client_command_pending(
void silc_client_unref_client(SilcClient client, SilcClientConnection conn,
SilcClientEntry client_entry)
{
- if (silc_atomic_sub_int8(&client_entry->internal.refcnt, 1) == 0) {
+ if (client_entry &&
+ silc_atomic_sub_int8(&client_entry->internal.refcnt, 1) == 0)
silc_client_del_client(client, conn, client_entry);
- return;
- }
}
/* Free client entry list */
{
SilcClientEntry client_entry;
- silc_dlist_start(client_list);
- while ((client_entry = silc_dlist_get(client_list)))
- silc_client_unref_client(client, conn, client_entry);
+ if (client_list) {
+ silc_dlist_start(client_list);
+ while ((client_entry = silc_dlist_get(client_list)))
+ silc_client_unref_client(client, conn, client_entry);
- silc_dlist_uninit(client_list);
+ silc_dlist_uninit(client_list);
+ }
}
if (!client->internal->params->nickname_format[0])
return;
- if (!client_entry->nickname)
+ if (!client_entry->nickname[0])
return;
/* Get all clients with same nickname. Do not perform the formatting
newnick[off] = 0;
memcpy(client_entry->nickname, newnick, strlen(newnick));
- silc_dlist_uninit(clients);
+ silc_client_list_free(client, conn, clients);
}
SilcPacket packet = state_context;
SilcMessagePayload payload = NULL;
SilcClientID remote_id;
- SilcClientEntry remote_client;
+ SilcClientEntry remote_client = NULL;
SilcMessageFlags flags;
unsigned char *message;
SilcUInt32 message_len;
/* Check whether we know this client already */
remote_client = silc_client_get_client_by_id(client, conn, &remote_id);
- if (!remote_client || !remote_client->nickname) {
+ if (!remote_client || !remote_client->nickname[0]) {
/* Resolve the client info. We return back to packet thread to receive
other packets while we wait for the resolving to finish. */
+ silc_client_unref_client(client, conn, remote_client);
silc_client_get_client_by_id_resolve(client, conn, &remote_id, NULL,
silc_client_private_message_resolved,
packet);
out:
/** Packet processed */
+ silc_client_unref_client(client, conn, remote_client);
if (payload)
silc_message_payload_free(payload);
silc_packet_free(packet);
SilcChannelEntry channel;
SilcBuffer clidp, chidp, args = NULL;
SilcPublicKey pubkey = NULL;
- SilcDList clients;
+ SilcDList clients = NULL;
char *nickname = NULL, *name;
char *invite = NULL;
unsigned char action[1];
cmd));
client_entry = silc_dlist_get(clients);
- silc_dlist_uninit(clients);
} else {
if (cmd->argv[2][0] == '+')
action[0] = 0x00;
silc_buffer_free(chidp);
silc_buffer_free(args);
silc_free(nickname);
+ silc_client_list_free(client, conn, clients);
/* Notify application */
COMMAND(SILC_STATUS_OK);
cmd));
target = silc_dlist_get(clients);
- silc_dlist_uninit(clients);
if (cmd->argc >= 3) {
if (strcasecmp(cmd->argv[2], "-pubkey"))
silc_buffer_free(idp);
silc_buffer_free(auth);
silc_free(nickname);
+ silc_client_list_free(client, conn, clients);
/* Notify application */
COMMAND(SILC_STATUS_OK);
SilcChannelUser chu;
SilcClientEntry client_entry;
SilcBuffer clidp, chidp, auth = NULL;
- SilcDList clients;
+ SilcDList clients = NULL;
unsigned char *name, *cp, modebuf[4];
SilcUInt32 mode = 0, add, len;
char *nickname = NULL;
cmd));
client_entry = silc_dlist_get(clients);
- silc_dlist_uninit(clients);
/* Get the current mode */
chu = silc_client_on_channel(channel, client_entry);
COMMAND(SILC_STATUS_OK);
out:
+ silc_client_list_free(client, conn, clients);
silc_free(nickname);
return SILC_FSM_FINISH;
}
SilcChannelEntry channel;
SilcBuffer idp, idp2;
SilcClientEntry target;
- SilcDList clients;
+ SilcDList clients = NULL;
char *name;
char *nickname = NULL;
goto out;
}
target = silc_dlist_get(clients);
- silc_dlist_uninit(clients);
/* Send KICK command to the server */
idp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
silc_buffer_free(idp);
silc_buffer_free(idp2);
silc_free(nickname);
+ silc_client_list_free(client, conn, clients);
/* Notify application */
COMMAND(SILC_STATUS_OK);
} else {
client_entry = silc_dlist_get(clients);
idp = silc_id_payload_encode(&client_entry->id, SILC_ID_CLIENT);
- silc_dlist_uninit(clients);
+ silc_client_list_free(client, conn, clients);
}
/* Send the commmand */
return;
client_entry = silc_client_get_client_by_id(client, conn, &id.u.client_id);
- if (client_entry)
+ if (client_entry) {
+ silc_client_unref_client(client, conn, client_entry);
silc_client_del_client(client, conn, client_entry);
+ }
}
}
realname, channel_list, mode, idle, fingerprint,
umodes, client_entry->attrs);
+ silc_client_unref_client(client, conn, client_entry);
if (has_channels) {
silc_dlist_uninit(channel_list);
silc_free(umodes);
SilcClient client = conn->client;
SilcCommandPayload payload = state_context;
SilcArgumentPayload args = silc_command_get_args(payload);
- SilcClientEntry client_entry;
+ SilcClientEntry client_entry = NULL;
SilcID id;
char *nickname, *username;
char *realname = NULL;
realname);
out:
+ silc_client_unref_client(client, conn, client_entry);
silc_fsm_next(fsm, silc_client_command_reply_process);
return SILC_FSM_CONTINUE;
}
/* Notify application */
silc_client_command_callback(cmd, client_entry, name, info);
+ silc_client_unref_client(client, conn, client_entry);
break;
case SILC_ID_SERVER:
silc_client_command_callback(cmd, client_entry);
/* Remove the client from all channels and free it */
- if (client_entry)
+ if (client_entry) {
silc_client_del_client(client, conn, client_entry);
+ silc_client_unref_client(client, conn, client_entry);
+ }
out:
silc_fsm_next(fsm, silc_client_command_reply_process);
/* Join client to the channel */
if (!silc_client_on_channel(channel, client_entry)) {
chu = silc_calloc(1, sizeof(*chu));
- if (!chu)
+ if (!chu) {
+ silc_client_unref_client(client, conn, client_entry);
goto out;
+ }
chu->client = client_entry;
chu->channel = channel;
chu->mode = mode;
silc_hash_table_add(channel->user_list, client_entry, chu);
silc_hash_table_add(client_entry->channels, channel, chu);
}
+ silc_client_unref_client(client, conn, client_entry);
- silc_buffer_pull(client_id_list, idp_len);
- silc_buffer_pull(client_mode_list, 4);
+ if (!silc_buffer_pull(client_id_list, idp_len))
+ goto out;
+ if (!silc_buffer_pull(client_mode_list, 4))
+ goto out;
}
silc_buffer_start(client_id_list);
silc_buffer_start(client_mode_list);
/* Notify application */
silc_client_command_callback(cmd, mode, channel, client_entry);
+ silc_client_unref_client(client, conn, client_entry);
+
out:
silc_fsm_next(fsm, silc_client_command_reply_process);
return SILC_FSM_CONTINUE;
/* Notify application */
silc_client_command_callback(cmd, channel, client_entry);
+ silc_client_unref_client(client, conn, client_entry);
+
out:
silc_fsm_next(fsm, silc_client_command_reply_process);
return SILC_FSM_CONTINUE;
client_entry = silc_client_get_client_by_id(client, conn, &id.u.client_id);
if (client_entry && !silc_client_on_channel(channel, client_entry)) {
chu = silc_calloc(1, sizeof(*chu));
- if (!chu)
+ if (!chu) {
+ silc_client_unref_client(client, conn, client_entry);
goto out;
+ }
chu->client = client_entry;
chu->mode = mode;
chu->channel = channel;
silc_hash_table_add(channel->user_list, client_entry, chu);
silc_hash_table_add(client_entry->channels, channel, chu);
}
+ silc_client_unref_client(client, conn, client_entry);
if (!silc_buffer_pull(&client_id_list, idp_len))
goto out;
/* Notify application */
silc_client_command_callback(cmd, SILC_ID_CLIENT, client_entry,
client_entry->public_key);
+ silc_client_unref_client(client, conn, client_entry);
} else if (id.type == SILC_ID_SERVER) {
/* Received server's public key */
server_entry = silc_client_get_server_by_id(client, conn, &id.u.server_id);