More client library rewrites.
authorPekka Riikonen <priikone@silcnet.org>
Thu, 30 Nov 2006 14:58:40 +0000 (14:58 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Thu, 30 Nov 2006 14:58:40 +0000 (14:58 +0000)
lib/silcclient/client_entry.c
lib/silcclient/client_notify.c
lib/silcclient/command.c
lib/silcclient/command_reply.c

index 58701bceabdb59c16169a67f4896169d30146c7c..e8441a696ce2545ff70558e569e474372a36e7fe 100644 (file)
@@ -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);
index 9087ba35f22c8f754887ea8f5a7b78b5719dccad..206425dc9379d212964bc48a5a415d708450f415 100644 (file)
@@ -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 */
   }
 
index 13d7fabda690fcddc0f0287295ef7be60cabcbd6..42a119bfa58ddf6a1fd7654b27ca7ddebb04b89b 100644 (file)
@@ -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);
 
index b3d91da78f912f07a51ed98f2d848a47a77b293d..55f8b4ab5f14a8eae15a7350e244ddacf584a95d 100644 (file)
@@ -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);