X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccore%2Fsilcnotify.c;h=fc3dd8b28f559fe7ebcb9155def0a18fab29ea43;hb=52e57c880aba9c5e89f59d962eb9af75670b76e0;hp=028ae025591ec1dfad9f09c1c78a3a378b7e5ec5;hpb=d3603be5fccbd7ecf6b009298a2bcbfc2216cb50;p=silc.git diff --git a/lib/silccore/silcnotify.c b/lib/silccore/silcnotify.c index 028ae025..fc3dd8b2 100644 --- a/lib/silccore/silcnotify.c +++ b/lib/silccore/silcnotify.c @@ -2,15 +2,14 @@ silcnotify.c - Author: Pekka Riikonen + Author: Pekka Riikonen - Copyright (C) 2000 Pekka Riikonen + Copyright (C) 2000 - 2007 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 @@ -19,7 +18,7 @@ */ /* $Id$ */ -#include "silcincludes.h" +#include "silc.h" #include "silcnotify.h" /****************************************************************************** @@ -30,122 +29,166 @@ struct SilcNotifyPayloadStruct { SilcNotifyType type; - unsigned int argc; - unsigned char *message; + 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, + SilcUInt32 payload_len) { - SilcNotifyPayload new; - unsigned short len; + SilcBufferStruct buffer; + SilcNotifyPayload newp; + SilcUInt16 len; + int ret; SILC_LOG_DEBUG(("Parsing Notify payload")); - 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); - - if (len > buffer->len) + silc_buffer_set(&buffer, (unsigned char *)payload, payload_len); + newp = silc_calloc(1, sizeof(*newp)); + if (!newp) + return NULL; + + ret = silc_buffer_unformat(&buffer, + SILC_STR_UI_SHORT(&newp->type), + SILC_STR_UI_SHORT(&len), + SILC_STR_UI_CHAR(&newp->argc), + SILC_STR_END); + if (ret == -1) goto err; - silc_buffer_pull(buffer, 5); - silc_buffer_unformat(buffer, - SILC_STR_UI_XNSTRING_ALLOC(&new->message, len), - SILC_STR_END); + if (len > silc_buffer_len(&buffer)) + goto err; - if (new->argc) { - silc_buffer_pull(buffer, len); - new->args = silc_argument_payload_parse(buffer, new->argc); - silc_buffer_push(buffer, len); + if (newp->argc) { + silc_buffer_pull(&buffer, 5); + newp->args = silc_argument_payload_parse(buffer.data, + silc_buffer_len(&buffer), + newp->argc); + if (!newp->args) + goto err; + silc_buffer_push(&buffer, 5); } - silc_buffer_push(buffer, 5); - - return new; + return newp; err: - silc_free(new); + silc_free(newp); return NULL; } /* 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 *, SilcUInt32 (len)}. */ -SilcBuffer silc_notify_payload_encode(SilcNotifyType type, char *message, - unsigned int argc, va_list ap) +SilcBuffer silc_notify_payload_encode(SilcNotifyType type, SilcUInt32 argc, + va_list ap) { SilcBuffer buffer; SilcBuffer args = NULL; unsigned char **argv; - unsigned int *argv_lens = NULL, *argv_types = NULL; + SilcUInt32 *argv_lens = NULL, *argv_types = NULL; unsigned char *x; - unsigned int x_len; - int i, len = 0; + SilcUInt32 x_len, len = 0; + int i, k = 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)); - - for (i = 0; i < argc; i++) { + if (!argv) + return NULL; + argv_lens = silc_calloc(argc, sizeof(SilcUInt32)); + if (!argv_lens) { + silc_free(argv); + return NULL; + } + argv_types = silc_calloc(argc, sizeof(SilcUInt32)); + if (!argv_types) { + silc_free(argv_lens); + silc_free(argv); + return NULL; + } + + for (i = 0, k = 0; i < argc; i++) { x = va_arg(ap, unsigned char *); - x_len = va_arg(ap, unsigned int); - - 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; + x_len = va_arg(ap, SilcUInt32); + + if (!x || !x_len) + continue; + + argv[k] = silc_memdup(x, x_len); + if (!argv[k]) + return NULL; + argv_lens[k] = x_len; + argv_types[k] = i + 1; + k++; } - args = silc_argument_payload_encode(argc, argv, argv_lens, argv_types); - len = args->len; + args = silc_argument_payload_encode(k, argv, argv_lens, argv_types); + len = silc_buffer_len(args); - for (i = 0; i < argc; i++) + for (i = 0; i < k; i++) silc_free(argv[i]); silc_free(argv); silc_free(argv_lens); silc_free(argv_types); } - - i = strlen(message); - len += 5 + i; - buffer = silc_buffer_alloc(len); - silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer)); + len += 5; + buffer = silc_buffer_alloc_size(len); + if (!buffer) + return NULL; silc_buffer_format(buffer, SILC_STR_UI_SHORT(type), - SILC_STR_UI_SHORT(i), - SILC_STR_UI_CHAR(argc), - SILC_STR_UI_XNSTRING(message, i), + SILC_STR_UI_SHORT(len), + SILC_STR_UI_CHAR(k), SILC_STR_END); - if (argc) { - silc_buffer_pull(buffer, 5 + i); + if (k) { silc_buffer_format(buffer, - SILC_STR_UI_XNSTRING(args->data, args->len), + SILC_STR_OFFSET(5), + SILC_STR_DATA(args->data, silc_buffer_len(args)), SILC_STR_END); - silc_buffer_push(buffer, 5 + i); silc_buffer_free(args); } 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, + SilcUInt32 argc, + SilcBuffer args) +{ + SilcBuffer buffer; + SilcUInt32 len; + + len = 5 + (args ? silc_buffer_len(args) : 0); + buffer = silc_buffer_alloc_size(len); + if (!buffer) + return NULL; + 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_format(buffer, + SILC_STR_OFFSET(5), + SILC_STR_DATA(args->data, silc_buffer_len(args)), + SILC_STR_END); + + return buffer; +} + +/* Frees notify payload */ void silc_notify_payload_free(SilcNotifyPayload payload) { if (payload) { silc_argument_payload_free(payload->args); - silc_free(payload->message); silc_free(payload); } } @@ -159,18 +202,11 @@ SilcNotifyType silc_notify_get_type(SilcNotifyPayload payload) /* Return argument nums */ -unsigned int silc_notify_get_arg_num(SilcNotifyPayload payload) +SilcUInt32 silc_notify_get_arg_num(SilcNotifyPayload payload) { return payload->argc; } -/* Return notify message */ - -unsigned char *silc_notify_get_message(SilcNotifyPayload payload) -{ - return payload->message; -} - /* Return argument payload */ SilcArgumentPayload silc_notify_get_args(SilcNotifyPayload payload)