updates.
authorPekka Riikonen <priikone@silcnet.org>
Mon, 8 Apr 2002 20:56:46 +0000 (20:56 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 8 Apr 2002 20:56:46 +0000 (20:56 +0000)
21 files changed:
CHANGES
TODO
TODO-1.0
apps/irssi/docs/help/in/umode.in
apps/irssi/src/silc/core/client_ops.c
apps/silcd/command.c
apps/silcd/command_reply.c
apps/silcd/packet_receive.c
apps/silcd/packet_send.c
apps/silcd/packet_send.h
doc/draft-riikonen-silc-commands-03.nroff
doc/draft-riikonen-silc-flags-payloads-00.nroff
doc/draft-riikonen-silc-ke-auth-05.nroff
lib/silcclient/client_notify.c
lib/silcclient/command.c
lib/silcclient/command_reply.c
lib/silcclient/command_reply.h
lib/silccore/silcchannel.c
lib/silccore/silccommand.c
lib/silccore/silccommand.h
lib/silccore/silcmode.h

diff --git a/CHANGES b/CHANGES
index 1b200a492da1a072dcf9cb94cc2d6e10cd36b77c..74309ce3538b962247e29e99ed3b4f6659584e75 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,13 @@
+Mon Apr  8 23:57:32 EEST 2002  Pekka Riikonen <priikone@silcnet.org>
+
+       * Redefined the Status Payload to include now two 8 bit fields,
+         instead of one 16 bit field.  This now makes it possible to
+         send list of errors.  Updated the protocol specs and the code
+         in core library, client library and server.  Protocol TODO #1.
+         Affected files are lib/silccore/silccommand.[ch],
+         lib/silcclient/command_reply.[ch], silcd/command.c,
+         silcd/command_reply.c and silcd/packet_receive.[ch].
+
 Mon Apr  8 19:57:40 CEST 2002  Johnny Mnemonic <johnny@themnemonic.org>
 
        * Added config parse status SILC_CONFIG_EPRINTLINE, this status
@@ -16,6 +26,15 @@ Mon Apr  8 19:57:40 CEST 2002  Johnny Mnemonic <johnny@themnemonic.org>
        * Drop root privileges when started in foreground.  Don't drop them
          if debugging also.  Affected file is silcd/silcd.c.
 
+Mon Apr  8 17:00:41 EEST 2002  Pekka Riikonen <priikone@silcnet.org>
+
+       * Added more IM-like features by introducing new user modes
+         for setting various presence information.  Added new modes:
+         INDISPOSED, BUSY, PAGE, HYPER and ROBOT.  Updated protocol
+          specs and code.  Protocol TODO #19. Affected files are 
+          lib/silccore/silcmode.h, irssi/src/silc/core/client_ops.c,
+         irssi/docs/help/in/umode.in and lib/silcclient/command.c.
+
 Sun Apr  7 17:07:59 EEST 2002  Pekka Riikonen <priikone@silcnet.org>
 
        * Added STATS command to the protocol after all, to return
diff --git a/TODO b/TODO
index 26c7660513134fde66ca703bd48721f9a2be9dfe..7e80cecf84fd283845dbc217f1f7dbf679629f39 100644 (file)
--- a/TODO
+++ b/TODO
@@ -106,18 +106,6 @@ Current protocol version is 1.0.  However, it is far from being perfect,
 and needs to include additional features.  Following protocol TODO entries
 describe new stuff to be added to protocol versions 1.x.
 
- 1. Re-define the Status Payload: it is now 16 bits, split it into two
-    8 bits fields.  First field includes status types from 0 - 9 and
-    10 - n *if* it is not an list of errors.  If it is list of errors then
-    the first field includes 1, 2 and/or 3, and the second field includes
-    the error status 10 - n.  This way it is possible to send multiple
-    errors (list of errors) and we have a way to tell the receiver that
-    there will be other errors as well.  The second field is used only
-    if there is list of errors.  If normal status, or normal (single)
-    error status the second field is set to zero, and must be ignored.
-    Hence, the status works same way as now except for list of errors.
-    To be included in protocol version 1.1.
-
  2. Define that WHOIS and IDENTIFY commands must send list of errors
     if multiple Client ID (or Channel ID and Server ID for IDENTIFY) was
     requested and was not found.  Each unfound entry must cause an error
@@ -138,9 +126,6 @@ describe new stuff to be added to protocol versions 1.x.
  17. Cell wide channel founder support, and permanent channels when
      founder mode set.
 
- 18. Describe the SSH public key, X509, OpenPGP and SPKI certificates
-     encoding format in SKE (from their respective definitions).
-
  o Inviting and banning by public key should be made possible.  To be
    included in protocol version 1.2.
 
index 2bd59736811e79e5a9d62863f3ce5f2e62b77c86..1dfbaf494ecf55786e56d21fe4e10a9d55d18f20 100644 (file)
--- a/TODO-1.0
+++ b/TODO-1.0
@@ -152,3 +152,5 @@ least could be done.
        o Something needs to be thought to the logging globals as well, 
          like silc_debug etc.  They won't work on EPOC.  Perhaps logging
          and debugging is to be disabled on EPOC.
+
+ o Check whether we can fully comply with RFC 2779.
index a833a0d0243a88293eddb86913a579a31e0a9dae..fd1102beb38b379cee16ea529ef0a16221f27627 100644 (file)
@@ -11,5 +11,10 @@ modes are available:
     s        Unset server operator privileges
     r        Unset router operator privileges
     g        Set/unset to be gone (or use /AWAY command)
+    i        Set/unset to be indisposed
+    b        Set/unset to be busy
+    p        Set/unset to await paging
+    h        Set/unset to be hyper active
+    t        Set/unset to be actually robot
 
 See also: CMODE, CUMODE, AWAY
index b76c467d59f7b936f904d2ed59c8f9ea20568586..727079c8a63a9a61393d5c179387df4fecc17cc5 100644 (file)
@@ -884,12 +884,22 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
        if ((mode & SILC_UMODE_SERVER_OPERATOR) ||
            (mode & SILC_UMODE_ROUTER_OPERATOR)) {
          strcat(buf, (mode & SILC_UMODE_SERVER_OPERATOR) ?
-                "Server Operator " :
+                "Server Operator" :
                 (mode & SILC_UMODE_ROUTER_OPERATOR) ?
-                "SILC Operator " : "[Unknown mode] ");
+                "SILC Operator" : "[Unknown mode]");
        }
        if (mode & SILC_UMODE_GONE)
-         strcat(buf, "away");
+         strcat(buf, " away");
+       if (mode & SILC_UMODE_INDISPOSED)
+         strcat(buf, " indisposed");
+       if (mode & SILC_UMODE_BUSY)
+         strcat(buf, " busy");
+       if (mode & SILC_UMODE_PAGE)
+         strcat(buf, " page to reach");
+       if (mode & SILC_UMODE_HYPER)
+         strcat(buf, " hyper active");
+       if (mode & SILC_UMODE_ROBOT)
+         strcat(buf, " robot");
 
        printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
                           SILCTXT_WHOIS_MODES, buf);
@@ -1179,8 +1189,18 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
        mode = silc_client_chumode_char(chu->mode);
        if (e->mode & SILC_UMODE_GONE)
          strcat(stat, "G");
-       else
+       else if (e->mode & SILC_UMODE_INDISPOSED)
+         strcat(stat, "I");
+       else if (e->mode & SILC_UMODE_BUSY)
+         strcat(stat, "B");
+       else if (e->mode & SILC_UMODE_PAGE)
+         strcat(stat, "P");
+       else if (e->mode & SILC_UMODE_HYPER)
          strcat(stat, "H");
+       else if (e->mode & SILC_UMODE_ROBOT)
+         strcat(stat, "R");
+       else
+         strcat(stat, "A");
        if (mode)
          strcat(stat, mode);
 
index d2622a084f5179d651b7a11a30cd3ad977f88cc9..974755eb5f6d0246be151b803912861de8f2cd6b 100644 (file)
@@ -395,7 +395,7 @@ silc_server_command_send_status_reply(SilcServerCommandContext cmd,
   SILC_LOG_DEBUG(("Sending command status %d", status));
 
   buffer = 
-    silc_command_reply_payload_encode_va(command, status, 
+    silc_command_reply_payload_encode_va(command, status, 0,
                                         silc_command_get_ident(cmd->payload),
                                         0);
   silc_server_packet_send(cmd->server, cmd->sock,
@@ -420,7 +420,7 @@ silc_server_command_send_status_data(SilcServerCommandContext cmd,
   SILC_LOG_DEBUG(("Sending command status %d", status));
 
   buffer = 
-    silc_command_reply_payload_encode_va(command, status, 
+    silc_command_reply_payload_encode_va(command, status, 0,
                                         silc_command_get_ident(cmd->payload),
                                         1, arg_type, arg, arg_len);
   silc_server_packet_send(cmd->server, cmd->sock,
@@ -439,16 +439,10 @@ silc_server_command_pending_error_check(SilcServerCommandContext cmd,
                                        SilcServerCommandReplyContext cmdr,
                                        SilcCommand command)
 {
-  SilcCommandStatus status;
-
   if (!cmd->pending || !cmdr)
     return FALSE;
 
-  SILC_GET16_MSB(status, silc_argument_get_arg_type(cmdr->args, 1, NULL));
-  if (status != SILC_STATUS_OK &&
-      status != SILC_STATUS_LIST_START &&
-      status != SILC_STATUS_LIST_ITEM &&
-      status != SILC_STATUS_LIST_END) {
+  if (!silc_command_get_status(cmdr->payload, NULL, NULL)) {
     SilcBuffer buffer;
 
     /* Send the same command reply payload */
@@ -802,7 +796,7 @@ silc_server_command_whois_send_reply(SilcServerCommandContext cmd,
 
     packet = 
       silc_command_reply_payload_encode_va(SILC_COMMAND_WHOIS,
-                                          status, ident, 8, 
+                                          status, 0, ident, 8, 
                                           2, idp->data, idp->len,
                                           3, nh, strlen(nh),
                                           4, uh, strlen(uh),
@@ -1160,7 +1154,7 @@ silc_server_command_whowas_send_reply(SilcServerCommandContext cmd,
       
     packet = 
       silc_command_reply_payload_encode_va(SILC_COMMAND_WHOWAS,
-                                          status, ident, 4, 
+                                          status, 0, ident, 4, 
                                           2, idp->data, idp->len,
                                           3, nh, strlen(nh),
                                           4, uh, strlen(uh),
@@ -1819,7 +1813,7 @@ silc_server_command_identify_send_reply(SilcServerCommandContext cmd,
 
       if (!entry->username) {
        packet = silc_command_reply_payload_encode_va(SILC_COMMAND_IDENTIFY,
-                                                     status, ident, 2,
+                                                     status, 0, ident, 2,
                                                      2, idp->data, idp->len, 
                                                      3, nh, strlen(nh));
       } else {
@@ -1832,7 +1826,7 @@ silc_server_command_identify_send_reply(SilcServerCommandContext cmd,
        }
        
        packet = silc_command_reply_payload_encode_va(SILC_COMMAND_IDENTIFY,
-                                                     status, ident, 3,
+                                                     status, 0, ident, 3,
                                                      2, idp->data, idp->len, 
                                                      3, nh, strlen(nh),
                                                      4, uh, strlen(uh));
@@ -1870,7 +1864,7 @@ silc_server_command_identify_send_reply(SilcServerCommandContext cmd,
       idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
       packet = 
        silc_command_reply_payload_encode_va(SILC_COMMAND_IDENTIFY,
-                                            status, ident, 2,
+                                            status, 0, ident, 2,
                                             2, idp->data, idp->len, 
                                             3, entry->server_name, 
                                             entry->server_name ? 
@@ -1907,7 +1901,7 @@ silc_server_command_identify_send_reply(SilcServerCommandContext cmd,
       idp = silc_id_payload_encode(entry->id, SILC_ID_CHANNEL);
       packet = 
        silc_command_reply_payload_encode_va(SILC_COMMAND_IDENTIFY,
-                                            status, ident, 2,
+                                            status, 0, ident, 2,
                                             2, idp->data, idp->len, 
                                             3, entry->channel_name, 
                                             entry->channel_name ? 
@@ -2062,7 +2056,7 @@ SILC_SERVER_CMD_FUNC(nick)
  send_reply:
   /* Send the new Client ID as reply command back to client */
   packet = silc_command_reply_payload_encode_va(SILC_COMMAND_NICK, 
-                                               SILC_STATUS_OK, ident, 1, 
+                                               SILC_STATUS_OK, 0, ident, 1, 
                                                2, nidp->data, nidp->len);
   silc_server_packet_send(cmd->server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
                          0, packet->data, packet->len, FALSE);
@@ -2137,7 +2131,7 @@ silc_server_command_list_send_reply(SilcServerCommandContext cmd,
     /* Send the reply */
     packet = 
       silc_command_reply_payload_encode_va(SILC_COMMAND_LIST, 
-                                          status, ident, 4,
+                                          status, 0, ident, 4,
                                           2, idp->data, idp->len,
                                           3, entry->channel_name, 
                                           strlen(entry->channel_name),
@@ -2176,7 +2170,7 @@ silc_server_command_list_send_reply(SilcServerCommandContext cmd,
     /* Send the reply */
     packet = 
       silc_command_reply_payload_encode_va(SILC_COMMAND_LIST, 
-                                          status, ident, 4,
+                                          status, 0, ident, 4,
                                           2, idp->data, idp->len,
                                           3, entry->channel_name, 
                                           strlen(entry->channel_name),
@@ -2362,7 +2356,7 @@ SILC_SERVER_CMD_FUNC(topic)
   /* Send the topic to client as reply packet */
   idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL);
   packet = silc_command_reply_payload_encode_va(SILC_COMMAND_TOPIC, 
-                                               SILC_STATUS_OK, ident, 2, 
+                                               SILC_STATUS_OK, 0, ident, 2, 
                                                2, idp->data, idp->len,
                                                3, channel->topic, 
                                                channel->topic ? 
@@ -2582,7 +2576,7 @@ SILC_SERVER_CMD_FUNC(invite)
   if (add || del)
     packet = 
       silc_command_reply_payload_encode_va(SILC_COMMAND_INVITE,
-                                          SILC_STATUS_OK, ident, 2,
+                                          SILC_STATUS_OK, 0, ident, 2,
                                           2, tmp, len,
                                           3, channel->invite_list,
                                           channel->invite_list ?
@@ -2590,7 +2584,7 @@ SILC_SERVER_CMD_FUNC(invite)
   else
     packet = 
       silc_command_reply_payload_encode_va(SILC_COMMAND_INVITE,
-                                          SILC_STATUS_OK, ident, 1,
+                                          SILC_STATUS_OK, 0, ident, 1,
                                           2, tmp, len);
   silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, 
                          packet->data, packet->len, FALSE);
@@ -2935,7 +2929,7 @@ SILC_SERVER_CMD_FUNC(info)
 
   /* Send the reply */
   packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INFO,
-                                               SILC_STATUS_OK, ident, 3,
+                                               SILC_STATUS_OK, 0, ident, 3,
                                                2, idp->data, idp->len,
                                                3, server_name, 
                                                strlen(server_name),
@@ -3075,7 +3069,7 @@ SILC_SERVER_CMD_FUNC(stats)
                     SILC_STR_END);
 
   packet = silc_command_reply_payload_encode_va(SILC_COMMAND_STATS, 
-                                               SILC_STATUS_OK, ident, 2,
+                                               SILC_STATUS_OK, 0, ident, 2,
                                                2, tmp, tmp_len,
                                                3, stats->data, stats->len);
   silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
@@ -3312,7 +3306,7 @@ static void silc_server_command_join_channel(SilcServer server,
 
   reply = 
     silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN,
-                                        SILC_STATUS_OK, ident, 13,
+                                        SILC_STATUS_OK, 0, ident, 13,
                                         2, channel->channel_name,
                                         strlen(channel->channel_name),
                                         3, chidp->data, chidp->len,
@@ -3633,13 +3627,15 @@ SILC_SERVER_CMD_FUNC(motd)
       
       motd[motd_len] = 0;
       packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
-                                                   SILC_STATUS_OK, ident, 2,
+                                                   SILC_STATUS_OK, 0, 
+                                                   ident, 2,
                                                    2, idp, idp->len,
                                                    3, motd, motd_len);
     } else {
       /* No motd */
       packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
-                                                   SILC_STATUS_OK, ident, 1,
+                                                   SILC_STATUS_OK, 0, 
+                                                   ident, 1,
                                                    2, idp, idp->len);
     }
 
@@ -3715,7 +3711,7 @@ SILC_SERVER_CMD_FUNC(motd)
 
     idp = silc_id_payload_encode(server->id_entry->id, SILC_ID_SERVER);
     packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
-                                                 SILC_STATUS_OK, ident, 2,
+                                                 SILC_STATUS_OK, 0, ident, 2,
                                                  2, idp, idp->len,
                                                  3, entry->motd,
                                                  entry->motd ? 
@@ -3775,7 +3771,7 @@ SILC_SERVER_CMD_FUNC(umode)
 
   /* Send command reply to sender */
   packet = silc_command_reply_payload_encode_va(SILC_COMMAND_UMODE,
-                                               SILC_STATUS_OK, ident, 1,
+                                               SILC_STATUS_OK, 0, ident, 1,
                                                2, tmp_mask, 4);
   silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, 
                          packet->data, packet->len, FALSE);
@@ -4149,7 +4145,7 @@ SILC_SERVER_CMD_FUNC(cmode)
 
   /* Send command reply to sender */
   packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CMODE,
-                                               SILC_STATUS_OK, ident, 2,
+                                               SILC_STATUS_OK, 0, ident, 2,
                                                2, tmp_id, tmp_len2,
                                                3, tmp_mask, 4);
   silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, 
@@ -4389,7 +4385,7 @@ SILC_SERVER_CMD_FUNC(cumode)
 
   /* Send command reply to sender */
   packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CUMODE,
-                                               SILC_STATUS_OK, ident, 3,
+                                               SILC_STATUS_OK, 0, ident, 3,
                                                2, tmp_mask, 4,
                                                3, tmp_ch_id, tmp_ch_len,
                                                4, tmp_id, tmp_len);
@@ -4848,7 +4844,7 @@ SILC_SERVER_CMD_FUNC(ban)
   /* Send the reply back to the client */
   packet = 
     silc_command_reply_payload_encode_va(SILC_COMMAND_BAN,
-                                        SILC_STATUS_OK, ident, 2,
+                                        SILC_STATUS_OK, 0, ident, 2,
                                         2, id, id_len,
                                         3, channel->ban_list, 
                                         channel->ban_list ? 
@@ -5062,7 +5058,7 @@ SILC_SERVER_CMD_FUNC(users)
   /* Send reply */
   idp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
   packet = silc_command_reply_payload_encode_va(SILC_COMMAND_USERS,
-                                               SILC_STATUS_OK, ident, 4,
+                                               SILC_STATUS_OK, 0, ident, 4,
                                                2, idp->data, idp->len,
                                                3, lc, 4,
                                                4, client_id_list->data,
@@ -5257,7 +5253,7 @@ SILC_SERVER_CMD_FUNC(getkey)
 
   tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
   packet = silc_command_reply_payload_encode_va(SILC_COMMAND_GETKEY,
-                                               SILC_STATUS_OK, ident, 
+                                               SILC_STATUS_OK, 0, ident, 
                                                pkdata ? 2 : 1,
                                                2, tmp, tmp_len,
                                                3, pkdata, pklen);
index 6300ebc10d40c0614d96a8a7d9be324a8968c1ee..9c8766798e5ab1849991bba87388a0665f38f396 100644 (file)
 #include "server_internal.h"
 #include "command_reply.h"
 
-/* All functions that call the COMMAND_CHECK_STATUS or the
-   COMMAND_CHECK_STATUS_LIST macros must have out: goto label. */
-
-#define COMMAND_CHECK_STATUS                                             \
-do {                                                                     \
-  SILC_LOG_DEBUG(("Start"));                                             \
-  SILC_GET16_MSB(status, silc_argument_get_arg_type(cmd->args, 1, NULL)); \
-  if (status != SILC_STATUS_OK)                                                  \
-    goto out;                                                            \
-} while(0)
-
-#define COMMAND_CHECK_STATUS_LIST                                        \
-do {                                                                     \
-  SILC_LOG_DEBUG(("Start"));                                             \
-  SILC_GET16_MSB(status, silc_argument_get_arg_type(cmd->args, 1, NULL)); \
-  if (status != SILC_STATUS_OK &&                                        \
-      status != SILC_STATUS_LIST_START &&                                \
-      status != SILC_STATUS_LIST_ITEM &&                                 \
-      status != SILC_STATUS_LIST_END)                                    \
-    goto out;                                                            \
+/* All functions that call the COMMAND_CHECK_STATUS macros must have
+   out: goto label. */
+
+#define COMMAND_CHECK_STATUS                                   \
+do {                                                           \
+  SILC_LOG_DEBUG(("Start"));                                   \
+  if (!silc_command_get_status(cmd->payload, &status, &error)) \
+    goto out;                                                  \
 } while(0)
 
 /* Server command reply list. Not all commands have reply function as
@@ -256,9 +244,9 @@ SILC_SERVER_CMD_REPLY_FUNC(whois)
 {
   SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
   SilcServer server = cmd->server;
-  SilcCommandStatus status;
+  SilcCommandStatus status, error;
 
-  COMMAND_CHECK_STATUS_LIST;
+  COMMAND_CHECK_STATUS;
 
   if (!silc_server_command_reply_whois_save(cmd))
     goto out;
@@ -273,7 +261,7 @@ SILC_SERVER_CMD_REPLY_FUNC(whois)
  out:
   /* If we received notify for invalid ID we'll remove the ID if we
      have it cached. */
-  if (status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID &&
+  if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID &&
       cmd->sock->type == SILC_SOCKET_TYPE_ROUTER) {
     SilcClientEntry client;
     SilcUInt32 tmp_len;
@@ -392,9 +380,9 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd)
 SILC_SERVER_CMD_REPLY_FUNC(whowas)
 {
   SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
-  SilcCommandStatus status;
+  SilcCommandStatus status, error;
 
-  COMMAND_CHECK_STATUS_LIST;
+  COMMAND_CHECK_STATUS;
 
   if (!silc_server_command_reply_whowas_save(cmd))
     goto out;
@@ -617,9 +605,9 @@ SILC_SERVER_CMD_REPLY_FUNC(identify)
 {
   SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
   SilcServer server = cmd->server;
-  SilcCommandStatus status;
+  SilcCommandStatus status, error;
 
-  COMMAND_CHECK_STATUS_LIST;
+  COMMAND_CHECK_STATUS;
 
   if (!silc_server_command_reply_identify_save(cmd))
     goto out;
@@ -634,7 +622,7 @@ SILC_SERVER_CMD_REPLY_FUNC(identify)
  out:
   /* If we received notify for invalid ID we'll remove the ID if we
      have it cached. */
-  if (status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID &&
+  if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID &&
       cmd->sock->type == SILC_SOCKET_TYPE_ROUTER) {
     SilcClientEntry client;
     SilcUInt32 tmp_len;
@@ -666,7 +654,7 @@ SILC_SERVER_CMD_REPLY_FUNC(info)
 {
   SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
   SilcServer server = cmd->server;
-  SilcCommandStatus status;
+  SilcCommandStatus status, error;
   SilcServerEntry entry;
   SilcServerID *server_id;
   SilcUInt32 tmp_len;
@@ -723,7 +711,7 @@ SILC_SERVER_CMD_REPLY_FUNC(motd)
 {
   SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
   SilcServer server = cmd->server;
-  SilcCommandStatus status;
+  SilcCommandStatus status, error;
   SilcServerEntry entry = NULL;
   SilcServerID *server_id;
   SilcUInt32 tmp_len;
@@ -772,7 +760,7 @@ SILC_SERVER_CMD_REPLY_FUNC(join)
   SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
   SilcServer server = cmd->server;
   SilcIDCacheEntry cache = NULL;
-  SilcCommandStatus status;
+  SilcCommandStatus status, error;
   SilcChannelID *id;
   SilcClientID *client_id = NULL;
   SilcChannelEntry entry;
@@ -974,7 +962,7 @@ SILC_SERVER_CMD_REPLY_FUNC(stats)
 {
   SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
   SilcServer server = cmd->server;
-  SilcCommandStatus status;
+  SilcCommandStatus status, error;
   unsigned char *tmp;
   SilcUInt32 tmp_len;
   SilcBufferStruct buf;
@@ -1012,7 +1000,7 @@ SILC_SERVER_CMD_REPLY_FUNC(users)
 {
   SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
   SilcServer server = cmd->server;
-  SilcCommandStatus status;
+  SilcCommandStatus status, error;
   SilcChannelEntry channel;
   SilcChannelID *channel_id = NULL;
   SilcBuffer client_id_list;
@@ -1101,7 +1089,7 @@ SILC_SERVER_CMD_REPLY_FUNC(getkey)
 {
   SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
   SilcServer server = cmd->server;
-  SilcCommandStatus status;
+  SilcCommandStatus status, error;
   SilcClientEntry client = NULL;
   SilcServerEntry server_entry = NULL;
   SilcClientID *client_id = NULL;
@@ -1186,7 +1174,7 @@ SILC_SERVER_CMD_REPLY_FUNC(list)
 {
   SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
   SilcServer server = cmd->server;
-  SilcCommandStatus status;
+  SilcCommandStatus status, error;
   SilcChannelID *channel_id = NULL;
   SilcChannelEntry channel;
   SilcIDCacheEntry cache;
@@ -1195,7 +1183,7 @@ SILC_SERVER_CMD_REPLY_FUNC(list)
   SilcUInt32 usercount = 0;
   bool global_list = FALSE;
 
-  COMMAND_CHECK_STATUS_LIST;
+  COMMAND_CHECK_STATUS;
 
   tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
   channel_id = silc_id_payload_parse_id(tmp, len, NULL);
index f58aadcbfd58c5d615062841e6b37ba935f9dd8f..e2e98bc66ba2610164323da924698f42eae4e524 100644 (file)
@@ -1466,11 +1466,11 @@ void silc_server_private_message(SilcServer server,
                                          client_id, SILC_ID_CLIENT,
                                          SILC_COMMAND_IDENTIFY,
                                          SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 
-                                         0, 1, 2, idp->data, idp->len);
+                                         0, 0, 1, 2, idp->data, idp->len);
       silc_free(client_id);
     } else {
       silc_server_send_command_reply(server, sock, SILC_COMMAND_IDENTIFY,
-                                    SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 
+                                    SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0,
                                     0, 1, 2, idp->data, idp->len);
     }
 
index 424a27333fc3cdce4bb4ccfcc143a0b730c6ca80..b37f1c7af79bd9a31e6acdd95a363eb1f3448bfa 100644 (file)
@@ -1720,6 +1720,7 @@ void silc_server_send_command_reply(SilcServer server,
                                    SilcSocketConnection sock,
                                    SilcCommand command, 
                                    SilcCommandStatus status,
+                                   SilcCommandStatus error,
                                    SilcUInt16 ident,
                                    SilcUInt32 argc, ...)
 {
@@ -1728,8 +1729,8 @@ void silc_server_send_command_reply(SilcServer server,
 
   va_start(ap, argc);
 
-  packet = silc_command_reply_payload_encode_vap(command, status, ident, 
-                                                argc, ap);
+  packet = silc_command_reply_payload_encode_vap(command, status, error,
+                                                ident, argc, ap);
   silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
                          packet->data, packet->len, TRUE);
   silc_buffer_free(packet);
@@ -1745,6 +1746,7 @@ void silc_server_send_dest_command_reply(SilcServer server,
                                         SilcIdType dst_id_type,
                                         SilcCommand command, 
                                         SilcCommandStatus status,
+                                        SilcCommandStatus error,
                                         SilcUInt16 ident,
                                         SilcUInt32 argc, ...)
 {
@@ -1753,8 +1755,8 @@ void silc_server_send_dest_command_reply(SilcServer server,
 
   va_start(ap, argc);
 
-  packet = silc_command_reply_payload_encode_vap(command, status, ident, 
-                                                argc, ap);
+  packet = silc_command_reply_payload_encode_vap(command, status, error,
+                                                ident, argc, ap);
   silc_server_packet_send_dest(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
                               dst_id, dst_id_type, packet->data, 
                               packet->len, TRUE);
index b2cbc8aae25cede3dad8c6efa3049c9cb27203ec..17dc349e1a7601002da0b587584830f7d0642290 100644 (file)
@@ -233,6 +233,7 @@ void silc_server_send_command_reply(SilcServer server,
                                    SilcSocketConnection sock,
                                    SilcCommand command, 
                                    SilcCommandStatus status,
+                                   SilcCommandStatus error,
                                    SilcUInt16 ident,
                                    SilcUInt32 argc, ...);
 void silc_server_send_dest_command_reply(SilcServer server, 
@@ -241,6 +242,7 @@ void silc_server_send_dest_command_reply(SilcServer server,
                                         SilcIdType dst_id_type,
                                         SilcCommand command, 
                                         SilcCommandStatus status,
+                                        SilcCommandStatus error,
                                         SilcUInt16 ident,
                                         SilcUInt32 argc, ...);
 void silc_server_send_heartbeat(SilcServer server,
index 6bf956d6aa8406034bbb095aa1dd7ea0d99172e5..f917a612e54be0d5ebba578f78471305238e9ad6 100644 (file)
@@ -984,7 +984,7 @@ List of all defined commands in SILC follows.
 
               No specific mode for client.  This is the initial
               setting when new client is created.  The client is
-              normal client now.
+              normal client and is present in the network.
 
 
            0x00000001    SILC_UMODE_SERVER_OPERATOR
@@ -1010,6 +1010,44 @@ List of all defined commands in SILC follows.
               Marks that the user is not currently present in the
               SILC Network.  Client MAY set and unset this mode.
 
+
+           0x00000008    SILC_UMODE_INDISPOSED
+
+              Marks that the user is currently indisposed and may
+              not be able to receive any messages, and that user may
+              not be present in the network.  Client MAY set and
+              unset this mode.
+
+
+           0x00000010    SILC_UMODE_BUSY
+
+              Marks that the user is currently busy and may not
+              want to receive any messages, and that user may not
+              be present in the network.  Client MAY set and unset
+              this mode.
+
+
+           0x00000020    SILC_UMODE_PAGE
+
+              User is not currently present or is unable to receive
+              messages, and prefers to be paged in some mechanism
+              if the user needs to be reached.  Client MAY set and
+              unset this mode.
+
+
+           0x00000040    SILC_UMODE_HYPER
+
+              Marks that the user is hyper active and is eager to
+              receive and send messages.   Client MAY set and unset
+              this mode.
+
+
+           0x00000080    SILC_UMODE_ROBOT
+
+              Marks that the client is actually a robot program.
+              Client MAY set and unset this mode.
+
+
         Reply messages to the command:
 
         Max Arguments:  2
@@ -1625,7 +1663,7 @@ represents the Command Status Payload (field is always in MSB order).
                      1
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-|        Status Message         |
+|     Status    |     Error     |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 .in 3
 
@@ -1634,10 +1672,49 @@ Figure 6:  SILC Command Status Payload
 
 
 .in 6
-o Status Message (2 bytes) - Indicates the status message.
-  All Status messages are described in the next section.
+o Status (1 byte) - Indicates the status message type,
+  error, start of list, entry of list or end of list.
+
+o Error (1 byte) - Indicates the error if the Status
+  field is some list status, which means there are list
+  of errors.
+.in 3
+
+The values in Status and Error fields are set according
+the following rules:
+
+.in 6
+o If there is single reply and error has not occurred
+  then Status field includes value SILC_STATUS_OK, and
+  the Error field MUST be ignored (and set to zero
+  value).
+
+o If there is single error, then Status field includes
+  one of the error values, and the Error field MUST be
+  ignored (and set to zero value).
+
+o If there will be multiple successful command replies
+  then Status field includes SILC_STATUS_LIST_START, 
+  SILC_STATUS_LIST_ITEM or SILC_STATUS_LIST_END value,
+  and Error field is set to SILC_STATUS_OK.
+
+o If there are multiple error replies then Status field
+  includes SILC_STATUS_LIST_START, SILC_STATUS_LIST_ITEM
+  or SILC_STATUS_LIST_END value, and the Error field
+  includes the error value.
 .in 3
 
+This way it is possible to send single successful or
+single error reply, but also multiple successful and
+multiple error replies.  Note that it is possible to
+send both list of successful replies and list of error
+replies at the same time, however in this case the
+list of error replies MUST be sent after the successful
+replies.  This way the recipient may ignore the multiple
+errors if it wishes to do so.
+
+All Status messages are described in the next section.
+
 
 .ti 0
 2.3.2 SILC Command Status List
index 8ba7d4516587f13780ac89685cb812fc7d5492da..9abce0d47caebc2c5fbb8a4620a5700d5f80f313 100644 (file)
@@ -215,9 +215,9 @@ Hence, the MIME Header in the message payload may be as follows:
 
 .in 8
 .nf
-MIME-Version: 1.0
-Content-Type: discrete/composite
-Content-Transfer-Encoding: binary
+MIME-Version: 1.0\\r
+Content-Type: discrete/composite\\r
+Content-Transfer-Encoding: binary\\r
 .in 3
 
 The Content-Transfer-Encoding field behaves as defined in [RFC2045] and 
index 495647ba38b7f90872aa7cfd65226bdda718047b..7089aa4810c884495c065760dcd94bfa976d4b8e 100644 (file)
@@ -483,7 +483,9 @@ o Public Key Type (2 bytes) - The public key (or certificate)
   be closed immediately.
 
 o Public Key (or certificate) (variable length) - The
-  public key or certificate.
+  public key or certificate.  The public key or certificate
+  in this field is encoded in the manner as defined in their
+  respective definitions;  see previous field.
 
 o Public Data Length (2 bytes) - The length of the Public Data
   field, not including any other field.
@@ -824,6 +826,7 @@ are defined:
 
     Provided version string was not acceptable.
 
+
 11  SILC_SKE_STATUS_INVALID_COOKIE
 
     The cookie in the Key Exchange Start Payload was malformed,
index 80182f5a9240f65a60a1c492956027929af6ef24..24e8854eb3173e3381cc466faeb796dc735628f7 100644 (file)
@@ -55,11 +55,8 @@ static void silc_client_notify_by_server_pending(void *context, void *context2)
 
   SILC_LOG_DEBUG(("Start"));
 
-  if (reply) {
-    SilcCommandStatus status = silc_command_get_status(reply->payload);
-    if (status != SILC_STATUS_OK)
-      goto out;
-  }
+  if (reply && !silc_command_get_status(reply->payload, NULL, NULL))
+    goto out;
 
   silc_client_notify_by_server(res->context, res->sock, res->packet);
 
index 48b7cd276bc3138c3be0bf210297764e5b906335..8fa6fd0e5934b6544fdb9b5da84515fd78cc1347 100644 (file)
@@ -322,8 +322,9 @@ SILC_CLIENT_CMD_FUNC(nick_change)
   SilcClientConnection conn = cmd->conn;
   SilcClientCommandReplyContext reply = 
     (SilcClientCommandReplyContext)context2;
-  SilcCommandStatus status = silc_command_get_status(reply->payload);
+  SilcCommandStatus status;
 
+  silc_command_get_status(reply->payload, &status, NULL);
   if (status == SILC_STATUS_OK) {
     /* Set the nickname */
     silc_idcache_del_by_context(conn->client_cache, conn->local_entry);
@@ -748,8 +749,9 @@ SILC_CLIENT_CMD_FUNC(kill_remove)
   SilcClientCommandContext cmd = (SilcClientCommandContext)context;
   SilcClientCommandReplyContext reply = 
     (SilcClientCommandReplyContext)context2;
-  SilcCommandStatus status = silc_command_get_status(reply->payload);
+  SilcCommandStatus status;
 
+  silc_command_get_status(reply->payload, &status, NULL);
   if (status == SILC_STATUS_OK) {
     /* Remove with timeout */
     silc_schedule_task_add(cmd->client->schedule, cmd->conn->sock->sock,
@@ -1141,6 +1143,36 @@ SILC_CLIENT_CMD_FUNC(umode)
       else
        mode &= ~SILC_UMODE_GONE;
       break;
+    case 'i':
+      if (add)
+       mode |= SILC_UMODE_INDISPOSED;
+      else
+       mode &= ~SILC_UMODE_INDISPOSED;
+      break;
+    case 'b':
+      if (add)
+       mode |= SILC_UMODE_BUSY;
+      else
+       mode &= ~SILC_UMODE_BUSY;
+      break;
+    case 'p':
+      if (add)
+       mode |= SILC_UMODE_PAGE;
+      else
+       mode &= ~SILC_UMODE_PAGE;
+      break;
+    case 'h':
+      if (add)
+       mode |= SILC_UMODE_HYPER;
+      else
+       mode &= ~SILC_UMODE_HYPER;
+      break;
+    case 't':
+      if (add)
+       mode |= SILC_UMODE_ROBOT;
+      else
+       mode &= ~SILC_UMODE_ROBOT;
+      break;
     default:
       COMMAND_ERROR;
       goto out;
@@ -2070,10 +2102,11 @@ SILC_CLIENT_CMD_FUNC(getkey)
       } else {
        SilcClientCommandReplyContext reply = 
          (SilcClientCommandReplyContext)context2;
-       SilcCommandStatus status = silc_command_get_status(reply->payload);
-       
+       SilcCommandStatus error;
+
        /* If nickname was not found, then resolve the server. */
-       if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
+       silc_command_get_status(reply->payload, NULL, &error);
+       if (error == SILC_STATUS_ERR_NO_SUCH_NICK) {
          /* This sends the IDENTIFY command to resolve the server. */
          silc_client_command_register(client, SILC_COMMAND_IDENTIFY, 
                                       NULL, NULL,
@@ -2091,11 +2124,11 @@ SILC_CLIENT_CMD_FUNC(getkey)
 
        /* If server was not found, then we've resolved both nickname and
           server and did not find anybody. */
-       if (status == SILC_STATUS_ERR_NO_SUCH_SERVER) {
+       if (error == SILC_STATUS_ERR_NO_SUCH_SERVER) {
          SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", 
             silc_client_command_status_message(SILC_STATUS_ERR_NO_SUCH_NICK));
          SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", 
-           silc_client_command_status_message(status));
+           silc_client_command_status_message(error));
          COMMAND_ERROR;
          goto out;
        }
index 616b2d86d950cc0b57617c1c5910c7ead070d2d7..097bdc093ec6266d227895d1eccfa3cbcf4fdd24 100644 (file)
@@ -92,28 +92,16 @@ const SilcCommandStatusMessage silc_command_status_messages[] = {
 
 #define SAY cmd->client->internal->ops->say
 
-/* All functions that call the COMMAND_CHECK_STATUS or the
-   COMMAND_CHECK_STATUS_LIST macros must have out: goto label. */
-
-#define COMMAND_CHECK_STATUS                   \
-do {                                           \
-  SILC_LOG_DEBUG(("Start"));                   \
-  if (cmd->status != SILC_STATUS_OK)  {                \
-    COMMAND_REPLY_ERROR;                       \
-    goto out;                                  \
-  }                                            \
-} while(0)
-
-#define COMMAND_CHECK_STATUS_LIST              \
-do {                                           \
-  SILC_LOG_DEBUG(("Start"));                   \
-  if (cmd->status != SILC_STATUS_OK &&         \
-      cmd->status != SILC_STATUS_LIST_START && \
-      cmd->status != SILC_STATUS_LIST_ITEM &&  \
-      cmd->status != SILC_STATUS_LIST_END) {   \
-    COMMAND_REPLY_ERROR;                       \
-    goto out;                                  \
-  }                                            \
+/* All functions that call the COMMAND_CHECK_STATUS macro must have 
+   out: goto label. */
+
+#define COMMAND_CHECK_STATUS                                   \
+do {                                                           \
+  SILC_LOG_DEBUG(("Start"));                                   \
+  if (!silc_command_get_status(cmd->payload, NULL, NULL)) {    \
+    COMMAND_REPLY_ERROR;                                       \
+    goto out;                                                  \
+  }                                                            \
 } while(0)
 
 /* Process received command reply. */
@@ -143,10 +131,10 @@ void silc_client_command_reply_process(SilcClient client,
   ctx->client = client;
   ctx->sock = sock;
   ctx->payload = payload;
-  ctx->status = silc_command_get_status(ctx->payload);
   ctx->args = silc_command_get_args(ctx->payload);
   ctx->packet = packet;
   ctx->ident = silc_command_get_ident(ctx->payload);
+  silc_command_get_status(ctx->payload, &ctx->status, &ctx->error);
 
   /* Check for pending commands and mark to be exeucted */
   silc_client_command_pending_check(sock->user_data, ctx, 
@@ -302,7 +290,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(whois)
   SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
   SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
 
-  COMMAND_CHECK_STATUS_LIST;
+  COMMAND_CHECK_STATUS;
 
   /* Save WHOIS info */
   silc_client_command_reply_whois_save(cmd, cmd->status, TRUE);
@@ -319,7 +307,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(whois)
 
   /* If we received notify for invalid ID we'll remove the ID if we
      have it cached. */
-  if (cmd->status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
+  if (cmd->error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
     SilcClientEntry client_entry;
     SilcUInt32 tmp_len;
     unsigned char *tmp =
@@ -353,7 +341,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(whowas)
   char *nickname, *username;
   char *realname = NULL;
 
-  COMMAND_CHECK_STATUS_LIST;
+  COMMAND_CHECK_STATUS;
 
   id_data = silc_argument_get_arg_type(cmd->args, 2, &len);
   if (!id_data) {
@@ -523,7 +511,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(identify)
   SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
   SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
 
-  COMMAND_CHECK_STATUS_LIST;
+  COMMAND_CHECK_STATUS;
 
   /* Save IDENTIFY info */
   silc_client_command_reply_identify_save(cmd, cmd->status, TRUE);
@@ -540,7 +528,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(identify)
 
   /* If we received notify for invalid ID we'll remove the ID if we
      have it cached. */
-  if (cmd->status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
+  if (cmd->error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
     SilcClientEntry client_entry;
     SilcUInt32 tmp_len;
     unsigned char *tmp =
@@ -574,10 +562,10 @@ SILC_CLIENT_CMD_REPLY_FUNC(nick)
 
   SILC_LOG_DEBUG(("Start"));
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
        "Cannot set nickname: %s", 
-       silc_client_command_status_message(cmd->status));
+       silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -621,7 +609,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(list)
   SilcChannelID *channel_id = NULL;
   SilcChannelEntry channel_entry;
 
-  COMMAND_CHECK_STATUS_LIST;
+  COMMAND_CHECK_STATUS;
 
   tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
   if (!tmp) {
@@ -688,9 +676,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(topic)
   char *topic;
   SilcUInt32 argc, len;
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(cmd->status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -742,9 +730,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(invite)
   unsigned char *tmp;
   SilcUInt32 len;
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(cmd->status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -784,9 +772,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(kill)
   SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
   SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(cmd->status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -814,9 +802,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(info)
 
   SILC_LOG_DEBUG(("Start"));
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", 
-       silc_client_command_status_message(cmd->status));
+       silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -870,9 +858,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(ping)
   int i;
   time_t diff, curtime;
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(cmd->status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -930,10 +918,10 @@ SILC_CLIENT_CMD_REPLY_FUNC(join)
 
   SILC_LOG_DEBUG(("Start"));
 
-  if (cmd->status != SILC_STATUS_OK) {
-    if (cmd->status != SILC_STATUS_ERR_USER_ON_CHANNEL)
+  if (cmd->error != SILC_STATUS_OK) {
+    if (cmd->error != SILC_STATUS_ERR_USER_ON_CHANNEL)
       SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-         "%s", silc_client_command_status_message(cmd->status));
+         "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -1110,9 +1098,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(motd)
   SilcUInt32 argc, i;
   char *motd = NULL, *cp, line[256];
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(cmd->status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     return;
   }
@@ -1167,9 +1155,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(umode)
   unsigned char *tmp;
   SilcUInt32 mode;
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(cmd->status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -1203,9 +1191,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(cmode)
   SilcChannelEntry channel;
   SilcUInt32 len;
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(cmd->status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -1262,9 +1250,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(cumode)
   unsigned char *modev, *tmp, *id;
   SilcUInt32 len, mode;
   
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(cmd->status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -1336,9 +1324,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(kick)
   SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
   SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(cmd->status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -1356,9 +1344,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(silcoper)
   SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
   SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(cmd->status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -1376,9 +1364,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(oper)
   SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
   SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(cmd->status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -1400,9 +1388,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(ban)
   unsigned char *tmp;
   SilcUInt32 len;
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(cmd->status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -1446,9 +1434,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(leave)
   unsigned char *tmp;
   SilcUInt32 len;
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(cmd->status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -1490,10 +1478,10 @@ static void silc_client_command_reply_users_cb(SilcClient client,
   if (!channels_count) {
     SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
     SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
-    SilcCommandStatus status = SILC_STATUS_ERR_NO_SUCH_CHANNEL;
 
+    cmd->status = cmd->error = SILC_STATUS_ERR_NO_SUCH_CHANNEL;
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_USERS);
     silc_client_command_reply_free(cmd);
@@ -1524,9 +1512,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(users)
 
   SILC_LOG_DEBUG(("Start"));
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(cmd->status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -1718,9 +1706,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(getkey)
 
   SILC_LOG_DEBUG(("Start"));
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(cmd->status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -1804,10 +1792,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(whois_i)
 
   SILC_LOG_DEBUG(("Start"));
 
-  if (cmd->status != SILC_STATUS_OK &&
-      cmd->status != SILC_STATUS_LIST_START &&
-      cmd->status != SILC_STATUS_LIST_ITEM &&
-      cmd->status != SILC_STATUS_LIST_END)
+  if (cmd->error != SILC_STATUS_OK)
     goto out;
 
   /* Save WHOIS info */
@@ -1825,7 +1810,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(whois_i)
 
   /* If we received notify for invalid ID we'll remove the ID if we
      have it cached. */
-  if (cmd->status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
+  if (cmd->error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
     SilcClientEntry client_entry;
     SilcUInt32 tmp_len;
     unsigned char *tmp =
@@ -1858,10 +1843,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(identify_i)
 
   SILC_LOG_DEBUG(("Start"));
 
-  if (cmd->status != SILC_STATUS_OK &&
-      cmd->status != SILC_STATUS_LIST_START &&
-      cmd->status != SILC_STATUS_LIST_ITEM &&
-      cmd->status != SILC_STATUS_LIST_END)
+  if (cmd->error != SILC_STATUS_OK)
     goto out;
 
   /* Save IDENTIFY info */
@@ -1879,7 +1861,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(identify_i)
 
   /* If we received notify for invalid ID we'll remove the ID if we
      have it cached. */
-  if (cmd->status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
+  if (cmd->error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
     SilcClientEntry client_entry;
     SilcUInt32 tmp_len;
     unsigned char *tmp =
@@ -1917,7 +1899,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(info_i)
 
   SILC_LOG_DEBUG(("Start"));
 
-  if (cmd->status != SILC_STATUS_OK)
+  if (cmd->error != SILC_STATUS_OK)
     goto out;
 
   /* Get server ID */
@@ -1962,9 +1944,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(connect)
   SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
   SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(cmd->status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -1982,9 +1964,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(close)
   SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
   SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(cmd->status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -2002,9 +1984,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(shutdown)
   SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
   SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
 
-  if (cmd->status != SILC_STATUS_OK) {
+  if (cmd->error != SILC_STATUS_OK) {
     SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
-       "%s", silc_client_command_status_message(cmd->status));
+       "%s", silc_client_command_status_message(cmd->error));
     COMMAND_REPLY_ERROR;
     goto out;
   }
index afc14f9a1802335f7201a1dd215108ad8072ab37..1d1d20834522dcbe1a14a84ab71833a4d9f77cdc 100644 (file)
@@ -32,6 +32,7 @@ struct SilcClientCommandReplyContextStruct {
   SilcSocketConnection sock;
   SilcCommandPayload payload;
   SilcCommandStatus status;
+  SilcCommandStatus error;
   SilcArgumentPayload args;
   SilcPacketContext *packet;
 
index 2bd7eb6fce3351cb8fbee08cc26a0856ba4d7619..5254c9ed59eb23d9b51b94623a058ba5d271c749 100644 (file)
@@ -304,9 +304,18 @@ bool silc_channel_message_payload_decrypt(unsigned char *data,
     silc_hmac_update(hmac, data + (data_len - iv_len), iv_len);
     silc_hmac_final(hmac, mac2, &mac_len);
     if (memcmp(mac, mac2, mac_len)) {
+#if 1
+      /* Backwards support for old mac checking, remove in 1.0 */
+      silc_hmac_make(hmac, dst, (data_len - iv_len - mac_len), mac2, &mac_len);
+      if (memcmp(mac, mac2, mac_len)) {
+#endif
+
       SILC_LOG_DEBUG(("Channel message MACs does not match"));
       silc_free(dst);
       return FALSE;
+#if 1
+      }
+#endif
     }
     SILC_LOG_DEBUG(("MAC is Ok"));
 
index 3be0583e3a04006ffbf3573184aaea3804abc9c0..20b90c66535918c43917306e7d59d03f5109aeef 100644 (file)
@@ -82,7 +82,8 @@ SilcCommandPayload silc_command_payload_parse(const unsigned char *payload,
 
   silc_buffer_pull(&buffer, SILC_COMMAND_PAYLOAD_LEN);
   if (args_num) {
-    newp->args = silc_argument_payload_parse(buffer.data, buffer.len, args_num);
+    newp->args = silc_argument_payload_parse(buffer.data, buffer.len, 
+                                            args_num);
     if (!newp->args) {
       silc_free(newp);
       return NULL;
@@ -271,6 +272,7 @@ SilcBuffer silc_command_payload_encode_vap(SilcCommand cmd,
 SilcBuffer 
 silc_command_reply_payload_encode_va(SilcCommand cmd, 
                                     SilcCommandStatus status,
+                                    SilcCommandStatus error,
                                     SilcUInt16 ident,
                                     SilcUInt32 argc, ...)
 {
@@ -278,7 +280,8 @@ silc_command_reply_payload_encode_va(SilcCommand cmd,
   SilcBuffer buffer;
 
   va_start(ap, argc);
-  buffer = silc_command_reply_payload_encode_vap(cmd, status, ident, argc, ap);
+  buffer = silc_command_reply_payload_encode_vap(cmd, status, error,
+                                                ident, argc, ap);
   va_end(ap);
 
   return buffer;
@@ -287,6 +290,7 @@ silc_command_reply_payload_encode_va(SilcCommand cmd,
 SilcBuffer 
 silc_command_reply_payload_encode_vap(SilcCommand cmd, 
                                      SilcCommandStatus status,
+                                     SilcCommandStatus error,
                                      SilcUInt16 ident, SilcUInt32 argc, 
                                      va_list ap)
 {
@@ -315,7 +319,8 @@ silc_command_reply_payload_encode_vap(SilcCommand cmd,
     return NULL;
   }
 
-  SILC_PUT16_MSB(status, status_data);
+  status_data[0] = status;
+  status_data[1] = error;
   argv[0] = silc_memdup(status_data, sizeof(status_data));
   if (!argv[0]) {
     silc_free(argv_types);
@@ -388,19 +393,45 @@ SilcUInt16 silc_command_get_ident(SilcCommandPayload payload)
 
 /* Return command status */
 
-SilcCommandStatus silc_command_get_status(SilcCommandPayload payload)
+bool silc_command_get_status(SilcCommandPayload payload, 
+                            SilcCommandStatus *status,
+                            SilcCommandStatus *error)
 {
   unsigned char *tmp;
-  SilcCommandStatus status;
+  SilcUInt32 tmp_len;
 
   if (!payload->args)
     return 0;
-  tmp = silc_argument_get_arg_type(payload->args, 1, NULL);
-  if (!tmp)
+  tmp = silc_argument_get_arg_type(payload->args, 1, &tmp_len);
+  if (!tmp || tmp_len != 2)
     return 0;
 
-  SILC_GET16_MSB(status, tmp);
-  return status;
+  /* Check for 1.0 protocol version which didn't have `error' */
+  if (tmp[0] == 0 && tmp[1] != 0) {
+    /* Protocol 1.0 version */
+    SilcCommandStatus s;
+    SILC_GET16_MSB(s, tmp);
+    if (status)
+      *status = s;
+    if (error)
+      *error = 0;
+    if (s >= SILC_STATUS_ERR_NO_SUCH_NICK && error)
+      *error = s;
+    return (s < SILC_STATUS_ERR_NO_SUCH_NICK);
+  }
+
+  /* Take both status and possible error */
+  if (status)
+    *status = (SilcCommandStatus)tmp[0];
+  if (error)
+    *error = (SilcCommandStatus)tmp[1];
+
+  /* If single error occurred have the both `status' and `error' indicate
+     the error value for convenience. */
+  if (tmp[0] >= SILC_STATUS_ERR_NO_SUCH_NICK && error)
+    *error = tmp[0];
+
+  return (tmp[0] < SILC_STATUS_ERR_NO_SUCH_NICK && tmp[1] == SILC_STATUS_OK);
 }
 
 /* Function to set identifier to already allocated Command Payload. Command
index d1888553cc9c4d594ccf9f97237a2c2011a2abb8..a7842622b271e56296f4e61455fdc7f7fea8de23 100644 (file)
@@ -162,7 +162,7 @@ typedef unsigned char SilcCommand;
  *
  * NAME
  * 
- *    typedef SilcUInt16 SilcCommandStatus;
+ *    typedef SilcUInt8 SilcCommandStatus;
  *
  * DESCRIPTION
  *
@@ -172,7 +172,7 @@ typedef unsigned char SilcCommand;
  *
  * SOURCE
  */
-typedef SilcUInt16 SilcCommandStatus;
+typedef SilcUInt8 SilcCommandStatus;
 
 /* Command Status messages */
 #define SILC_STATUS_OK                      0
@@ -324,20 +324,35 @@ SilcBuffer silc_command_payload_encode_vap(SilcCommand cmd,
  *    SilcBuffer 
  *    silc_command_reply_payload_encode_va(SilcCommand cmd, 
  *                                         SilcCommandStatus status,
+ *                                         SilcCommandStatus error,
  *                                         SilcUInt16 ident,
  *                                         SilcUInt32 argc, ...);
  *
  * DESCRIPTION
  *
  *    Same as silc_command_payload_encode_va except that this is used to 
- *    encode strictly command reply packets. The command status message
- *    to be returned is sent as extra argument to this function. The `argc'
- *    must not count `status' as on argument.
+ *    encode strictly command reply packets.  The `argc' must not count 
+ *    `status' and `error' as arguments.  The `status' includes the
+ *    command reply status.  If single reply will be sent then it includes
+ *    SILC_STATUS_OK if error did not occur.  It includes an error value
+ *    if error did occur.  In this case `error' field is ignored.  If
+ *    there will be multiple successful command replies then the `status'
+ *    includes a list value and `error' is ignored.  If there will
+ *    multiple error replies the `status' includes a list value, and
+ *    the `error' includes an error value.  Thus, the `error' value is
+ *    specified only if there will be list of errors.
+ *
+ * NOTES
+ *
+ *    Protocol defines that it is possible to send both list of successful
+ *    and list of error replies at the same time, as long as the error
+ *    replies are sent after the successful replies.
  *
  ***/
 SilcBuffer 
 silc_command_reply_payload_encode_va(SilcCommand cmd, 
                                     SilcCommandStatus status,
+                                    SilcCommandStatus error,
                                     SilcUInt16 ident,
                                     SilcUInt32 argc, ...);
 
@@ -348,6 +363,7 @@ silc_command_reply_payload_encode_va(SilcCommand cmd,
  *    SilcBuffer 
  *    silc_command_reply_payload_encode_vap(SilcCommand cmd, 
  *                                          SilcCommandStatus status,
+ *                                          SilcCommandStatus error,
  *                                          SilcUInt16 ident, SilcUInt32 argc,
  *                                          va_list ap);
  *
@@ -360,6 +376,7 @@ silc_command_reply_payload_encode_va(SilcCommand cmd,
 SilcBuffer 
 silc_command_reply_payload_encode_vap(SilcCommand cmd, 
                                      SilcCommandStatus status,
+                                     SilcCommandStatus error,
                                      SilcUInt16 ident, SilcUInt32 argc, 
                                      va_list ap);
 
@@ -423,15 +440,23 @@ SilcUInt16 silc_command_get_ident(SilcCommandPayload payload);
  *
  * SYNOPSIS
  *
- *    SilcCommandStatus silc_command_get_status(SilcCommandPayload payload);
+ *    bool silc_command_get_status(SilcCommandPayload payload, 
+ *                                 SilcCommandStatus *status,
+ *                                 SilcCommandStatus *error);
  *
  * DESCRIPTION
  *
- *    Returns the SilcCommandStatus from command reply payload's argument 
- *    payload.  Status can be returned only from command reply payload.
+ *    This function returns the command reply status into `status' and
+ *    error status, if error occurred into the `error'.  The function
+ *    returns TRUE if command reply status is not error, and FALSE if
+ *    error occurred.  In this case the `error' will include the actual
+ *    error status.  The `status' can be in this case some list value
+ *    which indicates that there will be list of errors.
  *
  ***/
-SilcCommandStatus silc_command_get_status(SilcCommandPayload payload);
+bool silc_command_get_status(SilcCommandPayload payload, 
+                            SilcCommandStatus *status,
+                            SilcCommandStatus *error);
 
 /****f* silccore/SilcCommandAPI/silc_command_set_ident
  *
index 6f47e7f827ecfa0792ce434fef26e4de31e3235b..df2ce260d9465c3374515dd8dade1099a617b480 100644 (file)
  *
  * DESCRIPTION
  *
- *    SILC User modes. These indicate the status of the client in the
- *    SILC network.
+ *    SILC User modes. These indicate the status and presence of the client
+ *    in the SILC network.
  *
  * SOURCE
  */
-#define SILC_UMODE_NONE                0x0000 /* Normal SILC user */
-#define SILC_UMODE_SERVER_OPERATOR     0x0001 /* Server operator */
-#define SILC_UMODE_ROUTER_OPERATOR     0x0002 /* Router (SILC) operator */
-#define SILC_UMODE_GONE                0x0004 /* Client is gone */
+#define SILC_UMODE_NONE                0x00000000 /* Normal SILC user */
+#define SILC_UMODE_SERVER_OPERATOR     0x00000001 /* Server operator */
+#define SILC_UMODE_ROUTER_OPERATOR     0x00000002 /* Router (SILC) operator */
+#define SILC_UMODE_GONE                0x00000004 /* Client is gone */
+#define SILC_UMODE_INDISPOSED          0x00000008 /* Client is indisposed */
+#define SILC_UMODE_BUSY                0x00000010 /* Client is busy */
+#define SILC_UMODE_PAGE                0x00000020 /* Client requests paging */
+#define SILC_UMODE_HYPER               0x00000040 /* Client is hyper active */
+#define SILC_UMODE_ROBOT               0x00000080 /* Client is really robot */
 /***/
 
 #endif