+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
* 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
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
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.
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.
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
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);
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);
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,
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,
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 */
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),
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),
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 {
}
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));
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 ?
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 ?
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);
/* 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),
/* 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),
/* 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 ?
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 ?
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);
/* 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),
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,
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,
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);
}
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 ?
/* 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);
/* 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,
/* 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);
/* 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 ?
/* 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,
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);
#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
{
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;
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;
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;
{
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;
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;
{
SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
SilcServer server = cmd->server;
- SilcCommandStatus status;
+ SilcCommandStatus status, error;
SilcServerEntry entry;
SilcServerID *server_id;
SilcUInt32 tmp_len;
{
SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
SilcServer server = cmd->server;
- SilcCommandStatus status;
+ SilcCommandStatus status, error;
SilcServerEntry entry = NULL;
SilcServerID *server_id;
SilcUInt32 tmp_len;
SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
SilcServer server = cmd->server;
SilcIDCacheEntry cache = NULL;
- SilcCommandStatus status;
+ SilcCommandStatus status, error;
SilcChannelID *id;
SilcClientID *client_id = NULL;
SilcChannelEntry entry;
{
SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
SilcServer server = cmd->server;
- SilcCommandStatus status;
+ SilcCommandStatus status, error;
unsigned char *tmp;
SilcUInt32 tmp_len;
SilcBufferStruct buf;
{
SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
SilcServer server = cmd->server;
- SilcCommandStatus status;
+ SilcCommandStatus status, error;
SilcChannelEntry channel;
SilcChannelID *channel_id = NULL;
SilcBuffer client_id_list;
{
SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
SilcServer server = cmd->server;
- SilcCommandStatus status;
+ SilcCommandStatus status, error;
SilcClientEntry client = NULL;
SilcServerEntry server_entry = NULL;
SilcClientID *client_id = NULL;
{
SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context;
SilcServer server = cmd->server;
- SilcCommandStatus status;
+ SilcCommandStatus status, error;
SilcChannelID *channel_id = NULL;
SilcChannelEntry channel;
SilcIDCacheEntry cache;
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);
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);
}
SilcSocketConnection sock,
SilcCommand command,
SilcCommandStatus status,
+ SilcCommandStatus error,
SilcUInt16 ident,
SilcUInt32 argc, ...)
{
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);
SilcIdType dst_id_type,
SilcCommand command,
SilcCommandStatus status,
+ SilcCommandStatus error,
SilcUInt16 ident,
SilcUInt32 argc, ...)
{
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);
SilcSocketConnection sock,
SilcCommand command,
SilcCommandStatus status,
+ SilcCommandStatus error,
SilcUInt16 ident,
SilcUInt32 argc, ...);
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,
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
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
1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-| Status Message |
+| Status | Error |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.in 3
.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
.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
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.
Provided version string was not acceptable.
+
11 SILC_SKE_STATUS_INVALID_COOKIE
The cookie in the Key Exchange Start Payload was malformed,
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);
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);
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,
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;
} 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,
/* 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;
}
#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. */
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,
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);
/* 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 =
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) {
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);
/* 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 =
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;
}
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) {
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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);
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;
}
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;
}
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 */
/* 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 =
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 */
/* 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 =
SILC_LOG_DEBUG(("Start"));
- if (cmd->status != SILC_STATUS_OK)
+ if (cmd->error != SILC_STATUS_OK)
goto out;
/* Get server ID */
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;
}
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;
}
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;
}
SilcSocketConnection sock;
SilcCommandPayload payload;
SilcCommandStatus status;
+ SilcCommandStatus error;
SilcArgumentPayload args;
SilcPacketContext *packet;
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"));
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;
SilcBuffer
silc_command_reply_payload_encode_va(SilcCommand cmd,
SilcCommandStatus status,
+ SilcCommandStatus error,
SilcUInt16 ident,
SilcUInt32 argc, ...)
{
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;
SilcBuffer
silc_command_reply_payload_encode_vap(SilcCommand cmd,
SilcCommandStatus status,
+ SilcCommandStatus error,
SilcUInt16 ident, SilcUInt32 argc,
va_list ap)
{
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);
/* 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
*
* NAME
*
- * typedef SilcUInt16 SilcCommandStatus;
+ * typedef SilcUInt8 SilcCommandStatus;
*
* DESCRIPTION
*
*
* SOURCE
*/
-typedef SilcUInt16 SilcCommandStatus;
+typedef SilcUInt8 SilcCommandStatus;
/* Command Status messages */
#define SILC_STATUS_OK 0
* 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, ...);
* SilcBuffer
* silc_command_reply_payload_encode_vap(SilcCommand cmd,
* SilcCommandStatus status,
+ * SilcCommandStatus error,
* SilcUInt16 ident, SilcUInt32 argc,
* va_list ap);
*
SilcBuffer
silc_command_reply_payload_encode_vap(SilcCommand cmd,
SilcCommandStatus status,
+ SilcCommandStatus error,
SilcUInt16 ident, SilcUInt32 argc,
va_list ap);
*
* 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
*
*
* 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