From c9f4df48dafd7c9a61d8ca1edaa376be8ecbcf07 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Thu, 30 Nov 2006 14:58:40 +0000 Subject: [PATCH] More client library rewrites. --- lib/silcclient/client_entry.c | 14 ++++++- lib/silcclient/client_notify.c | 72 ++++++++++++++++++---------------- lib/silcclient/command.c | 3 -- lib/silcclient/command_reply.c | 30 +++++++------- 4 files changed, 67 insertions(+), 52 deletions(-) diff --git a/lib/silcclient/client_entry.c b/lib/silcclient/client_entry.c index 58701bce..e8441a69 100644 --- a/lib/silcclient/client_entry.c +++ b/lib/silcclient/client_entry.c @@ -461,7 +461,7 @@ SilcUInt16 silc_client_get_clients_by_list(SilcClient client, res_argv[res_argc] = client_id_list->data; res_argv_lens[res_argc] = idp_len; - res_argv_types[res_argc] = res_argc + 5; + res_argv_types[res_argc] = res_argc + 4; res_argc++; } silc_client_unref_client(client, conn, entry); @@ -692,6 +692,7 @@ SilcClientEntry silc_client_add_client(SilcClient client, if (!client_entry) return NULL; + silc_atomic_init8(&client_entry->internal.refcnt, 0); client_entry->id = *id; client_entry->internal.valid = TRUE; client_entry->mode = mode; @@ -846,6 +847,9 @@ void silc_client_ref_client(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry) { silc_atomic_add_int8(&client_entry->internal.refcnt, 1); + SILC_LOG_DEBUG(("Client %p refcnt %d->%d", client_entry, + silc_atomic_get_int8(&client_entry->internal.refcnt) - 1, + silc_atomic_get_int8(&client_entry->internal.refcnt))); } /* Release reference of client entry */ @@ -853,6 +857,10 @@ void silc_client_ref_client(SilcClient client, SilcClientConnection conn, void silc_client_unref_client(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry) { + if (client_entry) + SILC_LOG_DEBUG(("Client %p refcnt %d->%d", client_entry, + silc_atomic_get_int8(&client_entry->internal.refcnt), + silc_atomic_get_int8(&client_entry->internal.refcnt) - 1)); if (client_entry && silc_atomic_sub_int8(&client_entry->internal.refcnt, 1) == 0) silc_client_del_client(client, conn, client_entry); @@ -929,7 +937,7 @@ void silc_client_nickname_format(SilcClient client, memset(newnick, 0, sizeof(newnick)); cp = client->internal->params->nickname_format; - while (*cp) { + while (cp && *cp) { if (*cp == '%') { cp++; continue; @@ -1256,6 +1264,7 @@ SilcChannelEntry silc_client_add_channel(SilcClient client, if (!channel) return NULL; + silc_atomic_init8(&channel->internal.refcnt, 0); channel->id = *channel_id; channel->mode = mode; @@ -1641,6 +1650,7 @@ SilcServerEntry silc_client_add_server(SilcClient client, if (!server_entry || !server_id) return NULL; + silc_atomic_init8(&server_entry->internal.refcnt, 0); server_entry->id = *server_id; if (server_name) server_entry->server_name = strdup(server_name); diff --git a/lib/silcclient/client_notify.c b/lib/silcclient/client_notify.c index 9087ba35..206425dc 100644 --- a/lib/silcclient/client_notify.c +++ b/lib/silcclient/client_notify.c @@ -285,7 +285,7 @@ SILC_FSM_STATE(silc_client_notify_invite) conn, SILC_COMMAND_NONE, channel->internal.resolve_cmd_ident, silc_client_notify_wait_continue, - fsm)); + notify)); /* NOT REACHED */ } @@ -303,7 +303,7 @@ SILC_FSM_STATE(silc_client_notify_invite) silc_client_get_client_by_id_resolve( client, conn, &id.u.client_id, NULL, silc_client_notify_resolved, - fsm)); + notify)); /* NOT REACHED */ } @@ -353,7 +353,7 @@ SILC_FSM_STATE(silc_client_notify_join) conn, SILC_COMMAND_NONE, channel->internal.resolve_cmd_ident, silc_client_notify_wait_continue, - fsm)); + notify)); /* NOT REACHED */ } @@ -372,7 +372,7 @@ SILC_FSM_STATE(silc_client_notify_join) silc_client_get_client_by_id_resolve( client, conn, &id.u.client_id, NULL, silc_client_notify_resolved, - fsm)); + notify)); /* NOT REACHED */ } @@ -430,7 +430,7 @@ SILC_FSM_STATE(silc_client_notify_leave) conn, SILC_COMMAND_NONE, channel->internal.resolve_cmd_ident, silc_client_notify_wait_continue, - fsm)); + notify)); /* NOT REACHED */ } @@ -573,7 +573,7 @@ SILC_FSM_STATE(silc_client_notify_topic_set) conn, SILC_COMMAND_NONE, channel->internal.resolve_cmd_ident, silc_client_notify_wait_continue, - fsm)); + notify)); /* NOT REACHED */ } @@ -597,7 +597,7 @@ SILC_FSM_STATE(silc_client_notify_topic_set) silc_client_get_client_by_id_resolve( client, conn, &id.u.client_id, NULL, silc_client_notify_resolved, - fsm)); + notify)); /* NOT REACHED */ } entry = client_entry; @@ -611,7 +611,7 @@ SILC_FSM_STATE(silc_client_notify_topic_set) silc_client_get_server_by_id_resolve( client, conn, &id.u.server_id, silc_client_notify_resolved, - fsm)); + notify)); /* NOT REACHED */ } entry = server; @@ -626,7 +626,7 @@ SILC_FSM_STATE(silc_client_notify_topic_set) silc_client_get_channel_by_id_resolve( client, conn, &id.u.channel_id, silc_client_notify_resolved, - fsm)); + notify)); /* NOT REACHED */ } entry = channel_entry; @@ -667,7 +667,7 @@ SILC_FSM_STATE(silc_client_notify_nick_change) SilcClientEntry client_entry = NULL; unsigned char *tmp, *nick, oldnick[128 + 1]; SilcUInt32 tmp_len; - SilcID id; + SilcID id, id2; SILC_LOG_DEBUG(("Notify: NICK_CHANGE")); @@ -680,6 +680,15 @@ SILC_FSM_STATE(silc_client_notify_nick_change) SILC_ID_CLIENT_COMPARE(&id.u.client_id, conn->local_id)) goto out; + /* Get new Client ID */ + if (!silc_argument_get_decoded(args, 2, SILC_ARGUMENT_ID, &id2, NULL)) + goto out; + + /* Ignore my ID */ + if (conn->local_id && + SILC_ID_CLIENT_COMPARE(&id2.u.client_id, conn->local_id)) + goto out; + /* Find old Client entry */ client_entry = silc_client_get_client_by_id(client, conn, &id.u.client_id); if (!client_entry || !client_entry->nickname[0]) { @@ -688,14 +697,10 @@ SILC_FSM_STATE(silc_client_notify_nick_change) SILC_FSM_CALL(silc_client_get_client_by_id_resolve( client, conn, &id.u.client_id, NULL, silc_client_notify_resolved, - fsm)); + notify)); /* NOT REACHED */ } - /* Get new Client ID */ - if (!silc_argument_get_decoded(args, 2, SILC_ARGUMENT_ID, &id, NULL)) - goto out; - /* Take the new nickname */ tmp = silc_argument_get_arg_type(args, 3, &tmp_len); if (!tmp) @@ -704,12 +709,13 @@ SILC_FSM_STATE(silc_client_notify_nick_change) /* Check whether nickname changed at all. It is possible that nick change notify is received but nickname didn't change, only the ID changes. If Client ID hash match, nickname didn't change. */ - if (SILC_ID_COMPARE_HASH(&client_entry->id, &id.u.client_id) && + if (SILC_ID_COMPARE_HASH(&client_entry->id, &id2.u.client_id) && silc_utf8_strcasecmp(tmp, client_entry->nickname)) { /* Nickname didn't change. Update only Client ID. We don't notify application because nickname didn't change. */ silc_idcache_update(conn->internal->client_cache, client_entry, - &client_entry->id, &id.u.client_id, NULL, NULL, FALSE); + &client_entry->id, &id2.u.client_id, NULL, + NULL, FALSE); goto out; } @@ -781,7 +787,7 @@ SILC_FSM_STATE(silc_client_notify_cmode_change) conn, SILC_COMMAND_NONE, channel->internal.resolve_cmd_ident, silc_client_notify_wait_continue, - fsm)); + notify)); /* NOT REACHED */ } @@ -806,7 +812,7 @@ SILC_FSM_STATE(silc_client_notify_cmode_change) silc_client_get_client_by_id_resolve( client, conn, &id.u.client_id, NULL, silc_client_notify_resolved, - fsm)); + notify)); /* NOT REACHED */ } entry = client_entry; @@ -820,7 +826,7 @@ SILC_FSM_STATE(silc_client_notify_cmode_change) silc_client_get_server_by_id_resolve( client, conn, &id.u.server_id, silc_client_notify_resolved, - fsm)); + notify)); /* NOT REACHED */ } entry = server; @@ -835,7 +841,7 @@ SILC_FSM_STATE(silc_client_notify_cmode_change) silc_client_get_channel_by_id_resolve( client, conn, &id.u.channel_id, silc_client_notify_resolved, - fsm)); + notify)); /* NOT REACHED */ } entry = channel_entry; @@ -957,7 +963,7 @@ SILC_FSM_STATE(silc_client_notify_cumode_change) conn, SILC_COMMAND_NONE, channel->internal.resolve_cmd_ident, silc_client_notify_wait_continue, - fsm)); + notify)); /* NOT REACHED */ } @@ -982,7 +988,7 @@ SILC_FSM_STATE(silc_client_notify_cumode_change) silc_client_get_client_by_id_resolve( client, conn, &id.u.client_id, NULL, silc_client_notify_resolved, - fsm)); + notify)); /* NOT REACHED */ } entry = client_entry; @@ -996,7 +1002,7 @@ SILC_FSM_STATE(silc_client_notify_cumode_change) silc_client_get_server_by_id_resolve( client, conn, &id.u.server_id, silc_client_notify_resolved, - fsm)); + notify)); /* NOT REACHED */ } entry = server; @@ -1011,7 +1017,7 @@ SILC_FSM_STATE(silc_client_notify_cumode_change) silc_client_get_channel_by_id_resolve( client, conn, &id.u.channel_id, silc_client_notify_resolved, - fsm)); + notify)); /* NOT REACHED */ } entry = channel_entry; @@ -1030,7 +1036,7 @@ SILC_FSM_STATE(silc_client_notify_cumode_change) SILC_FSM_CALL(silc_client_get_client_by_id_resolve( client, conn, &id2.u.client_id, NULL, silc_client_notify_resolved, - fsm)); + notify)); /* NOT REACHED */ } @@ -1121,7 +1127,7 @@ SILC_FSM_STATE(silc_client_notify_channel_change) conn, SILC_COMMAND_NONE, channel->internal.resolve_cmd_ident, silc_client_notify_wait_continue, - fsm)); + notify)); /* NOT REACHED */ } @@ -1180,7 +1186,7 @@ SILC_FSM_STATE(silc_client_notify_kicked) conn, SILC_COMMAND_NONE, channel->internal.resolve_cmd_ident, silc_client_notify_wait_continue, - fsm)); + notify)); /* NOT REACHED */ } @@ -1208,7 +1214,7 @@ SILC_FSM_STATE(silc_client_notify_kicked) silc_client_get_client_by_id_resolve( client, conn, &id.u.client_id, NULL, silc_client_notify_resolved, - fsm)); + notify)); /* NOT REACHED */ } @@ -1294,7 +1300,7 @@ SILC_FSM_STATE(silc_client_notify_killed) SILC_FSM_CALL(silc_client_get_client_by_id_resolve( client, conn, &id.u.client_id, NULL, silc_client_notify_resolved, - fsm)); + notify)); /* NOT REACHED */ } entry = client_entry2; @@ -1306,7 +1312,7 @@ SILC_FSM_STATE(silc_client_notify_killed) SILC_FSM_CALL(silc_client_get_server_by_id_resolve( client, conn, &id.u.server_id, silc_client_notify_resolved, - fsm)); + notify)); /* NOT REACHED */ } entry = server; @@ -1319,7 +1325,7 @@ SILC_FSM_STATE(silc_client_notify_killed) SILC_FSM_CALL(silc_client_get_channel_by_id_resolve( client, conn, &id.u.channel_id, silc_client_notify_resolved, - fsm)); + notify)); /* NOT REACHED */ } entry = channel_entry; @@ -1476,7 +1482,7 @@ SILC_FSM_STATE(silc_client_notify_watch) SILC_FSM_CALL(silc_client_get_client_by_id_resolve( client, conn, &id.u.client_id, NULL, silc_client_notify_resolved, - fsm)); + notify)); /* NOT REACHED */ } diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index 13d7fabd..42a119bf 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -238,9 +238,6 @@ silc_client_command_add_pending(SilcClientConnection conn, silc_list_add(cmd->reply_callbacks, cb); } - SILC_LOG_DEBUG(("pending: cmd %p, command %d, ident %d", cmd, cmd->cmd, - cmd->cmd_ident)); - /* Add pending reply */ silc_list_add(conn->internal->pending_commands, cmd); diff --git a/lib/silcclient/command_reply.c b/lib/silcclient/command_reply.c index b3d91da7..55f8b4ab 100644 --- a/lib/silcclient/command_reply.c +++ b/lib/silcclient/command_reply.c @@ -32,13 +32,14 @@ do { \ silc_status_get_args(cmd->status, args, &arg1, &arg2); \ else \ cmd->status = error; \ - SILC_LOG_DEBUG(("Error in command reply")); \ + SILC_LOG_DEBUG(("Error in command reply: %s", \ + silc_get_status_message(cmd->status))); \ silc_client_command_callback(cmd, arg1, arg2); \ } while(0) /* Check for error */ #define CHECK_STATUS(msg) \ - SILC_LOG_DEBUG(("Start")); \ + SILC_LOG_DEBUG(("%s", silc_get_command_name(cmd->cmd))); \ if (cmd->error != SILC_STATUS_OK) { \ if (cmd->verbose) \ SAY(cmd->conn->client, cmd->conn, SILC_CLIENT_MESSAGE_ERROR, \ @@ -46,7 +47,7 @@ do { \ ERROR_CALLBACK(cmd->error); \ silc_client_command_process_error(cmd, state_context, cmd->error); \ silc_fsm_next(fsm, silc_client_command_reply_process); \ - return SILC_FSM_YIELD; \ + return SILC_FSM_CONTINUE; \ } /* Check for correct arguments */ @@ -55,7 +56,7 @@ do { \ silc_argument_get_arg_num(args) > max) { \ ERROR_CALLBACK(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); \ silc_fsm_next(fsm, silc_client_command_reply_process); \ - return SILC_FSM_YIELD; \ + return SILC_FSM_CONTINUE; \ } #define SAY cmd->conn->client->internal->ops->say @@ -74,9 +75,7 @@ silc_client_command_callback(SilcClientCommandContext cmd, ...) /* Default reply callback */ if (cmd->called) { - SILC_LOG_DEBUG(("cp %p, ap %p", cp, ap)); silc_va_copy(cp, ap); - SILC_LOG_DEBUG(("cp %p, ap %p", cp, ap)); cmd->conn->client->internal->ops->command_reply( cmd->conn->client, cmd->conn, cmd->cmd, cmd->status, cmd->error, cp); @@ -87,11 +86,9 @@ silc_client_command_callback(SilcClientCommandContext cmd, ...) silc_list_start(cmd->reply_callbacks); while ((cb = silc_list_get(cmd->reply_callbacks))) if (!cb->do_not_call) { - SILC_LOG_DEBUG(("cp %p, ap %p", cp, ap)); silc_va_copy(cp, ap); - SILC_LOG_DEBUG(("cp %p, ap %p", cp, ap)); - cb->do_not_call = cb->reply(cmd->conn->client, cmd->conn, cmd->cmd, - cmd->status, cmd->error, cb->context, cp); + cb->do_not_call = !cb->reply(cmd->conn->client, cmd->conn, cmd->cmd, + cmd->status, cmd->error, cb->context, cp); va_end(cp); } @@ -151,8 +148,6 @@ SILC_FSM_STATE(silc_client_command_reply) silc_mutex_lock(conn->internal->lock); silc_list_start(conn->internal->pending_commands); while ((cmd = silc_list_get(conn->internal->pending_commands))) { - SILC_LOG_DEBUG(("cmd %p, command %d, ident %d", cmd, cmd->cmd, - cmd->cmd_ident)); if ((cmd->cmd == command || cmd->cmd == SILC_COMMAND_NONE) && cmd->cmd_ident == cmd_ident) { silc_list_del(conn->internal->pending_commands, cmd); @@ -167,8 +162,6 @@ SILC_FSM_STATE(silc_client_command_reply) return SILC_FSM_FINISH; } - SILC_LOG_DEBUG(("cmd %p, command %d", cmd, cmd->cmd)); - /* Signal command thread that command reply has arrived */ silc_fsm_set_state_context(&cmd->thread, payload); silc_fsm_next(&cmd->thread, silc_client_command_reply_process); @@ -331,6 +324,7 @@ SILC_FSM_STATE(silc_client_command_reply_process) SILC_FSM_STATE(silc_client_command_reply_processed) { SilcClientCommandContext cmd = fsm_context; + SilcClientConnection conn = cmd->conn; SilcCommandPayload payload = state_context; silc_command_payload_free(payload); @@ -339,6 +333,12 @@ SILC_FSM_STATE(silc_client_command_reply_processed) SILC_STATUS_IS_ERROR(cmd->status)) return SILC_FSM_FINISH; + /* Add back to pending command reply list */ + silc_mutex_lock(conn->internal->lock); + cmd->resolved = FALSE; + silc_list_add(conn->internal->pending_commands, cmd); + silc_mutex_unlock(conn->internal->lock); + /** Wait more command payloads */ silc_fsm_next(fsm, silc_client_command_reply_wait); return SILC_FSM_CONTINUE; @@ -422,6 +422,7 @@ SILC_FSM_STATE(silc_client_command_reply_whois) ERROR_CALLBACK(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); goto out; } + silc_client_ref_client(client, conn, client_entry); } else { silc_client_update_client(client, conn, client_entry, nickname, username, realname, mode); @@ -557,6 +558,7 @@ SILC_FSM_STATE(silc_client_command_reply_identify) ERROR_CALLBACK(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); goto out; } + silc_client_ref_client(client, conn, client_entry); } else { silc_client_update_client(client, conn, client_entry, name, info, NULL, 0); -- 2.24.0