Merged from silc_1_0_branch.
[silc.git] / lib / silcclient / silcclient.h
index a1f8e48b87005a187c04321e5c385df244b60697..d87dff84b92f2054edc34d15498df2fa459195e0 100644 (file)
 extern "C" {
 #endif
 
-/* Forward declarations */
-typedef struct SilcClientStruct *SilcClient;
-typedef struct SilcClientConnectionStruct *SilcClientConnection;
-typedef struct SilcClientPingStruct SilcClientPing;
-typedef struct SilcClientAwayStruct SilcClientAway;
-typedef struct SilcClientKeyAgreementStruct *SilcClientKeyAgreement;
-typedef struct SilcClientFtpSessionStruct *SilcClientFtpSession;
-typedef struct SilcClientEntryStruct *SilcClientEntry;
-typedef struct SilcChannelEntryStruct *SilcChannelEntry;
-typedef struct SilcServerEntryStruct *SilcServerEntry;
-typedef struct SilcClientCommandStruct *SilcClientCommand;
-typedef struct SilcClientCommandContextStruct *SilcClientCommandContext;
-typedef struct SilcClientCommandReplyContextStruct 
-                                           *SilcClientCommandReplyContext;
-typedef struct SilcChannelUserStruct *SilcChannelUser;
+#include "client.h"
 
 /* General definitions */
 
+/****s* silcclient/SilcClientAPI/SilcClient
+ *
+ * NAME
+ *
+ *    typedef struct SilcClientStruct { ... } *SilcClient
+ *
+ * DESCRIPTION
+ *
+ *    This is the actual SILC Client structure which represents one
+ *    SILC Client.  It is allocated with the silc_client_alloc function
+ *    and given as argument to all SILC Client Library functions.  It
+ *    is initialized with silc_client_init function, and freed with
+ *    silc_client_free function.
+ *
+ * SOURCE
+ */
+struct SilcClientStruct {
+  /*
+   * The following fields are set by application
+   */
+  char *nickname;               /* Nickname, MAY be set by application  */
+  char *username;               /* Username, MUST be set by application */
+  char *hostname;               /* hostname, MUST be set by application */
+  char *realname;               /* Real name, MUST be set be application */
+  
+  SilcPublicKey public_key;     /* Public key of user, set by application */
+  SilcPrivateKey private_key;   /* Private key of user, set by application */
+  SilcPKCS pkcs;                /* PKCS allocated by application */
+
+  /*
+   * The following fields are set by the library
+   */
+
+  /* Scheduler, set by library.  Application may use this pointer. */
+  SilcSchedule schedule;
+  
+  /* Random Number Generator. Application should use this as its primary
+     random number generator. */
+  SilcRng rng;
+  
+  /* Application specific user data pointer. Client library does not
+     touch this.  This the context sent as argument to silc_client_alloc.
+     Application can use it freely. */
+  void *application;
+     
+  /* Generic hash context for application usage */
+  SilcHash md5hash;
+  SilcHash sha1hash;
+
+  /* Internal data for client library. Application cannot access this
+     data at all. */
+  SilcClientInternal internal;
+};  
+/***/
+
+/****s* silcclient/SilcClientAPI/SilcClientConnection
+ *
+ * NAME
+ *
+ *    typedef struct SilcClientConnectionStruct { ... }
+ *                      *SilcClientConnection
+ *
+ * DESCRIPTION
+ *
+ *    This structure represents a connection.  When connection is created
+ *    to server this is context is returned to the application in the
+ *    "connected" client operation.  It includes all the important
+ *    data for the session, such as nickname, local and remote IDs, and
+ *    other information.
+ *
+ * SOURCE
+ */
+struct SilcClientConnectionStruct {
+  /*
+   * Local data
+   */
+  char *nickname;                /* Current nickname */
+  SilcClientEntry local_entry;   /* Own Client Entry */
+  SilcClientID *local_id;        /* Current Client ID */
+  unsigned char *local_id_data;          /* Current Client ID decoded */
+  SilcUInt32 local_id_data_len;
+
+  /*
+   * Remote data
+   */
+  char *remote_host;             /* Remote host name */
+  int remote_port;               /* Remote port */
+  SilcServerID *remote_id;       /* Remote Server ID */
+  unsigned char *remote_id_data;  /* Remote Server ID decoded */
+  SilcUInt32 remote_id_data_len;
+
+  /*
+   * Common data
+   */
+
+  /* Current command identifier for a command that was sent last.
+     Application may get the value from this variable to find out the
+     command identifier for last command. */
+  SilcUInt16 cmd_ident;
+
+  /* User data context. Library does not touch this. Application may
+     freely set and use this pointer for its needs. */
+  void *context;
+
+  /* Pointer back to the SilcClient.  Application may use this. */
+  SilcClient client;
+
+  /* Current channel.  Application may use and set this pointer if needed. */
+  SilcChannelEntry current_channel;
+
+  /* Socket connection object for this connection.  Application may
+     use this if needed.  The sock->user_data is back pointer to this
+     structure. */
+  SilcSocketConnection sock;
+
+  /* Internal data for client library. Application cannot access this
+     data at all. */
+  SilcClientConnectionInternal internal;
+};
+/***/
+
+/****s* silcclient/SilcClientAPI/SilcClientEntry
+ *
+ * NAME
+ *
+ *    typedef struct SilcClientEntryStruct { ... } *SilcClientEntry
+ *
+ * DESCRIPTION
+ *
+ *    This structure represents a client or a user in the SILC network.
+ *    The local user has this structure also and it can be accessed from
+ *    SilcClientConnection structure.  All other users in the SILC network
+ *    that are accessed using the Client Library routines will have their
+ *    own SilcClientEntry structure.  For example, when finding users by
+ *    their nickname the Client Library returns this structure back to
+ *    the application.
+ *
+ * SOURCE
+ */
+struct SilcClientEntryStruct {
+  /* General information */
+  char *nickname;              /* nickname */
+  char *username;              /* username */
+  char *hostname;              /* hostname */
+  char *server;                        /* SILC server name */
+  char *realname;              /* Realname (userinfo) */
+
+  /* Mode, ID and other information */
+  SilcUInt32 mode;             /* User mode in SILC */
+  SilcClientID *id;            /* The Client ID */
+  SilcDList attrs;             /* Requested Attributes (maybe NULL) */
+  unsigned char *fingerprint;  /* Fingerprint of client's public key */
+  SilcUInt32 fingerprint_len;  /* Length of the fingerprint */
+
+  /* Private message keys */
+  SilcCipher send_key;         /* Private message key for sending */
+  SilcCipher receive_key;      /* Private message key for receiving */
+  SilcHmac hmac_send;          /* Private mesage key HMAC for sending */
+  SilcHmac hmac_receive;       /* Private mesage key HMAC for receiving */
+  unsigned char *key;          /* Set only if application provided the
+                                  key material. NULL if the library 
+                                  generated the key. */
+  SilcUInt32 key_len;          /* Key length */
+  SilcClientKeyAgreement ke;   /* Current key agreement context or NULL */
+
+  /* SilcClientEntry status information */
+  SilcEntryStatus status;      /* Status mask */
+  SilcHashTable channels;      /* All channels client has joined */
+  SilcUInt16 resolve_cmd_ident;        /* Command identifier when resolving */
+  bool generated;              /* TRUE if library generated `key' */
+  bool valid;                  /* FALSE if this entry is not valid */
+};
+/***/
+
+/****s* silcclient/SilcClientAPI/SilcChannelEntry
+ *
+ * NAME
+ *
+ *    typedef struct SilcChannelEntryStruct { ... } *SilcChannelEntry
+ *
+ * DESCRIPTION
+ *
+ *    This structure represents a channel in the SILC network.  All
+ *    channels that the client are aware of or have joined in will be
+ *    represented as SilcChannelEntry.  The structure includes information
+ *    about the channel.
+ *
+ * SOURCE
+ */
+struct SilcChannelEntryStruct {
+  /* General information */
+  char *channel_name;                       /* Channel name */
+  SilcChannelID *id;                        /* Channel ID */
+  SilcUInt32 mode;                          /* Channel mode */
+
+  /* All clients that has joined this channel */
+  SilcHashTable user_list;
+
+  /* Channel keys */
+  SilcCipher channel_key;                    /* The channel key */
+  unsigned char *key;                       /* Raw key data */
+  SilcUInt32 key_len;                       /* Raw key data length */
+  unsigned char iv[SILC_CIPHER_MAX_IV_SIZE]; /* Current IV */
+  SilcHmac hmac;                            /* Current HMAC */
+
+  /* Channel private keys */
+  SilcDList private_keys;                   /* List of private keys or NULL */
+  SilcChannelPrivateKey curr_key;           /* Current private key */
+
+  /* SilcChannelEntry status information */
+  SilcCipher old_channel_key;
+  SilcHmac old_hmac;
+  SilcTask rekey_task;
+  SilcUInt16 resolve_cmd_ident;                     /* Command identifier when
+                                               resolving this entry */
+};
+/***/
+
+/****s* silcclient/SilcClientAPI/SilcServerEntry
+ *
+ * NAME
+ *
+ *    typedef struct SilcServerEntryStruct { ... } *SilcServerEntry
+ *
+ * DESCRIPTION
+ *
+ *    This structure represents a server in the SILC network.  All servers
+ *    that the client is aware of and have for example resolved with
+ *    SILC_COMMAND_INFO command have their on SilcServerEntry structure.
+ *
+ * SOURCE
+ */
+struct SilcServerEntryStruct {
+  /* General information */
+  char *server_name;                        /* Server name */
+  char *server_info;                        /* Server info */
+  SilcServerID *server_id;                  /* Server ID */
+  SilcUInt16 resolve_cmd_ident;                     /* Command identifier when
+                                               resolving this entry */
+};
+/***/
+
 /****d* silcclient/SilcClientAPI/SilcKeyAgreementStatus
  *
  * NAME
@@ -92,6 +320,8 @@ typedef enum {
   SILC_KEY_AGREEMENT_FAILURE,         /* The protocol failed */
   SILC_KEY_AGREEMENT_TIMEOUT,         /* The protocol timeout */
   SILC_KEY_AGREEMENT_ABORTED,         /* The protocol aborted */
+  SILC_KEY_AGREEMENT_ALREADY_STARTED,  /* Already started */
+  SILC_KEY_AGREEMENT_SELF_DENIED,      /* Negotiationg with itself denied */
 } SilcKeyAgreementStatus;
 /***/
 
@@ -153,7 +383,8 @@ typedef struct {
  *
  * NAME
  *
- *    typedef struct { ... } SilcChannelPrivateKey;
+ *    typedef struct SilcChannelPrivateKeyStruct { ... }
+ *                      *SilcChannelPrivateKey;
  *
  * DESCRIPTION
  *
@@ -162,13 +393,13 @@ typedef struct {
  *
  * SOURCE
  */
-typedef struct SilcChannelPrivateKeyStruct {
+struct SilcChannelPrivateKeyStruct {
   char *name;                        /* Application given name */
   SilcCipher cipher;                 /* The cipher and key */
   SilcHmac hmac;                     /* The HMAC and hmac key */
   unsigned char *key;                /* The key data */
   SilcUInt32 key_len;                /* The key length */
-} *SilcChannelPrivateKey;
+};
 /***/
 
 /****f* silcclient/SilcClientAPI/SilcAskPassphrase
@@ -254,6 +485,28 @@ typedef enum {
 } SilcClientMessageType;
 /***/
 
+/****d* silcclient/SilcClientAPI/SilcClientConnectionStatus
+ *
+ * NAME
+ *
+ *    typedef enum { ... } SilcClientConnectionStatus
+ *
+ * DESCRIPTION
+ *
+ *    This type is returned to the `connect' client operation to indicate
+ *    the status of the created connection.  It can indicated if it was
+ *    successful or whether an error occurred.
+ *
+ * SOURCE
+ */
+typedef enum {
+  SILC_CLIENT_CONN_SUCCESS,           /* Successfully connected */
+  SILC_CLIENT_CONN_SUCCESS_RESUME,     /* Successfully connected and
+                                         resumed old detached session */
+  SILC_CLIENT_CONN_ERROR,             /* Error occurred during connecting */
+} SilcClientConnectionStatus;
+/***/
+
 /****s* silcclient/SilcClientAPI/SilcClientOperations
  *
  * NAME
@@ -273,24 +526,30 @@ typedef struct {
   /* Message sent to the application by library. `conn' associates the
      message to a specific connection.  `conn', however, may be NULL. 
      The `type' indicates the type of the message sent by the library.
-     The applicationi can for example filter the message according the
+     The application can for example filter the message according the
      type. */
   void (*say)(SilcClient client, SilcClientConnection conn, 
              SilcClientMessageType type, char *msg, ...);
 
   /* Message for a channel. The `sender' is the sender of the message 
-     The `channel' is the channel. The `msg' is the message.  Note that
-     `msg' maybe NULL. */
+     The `channel' is the channel. The `message' is the message.  Note 
+     that `message' maybe NULL.  The `flags' indicates message flags 
+     and it is used to determine how the message can be interpreted
+     (like it may tell the message is multimedia message). */
   void (*channel_message)(SilcClient client, SilcClientConnection conn, 
                          SilcClientEntry sender, SilcChannelEntry channel, 
-                         SilcMessageFlags flags,
+                         SilcMessagePayload payload, SilcMessageFlags flags,
                          const unsigned char *message,
                          SilcUInt32 message_len);
 
   /* Private message to the client. The `sender' is the sender of the
-     message. */
+     message. The message is `message'and maybe NULL.  The `flags' 
+     indicates message flags  and it is used to determine how the message 
+     can be interpreted (like it may tell the message is multimedia 
+     message). */
   void (*private_message)(SilcClient client, SilcClientConnection conn,
-                         SilcClientEntry sender, SilcMessageFlags flags,
+                         SilcClientEntry sender, SilcMessagePayload payload,
+                         SilcMessageFlags flags,
                          const unsigned char *message,
                          SilcUInt32 message_len);
 
@@ -314,8 +573,8 @@ typedef struct {
      after application has called the command. Just to tell application
      that the command really was processed. */
   void (*command)(SilcClient client, SilcClientConnection conn, 
-                 SilcClientCommandContext cmd_context, int success,
-                 SilcCommand command);
+                 SilcClientCommandContext cmd_context, bool success,
+                 SilcCommand command, SilcStatus status);
 
   /* Command reply handler. This function is called always in the command reply
      function. If error occurs it will be called as well. Normal scenario
@@ -340,18 +599,24 @@ typedef struct {
      ID. For example, if Client ID is receives application receives 
      SilcClientEntry. */
   void (*command_reply)(SilcClient client, SilcClientConnection conn,
-                       SilcCommandPayload cmd_payload, int success,
-                       SilcCommand command, SilcCommandStatus status, ...);
+                       SilcCommandPayload cmd_payload, bool success,
+                       SilcCommand command, SilcStatus status, ...);
 
   /* Called to indicate that connection was either successfully established
      or connecting failed.  This is also the first time application receives
      the SilcClientConnection object which it should save somewhere.
-     If the `success' is FALSE the application must always call the function
+     The `status' indicated whether the connection were successful.  If it
+     is error value the application must always call the function
      silc_client_close_connection. */
-  void (*connect)(SilcClient client, SilcClientConnection conn, int success);
+  void (*connected)(SilcClient client, SilcClientConnection conn,
+                   SilcClientConnectionStatus status);
 
-  /* Called to indicate that connection was disconnected to the server. */
-  void (*disconnect)(SilcClient client, SilcClientConnection conn);
+  /* Called to indicate that connection was disconnected to the server.
+     The `status' may tell the reason of the disconnection, and if the
+     `message' is non-NULL it may include the disconnection message
+     received from server. */
+  void (*disconnected)(SilcClient client, SilcClientConnection conn,
+                      SilcStatus status, const char *message);
 
   /* Find authentication method and authentication data by hostname and
      port. The hostname may be IP address as well. When the authentication
@@ -364,8 +629,9 @@ typedef struct {
 
   /* Verifies received public key. The `conn_type' indicates which entity
      (server, client etc.) has sent the public key. If user decides to trust
-     the key may be saved as trusted public key for later use. The 
-     `completion' must be called after the public key has been verified. */
+     the application may save the key as trusted public key for later 
+     use. The `completion' must be called after the public key has been 
+     verified. */
   void (*verify_public_key)(SilcClient client, SilcClientConnection conn,
                            SilcSocketType conn_type, unsigned char *pk, 
                            SilcUInt32 pk_len, SilcSKEPKType pk_type,
@@ -395,10 +661,10 @@ typedef struct {
      desired (application may start it later by calling the function
      silc_client_perform_key_agreement). If TRUE is returned also the
      `completion' and `context' arguments must be set by the application. */
-  int (*key_agreement)(SilcClient client, SilcClientConnection conn,
-                      SilcClientEntry client_entry, const char *hostname,
-                      SilcUInt16 port, SilcKeyAgreementCallback *completion,
-                      void **context);
+  bool (*key_agreement)(SilcClient client, SilcClientConnection conn,
+                       SilcClientEntry client_entry, const char *hostname,
+                       SilcUInt16 port, SilcKeyAgreementCallback *completion,
+                       void **context);
 
   /* Notifies application that file transfer protocol session is being
      requested by the remote client indicated by the `client_entry' from
@@ -409,6 +675,26 @@ typedef struct {
   void (*ftp)(SilcClient client, SilcClientConnection conn,
              SilcClientEntry client_entry, SilcUInt32 session_id,
              const char *hostname, SilcUInt16 port);
+
+  /* Delivers SILC session detachment data indicated by `detach_data' to the
+     application.  If application has issued SILC_COMMAND_DETACH command     
+     the client session in the SILC network is not quit.  The client remains 
+     in the network but is detached.  The detachment data may be used later
+     to resume the session in the SILC Network.  The appliation is   
+     responsible of saving the `detach_data', to for example in a file.
+
+     The detachment data can be given as argument to the functions
+     silc_client_connect_to_server, or silc_client_add_connection when
+     creating connection to remote server, inside SilcClientConnectionParams
+     structure.  If it is provided the client library will attempt to resume
+     the session in the network.  After the connection is created
+     successfully, the application is responsible of setting the user
+     interface for user into the same state it was before detaching (showing
+     same channels, channel modes, etc).  It can do this by fetching the
+     information (like joined channels) from the client library. */
+  void (*detach)(SilcClient client, SilcClientConnection conn,
+                const unsigned char *detach_data,
+                SilcUInt32 detach_data_len);
 } SilcClientOperations;
 /***/
 
@@ -511,6 +797,15 @@ typedef struct {
      nickname string whenever it needs the true nickname. */
   SilcNicknameFormatParse nickname_parse;
 
+  /* If this is set to TRUE then the client will ignore all incoming
+     Requested Attributes queries and does not reply anything back.  This
+     usually leads into situation where server does not anymore send
+     the queries after seeing that client does not reply anything back.
+     If your application does not support Requested Attributes or you do
+     not want to use them set this to TRUE.  See SilcAttribute and
+     silc_client_attribute_add for more information on attributes. */
+  bool ignore_requested_attributes;
+
 } SilcClientParams;
 /***/
 
@@ -533,13 +828,14 @@ typedef struct {
  *    the client. The `application' is application specific user data pointer
  *    and caller must free it. The `silc_version' is the application version
  *    that will be used to compare against remote host's (usually a server)
- *    version string.
+ *    version string.  The `application' context is accessible by the
+ *    application by client->application, client being SilcClient.
  *
  ***/
 SilcClient silc_client_alloc(SilcClientOperations *ops, 
                             SilcClientParams *params,
                             void *application,
-                            const char *silc_version);
+                            const char *version_string);
 
 /****f* silcclient/SilcClientAPI/silc_client_free
  *
@@ -560,7 +856,7 @@ void silc_client_free(SilcClient client);
  *
  * SYNOPSIS
  *
- *    int silc_client_init(SilcClient client);
+ *    bool silc_client_init(SilcClient client);
  *
  * DESCRIPTION
  *
@@ -569,7 +865,7 @@ void silc_client_free(SilcClient client);
  *    client. Returns FALSE if error occurred, TRUE otherwise.
  *
  ***/
-int silc_client_init(SilcClient client);
+bool silc_client_init(SilcClient client);
 
 /****f* silcclient/SilcClientAPI/silc_client_run
  *
@@ -581,6 +877,7 @@ int silc_client_init(SilcClient client);
  *
  *    Runs the client. This starts the scheduler from the utility library.
  *    When this functions returns the execution of the appliation is over.
+ *    The client must be initialized before calling this.
  *
  ***/
 void silc_client_run(SilcClient client);
@@ -622,12 +919,45 @@ void silc_client_stop(SilcClient client);
 
 /* Connecting functions (client.c) */
 
+/****s* silcclient/SilcClientAPI/SilcClientConnectionParams
+ *
+ * NAME
+ *
+ *    typedef struct { ... } SilcClientConnectionParams;
+ *
+ * DESCRIPTION
+ *
+ *    Client connection parameters.  This can be filled by the application
+ *    and given as argument to silc_client_connect_to_server or to
+ *    silc_client_add_connection.
+ *
+ * SOURCE
+ */
+typedef struct {
+  /* The SILC session detachment data that was returned by `detach' client
+     operation when the application detached from the network.  Application
+     is responsible of saving the data and giving it as argument here
+     for resuming the session in the SILC network.
+
+     If this is provided here the client library will attempt to resume
+     the session in the network.  After the connection is created
+     successfully, the application is responsible of setting the user
+     interface for user into the same state it was before detaching (showing
+     same channels, channel modes, etc).  It can do this by fetching the
+     information (like joined channels) from the client library. */
+  unsigned char *detach_data;
+  SilcUInt32 detach_data_len;
+
+} SilcClientConnectionParams;
+/***/
+
 /****f* silcclient/SilcClientAPI/silc_client_connect_to_server
  *
  * SYNOPSIS
  *
- *    int silc_client_connect_to_server(SilcClient client, int port,
- *                                      char *host, void *context);
+ *    bool silc_client_connect_to_server(SilcClient client, 
+ *                                      SilcClientConnectionParams *params,
+ *                                      int port, char *host, void *context);
  *
  * DESCRIPTION
  *
@@ -637,20 +967,24 @@ void silc_client_stop(SilcClient client);
  *    that is created after the connection is created. Note that application
  *    may handle the connecting process outside the library. If this is the
  *    case then this function is not used at all. When the connecting is
- *    done the `connect' client operation is called.
+ *    done the `connect' client operation is called, and the `context' is
+ *    accessible with conn->context, conn being SilcClientConnection.
+ *    If the `params' is provided they are used by the routine.
  *
  ***/
-int silc_client_connect_to_server(SilcClient client, int port,
-                                 char *host, void *context);
+bool silc_client_connect_to_server(SilcClient client, 
+                                  SilcClientConnectionParams *params,
+                                  int port, char *host, void *context);
 
 /****f* silcclient/SilcClientAPI/silc_client_add_connection
  *
  * SYNOPSIS
  *
- *    SilcClientConnection silc_client_add_connection(SilcClient client,
- *                                                    char *hostname,
- *                                                   int port,
- *                                                   void *context);
+ *
+ *    SilcClientConnection
+ *    silc_client_add_connection(SilcClient client,
+ *                               SilcClientConnectionParams *params,
+ *                               char *hostname, int port, void *context);
  *
  * DESCRIPTION
  *
@@ -658,15 +992,21 @@ int silc_client_connect_to_server(SilcClient client, int port,
  *    connection to the connection table and returns a pointer to it. A client
  *    can have multiple connections to multiple servers. Every connection must
  *    be added to the client using this function. User data `context' may
- *    be sent as argument. This function is normally used only if the 
- *    application performed the connecting outside the library. The library
+ *    be sent as argument.  If the `params' is provided they are used by 
+ *    the routine.
+ *
+ * NOTES
+ *
+ *    This function is normally used only if the application performed 
+ *    the connecting outside the library, and did not called the
+ *    silc_client_connect_to_server function at all. The library
  *    however may use this internally.
  *
  ***/
-SilcClientConnection silc_client_add_connection(SilcClient client,
-                                               char *hostname,
-                                               int port,
-                                               void *context);
+SilcClientConnection
+silc_client_add_connection(SilcClient client,
+                          SilcClientConnectionParams *params,
+                          char *hostname, int port, void *context);
 
 /****f* silcclient/SilcClientAPI/silc_client_del_connection
  *
@@ -770,7 +1110,7 @@ void silc_client_close_connection(SilcClient client,
  *                                          SilcMessageFlags flags,
  *                                          unsigned char *data, 
  *                                          SilcUInt32 data_len, 
- *                                          int force_send);
+ *                                          bool_force_send);
  *
  * DESCRIPTION
  *
@@ -787,6 +1127,9 @@ void silc_client_close_connection(SilcClient client,
  *    keys are set then the first key (the key that was added first as
  *    private key) is used. 
  *
+ *    If the `flags' includes SILC_MESSAGE_FLAG_SIGNED the message will be
+ *    digitally signed with the SILC key pair.
+ *
  ***/
 void silc_client_send_channel_message(SilcClient client, 
                                      SilcClientConnection conn,
@@ -795,7 +1138,7 @@ void silc_client_send_channel_message(SilcClient client,
                                      SilcMessageFlags flags,
                                      unsigned char *data, 
                                      SilcUInt32 data_len, 
-                                     int force_send);
+                                     bool force_send);
 
 /****f* silcclient/SilcClientAPI/silc_client_send_private_message
  *
@@ -807,7 +1150,7 @@ void silc_client_send_channel_message(SilcClient client,
  *                                          SilcMessageFlags flags,
  *                                          unsigned char *data, 
  *                                          SilcUInt32 data_len, 
- *                                          int force_send);
+ *                                          bool force_send);
  *
  * DESCRIPTION
  *
@@ -819,6 +1162,9 @@ void silc_client_send_channel_message(SilcClient client,
  *    message. The `data' is the private message. If the `force_send' is
  *    TRUE the packet is sent immediately. 
  *
+ *    If the `flags' includes SILC_MESSAGE_FLAG_SIGNED the message will be
+ *    digitally signed with the SILC key pair.
+ *
  ***/
 void silc_client_send_private_message(SilcClient client,
                                      SilcClientConnection conn,
@@ -826,7 +1172,7 @@ void silc_client_send_private_message(SilcClient client,
                                      SilcMessageFlags flags,
                                      unsigned char *data, 
                                      SilcUInt32 data_len, 
-                                     int force_send);
+                                     bool force_send);
 
 
 /* Client and Channel entry retrieval (idlist.c) */
@@ -975,6 +1321,7 @@ SilcClientEntry silc_client_get_client_by_id(SilcClient client,
  *    silc_client_get_client_by_id_resolve(SilcClient client,
  *                                         SilcClientConnection conn,
  *                                         SilcClientID *client_id,
+ *                                         SilcBuffer attributes,
  *                                         SilcGetClientCallback completion,
  *                                         void *context);
  *
@@ -986,10 +1333,18 @@ SilcClientEntry silc_client_get_client_by_id(SilcClient client,
  *    is its ID. When server returns the client information it will be
  *    cache and can be accessed locally at a later time.
  *
+ *    If the `attributes' is non-NULL then the buffer includes Requested
+ *    Attributes which can be used to fetch very detailed information
+ *    about the user. If it is NULL then only normal WHOIS query is
+ *    made (for more information about attributes see SilcAttribute).
+ *    Caller may create the `attributes' with silc_client_attributes_request
+ *    function.
+ *
  ***/
 void silc_client_get_client_by_id_resolve(SilcClient client,
                                          SilcClientConnection conn,
                                          SilcClientID *client_id,
+                                         SilcBuffer attributes,
                                          SilcGetClientCallback completion,
                                          void *context);
 
@@ -1052,16 +1407,14 @@ SilcChannelEntry silc_client_get_channel(SilcClient client,
                                         SilcClientConnection conn,
                                         char *channel);
 
-/****f* silcclient/SilcClientAPI/silc_client_get_channel_id_resolve
+/****f* silcclient/SilcClientAPI/silc_client_get_channel_by_id
  *
  * SYNOPSIS
  *
- *    void 
- *    silc_client_get_channel_by_id_resolve(SilcClient client,
- *                                          SilcClientConnection conn,
- *                                          SilcChannelID *channel_id,
- *                                          SilcGetClientCallback completion,
- *                                          void *context);
+ *    SilcChannelEntry
+ *    silc_client_get_channel_by_id(SilcClient client,
+ *                                  SilcClientConnection conn,
+ *                                  SilcChannelID *channel_id);
  *
  * DESCRIPTION
  *
@@ -1185,92 +1538,47 @@ SilcChannelUser silc_client_on_channel(SilcChannelEntry channel,
 
 /* Command management (command.c) */
 
-/****f* silcclient/SilcClientAPI/silc_client_command_alloc
- *
- * SYNOPSIS
- *
- *    SilcClientCommandContext silc_client_command_alloc(void);
- *
- * DESCRIPTION
- *
- *    Allocate Command Context. The context is defined in `command.h' file.
- *    The context is used by the library commands and applications should use
- *    it as well. However, application may choose to use some own context
- *    for its local commands. All library commands, however, must use this
- *    context. 
- *
- ***/
-SilcClientCommandContext silc_client_command_alloc(void);
-
-/****f* silcclient/SilcClientAPI/silc_client_command_free
- *
- * SYNOPSIS
- *
- *    void silc_client_command_free(SilcClientCommandContext ctx);
- *
- * DESCRIPTION
- *
- *    Free command context and its internals.  If the contex was duplicated
- *    with silc_client_command_dup this may not actually free the data, 
- *    instead it will decrease the reference counter of the context.  The
- *    context will be freed when the reference counter hits zero.
- *
- ***/
-void silc_client_command_free(SilcClientCommandContext ctx);
-
-/****f* silcclient/SilcClientAPI/silc_client_command_dup
+/****f* silcclient/SilcClientAPI/silc_client_command_call
  *
  * SYNOPSIS
  *
- *    SilcClientCommandContext 
- *    silc_client_command_dup(SilcClientCommandContext ctx);
+ *    bool silc_client_command_call(SilcClient client,
+ *                                  SilcClientConnection conn,
+ *                                  const char *command_line, ...);
  *
  * DESCRIPTION
  *
- *    Duplicate Command Context by adding reference counter. The context won't
- *    be free'd untill it hits zero. 
+ *    Calls and executes the command indicated by the `command_name'.
+ *    The `command_line' is a string which includes the command's name and
+ *    its arguments separated with whitespaces (' ').  If `command_line'
+ *    is non-NULL then all variable arguments are ignored by default.
  *
- ***/
-SilcClientCommandContext silc_client_command_dup(SilcClientCommandContext ctx);
-
-/****f* silcclient/SilcClientAPI/silc_client_command_find
+ *    If `command_line' is NULL, then the variable arguments define the
+ *    command's name and its arguments.  The first variable argument must
+ *    be the command name.  The variable argument list must be terminated
+ *    with NULL.
  *
- * SYNOPSIS
+ *    Returns FALSE if the command is not known and TRUE after command.
+ *    execution.  The "command" client operation is called when the
+ *    command is executed to indicate whether the command executed
+ *    successfully or not.
  *
- *    SilcClientCommand silc_client_command_find(SilcClient client,
- *                                               const char *name);
+ *    The "command_reply" client operation will be called when reply is
+ *    received from the server to the command.  Application may also use
+ *    the silc_client_command_pending to attach to the command reply.
+ *    The command identifier for silc_client_command_pending function after
+ *    this function call is conn->cmd_ident, which application may use.
  *
- * DESCRIPTION
+ * EXAMPLE
  *
- *    Finds and returns a pointer to the command list. Return NULL if the
- *    command is not found. See the `command.[ch]' for the command list. 
- *    Command names are not case-sensitive.
+ *    silc_client_command_call(client, conn, NULL, "PING", "silc.silcnet.org",
+ *                             NULL);
+ *    silc_client_command_call(client, conn, "PING silc.silcnet.org");
  *
  ***/
-SilcClientCommand silc_client_command_find(SilcClient client,
-                                          const char *name);
-
-/****f* silcclient/SilcClientAPI/silc_client_command_call
- *
- * SYNOPSIS
- *
- *    void silc_client_command_call(SilcClientCommand command);
- *
- * DESCRIPTION
- *
- *    Calls the command (executes it).  Application can call this after
- *    it has allocated the SilcClientCommandContext with the function
- *    silc_client_command_alloc and found the command from the client
- *    library by calling silc_client_command_find.  This will execute
- *    the command.
- *
- *    Application can call the command function directly too if it
- *    wishes to do so.  See the command.h for details of the
- *    SilcClientCommand structure.
- *
- ***/
-void silc_client_command_call(SilcClientCommand command,
-                             SilcClientCommandContext cmd);
+bool silc_client_command_call(SilcClient client,
+                             SilcClientConnection conn,
+                             const char *command_line, ...);
 
 /****f* silcclient/SilcClientAPI/silc_client_command_send
  *
@@ -1288,6 +1596,16 @@ void silc_client_command_call(SilcClientCommand command,
  *    to perform the commands by itself, it can do so and send the data
  *    directly to the server using this function.  If application is using
  *    the silc_client_command_call, this function is usually not used.
+ *    Note that this overriders the Client Librarys commands and sends
+ *    the command packet directly to server.
+ *
+ *    The variable arguments are a pair of { type, data, data_length },
+ *    and the `argc' is the number of these pairs.
+ *
+ * EXAMPLE
+ *
+ *    silc_client_command_send(client, conn, SILC_COMMAND_WHOIS, 0, 1,
+ *                             1, nickname, strlen(nickname));
  *
  ***/
 void silc_client_command_send(SilcClient client, SilcClientConnection conn,
@@ -1306,15 +1624,43 @@ void silc_client_command_send(SilcClient client, SilcClientConnection conn,
  *
  * DESCRIPTION
  *
- *    Add new pending command to be executed when reply to a command has been
- *    received.  The `reply_cmd' is the command that will call the `callback'
- *    with `context' when reply has been received.  If `ident' is non-zero
- *    the `callback' will be executed when received reply with command 
- *    identifier `ident'. 
+ *    This function can be used to add pending command callback to be
+ *    called when an command reply is received to an earlier sent command.
+ *    The `reply_cmd' is the command that must be received in order for
+ *    the pending command callback indicated by `callback' to be called.
+ *    The `callback' will deliver the `context' and 
+ *    SilcClientCommandReplyContext which includes the internals of the 
+ *    command reply.
+ *
+ *    The `ident' is a command identifier which was set for the earlier
+ *    sent command.  The command reply will include the same identifier
+ *    and pending command callback will be called when the reply is 
+ *    received with the same command identifier.  It is possible to
+ *    add multiple pending command callbacks for same command and for
+ *    same identifier.
  *
- *    Note that the application is notified about the received command
+ *    Application may use this function to add its own command reply
+ *    handlers if it wishes not to use the standard `command_reply'
+ *    client operation.  However, note that the pending command callback
+ *    does not deliver parsed command reply, but application must parse
+ *    it itself.
+ *
+ *    Note also that the application is notified about the received command
  *    reply through the `command_reply' client operation before calling
- *    the `callback` pending command callback.
+ *    the `callback` pending command callback.  That is the normal 
+ *    command reply handling, and is called regardless whether pending
+ *    command callbacks are used or not.
+ *
+ *    Commands that application calls with silc_client_command_call
+ *    will use a command identifier from conn->cmd_ident variable.  After
+ *    calling the silc_client_command_call, the conn->cmd_ident includes
+ *    the command identifier that was used for the command sending.
+ *
+ * EXAMPLE
+ *
+ *    silc_client_command_call(client, conn, "PING silc.silcnet.org");
+ *    silc_client_command_pending(conn, SILC_COMMAND_PING, conn->cmd_ident,
+ *                                my_ping_handler, my_ping_context);
  *
  ***/
 void silc_client_command_pending(SilcClientConnection conn,
@@ -1330,14 +1676,15 @@ void silc_client_command_pending(SilcClientConnection conn,
  *
  * SYNOPSIS
  *
- *    int silc_client_add_private_message_key(SilcClient client,
- *                                            SilcClientConnection conn,
- *                                            SilcClientEntry client_entry,
- *                                            char *cipher,
- *                                            unsigned char *key,
- *                                            SilcUInt32 key_len,
- *                                            bool generate_key,
- *                                            bool responder);
+ *    bool silc_client_add_private_message_key(SilcClient client,
+ *                                             SilcClientConnection conn,
+ *                                             SilcClientEntry client_entry,
+ *                                             const char *cipher,
+ *                                             const char *hmac,
+ *                                             unsigned char *key,
+ *                                             SilcUInt32 key_len,
+ *                                             bool generate_key,
+ *                                             bool responder);
  *
  * DESCRIPTION
  *
@@ -1346,9 +1693,9 @@ void silc_client_command_pending(SilcClientConnection conn,
  *    indicated by the `client_entry'. If the `key' is NULL and the boolean
  *    value `generate_key' is TRUE the library will generate random key.
  *    The `key' maybe for example pre-shared-key, passphrase or similar.
- *    The `cipher' MAY be provided but SHOULD be NULL to assure that the
- *    requirements of the SILC protocol are met. The API, however, allows
- *    to allocate any cipher.
+ *    The `cipher' and `hmac' MAY be provided but SHOULD be NULL to assure
+ *    that the requirements of the SILC protocol are met. The API, however,
+ *    allows to allocate any cipher and HMAC.
  *
  *    If `responder' is TRUE then the sending and receiving keys will be
  *    set according the client being the receiver of the private key.  If
@@ -1363,75 +1710,52 @@ void silc_client_command_pending(SilcClientConnection conn,
  *    otherwise. 
  *
  ***/
-int silc_client_add_private_message_key(SilcClient client,
-                                       SilcClientConnection conn,
-                                       SilcClientEntry client_entry,
-                                       char *cipher,
-                                       unsigned char *key,
-                                       SilcUInt32 key_len,
-                                       bool generate_key,
-                                       bool responder);
+bool silc_client_add_private_message_key(SilcClient client,
+                                        SilcClientConnection conn,
+                                        SilcClientEntry client_entry,
+                                        const char *cipher,
+                                        const char *hmac,
+                                        unsigned char *key,
+                                        SilcUInt32 key_len,
+                                        bool generate_key,
+                                        bool responder);
 
 /****f* silcclient/SilcClientAPI/silc_client_add_private_message_key_ske
  *
  * SYNOPSIS
  *
- *    int silc_client_add_private_message_key_ske(SilcClient client,
- *                                                SilcClientConnection conn,
- *                                                SilcClientEntry client_entry,
- *                                                char *cipher,
- *                                                SilcSKEKeyMaterial *key);
+ *    bool
+ *    silc_client_add_private_message_key_ske(SilcClient client,
+ *                                            SilcClientConnection conn,
+ *                                            SilcClientEntry client_entry,
+ *                                            const char *cipher,
+ *                                            const char *hmac,
+ *                                            SilcSKEKeyMaterial *key);
  *
  * DESCRIPTION
  *
  *    Same as silc_client_add_private_message_key but takes the key material
  *    from the SKE key material structure. This structure is received if
  *    the application uses the silc_client_send_key_agreement to negotiate
- *    the key material. The `cipher' SHOULD be provided as it is negotiated
- *    also in the SKE protocol. 
+ *    the key material. The `cipher' and `hmac' SHOULD be provided as it is
+ *    negotiated also in the SKE protocol. 
  *
  ***/
-int silc_client_add_private_message_key_ske(SilcClient client,
-                                           SilcClientConnection conn,
-                                           SilcClientEntry client_entry,
-                                           char *cipher,
-                                           SilcSKEKeyMaterial *key,
-                                           bool responder);
-
-/****f* silcclient/SilcClientAPI/silc_client_send_private_message_key
- *
- * SYNOPSIS
- *
- *    int silc_client_send_private_message_key(SilcClient client,
- *                                             SilcClientConnection conn,
- *                                             SilcClientEntry client_entry,
- *                                             int force_send);
- *
- * DESCRIPTION
- *
- *    Sends private message key payload to the remote client indicated by
- *    the `client_entry'. If the `force_send' is TRUE the packet is sent
- *    immediately. Returns FALSE if error occurs, TRUE otherwise. The
- *    application should call this function after setting the key to the
- *    client.
- *
- *    Note that the key sent using this function is sent to the remote client
- *    through the SILC network. The packet is protected using normal session
- *    keys. 
- *
- ***/
-int silc_client_send_private_message_key(SilcClient client,
-                                        SilcClientConnection conn,
-                                        SilcClientEntry client_entry,
-                                        int force_send);
+bool silc_client_add_private_message_key_ske(SilcClient client,
+                                            SilcClientConnection conn,
+                                            SilcClientEntry client_entry,
+                                            const char *cipher,
+                                            const char *hmac,
+                                            SilcSKEKeyMaterial *key,
+                                            bool responder);
 
 /****f* silcclient/SilcClientAPI/silc_client_del_private_message_key
  *
  * SYNOPSIS
  *
- *    int silc_client_del_private_message_key(SilcClient client,
- *                                            SilcClientConnection conn,
- *                                            SilcClientEntry client_entry);
+ *    bool silc_client_del_private_message_key(SilcClient client,
+ *                                             SilcClientConnection conn,
+ *                                             SilcClientEntry client_entry);
  *
  * DESCRIPTION
  *
@@ -1440,9 +1764,9 @@ int silc_client_send_private_message_key(SilcClient client,
  *    client. Returns FALSE on error, TRUE otherwise. 
  *
  ***/
-int silc_client_del_private_message_key(SilcClient client,
-                                       SilcClientConnection conn,
-                                       SilcClientEntry client_entry);
+bool silc_client_del_private_message_key(SilcClient client,
+                                        SilcClientConnection conn,
+                                        SilcClientEntry client_entry);
 
 /****f* silcclient/SilcClientAPI/silc_client_list_private_message_keys
  *
@@ -1493,14 +1817,14 @@ void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys,
  *
  * SYNOPSIS
  *
- *    int silc_client_add_channel_private_key(SilcClient client,
- *                                            SilcClientConnection conn,
- *                                            SilcChannelEntry channel,
- *                                            const char *name,
- *                                            char *cipher,
- *                                            char *hmac,
- *                                            unsigned char *key,
- *                                            SilcUInt32 key_len);
+ *    bool silc_client_add_channel_private_key(SilcClient client,
+ *                                             SilcClientConnection conn,
+ *                                             SilcChannelEntry channel,
+ *                                             const char *name,
+ *                                             char *cipher,
+ *                                             char *hmac,
+ *                                             unsigned char *key,
+ *                                             SilcUInt32 key_len);
  * 
  * DESCRIPTION
  *
@@ -1534,22 +1858,22 @@ void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys,
  *    as channel private key. However, this API allows it. 
  *
  ***/
-int silc_client_add_channel_private_key(SilcClient client,
-                                       SilcClientConnection conn,
-                                       SilcChannelEntry channel,
-                                       const char *name,
-                                       char *cipher,
-                                       char *hmac,
-                                       unsigned char *key,
-                                       SilcUInt32 key_len);
+bool silc_client_add_channel_private_key(SilcClient client,
+                                        SilcClientConnection conn,
+                                        SilcChannelEntry channel,
+                                        const char *name,
+                                        char *cipher,
+                                        char *hmac,
+                                        unsigned char *key,
+                                        SilcUInt32 key_len);
 
 /****f* silcclient/SilcClientAPI/silc_client_del_channel_private_keys
  *
  * SYNOPSIS
  *
- *    int silc_client_del_channel_private_keys(SilcClient client,
- *                                             SilcClientConnection conn,
- *                                             SilcChannelEntry channel);
+ *    bool silc_client_del_channel_private_keys(SilcClient client,
+ *                                              SilcClientConnection conn,
+ *                                              SilcChannelEntry channel);
  * 
  * DESCRIPTION
  *
@@ -1558,15 +1882,15 @@ int silc_client_add_channel_private_key(SilcClient client,
  *    on error, TRUE otherwise. 
  *
  ***/
-int silc_client_del_channel_private_keys(SilcClient client,
-                                        SilcClientConnection conn,
-                                        SilcChannelEntry channel);
+bool silc_client_del_channel_private_keys(SilcClient client,
+                                         SilcClientConnection conn,
+                                         SilcChannelEntry channel);
 
 /****f* silcclient/SilcClientAPI/silc_client_del_channel_private_key
  *
  * SYNOPSIS
  *
- *    int silc_client_del_channel_private_key(SilcClient client,
+ *    bool silc_client_del_channel_private_key(SilcClient client,
  *                                            SilcClientConnection conn,
  *                                            SilcChannelEntry channel,
  *                                            SilcChannelPrivateKey key);
@@ -1581,10 +1905,10 @@ int silc_client_del_channel_private_keys(SilcClient client,
  *    on error, TRUE otherwise. 
  *
  ***/
-int silc_client_del_channel_private_key(SilcClient client,
-                                       SilcClientConnection conn,
-                                       SilcChannelEntry channel,
-                                       SilcChannelPrivateKey key);
+bool silc_client_del_channel_private_key(SilcClient client,
+                                        SilcClientConnection conn,
+                                        SilcChannelEntry channel,
+                                        SilcChannelPrivateKey key);
 
 /****f* silcclient/SilcClientAPI/silc_client_list_channel_private_keys
  *
@@ -1840,7 +2164,6 @@ void silc_client_set_away_message(SilcClient client,
                                  SilcClientConnection conn,
                                  char *message);
 
-
 /****f* silcclient/SilcClientAPI/SilcConnectionAuthRequest
  *
  * SYNOPSIS
@@ -1989,6 +2312,7 @@ typedef void (*SilcClientFileMonitor)(SilcClient client,
  *                          void *monitor_context,
  *                          const char *local_ip,
  *                          SilcUInt32 local_port,
+ *                          bool do_not_bind,
  *                          SilcClientEntry client_entry,
  *                          const char *filepath);
  *                          SilcUInt32 *session_id);
@@ -2002,7 +2326,7 @@ typedef void (*SilcClientFileMonitor)(SilcClient client,
  *    transmission of the file.
  *
  *    This returns a file session ID for the file transmission to the
- *    `session_id' pointer..  It can be used to close the session (and
+ *    `session_id' pointer.  It can be used to close the session (and
  *    abort the file transmission) by calling the silc_client_file_close
  *    function.  The session ID is also returned in the `monitor' callback. 
  *
@@ -2010,9 +2334,9 @@ typedef void (*SilcClientFileMonitor)(SilcClient client,
  *    listener for key exchange protocol to that IP.  If `local_port' is
  *    non-zero that port is used.  If `local_ip' is NULL then this will
  *    automatically attempt to bind it to local IP address of the machine.
- *    If that fails then this does not bind to any address and port, and
- *    assume that the remote client will provide the listener for the
- *    key exchange protocol.
+ *    If `do_not_bind' is TRUE then the `local_ip' and `local_port' are
+ *    ignored and it is expected that the receiver will provide the
+ *    point of contact.  This is usefull if the sender is behind NAT.
  *
  *    If error will occur during the file transfer process the error
  *    status will be returned in the monitor callback.  In this case
@@ -2027,6 +2351,7 @@ silc_client_file_send(SilcClient client,
                      void *monitor_context,
                      const char *local_ip,
                      SilcUInt32 local_port,
+                     bool do_not_bind,
                      SilcClientEntry client_entry,
                      const char *filepath,
                      SilcUInt32 *session_id);
@@ -2040,6 +2365,7 @@ silc_client_file_send(SilcClient client,
  *                             SilcClientConnection conn,
  *                             SilcClientFileMonitor monitor,
  *                             void *monitor_context,
+ *                             const char *path,
  *                             SilcUInt32 session_id);
  *
  * DESCRIPTION
@@ -2049,7 +2375,9 @@ silc_client_file_send(SilcClient client,
  *    received in the `ftp' client operation function.  This will actually
  *    perform the key agreement protocol with the remote client before
  *    actually starting the file transmission.  The `monitor' callback
- *    will be called to monitor the transmission.
+ *    will be called to monitor the transmission.  If `path' is non NULL
+ *    the file will be saved into that directory.  If NULL the file is
+ *    saved in the current working directory.
  *
  *    If error will occur during the file transfer process the error
  *    status will be returned in the monitor callback.  In this case
@@ -2062,6 +2390,7 @@ silc_client_file_receive(SilcClient client,
                         SilcClientConnection conn,
                         SilcClientFileMonitor monitor,
                         void *monitor_context,
+                        const char *path,
                         SilcUInt32 session_id);
 
 /****f* silcclient/SilcClientAPI/silc_client_file_close
@@ -2085,7 +2414,137 @@ SilcClientFileError silc_client_file_close(SilcClient client,
                                           SilcClientConnection conn,
                                           SilcUInt32 session_id);
 
-#include "client.h"
+/****f* silcclient/SilcClientAPI/silc_client_attribute_add
+ *
+ * SYNOPSIS
+ *
+ *    SilcAttributePayload
+ *    silc_client_attribute_add(SilcClient client,
+ *                              SilcClientConnection conn,
+ *                              SilcAttribute attribute,
+ *                              void *object,
+ *                              SilcUInt32 object_size);
+ *
+ * DESCRIPTION
+ *
+ *    Add new Requsted Attribute for WHOIS command to the client library.
+ *    The `attribute' object indicated by `object' is added and allocated
+ *    SilcAttributePayload is returned.  The `object' must be of correct
+ *    type and of correct size.  See the SilcAttribute for object types
+ *    for different attributes.  You may also get all added attributes
+ *    from the client with silc_client_attributes_get function.
+ *
+ *    Requested Attributes are different personal information about the
+ *    user, status information and other information which other users
+ *    may query with WHOIS command.  Application may set these so that
+ *    if someone sends WHOIS query these attributes will be replied back
+ *    to the sender.  The library always puts the public key to the
+ *    Requested Attributes, but if application wishes to add additional
+ *    public keys (or certificates) it can be done with this interface.
+ *    Library also always computes digital signature of the attributes
+ *    automatically, so application does not need to do that.
+ *
+ ***/
+SilcAttributePayload silc_client_attribute_add(SilcClient client,
+                                              SilcClientConnection conn,
+                                              SilcAttribute attribute,
+                                              void *object,
+                                              SilcUInt32 object_size);
+
+/****f* silcclient/SilcClientAPI/silc_client_attribute_del
+ *
+ * SYNOPSIS
+ *
+ *    bool silc_client_attribute_del(SilcClient client,
+ *                                   SilcClientConnection conn,
+ *                                   SilcAttribute attribute,
+ *                                   SilcAttributePayload attr);
+ *
+ * DESCRIPTION
+ *
+ *    Delete a Requested Attribute from the client.  If the `attribute'
+ *    is non-zero then all attributes of that type are deleted and the
+ *    `attr' is ignored.  If `attr' is non-NULL then that specific
+ *    attribute is deleted and `attribute' is ignored.
+ *    
+ *    You may get all added attributes with the function
+ *    silc_client_attributes_get and to get the SilcAttributePayload.
+ *    This function Returns TRUE if the attribute was found and deleted.
+ *
+ ***/
+bool silc_client_attribute_del(SilcClient client,
+                              SilcClientConnection conn,
+                              SilcAttribute attribute,
+                              SilcAttributePayload attr);
+
+/****f* silcclient/SilcClientAPI/silc_client_attributes_get
+ *
+ * SYNOPSIS
+ *
+ *    const SilcHashTable
+ *    silc_client_attributes_get(SilcClient client,
+ *                               SilcClientConnection conn);
+ *
+ * DESCRIPTION
+ *
+ *    Returns pointer to the SilcHashTable which includes all the added
+ *    Requested Attributes.  The caller must not free the hash table.
+ *    The caller may use SilcHashTableList and silc_hash_table_list to
+ *    traverse the table.  Each entry in the hash table is one added
+ *    SilcAttributePayload.  It is possible to delete a attribute
+ *    payload while traversing the table.
+ *
+ ***/
+const SilcHashTable silc_client_attributes_get(SilcClient client,
+                                              SilcClientConnection conn);
+
+/****f* silcclient/SilcClientAPI/silc_client_attributes_request
+ *
+ * SYNOPSIS
+ *
+ *    SilcBuffer silc_client_attributes_request(SilcAttribute attribute, ...);
+ *
+ * DESCRIPTION
+ *
+ *    Constructs a Requested Attributes buffer. If the `attribute' is zero (0)
+ *    then all attributes are requested.  Alternatively, `attribute' and
+ *    all variable arguments can each be requested attribute.  In this case
+ *    the last must be set to zero (0) to complete the variable list of
+ *    requested attributes.  See SilcAttribute for all attributes.
+ *    You can give the returned buffer as argument to for example
+ *    silc_client_get_client_by_id_resolve function.
+ *
+ ***/
+SilcBuffer silc_client_attributes_request(SilcAttribute attribute, ...);
+
+/* Low level packet sending functions */
+
+/****f* silcclient/SilcClientAPI/silc_client_send_packet
+ *
+ * SYNOPSIS
+ *
+ *     bool silc_client_send_packet(SilcClient client, 
+ *                                  SilcClientConnection conn,
+ *                                  SilcPacketType type, 
+ *                                  const unsigned char *data, 
+ *                                  SilcUInt32 data_len);
+ *
+ * DESCRIPTION
+ *
+ *    This routine can be used by application to send packets directly
+ *    to a connection indicated by `conn'.  Usually application does not
+ *    need this routine since the Client Library handles the packet
+ *    sending.  The `type' indicates the packet type.  If `data' is
+ *    NULL then empty packet is sent.  This returns FALSE if packet cannot 
+ *    be sent.
+ *
+ ***/
+bool silc_client_send_packet(SilcClient client, 
+                            SilcClientConnection conn,
+                            SilcPacketType type, 
+                            const unsigned char *data, 
+                            SilcUInt32 data_len);
+
 #include "command.h"
 #include "command_reply.h"
 #include "idlist.h"