+ SILC_CLIENT_CMDU(service, SERVICE, "SERVICE");
+}
+
+/****************** Client Side Incoming Command Handling *******************/
+
+typedef struct {
+ SilcClientConnection conn;
+ SilcUInt16 cmd_ident;
+} *SilcClientProcessWhois;
+
+/* Send reply to WHOIS from server */
+
+static void
+silc_client_command_process_whois_send(SilcBool success,
+ const unsigned char *data,
+ SilcUInt32 data_len, void *context)
+{
+ SilcClientProcessWhois w = context;
+ SilcBufferStruct buffer;
+ SilcBuffer packet;
+
+ if (!data) {
+ silc_free(w);
+ return;
+ }
+
+ silc_buffer_set(&buffer, (unsigned char *)data, data_len);
+
+ /* Send the attributes back in COMMAND_REPLY packet */
+ packet =
+ silc_command_reply_payload_encode_va(SILC_COMMAND_WHOIS,
+ SILC_STATUS_OK, 0, w->cmd_ident,
+ 1, 11, buffer.data,
+ silc_buffer_len(&buffer));
+ if (!packet) {
+ silc_free(w);
+ return;
+ }
+
+ SILC_LOG_DEBUG(("Sending back requested WHOIS attributes"));
+
+ silc_packet_send(w->conn->stream, SILC_PACKET_COMMAND_REPLY, 0,
+ silc_buffer_datalen(packet));
+
+ silc_buffer_free(packet);
+ silc_free(w);
+}
+
+/* Process WHOIS command from server */
+
+static void silc_client_command_process_whois(SilcClient client,
+ SilcClientConnection conn,
+ SilcCommandPayload payload,
+ SilcArgumentPayload args)
+{
+ SilcClientProcessWhois w;
+ SilcDList attrs;
+ unsigned char *tmp;
+ SilcUInt32 tmp_len;
+
+ SILC_LOG_DEBUG(("Received WHOIS command"));
+
+ /* Try to take the Requested Attributes */
+ tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
+ if (!tmp)
+ return;
+
+ attrs = silc_attribute_payload_parse(tmp, tmp_len);
+ if (!attrs)
+ return;
+
+ w = silc_calloc(1, sizeof(*w));
+ if (!w) {
+ silc_attribute_payload_list_free(attrs);
+ return;
+ }
+ w->conn = conn;
+ w->cmd_ident = silc_command_get_ident(payload);
+
+ /* Process requested attributes */
+ silc_client_attributes_process(client, conn, attrs,
+ silc_client_command_process_whois_send, w);
+ silc_attribute_payload_list_free(attrs);
+}
+
+/* Client is able to receive some command packets even though they are
+ special case. Server may send WHOIS command to the client to retrieve
+ Requested Attributes information for WHOIS query the server is
+ processing. This function currently handles only the WHOIS command,
+ but if in the future more commands may arrive then this can be made
+ to support other commands too. */
+
+SILC_FSM_STATE(silc_client_command)
+{
+ SilcClientConnection conn = fsm_context;
+ SilcClient client = conn->client;
+ SilcPacket packet = state_context;
+ SilcCommandPayload payload;
+ SilcCommand command;
+ SilcArgumentPayload args;
+
+ /* Get command payload from packet */
+ payload = silc_command_payload_parse(packet->buffer.data,
+ silc_buffer_len(&packet->buffer));
+ if (!payload) {
+ SILC_LOG_DEBUG(("Bad command packet"));
+ return SILC_FSM_FINISH;
+ }
+
+ /* Get arguments */
+ args = silc_command_get_args(payload);
+
+ /* Get the command */
+ command = silc_command_get(payload);
+ switch (command) {
+
+ case SILC_COMMAND_WHOIS:
+ /* Ignore everything if requested by application */
+ if (conn->internal->params.ignore_requested_attributes)
+ break;
+
+ silc_client_command_process_whois(client, conn, payload, args);
+ break;
+
+ default:
+ break;
+ }
+
+ silc_command_payload_free(payload);
+ return SILC_FSM_FINISH;