Merged from silc_1_0_branch.
[silc.git] / lib / silcclient / silcclient.h
index 2dcb7a58a8aaf9bf9c05b1d984a5f303d1afe741..d87dff84b92f2054edc34d15498df2fa459195e0 100644 (file)
 extern "C" {
 #endif
 
 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 SilcChannelPrivateKeyStruct *SilcChannelPrivateKey;
-typedef struct SilcChannelUserStruct *SilcChannelUser;
+#include "client.h"
 
 /* General definitions */
 
 
 /* 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
 /****d* silcclient/SilcClientAPI/SilcKeyAgreementStatus
  *
  * NAME
@@ -93,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_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;
 /***/
 
 } SilcKeyAgreementStatus;
 /***/
 
@@ -150,6 +379,28 @@ typedef struct {
 } *SilcPrivateMessageKeys;
 /***/
 
 } *SilcPrivateMessageKeys;
 /***/
 
+/****s* silcclient/SilcClientAPI/SilcChannelPrivateKey
+ *
+ * NAME
+ *
+ *    typedef struct SilcChannelPrivateKeyStruct { ... }
+ *                      *SilcChannelPrivateKey;
+ *
+ * DESCRIPTION
+ *
+ *    Structure to hold one channel private key. The array of this structure
+ *    is returned by silc_client_list_channel_private_keys function.
+ *
+ * SOURCE
+ */
+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 */
+};
+/***/
 
 /****f* silcclient/SilcClientAPI/SilcAskPassphrase
  *
 
 /****f* silcclient/SilcClientAPI/SilcAskPassphrase
  *
@@ -163,7 +414,9 @@ typedef struct {
  *
  *    Ask passphrase callback. This is called by the application when the
  *    library calls `ask_passphrase' client operation.  The callback delivers
  *
  *    Ask passphrase callback. This is called by the application when the
  *    library calls `ask_passphrase' client operation.  The callback delivers
- *    the passphrase to the library.
+ *    the passphrase to the library.  The passphrases in SILC protocol
+ *    MUST be in UTF-8 encoding, therefore the `passphrase' SHOULD be UTF-8
+ *    encoded, and if it is not then library will attempt to encode it.
  *
  ***/
 typedef void (*SilcAskPassphrase)(unsigned char *passphrase,
  *
  ***/
 typedef void (*SilcAskPassphrase)(unsigned char *passphrase,
@@ -232,6 +485,28 @@ typedef enum {
 } SilcClientMessageType;
 /***/
 
 } 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
 /****s* silcclient/SilcClientAPI/SilcClientOperations
  *
  * NAME
@@ -251,23 +526,32 @@ 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.
   /* 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 
      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, 
   void (*channel_message)(SilcClient client, SilcClientConnection conn, 
                          SilcClientEntry sender, SilcChannelEntry channel, 
-                         SilcMessageFlags flags, char *msg);
+                         SilcMessagePayload payload, SilcMessageFlags flags,
+                         const unsigned char *message,
+                         SilcUInt32 message_len);
 
   /* Private message to the client. The `sender' is the sender of the
 
   /* 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,
   void (*private_message)(SilcClient client, SilcClientConnection conn,
-                         SilcClientEntry sender, SilcMessageFlags flags,
-                         char *msg);
+                         SilcClientEntry sender, SilcMessagePayload payload,
+                         SilcMessageFlags flags,
+                         const unsigned char *message,
+                         SilcUInt32 message_len);
 
   /* Notify message to the client. The notify arguments are sent in the
      same order as servers sends them. The arguments are same as received
 
   /* Notify message to the client. The notify arguments are sent in the
      same order as servers sends them. The arguments are same as received
@@ -289,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, 
      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
 
   /* Command reply handler. This function is called always in the command reply
      function. If error occurs it will be called as well. Normal scenario
@@ -307,20 +591,32 @@ typedef struct {
      the command reply status server returned. The `command' is the command
      reply being processed. The function has variable argument list and each
      command defines the number and type of arguments it passes to the
      the command reply status server returned. The `command' is the command
      reply being processed. The function has variable argument list and each
      command defines the number and type of arguments it passes to the
-     application (on error they are not sent). */
+     application (on error they are not sent).
+
+     The arguments are sent in the same order as servers sends them.  The 
+     arguments are same as received from the server except for ID's.  If 
+     ID is received application receives the corresponding entry to the 
+     ID. For example, if Client ID is receives application receives 
+     SilcClientEntry. */
   void (*command_reply)(SilcClient client, SilcClientConnection conn,
   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
 
   /* Called to indicate that connection was either successfully established
      or connecting failed.  This is also the first time application receives
-     the SilcClientConnection objecet which it should save somewhere.
-     If the `success' is FALSE the application must always call the function
+     the SilcClientConnection object which it should save somewhere.
+     The `status' indicated whether the connection were successful.  If it
+     is error value the application must always call the function
      silc_client_close_connection. */
      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
 
   /* Find authentication method and authentication data by hostname and
      port. The hostname may be IP address as well. When the authentication
@@ -333,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
 
   /* 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,
   void (*verify_public_key)(SilcClient client, SilcClientConnection conn,
                            SilcSocketType conn_type, unsigned char *pk, 
                            SilcUInt32 pk_len, SilcSKEPKType pk_type,
@@ -342,7 +639,8 @@ typedef struct {
 
   /* Ask (interact, that is) a passphrase from user. The passphrase is
      returned to the library by calling the `completion' callback with
 
   /* Ask (interact, that is) a passphrase from user. The passphrase is
      returned to the library by calling the `completion' callback with
-     the `context'. */
+     the `context'. The returned passphrase SHOULD be in UTF-8 encoded,
+     if not then the library will attempt to encode. */
   void (*ask_passphrase)(SilcClient client, SilcClientConnection conn,
                         SilcAskPassphrase completion, void *context);
 
   void (*ask_passphrase)(SilcClient client, SilcClientConnection conn,
                         SilcAskPassphrase completion, void *context);
 
@@ -363,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. */
      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
 
   /* Notifies application that file transfer protocol session is being
      requested by the remote client indicated by the `client_entry' from
@@ -377,6 +675,26 @@ typedef struct {
   void (*ftp)(SilcClient client, SilcClientConnection conn,
              SilcClientEntry client_entry, SilcUInt32 session_id,
              const char *hostname, SilcUInt16 port);
   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;
 /***/
 
 } SilcClientOperations;
 /***/
 
@@ -479,6 +797,15 @@ typedef struct {
      nickname string whenever it needs the true nickname. */
   SilcNicknameFormatParse nickname_parse;
 
      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;
 /***/
 
 } SilcClientParams;
 /***/
 
@@ -501,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)
  *    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,
  *
  ***/
 SilcClient silc_client_alloc(SilcClientOperations *ops, 
                             SilcClientParams *params,
                             void *application,
-                            const char *silc_version);
+                            const char *version_string);
 
 /****f* silcclient/SilcClientAPI/silc_client_free
  *
 
 /****f* silcclient/SilcClientAPI/silc_client_free
  *
@@ -528,7 +856,7 @@ void silc_client_free(SilcClient client);
  *
  * SYNOPSIS
  *
  *
  * SYNOPSIS
  *
- *    int silc_client_init(SilcClient client);
+ *    bool silc_client_init(SilcClient client);
  *
  * DESCRIPTION
  *
  *
  * DESCRIPTION
  *
@@ -537,7 +865,7 @@ void silc_client_free(SilcClient client);
  *    client. Returns FALSE if error occurred, TRUE otherwise.
  *
  ***/
  *    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
  *
 
 /****f* silcclient/SilcClientAPI/silc_client_run
  *
@@ -549,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.
  *
  *    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);
  *
  ***/
 void silc_client_run(SilcClient client);
@@ -590,12 +919,45 @@ void silc_client_stop(SilcClient client);
 
 /* Connecting functions (client.c) */
 
 
 /* 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
  *
 /****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
  *
  *
  * DESCRIPTION
  *
@@ -605,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
  *    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
  *
 
 /****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
  *
  *
  * DESCRIPTION
  *
@@ -626,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
  *    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.
  *
  ***/
  *    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
  *
 
 /****f* silcclient/SilcClientAPI/silc_client_del_connection
  *
@@ -713,22 +1085,15 @@ void silc_client_start_key_exchange(SilcClient client,
  * SYNOPSIS
  *
  *    void silc_client_close_connection(SilcClient client,
  * SYNOPSIS
  *
  *    void silc_client_close_connection(SilcClient client,
- *                                      SilcSocketConnection sock,
  *                                      SilcClientConnection conn);
  *
  * DESCRIPTION
  *
  *    Closes connection to remote end. Free's all allocated data except
  *    for some information such as nickname etc. that are valid at all time. 
  *                                      SilcClientConnection conn);
  *
  * DESCRIPTION
  *
  *    Closes connection to remote end. Free's all allocated data except
  *    for some information such as nickname etc. that are valid at all time. 
- *    If the `sock' is NULL then the conn->sock will be used.  If `sock' is
- *    provided it will be checked whether the sock and `conn->sock' are the
- *    same (they can be different, ie. a socket can use `conn' as its
- *    connection but `conn->sock' might be actually a different connection
- *    than the `sock'). 
  *
  ***/
 void silc_client_close_connection(SilcClient client,
  *
  ***/
 void silc_client_close_connection(SilcClient client,
-                                 SilcSocketConnection sock,
                                  SilcClientConnection conn);
 
 
                                  SilcClientConnection conn);
 
 
@@ -745,7 +1110,7 @@ void silc_client_close_connection(SilcClient client,
  *                                          SilcMessageFlags flags,
  *                                          unsigned char *data, 
  *                                          SilcUInt32 data_len, 
  *                                          SilcMessageFlags flags,
  *                                          unsigned char *data, 
  *                                          SilcUInt32 data_len, 
- *                                          int force_send);
+ *                                          bool_force_send);
  *
  * DESCRIPTION
  *
  *
  * DESCRIPTION
  *
@@ -762,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. 
  *
  *    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,
  ***/
 void silc_client_send_channel_message(SilcClient client, 
                                      SilcClientConnection conn,
@@ -770,7 +1138,7 @@ void silc_client_send_channel_message(SilcClient client,
                                      SilcMessageFlags flags,
                                      unsigned char *data, 
                                      SilcUInt32 data_len, 
                                      SilcMessageFlags flags,
                                      unsigned char *data, 
                                      SilcUInt32 data_len, 
-                                     int force_send);
+                                     bool force_send);
 
 /****f* silcclient/SilcClientAPI/silc_client_send_private_message
  *
 
 /****f* silcclient/SilcClientAPI/silc_client_send_private_message
  *
@@ -782,7 +1150,7 @@ void silc_client_send_channel_message(SilcClient client,
  *                                          SilcMessageFlags flags,
  *                                          unsigned char *data, 
  *                                          SilcUInt32 data_len, 
  *                                          SilcMessageFlags flags,
  *                                          unsigned char *data, 
  *                                          SilcUInt32 data_len, 
- *                                          int force_send);
+ *                                          bool force_send);
  *
  * DESCRIPTION
  *
  *
  * DESCRIPTION
  *
@@ -794,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. 
  *
  *    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,
  ***/
 void silc_client_send_private_message(SilcClient client,
                                      SilcClientConnection conn,
@@ -801,7 +1172,7 @@ void silc_client_send_private_message(SilcClient client,
                                      SilcMessageFlags flags,
                                      unsigned char *data, 
                                      SilcUInt32 data_len, 
                                      SilcMessageFlags flags,
                                      unsigned char *data, 
                                      SilcUInt32 data_len, 
-                                     int force_send);
+                                     bool force_send);
 
 
 /* Client and Channel entry retrieval (idlist.c) */
 
 
 /* Client and Channel entry retrieval (idlist.c) */
@@ -950,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,
  *    silc_client_get_client_by_id_resolve(SilcClient client,
  *                                         SilcClientConnection conn,
  *                                         SilcClientID *client_id,
+ *                                         SilcBuffer attributes,
  *                                         SilcGetClientCallback completion,
  *                                         void *context);
  *
  *                                         SilcGetClientCallback completion,
  *                                         void *context);
  *
@@ -961,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.
  *
  *    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,
  ***/
 void silc_client_get_client_by_id_resolve(SilcClient client,
                                          SilcClientConnection conn,
                                          SilcClientID *client_id,
+                                         SilcBuffer attributes,
                                          SilcGetClientCallback completion,
                                          void *context);
 
                                          SilcGetClientCallback completion,
                                          void *context);
 
@@ -1027,16 +1407,14 @@ SilcChannelEntry silc_client_get_channel(SilcClient client,
                                         SilcClientConnection conn,
                                         char *channel);
 
                                         SilcClientConnection conn,
                                         char *channel);
 
-/****f* silcclient/SilcClientAPI/silc_client_get_channel_id_resolve
+/****f* silcclient/SilcClientAPI/silc_client_get_channel_by_id
  *
  * SYNOPSIS
  *
  *
  * 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
  *
  *
  * DESCRIPTION
  *
@@ -1160,92 +1538,47 @@ SilcChannelUser silc_client_on_channel(SilcChannelEntry channel,
 
 /* Command management (command.c) */
 
 
 /* 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
- *
- * SYNOPSIS
- *
- *    SilcClientCommandContext 
- *    silc_client_command_dup(SilcClientCommandContext ctx);
- *
- * DESCRIPTION
- *
- *    Duplicate Command Context by adding reference counter. The context won't
- *    be free'd untill it hits zero. 
- *
- ***/
-SilcClientCommandContext silc_client_command_dup(SilcClientCommandContext ctx);
-
-/****f* silcclient/SilcClientAPI/silc_client_command_find
+/****f* silcclient/SilcClientAPI/silc_client_command_call
  *
  * SYNOPSIS
  *
  *
  * SYNOPSIS
  *
- *    SilcClientCommand silc_client_command_find(SilcClient client,
- *                                               const char *name);
+ *    bool silc_client_command_call(SilcClient client,
+ *                                  SilcClientConnection conn,
+ *                                  const char *command_line, ...);
  *
  * DESCRIPTION
  *
  *
  * DESCRIPTION
  *
- *    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.
- *
- ***/
-SilcClientCommand silc_client_command_find(SilcClient client,
-                                          const char *name);
-
-/****f* silcclient/SilcClientAPI/silc_client_command_call
+ *    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.
  *
  *
- * SYNOPSIS
+ *    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.
  *
  *
- *    void silc_client_command_call(SilcClientCommand command);
+ *    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.
  *
  *
- * DESCRIPTION
+ *    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.
  *
  *
- *    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.
+ * EXAMPLE
  *
  *
- *    Application can call the command function directly too if it
- *    wishes to do so.  See the command.h for details of the
- *    SilcClientCommand structure.
+ *    silc_client_command_call(client, conn, NULL, "PING", "silc.silcnet.org",
+ *                             NULL);
+ *    silc_client_command_call(client, conn, "PING silc.silcnet.org");
  *
  ***/
  *
  ***/
-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
  *
 
 /****f* silcclient/SilcClientAPI/silc_client_command_send
  *
@@ -1263,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.
  *    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,
  *
  ***/
 void silc_client_command_send(SilcClient client, SilcClientConnection conn,
@@ -1281,15 +1624,43 @@ void silc_client_command_send(SilcClient client, SilcClientConnection conn,
  *
  * DESCRIPTION
  *
  *
  * 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.
+ *
+ *    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 that the application is notified about the received command
+ *    Note also that the application is notified about the received command
  *    reply through the `command_reply' client operation before calling
  *    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,
  *
  ***/
 void silc_client_command_pending(SilcClientConnection conn,
@@ -1305,14 +1676,15 @@ void silc_client_command_pending(SilcClientConnection conn,
  *
  * SYNOPSIS
  *
  *
  * 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
  *
  *
  * DESCRIPTION
  *
@@ -1321,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.
  *    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
  *
  *    If `responder' is TRUE then the sending and receiving keys will be
  *    set according the client being the receiver of the private key.  If
@@ -1338,75 +1710,52 @@ void silc_client_command_pending(SilcClientConnection conn,
  *    otherwise. 
  *
  ***/
  *    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
  *
 
 /****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
  *
  * 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. 
- *
- ***/
-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. 
+ *    the key material. The `cipher' and `hmac' SHOULD be provided as it is
+ *    negotiated also in the SKE protocol. 
  *
  ***/
  *
  ***/
-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
  *
 
 /****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
  *
  *
  * DESCRIPTION
  *
@@ -1415,9 +1764,9 @@ int silc_client_send_private_message_key(SilcClient client,
  *    client. Returns FALSE on error, TRUE otherwise. 
  *
  ***/
  *    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
  *
 
 /****f* silcclient/SilcClientAPI/silc_client_list_private_message_keys
  *
@@ -1468,13 +1817,14 @@ void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys,
  *
  * SYNOPSIS
  *
  *
  * SYNOPSIS
  *
- *    int silc_client_add_channel_private_key(SilcClient client,
- *                                            SilcClientConnection conn,
- *                                            SilcChannelEntry channel,
- *                                            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
  *
  * 
  * DESCRIPTION
  *
@@ -1485,6 +1835,7 @@ void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys,
  *    key in order to decrypt the messages. However, it is possible to have
  *    several private keys per one channel. In this case only some of the
  *    clients on the channel may know the one key and only some the other key.
  *    key in order to decrypt the messages. However, it is possible to have
  *    several private keys per one channel. In this case only some of the
  *    clients on the channel may know the one key and only some the other key.
+ *    The `name' can be application given name for the key.
  *
  *    The private key for channel is optional. If it is not set then the
  *    channel messages are encrypted using the channel key generated by the
  *
  *    The private key for channel is optional. If it is not set then the
  *    channel messages are encrypted using the channel key generated by the
@@ -1507,21 +1858,22 @@ void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys,
  *    as channel private key. However, this API allows it. 
  *
  ***/
  *    as channel private key. However, this API allows it. 
  *
  ***/
-int silc_client_add_channel_private_key(SilcClient client,
-                                       SilcClientConnection conn,
-                                       SilcChannelEntry channel,
-                                       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
  *
 
 /****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
  *
  * 
  * DESCRIPTION
  *
@@ -1530,15 +1882,15 @@ int silc_client_add_channel_private_key(SilcClient client,
  *    on error, TRUE otherwise. 
  *
  ***/
  *    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
  *
 
 /****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);
  *                                            SilcClientConnection conn,
  *                                            SilcChannelEntry channel,
  *                                            SilcChannelPrivateKey key);
@@ -1553,10 +1905,10 @@ int silc_client_del_channel_private_keys(SilcClient client,
  *    on error, TRUE otherwise. 
  *
  ***/
  *    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
  *
 
 /****f* silcclient/SilcClientAPI/silc_client_list_channel_private_keys
  *
@@ -1598,6 +1950,27 @@ silc_client_list_channel_private_keys(SilcClient client,
 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
                                           SilcUInt32 key_count);
 
 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
                                           SilcUInt32 key_count);
 
+/****f* silcclient/SilcClientAPI/silc_client_current_channel_private_key
+ *
+ * SYNOPSIS
+ *
+ *    void silc_client_current_channel_private_key(SilcClient client,
+ *                                                 SilcClientConnection conn,
+ *                                                 SilcChannelEntry channel,
+ *                                                 SilcChannelPrivateKey key);
+ *
+ * DESCRIPTION
+ *
+ *    Sets the `key' to be used as current channel private key on the
+ *    `channel'.  Packet sent after calling this function will be secured
+ *    with `key'.
+ *
+ ***/
+void silc_client_current_channel_private_key(SilcClient client,
+                                            SilcClientConnection conn,
+                                            SilcChannelEntry channel,
+                                            SilcChannelPrivateKey key);
+
 
 /* Key Agreement routines (client_keyagr.c) */
 
 
 /* Key Agreement routines (client_keyagr.c) */
 
@@ -1791,7 +2164,6 @@ void silc_client_set_away_message(SilcClient client,
                                  SilcClientConnection conn,
                                  char *message);
 
                                  SilcClientConnection conn,
                                  char *message);
 
-
 /****f* silcclient/SilcClientAPI/SilcConnectionAuthRequest
  *
  * SYNOPSIS
 /****f* silcclient/SilcClientAPI/SilcConnectionAuthRequest
  *
  * SYNOPSIS
@@ -1940,6 +2312,7 @@ typedef void (*SilcClientFileMonitor)(SilcClient client,
  *                          void *monitor_context,
  *                          const char *local_ip,
  *                          SilcUInt32 local_port,
  *                          void *monitor_context,
  *                          const char *local_ip,
  *                          SilcUInt32 local_port,
+ *                          bool do_not_bind,
  *                          SilcClientEntry client_entry,
  *                          const char *filepath);
  *                          SilcUInt32 *session_id);
  *                          SilcClientEntry client_entry,
  *                          const char *filepath);
  *                          SilcUInt32 *session_id);
@@ -1953,7 +2326,7 @@ typedef void (*SilcClientFileMonitor)(SilcClient client,
  *    transmission of the file.
  *
  *    This returns a file session ID for the file transmission to the
  *    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. 
  *
  *    abort the file transmission) by calling the silc_client_file_close
  *    function.  The session ID is also returned in the `monitor' callback. 
  *
@@ -1961,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.
  *    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
  *
  *    If error will occur during the file transfer process the error
  *    status will be returned in the monitor callback.  In this case
@@ -1978,6 +2351,7 @@ silc_client_file_send(SilcClient client,
                      void *monitor_context,
                      const char *local_ip,
                      SilcUInt32 local_port,
                      void *monitor_context,
                      const char *local_ip,
                      SilcUInt32 local_port,
+                     bool do_not_bind,
                      SilcClientEntry client_entry,
                      const char *filepath,
                      SilcUInt32 *session_id);
                      SilcClientEntry client_entry,
                      const char *filepath,
                      SilcUInt32 *session_id);
@@ -1991,6 +2365,7 @@ silc_client_file_send(SilcClient client,
  *                             SilcClientConnection conn,
  *                             SilcClientFileMonitor monitor,
  *                             void *monitor_context,
  *                             SilcClientConnection conn,
  *                             SilcClientFileMonitor monitor,
  *                             void *monitor_context,
+ *                             const char *path,
  *                             SilcUInt32 session_id);
  *
  * DESCRIPTION
  *                             SilcUInt32 session_id);
  *
  * DESCRIPTION
@@ -2000,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
  *    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
  *
  *    If error will occur during the file transfer process the error
  *    status will be returned in the monitor callback.  In this case
@@ -2013,6 +2390,7 @@ silc_client_file_receive(SilcClient client,
                         SilcClientConnection conn,
                         SilcClientFileMonitor monitor,
                         void *monitor_context,
                         SilcClientConnection conn,
                         SilcClientFileMonitor monitor,
                         void *monitor_context,
+                        const char *path,
                         SilcUInt32 session_id);
 
 /****f* silcclient/SilcClientAPI/silc_client_file_close
                         SilcUInt32 session_id);
 
 /****f* silcclient/SilcClientAPI/silc_client_file_close
@@ -2036,7 +2414,137 @@ SilcClientFileError silc_client_file_close(SilcClient client,
                                           SilcClientConnection conn,
                                           SilcUInt32 session_id);
 
                                           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"
 #include "command.h"
 #include "command_reply.h"
 #include "idlist.h"