Client library rewrites.
[silc.git] / lib / silcclient / command.c
index ce4a03ea546aba268238bb4abc05c13b12b2243c..68e9eed62fdd04794363438368bee6c031968ce3 100644 (file)
@@ -567,7 +567,7 @@ SilcBool silc_client_command_pending(SilcClientConnection conn,
 
   silc_mutex_unlock(conn->internal->lock);
 
-  return FALSE;
+  return TRUE;
 }
 
 /******************************** WHOIS *************************************/
@@ -596,10 +596,10 @@ SILC_FSM_STATE(silc_client_command_whois)
 
   for (i = 1; i < cmd->argc; i++) {
     if (!strcasecmp(cmd->argv[i], "-details")) {
-       details = TRUE;
+      details = TRUE;
     } else if (!strcasecmp(cmd->argv[i], "-pubkey") && cmd->argc > i + 1) {
-       pubkey = cmd->argv[i + 1];
-       i++;
+      pubkey = cmd->argv[i + 1];
+      i++;
     } else {
       /* We assume that the first parameter is the nickname, if it isn't
          -details or -pubkey. The last parameter should always be the count */
@@ -826,7 +826,7 @@ SILC_FSM_STATE(silc_client_command_list)
     /* Get the Channel ID of the channel */
     channel = silc_client_get_channel(conn->client, cmd->conn, cmd->argv[1]);
     if (channel)
-      idp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
+      idp = silc_id_payload_encode(&channel->id, SILC_ID_CHANNEL);
   }
 
   if (!idp)
@@ -887,7 +887,7 @@ SILC_FSM_STATE(silc_client_command_topic)
     goto out;
   }
 
-  idp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
+  idp = silc_id_payload_encode(&channel->id, SILC_ID_CHANNEL);
 
   /* Send TOPIC command to the server */
   if (cmd->argc > 2)
@@ -925,7 +925,7 @@ SILC_FSM_STATE(silc_client_command_invite)
   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];
@@ -975,7 +975,6 @@ SILC_FSM_STATE(silc_client_command_invite)
                                      cmd));
 
       client_entry = silc_dlist_get(clients);
-      silc_dlist_uninit(clients);
     } else {
       if (cmd->argv[2][0] == '+')
        action[0] = 0x00;
@@ -1007,7 +1006,7 @@ SILC_FSM_STATE(silc_client_command_invite)
   }
 
   /* Send the command */
-  chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
+  chidp = silc_id_payload_encode(&channel->id, SILC_ID_CHANNEL);
   if (client_entry) {
     clidp = silc_id_payload_encode(&client_entry->id, SILC_ID_CLIENT);
     silc_client_command_send_va(conn, cmd, cmd->cmd, NULL, NULL, 4,
@@ -1026,6 +1025,7 @@ SILC_FSM_STATE(silc_client_command_invite)
   silc_buffer_free(chidp);
   silc_buffer_free(args);
   silc_free(nickname);
+  silc_client_list_free(client, conn, clients);
 
   /* Notify application */
   COMMAND(SILC_STATUS_OK);
@@ -1052,10 +1052,13 @@ SILC_FSM_STATE(silc_client_command_quit_final)
   /* Notify application */
   COMMAND(SILC_STATUS_OK);
 
-  /* Close connection */
+  /* Call connection callback */
   conn->callback(client, conn, SILC_CLIENT_CONN_DISCONNECTED,
-                conn->context);
-  //  silc_client_close_connection(q->client, q->conn->sock->user_data);
+                0, NULL, conn->context);
+
+  /* Signal to close connection */
+  conn->internal->disconnected = TRUE;
+  SILC_FSM_SEMA_POST(&conn->internal->wait_event);
 
   return SILC_FSM_FINISH;
 }
@@ -1123,7 +1126,6 @@ SILC_FSM_STATE(silc_client_command_kill)
                                          cmd));
 
   target = silc_dlist_get(clients);
-  silc_dlist_uninit(clients);
 
   if (cmd->argc >= 3) {
     if (strcasecmp(cmd->argv[2], "-pubkey"))
@@ -1149,6 +1151,7 @@ SILC_FSM_STATE(silc_client_command_kill)
   silc_buffer_free(idp);
   silc_buffer_free(auth);
   silc_free(nickname);
+  silc_client_list_free(client, conn, clients);
 
   /* Notify application */
   COMMAND(SILC_STATUS_OK);
@@ -1737,7 +1740,7 @@ SILC_FSM_STATE(silc_client_command_cmode)
 
        if (cmd->argc == 3) {
          /* Send empty command to receive the public key list. */
-         chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
+         chidp = silc_id_payload_encode(&channel->id, SILC_ID_CHANNEL);
          silc_client_command_send_va(conn, cmd, SILC_COMMAND_CMODE,
                                      NULL, NULL, 1,
                                      1, silc_buffer_datalen(chidp));
@@ -1791,7 +1794,7 @@ SILC_FSM_STATE(silc_client_command_cmode)
     }
   }
 
-  chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
+  chidp = silc_id_payload_encode(&channel->id, SILC_ID_CHANNEL);
   SILC_PUT32_MSB(mode, modebuf);
 
   /* Send the command. We support sending only one mode at once that
@@ -1836,7 +1839,7 @@ SILC_FSM_STATE(silc_client_command_cumode)
   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;
@@ -1882,7 +1885,6 @@ SILC_FSM_STATE(silc_client_command_cumode)
                                          cmd));
 
   client_entry = silc_dlist_get(clients);
-  silc_dlist_uninit(clients);
 
   /* Get the current mode */
   chu = silc_client_on_channel(channel, client_entry);
@@ -1976,7 +1978,7 @@ SILC_FSM_STATE(silc_client_command_cumode)
     }
   }
 
-  chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
+  chidp = silc_id_payload_encode(&channel->id, SILC_ID_CHANNEL);
   SILC_PUT32_MSB(mode, modebuf);
   clidp = silc_id_payload_encode(&client_entry->id, SILC_ID_CLIENT);
 
@@ -1992,11 +1994,18 @@ SILC_FSM_STATE(silc_client_command_cumode)
   silc_buffer_free(clidp);
   if (auth)
     silc_buffer_free(auth);
+  silc_free(nickname);
+  silc_client_list_free(client, conn, clients);
 
   /* Notify application */
   COMMAND(SILC_STATUS_OK);
 
+  /** Wait for command reply */
+  silc_fsm_next(fsm, silc_client_command_reply_wait);
+  return SILC_FSM_CONTINUE;
+
  out:
+  silc_client_list_free(client, conn, clients);
   silc_free(nickname);
   return SILC_FSM_FINISH;
 }
@@ -2013,7 +2022,7 @@ SILC_FSM_STATE(silc_client_command_kick)
   SilcChannelEntry channel;
   SilcBuffer idp, idp2;
   SilcClientEntry target;
-  SilcDList clients;
+  SilcDList clients = NULL;
   char *name;
   char *nickname = NULL;
 
@@ -2062,10 +2071,9 @@ SILC_FSM_STATE(silc_client_command_kick)
     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);
+  idp = silc_id_payload_encode(&channel->id, SILC_ID_CHANNEL);
   idp2 = silc_id_payload_encode(&target->id, SILC_ID_CLIENT);
   if (cmd->argc == 3)
     silc_client_command_send_va(conn, cmd, cmd->cmd, NULL, NULL, 2,
@@ -2080,6 +2088,7 @@ SILC_FSM_STATE(silc_client_command_kick)
   silc_buffer_free(idp);
   silc_buffer_free(idp2);
   silc_free(nickname);
+  silc_client_list_free(client, conn, clients);
 
   /* Notify application */
   COMMAND(SILC_STATUS_OK);
@@ -2286,7 +2295,7 @@ SILC_FSM_STATE(silc_client_command_ban)
     }
   }
 
-  chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
+  chidp = silc_id_payload_encode(&channel->id, SILC_ID_CHANNEL);
 
   /* Send the command */
   silc_client_command_send_va(conn, cmd, cmd->cmd, NULL, NULL, 3,
@@ -2437,7 +2446,7 @@ SILC_FSM_STATE(silc_client_command_leave)
     goto out;
   }
 
-  idp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
+  idp = silc_id_payload_encode(&channel->id, SILC_ID_CHANNEL);
 
   /* Send LEAVE command to the server */
   silc_client_command_send_va(conn, cmd, cmd->cmd, NULL, NULL, 1,
@@ -2529,8 +2538,10 @@ SILC_FSM_STATE(silc_client_command_getkey)
     client->internal->params->nickname_parse(cmd->argv[1], &nickname);
   else
     nickname = strdup(cmd->argv[1]);
-  if (!nickname)
+  if (!nickname) {
+    COMMAND_ERROR(SILC_STATUS_ERR_RESOURCE_LIMIT);
     return SILC_FSM_FINISH;
+  }
 
   /* Find client entry */
   clients = silc_client_get_clients_local(client, conn, nickname,
@@ -2549,11 +2560,11 @@ SILC_FSM_STATE(silc_client_command_getkey)
                                             2, cmd->argv[1],
                                             strlen(cmd->argv[1])));
     }
-    idp = silc_id_payload_encode(server_entry->server_id, SILC_ID_SERVER);
+    idp = silc_id_payload_encode(&server_entry->id, SILC_ID_SERVER);
   } 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 */
@@ -2748,10 +2759,8 @@ SILC_FSM_STATE(silc_client_command)
   payload = silc_command_payload_parse(packet->buffer.data,
                                       silc_buffer_len(&packet->buffer));
   if (!payload) {
-    /** Bad command payload */
     SILC_LOG_DEBUG(("Bad command packet"));
-    silc_fsm_next(fsm, silc_client_connection_st_packet);
-    return SILC_FSM_CONTINUE;
+    return SILC_FSM_FINISH;
   }
 
   /* Get arguments */
@@ -2774,8 +2783,5 @@ SILC_FSM_STATE(silc_client_command)
   }
 
   silc_command_payload_free(payload);
-
-  /** Packet processed */
-  silc_fsm_next(fsm, silc_client_connection_st_packet);
-  return SILC_FSM_CONTINUE;
+  return SILC_FSM_FINISH;
 }