X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccore%2Fsilcnotify.c;h=c3600c52eefcfe428a40bd0ccefe700c4788f7c2;hb=386c883d8774999c6e74d7c6c37e52e4163a4cb1;hp=b76d675275c9f3cfd44da3be54c0da7e344a4658;hpb=4d35af3be05cacf69ca4bd634973cdcd25118e98;p=silc.git diff --git a/lib/silccore/silcnotify.c b/lib/silccore/silcnotify.c index b76d6752..c3600c52 100644 --- a/lib/silccore/silcnotify.c +++ b/lib/silccore/silcnotify.c @@ -30,34 +30,41 @@ struct SilcNotifyPayloadStruct { SilcNotifyType type; - unsigned int argc; + unsigned char argc; SilcArgumentPayload args; }; /* Parse notify payload buffer and return data into payload structure */ -SilcNotifyPayload silc_notify_payload_parse(SilcBuffer buffer) +SilcNotifyPayload silc_notify_payload_parse(const unsigned char *payload, + uint32 payload_len) { + SilcBufferStruct buffer; SilcNotifyPayload new; - unsigned short len; + uint16 len; + int ret; SILC_LOG_DEBUG(("Parsing Notify payload")); + silc_buffer_set(&buffer, (unsigned char *)payload, payload_len); new = silc_calloc(1, sizeof(*new)); - silc_buffer_unformat(buffer, - SILC_STR_UI_SHORT(&new->type), - SILC_STR_UI_SHORT(&len), - SILC_STR_UI_CHAR(&new->argc), - SILC_STR_END); + ret = silc_buffer_unformat(&buffer, + SILC_STR_UI_SHORT(&new->type), + SILC_STR_UI_SHORT(&len), + SILC_STR_UI_CHAR(&new->argc), + SILC_STR_END); + if (ret == -1) + goto err; - if (len > buffer->len) + if (len > buffer.len) goto err; if (new->argc) { - silc_buffer_pull(buffer, 5); - new->args = silc_argument_payload_parse(buffer, new->argc); - silc_buffer_push(buffer, 5); + silc_buffer_pull(&buffer, 5); + new->args = silc_argument_payload_parse(buffer.data, buffer.len, + new->argc); + silc_buffer_push(&buffer, 5); } return new; @@ -69,38 +76,41 @@ SilcNotifyPayload silc_notify_payload_parse(SilcBuffer buffer) /* Encode notify payload with variable argument list. If `argc' is > 0 argument payloads will be associated to the notify payload. Variable - arguments must be {usigned char *, unsigned int (len)}. */ + arguments must be {usigned char *, uint32 (len)}. */ -SilcBuffer silc_notify_payload_encode(SilcNotifyType type, unsigned int argc, +SilcBuffer silc_notify_payload_encode(SilcNotifyType type, uint32 argc, va_list ap) { SilcBuffer buffer; SilcBuffer args = NULL; unsigned char **argv; - unsigned int *argv_lens = NULL, *argv_types = NULL; + uint32 *argv_lens = NULL, *argv_types = NULL; unsigned char *x; - unsigned int x_len; - int i, len = 0; + uint32 x_len; + int i, k = 0, len = 0; if (argc) { argv = silc_calloc(argc, sizeof(unsigned char *)); - argv_lens = silc_calloc(argc, sizeof(unsigned int)); - argv_types = silc_calloc(argc, sizeof(unsigned int)); + argv_lens = silc_calloc(argc, sizeof(uint32)); + argv_types = silc_calloc(argc, sizeof(uint32)); - for (i = 0; i < argc; i++) { + for (i = 0, k = 0; i < argc; i++) { x = va_arg(ap, unsigned char *); - x_len = va_arg(ap, unsigned int); + x_len = va_arg(ap, uint32); + + if (!x || !x_len) + continue; - argv[i] = silc_calloc(x_len + 1, sizeof(unsigned char)); - memcpy(argv[i], x, x_len); - argv_lens[i] = x_len; - argv_types[i] = i + 1; + argv[k] = silc_memdup(x, x_len); + argv_lens[k] = x_len; + argv_types[k] = i + 1; + k++; } - args = silc_argument_payload_encode(argc, argv, argv_lens, argv_types); + args = silc_argument_payload_encode(k, argv, argv_lens, argv_types); len = args->len; - for (i = 0; i < argc; i++) + for (i = 0; i < k; i++) silc_free(argv[i]); silc_free(argv); silc_free(argv_lens); @@ -113,10 +123,10 @@ SilcBuffer silc_notify_payload_encode(SilcNotifyType type, unsigned int argc, silc_buffer_format(buffer, SILC_STR_UI_SHORT(type), SILC_STR_UI_SHORT(len), - SILC_STR_UI_CHAR(argc), + SILC_STR_UI_CHAR(k), SILC_STR_END); - if (argc) { + if (k) { silc_buffer_pull(buffer, 5); silc_buffer_format(buffer, SILC_STR_UI_XNSTRING(args->data, args->len), @@ -128,7 +138,36 @@ SilcBuffer silc_notify_payload_encode(SilcNotifyType type, unsigned int argc, return buffer; } -/* Free's notify payload */ +/* Same as above but takes argument from the `args' Argument Payload. */ + +SilcBuffer silc_notify_payload_encode_args(SilcNotifyType type, + uint32 argc, + SilcBuffer args) +{ + SilcBuffer buffer; + int len; + + len = 5 + (args ? args->len : 0); + buffer = silc_buffer_alloc(len); + silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer)); + silc_buffer_format(buffer, + SILC_STR_UI_SHORT(type), + SILC_STR_UI_SHORT(len), + SILC_STR_UI_CHAR(argc), + SILC_STR_END); + + if (args) { + silc_buffer_pull(buffer, 5); + silc_buffer_format(buffer, + SILC_STR_UI_XNSTRING(args->data, args->len), + SILC_STR_END); + silc_buffer_push(buffer, 5); + } + + return buffer; +} + +/* Frees notify payload */ void silc_notify_payload_free(SilcNotifyPayload payload) { @@ -147,7 +186,7 @@ SilcNotifyType silc_notify_get_type(SilcNotifyPayload payload) /* Return argument nums */ -unsigned int silc_notify_get_arg_num(SilcNotifyPayload payload) +uint32 silc_notify_get_arg_num(SilcNotifyPayload payload) { return payload->argc; }