X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccore%2Fsilcargument.c;h=9c088b51cd67fb3b94311e7d193e3c26d8a4314b;hb=413da0f8686910f5e627393157566ae729ca99c4;hp=471e92c78fe18130da9bbbd89caac6ad4d7e8394;hpb=4e64dd02ccecc9c497b8db8ecb09d017b9cef9a4;p=silc.git diff --git a/lib/silccore/silcargument.c b/lib/silccore/silcargument.c index 471e92c7..9c088b51 100644 --- a/lib/silccore/silcargument.c +++ b/lib/silccore/silcargument.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2001 Pekka Riikonen + Copyright (C) 2001 - 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 @@ -29,34 +29,40 @@ ******************************************************************************/ struct SilcArgumentPayloadStruct { - uint32 argc; + SilcUInt32 argc; unsigned char **argv; - uint32 *argv_lens; - uint32 *argv_types; - uint32 pos; + SilcUInt32 *argv_lens; + SilcUInt32 *argv_types; + SilcUInt32 pos; }; /* Parses arguments and returns them into Argument Payload structure. */ SilcArgumentPayload silc_argument_payload_parse(const unsigned char *payload, - uint32 payload_len, - uint32 argc) + SilcUInt32 payload_len, + SilcUInt32 argc) { SilcBufferStruct buffer; - SilcArgumentPayload new; - uint16 p_len = 0; + SilcArgumentPayload newp; + SilcUInt16 p_len = 0; unsigned char arg_num = 0; unsigned char arg_type = 0; - uint32 pull_len = 0; + SilcUInt32 pull_len = 0; int i = 0, ret; - SILC_LOG_DEBUG(("Parsing argument payload")); - silc_buffer_set(&buffer, (unsigned char *)payload, payload_len); - new = silc_calloc(1, sizeof(*new)); - new->argv = silc_calloc(argc, sizeof(unsigned char *)); - new->argv_lens = silc_calloc(argc, sizeof(uint32)); - new->argv_types = silc_calloc(argc, sizeof(uint32)); + newp = silc_calloc(1, sizeof(*newp)); + if (!newp) + return NULL; + newp->argv = silc_calloc(argc, sizeof(unsigned char *)); + if (!newp->argv) + goto err; + newp->argv_lens = silc_calloc(argc, sizeof(SilcUInt32)); + if (!newp->argv_lens) + goto err; + newp->argv_types = silc_calloc(argc, sizeof(SilcUInt32)); + if (!newp->argv_types) + goto err; /* Get arguments */ arg_num = 1; @@ -65,19 +71,16 @@ SilcArgumentPayload silc_argument_payload_parse(const unsigned char *payload, SILC_STR_UI_SHORT(&p_len), SILC_STR_UI_CHAR(&arg_type), SILC_STR_END); - if (ret == -1) + if (ret == -1 || p_len > buffer.len - 3) goto err; - - new->argv_lens[i] = p_len; - new->argv_types[i] = arg_type; - if (p_len > buffer.len - 3) - break; - + newp->argv_lens[i] = p_len; + newp->argv_types[i] = arg_type; + /* Get argument data */ silc_buffer_pull(&buffer, 3); ret = silc_buffer_unformat(&buffer, - SILC_STR_UI_XNSTRING_ALLOC(&new->argv[i], + SILC_STR_UI_XNSTRING_ALLOC(&newp->argv[i], p_len), SILC_STR_END); if (ret == -1) @@ -87,62 +90,59 @@ SilcArgumentPayload silc_argument_payload_parse(const unsigned char *payload, pull_len += 3 + p_len; } - if (buffer.len != 0) + if (buffer.len != 0) { + SILC_LOG_DEBUG(("Malformed argument payload")); goto err; + } - new->argc = argc; - new->pos = 0; + newp->argc = argc; + newp->pos = 0; silc_buffer_push(&buffer, pull_len); - return new; + return newp; err: - if (i) { - int k; - - for (k = 0; k < i; k++) - silc_free(new->argv[k]); - } + SILC_LOG_DEBUG(("Error parsing argument payload")); + if (i) + for (ret = 0; ret < i; ret++) + silc_free(newp->argv[ret]); - silc_free(new->argv); - silc_free(new->argv_lens); - silc_free(new->argv_types); - - if (new) - silc_free(new); + silc_free(newp->argv); + silc_free(newp->argv_lens); + silc_free(newp->argv_types); + silc_free(newp); return NULL; } /* Encodes arguments in to Argument Paylods returning them to SilcBuffer. */ -SilcBuffer silc_argument_payload_encode(uint32 argc, +SilcBuffer silc_argument_payload_encode(SilcUInt32 argc, unsigned char **argv, - uint32 *argv_lens, - uint32 *argv_types) + SilcUInt32 *argv_lens, + SilcUInt32 *argv_types) { SilcBuffer buffer; - uint32 len; + SilcUInt32 len; int i; - SILC_LOG_DEBUG(("Encoding Argument payload")); - len = 0; for (i = 0; i < argc; i++) - len += 3 + argv_lens[i]; + len += 3 + (SilcUInt16)argv_lens[i]; - buffer = silc_buffer_alloc(len); - silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer)); + buffer = silc_buffer_alloc_size(len); + if (!buffer) + return NULL; /* Put arguments */ for (i = 0; i < argc; i++) { silc_buffer_format(buffer, SILC_STR_UI_SHORT(argv_lens[i]), SILC_STR_UI_CHAR(argv_types[i]), - SILC_STR_UI_XNSTRING(argv[i], argv_lens[i]), + SILC_STR_UI_XNSTRING(argv[i], (SilcUInt16)argv_lens[i]), SILC_STR_END); - silc_buffer_pull(buffer, 3 + argv_lens[i]); + silc_buffer_pull(buffer, 3 + (SilcUInt16)argv_lens[i]); } silc_buffer_push(buffer, len); @@ -150,23 +150,49 @@ SilcBuffer silc_argument_payload_encode(uint32 argc, return buffer; } +/* Encode one argument to buffer */ + +SilcBuffer silc_argument_payload_encode_one(SilcBuffer args, + unsigned char *arg, + SilcUInt32 arg_len, + SilcUInt32 arg_type) +{ + SilcBuffer buffer = args; + SilcUInt32 len; + + len = 3 + (SilcUInt16)arg_len; + buffer = silc_buffer_realloc(buffer, + (buffer ? buffer->truelen + len : len)); + if (!buffer) + return NULL; + silc_buffer_pull(buffer, buffer->len); + silc_buffer_pull_tail(buffer, len); + silc_buffer_format(buffer, + SILC_STR_UI_SHORT(arg_len), + SILC_STR_UI_CHAR(arg_type), + SILC_STR_UI_XNSTRING(arg, (SilcUInt16)arg_len), + SILC_STR_END); + silc_buffer_push(buffer, buffer->data - buffer->head); + + return buffer; +} + /* Same as above but encode the buffer from SilcArgumentPayload structure instead of raw data. */ SilcBuffer silc_argument_payload_encode_payload(SilcArgumentPayload payload) { SilcBuffer buffer; - uint32 len; + SilcUInt32 len; int i; - SILC_LOG_DEBUG(("Encoding Argument payload")); - len = 0; for (i = 0; i < payload->argc; i++) len += 3 + payload->argv_lens[i]; - buffer = silc_buffer_alloc(len); - silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer)); + buffer = silc_buffer_alloc_size(len); + if (!buffer) + return NULL; /* Put arguments */ for (i = 0; i < payload->argc; i++) { @@ -203,7 +229,7 @@ void silc_argument_payload_free(SilcArgumentPayload payload) /* Returns number of arguments in payload */ -uint32 silc_argument_get_arg_num(SilcArgumentPayload payload) +SilcUInt32 silc_argument_get_arg_num(SilcArgumentPayload payload) { return payload ? payload->argc : 0; } @@ -211,13 +237,16 @@ uint32 silc_argument_get_arg_num(SilcArgumentPayload payload) /* Returns first argument from payload. */ unsigned char *silc_argument_get_first_arg(SilcArgumentPayload payload, - uint32 *ret_len) + SilcUInt32 *type, + SilcUInt32 *ret_len) { if (!payload) return NULL; payload->pos = 0; + if (type) + *type = payload->argv_types[payload->pos]; if (ret_len) *ret_len = payload->argv_lens[payload->pos]; @@ -227,7 +256,8 @@ unsigned char *silc_argument_get_first_arg(SilcArgumentPayload payload, /* Returns next argument from payload or NULL if no more arguments. */ unsigned char *silc_argument_get_next_arg(SilcArgumentPayload payload, - uint32 *ret_len) + SilcUInt32 *type, + SilcUInt32 *ret_len) { if (!payload) return NULL; @@ -235,6 +265,8 @@ unsigned char *silc_argument_get_next_arg(SilcArgumentPayload payload, if (payload->pos >= payload->argc) return NULL; + if (type) + *type = payload->argv_types[payload->pos]; if (ret_len) *ret_len = payload->argv_lens[payload->pos]; @@ -244,8 +276,8 @@ unsigned char *silc_argument_get_next_arg(SilcArgumentPayload payload, /* Returns argument which type is `type'. */ unsigned char *silc_argument_get_arg_type(SilcArgumentPayload payload, - uint32 type, - uint32 *ret_len) + SilcUInt32 type, + SilcUInt32 *ret_len) { int i;