X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccore%2Fsilccommand.c;h=7a3eeb1c75da9b79ebff95e1cc404daadd191a9d;hb=c257b555225193e54d85daf541d29578b3c93882;hp=aaa190c2732e1a04b30b457386553f96a1ab1161;hpb=6adc48fa2d165fb7522351375ea9e1c0ed01d714;p=silc.git diff --git a/lib/silccore/silccommand.c b/lib/silccore/silccommand.c index aaa190c2..7a3eeb1c 100644 --- a/lib/silccore/silccommand.c +++ b/lib/silccore/silccommand.c @@ -1,16 +1,15 @@ /* - silccommand.c + silccommand.c Author: Pekka Riikonen - Copyright (C) 1997 - 2001 Pekka Riikonen + Copyright (C) 1997 - 2002 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - + the Free Software Foundation; version 2 of the License. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -65,24 +64,27 @@ SilcCommandPayload silc_command_payload_parse(const unsigned char *payload, SILC_STR_UI_SHORT(&newp->ident), SILC_STR_END); if (ret == -1) { + SILC_LOG_ERROR(("Incorrect command payload in packet")); silc_free(newp); return NULL; } if (p_len != buffer.len) { - SILC_LOG_ERROR(("Incorrect command payload in packet, packet dropped")); + SILC_LOG_ERROR(("Incorrect command payload in packet")); silc_free(newp); return NULL; } if (newp->cmd == 0) { + SILC_LOG_ERROR(("Incorrect command type in command payload")); silc_free(newp); return NULL; } 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; @@ -110,6 +112,8 @@ SilcBuffer silc_command_payload_encode(SilcCommand cmd, if (argc) { args = silc_argument_payload_encode(argc, argv, argv_lens, argv_types); + if (!args) + return NULL; len = args->len; } @@ -153,7 +157,8 @@ SilcBuffer silc_command_payload_encode_payload(SilcCommandPayload payload) if (payload->args) { args = silc_argument_payload_encode_payload(payload->args); - len = args->len; + if (args) + len = args->len; argc = silc_argument_get_arg_num(payload->args); } @@ -270,7 +275,8 @@ SilcBuffer silc_command_payload_encode_vap(SilcCommand cmd, SilcBuffer silc_command_reply_payload_encode_va(SilcCommand cmd, - SilcCommandStatus status, + SilcStatus status, + SilcStatus error, SilcUInt16 ident, SilcUInt32 argc, ...) { @@ -278,7 +284,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; @@ -286,7 +293,8 @@ silc_command_reply_payload_encode_va(SilcCommand cmd, SilcBuffer silc_command_reply_payload_encode_vap(SilcCommand cmd, - SilcCommandStatus status, + SilcStatus status, + SilcStatus error, SilcUInt16 ident, SilcUInt32 argc, va_list ap) { @@ -315,7 +323,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); @@ -386,6 +395,49 @@ SilcUInt16 silc_command_get_ident(SilcCommandPayload payload) return payload->ident; } +/* Return command status */ + +bool silc_command_get_status(SilcCommandPayload payload, + SilcStatus *status, + SilcStatus *error) +{ + unsigned char *tmp; + SilcUInt32 tmp_len; + + if (!payload->args) + return 0; + tmp = silc_argument_get_arg_type(payload->args, 1, &tmp_len); + if (!tmp || tmp_len != 2) + return 0; + + /* Check for 1.0 protocol version which didn't have `error' */ + if (tmp[0] == 0 && tmp[1] != 0) { + /* Protocol 1.0 version */ + SilcStatus 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 = (SilcStatus)tmp[0]; + if (error) + *error = (SilcStatus)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 payloads are frequentlly resent in SILC and thusly this makes it easy to set the identifier. */