res->context = client;
res->sock = silc_socket_dup(conn->sock);
- silc_client_send_command(client, conn, SILC_COMMAND_WHOIS, ++conn->cmd_ident,
+ silc_client_command_register(client, SILC_COMMAND_WHOIS, NULL, NULL,
+ silc_client_command_reply_whois_i, 0,
+ ++conn->cmd_ident);
+ silc_client_command_send(client, conn, SILC_COMMAND_WHOIS, conn->cmd_ident,
1, 3, idp->data, idp->len);
silc_client_command_pending(conn, SILC_COMMAND_WHOIS, conn->cmd_ident,
silc_client_notify_by_server_destructor,
unsigned char *tmp;
uint32 tmp_len, mode;
- payload = silc_notify_payload_parse(buffer);
+ SILC_LOG_DEBUG(("Start"));
+
+ payload = silc_notify_payload_parse(buffer->data, buffer->len);
if (!payload)
goto out;
switch(type) {
case SILC_NOTIFY_TYPE_NONE:
/* Notify application */
- client->ops->notify(client, conn, type,
- silc_argument_get_arg_type(args, 1, NULL));
+ client->internal->ops->notify(client, conn, type,
+ silc_argument_get_arg_type(args, 1, NULL));
break;
case SILC_NOTIFY_TYPE_INVITE:
* for the application.
*/
+ SILC_LOG_DEBUG(("Notify: INVITE"));
+
/* Get Channel ID */
tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
if (!tmp)
goto out;
/* Notify application */
- client->ops->notify(client, conn, type, channel, tmp, client_entry);
+ client->internal->ops->notify(client, conn, type, channel, tmp,
+ client_entry);
break;
case SILC_NOTIFY_TYPE_JOIN:
* cache them for later use.
*/
+ SILC_LOG_DEBUG(("Notify: JOIN"));
+
/* Get Client ID */
tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
if (!tmp)
client_entry->status |= SILC_CLIENT_STATUS_RESOLVING;
silc_client_notify_by_server_resolve(client, conn, packet, client_id);
goto out;
+ } else {
+ if (client_entry != conn->local_entry)
+ silc_client_nickname_format(client, conn, client_entry);
}
/* Get Channel ID */
/* Notify application. The channel entry is sent last as this notify
is for channel but application don't know it from the arguments
sent by server. */
- client->ops->notify(client, conn, type, client_entry, channel);
+ client->internal->ops->notify(client, conn, type, client_entry, channel);
break;
case SILC_NOTIFY_TYPE_LEAVE:
* we'll keep it in the cache in case we'll need it later.
*/
+ SILC_LOG_DEBUG(("Notify: LEAVE"));
+
/* Get Client ID */
tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
if (!tmp)
/* Notify application. The channel entry is sent last as this notify
is for channel but application don't know it from the arguments
sent by server. */
- client->ops->notify(client, conn, type, client_entry, channel);
+ client->internal->ops->notify(client, conn, type, client_entry, channel);
break;
case SILC_NOTIFY_TYPE_SIGNOFF:
* Someone left SILC. We'll remove it from all channels and from cache.
*/
+ SILC_LOG_DEBUG(("Notify: SIGNOFF"));
+
/* Get Client ID */
tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
if (!tmp)
tmp = NULL;
/* Notify application */
- client->ops->notify(client, conn, type, client_entry, tmp);
+ client->internal->ops->notify(client, conn, type, client_entry, tmp);
/* Free data */
silc_client_del_client_entry(client, conn, client_entry);
* Someone set the topic on a channel.
*/
+ SILC_LOG_DEBUG(("Notify: TOPIC_SET"));
+
/* Get Client ID */
tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
if (!tmp)
goto out;
- client_id = silc_id_payload_parse_id(tmp, tmp_len);
- if (!client_id)
+ idp = silc_id_payload_parse(tmp, tmp_len);
+ if (!idp)
goto out;
/* Find Client entry */
- client_entry =
- silc_client_get_client_by_id(client, conn, client_id);
- if (!client_entry)
- goto out;
+ if (silc_id_payload_get_type(idp) == SILC_ID_CLIENT) {
+ client_id = silc_id_payload_parse_id(tmp, tmp_len);
+ if (!client_id) {
+ silc_id_payload_free(idp);
+ goto out;
+ }
+
+ /* Find Client entry */
+ client_entry =
+ silc_client_get_client_by_id(client, conn, client_id);
+ if (!client_entry)
+ goto out;
+ } else if (silc_id_payload_get_type(idp) == SILC_ID_SERVER) {
+ server_id = silc_id_payload_parse_id(tmp, tmp_len);
+ if (!server_id) {
+ silc_id_payload_free(idp);
+ goto out;
+ }
+
+ server = silc_client_get_server_by_id(client, conn, server_id);
+ if (!server) {
+ silc_id_payload_free(idp);
+ silc_free(server_id);
+ goto out;
+ }
+
+ /* Save the pointer to the client_entry pointer */
+ client_entry = (SilcClientEntry)server;
+ silc_free(server_id);
+ } else {
+ channel_id = silc_id_payload_parse_id(tmp, tmp_len);
+ if (!channel_id) {
+ silc_id_payload_free(idp);
+ goto out;
+ }
+
+ channel = silc_client_get_channel_by_id(client, conn, channel_id);
+ if (!channel) {
+ silc_id_payload_free(idp);
+ silc_free(channel_id);
+ goto out;
+ }
+
+ /* Save the pointer to the client_entry pointer */
+ client_entry = (SilcClientEntry)channel;
+ silc_free(channel_id);
+ }
/* Get topic */
tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
/* Notify application. The channel entry is sent last as this notify
is for channel but application don't know it from the arguments
sent by server. */
- client->ops->notify(client, conn, type, client_entry, tmp, channel);
+ client->internal->ops->notify(client, conn, type,
+ silc_id_payload_get_type(idp),
+ client_entry, tmp, channel);
+
+ silc_id_payload_free(idp);
break;
case SILC_NOTIFY_TYPE_NICK_CHANGE:
* application.
*/
+ SILC_LOG_DEBUG(("Notify: NICK_CHANGE"));
+
/* Get old Client ID */
tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
if (!tmp)
if (!client_entry2) {
silc_client_notify_by_server_resolve(client, conn, packet, client_id);
goto out;
+ } else {
+ if (client_entry2 != conn->local_entry)
+ silc_client_nickname_format(client, conn, client_entry2);
}
/* Remove the old from cache */
client_entry2);
/* Notify application */
- client->ops->notify(client, conn, type, client_entry, client_entry2);
+ client->internal->ops->notify(client, conn, type,
+ client_entry, client_entry2);
/* Free data */
silc_client_del_client_entry(client, conn, client_entry);
* Someone changed a channel mode
*/
+ SILC_LOG_DEBUG(("Notify: CMODE_CHANGE"));
+
/* Get Client ID */
tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
if (!tmp)
goto out;
- idp = silc_id_payload_parse_data(tmp, tmp_len);
+ idp = silc_id_payload_parse(tmp, tmp_len);
if (!idp)
goto out;
/* Notify application. The channel entry is sent last as this notify
is for channel but application don't know it from the arguments
sent by server. */
- client->ops->notify(client, conn, type, silc_id_payload_get_type(idp),
- client_entry, mode, NULL, tmp, channel);
+ client->internal->ops->notify(client, conn, type,
+ silc_id_payload_get_type(idp),
+ client_entry, mode, NULL, tmp, channel);
silc_id_payload_free(idp);
break;
* Someone changed user's mode on a channel
*/
+ SILC_LOG_DEBUG(("Notify: CUMODE_CHANGE"));
+
/* Get Client ID */
tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
if (!tmp)
/* Notify application. The channel entry is sent last as this notify
is for channel but application don't know it from the arguments
sent by server. */
- client->ops->notify(client, conn, type, client_entry, mode,
- client_entry2, channel);
+ client->internal->ops->notify(client, conn, type,
+ client_entry, mode,
+ client_entry2, channel);
break;
case SILC_NOTIFY_TYPE_MOTD:
* Received Message of the day
*/
+ SILC_LOG_DEBUG(("Notify: MOTD"));
+
/* Get motd */
tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
if (!tmp)
goto out;
/* Notify application */
- client->ops->notify(client, conn, type, tmp);
+ client->internal->ops->notify(client, conn, type, tmp);
break;
case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
* ID to the one provided here.
*/
+ SILC_LOG_DEBUG(("Notify: CHANNEL_CHANGE"));
+
/* Get the old ID */
tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
if (!tmp)
SILC_LOG_DEBUG(("Old Channel ID id(%s)",
silc_id_render(channel->id, SILC_ID_CHANNEL)));
+ /* Remove the old channel entry */
+ silc_idcache_del_by_context(conn->channel_cache, channel);
+
/* Free the old ID */
silc_free(channel->id);
SILC_LOG_DEBUG(("New Channel ID id(%s)",
silc_id_render(channel->id, SILC_ID_CHANNEL)));
- /* Remove the old cache entry and create a new one */
- silc_idcache_del_by_context(conn->channel_cache, channel);
+ /* Add the channel entry again to ID cache */
silc_idcache_add(conn->channel_cache, channel->channel_name,
- channel->id, channel, FALSE);
+ channel->id, channel, 0, NULL);
/* Notify application */
- client->ops->notify(client, conn, type, channel, channel);
+ client->internal->ops->notify(client, conn, type, channel, channel);
break;
case SILC_NOTIFY_TYPE_KICKED:
* A client (maybe me) was kicked from a channel
*/
+ SILC_LOG_DEBUG(("Notify: KICKED"));
+
/* Get Client ID */
tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
if (!tmp)
if (!channel_id)
goto out;
if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id,
- &id_cache))
+ &id_cache))
break;
channel = (SilcChannelEntry)id_cache->context;
+ /* Get the kicker */
+ tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
+ if (!tmp)
+ goto out;
+
+ client_id = silc_id_payload_parse_id(tmp, tmp_len);
+ if (!client_id)
+ goto out;
+
+ /* Find kicker's client entry and if not found resolve it */
+ client_entry2 = silc_client_get_client_by_id(client, conn, client_id);
+ if (!client_entry2) {
+ silc_client_notify_by_server_resolve(client, conn, packet, client_id);
+ goto out;
+ } else {
+ if (client_entry2 != conn->local_entry)
+ silc_client_nickname_format(client, conn, client_entry2);
+ }
+
/* Get comment */
tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
/* Notify application. The channel entry is sent last as this notify
is for channel but application don't know it from the arguments
sent by server. */
- client->ops->notify(client, conn, type, client_entry, tmp, channel);
+ client->internal->ops->notify(client, conn, type, client_entry, tmp,
+ client_entry2, channel);
/* If I was kicked from channel, remove the channel */
if (client_entry == conn->local_entry) {
* A client (maybe me) was killed from the network.
*/
+ SILC_LOG_DEBUG(("Notify: KILLED"));
+
/* Get Client ID */
tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
if (!tmp)
tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
/* Notify application. */
- client->ops->notify(client, conn, type, client_entry, tmp);
+ client->internal->ops->notify(client, conn, type, client_entry, tmp);
if (client_entry != conn->local_entry) {
/* Remove client from all channels */
uint32 clients_count = 0;
int i;
+ SILC_LOG_DEBUG(("Notify: SIGNOFF"));
+
for (i = 1; i < silc_argument_get_arg_num(args); i++) {
/* Get Client ID */
tmp = silc_argument_get_arg_type(args, i + 1, &tmp_len);
/* Notify application. We don't keep server entries so the server
entry is returned as NULL. The client's are returned as array
of SilcClientEntry pointers. */
- client->ops->notify(client, conn, type, NULL, clients, clients_count);
+ client->internal->ops->notify(client, conn, type, NULL,
+ clients, clients_count);
for (i = 0; i < clients_count; i++) {
/* Remove client from all channels */