X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcsftp%2Fsftp_util.c;h=b3f79d5a87d978f8f69267714e46960c69d1a719;hb=40f8443d8d3a6577336ee66d18e04d9ac4d956bb;hp=349f8a0fdbe5446702478cacf17725d1a67303a7;hpb=e5d8d3db6caa344b3d419b884556c21b15e7d123;p=silc.git diff --git a/lib/silcsftp/sftp_util.c b/lib/silcsftp/sftp_util.c index 349f8a0f..b3f79d5a 100644 --- a/lib/silcsftp/sftp_util.c +++ b/lib/silcsftp/sftp_util.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 @@ -16,23 +16,27 @@ GNU General Public License for more details. */ +/* $Id$ */ -#include "silcincludes.h" +#include "silc.h" #include "silcsftp.h" #include "sftp_util.h" /* Encodes a SFTP packet of type `packet' of length `len'. The variable argument list is encoded as data payload to the buffer. Returns the encoded packet or NULL on error. The caller must free the returned - buffer. */ + buffer. If `packet_buf' is non-NULL then the new packet data is put + to that buffer instead of allocating new one. If the new data cannot + fit to `packet_buf' will be reallocated. */ -SilcBuffer silc_sftp_packet_encode(SilcSFTPPacket packet, uint32 len, ...) +SilcBuffer silc_sftp_packet_encode(SilcSFTPPacket packet, + SilcBuffer packet_buf, SilcUInt32 len, ...) { SilcBuffer buffer; va_list vp; va_start(vp, len); - buffer = silc_sftp_packet_encode_vp(packet, len, vp); + buffer = silc_sftp_packet_encode_vp(packet, packet_buf, len, vp); va_end(vp); return buffer; @@ -41,13 +45,30 @@ SilcBuffer silc_sftp_packet_encode(SilcSFTPPacket packet, uint32 len, ...) /* Same as silc_sftp_packet_encode but takes the variable argument list pointer as argument. */ -SilcBuffer silc_sftp_packet_encode_vp(SilcSFTPPacket packet, uint32 len, +SilcBuffer silc_sftp_packet_encode_vp(SilcSFTPPacket packet, + SilcBuffer packet_buf, SilcUInt32 len, va_list vp) { SilcBuffer buffer; + bool dyn; int ret; - buffer = silc_buffer_alloc(4 + 1 + len); + if (packet_buf) { + if (packet_buf->truelen < 4 + 1 + len) { + packet_buf = silc_buffer_realloc(packet_buf, 4 + 1 + len); + if (!packet_buf) + return NULL; + } + + buffer = packet_buf; + dyn = FALSE; + } else { + buffer = silc_buffer_alloc(4 + 1 + len); + if (!buffer) + return NULL; + dyn = TRUE; + } + silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer)); silc_buffer_format(buffer, SILC_STR_UI_INT(len), @@ -57,7 +78,8 @@ SilcBuffer silc_sftp_packet_encode_vp(SilcSFTPPacket packet, uint32 len, ret = silc_buffer_format_vp(buffer, vp); if (ret < 0) { - silc_buffer_free(buffer); + if (dyn) + silc_buffer_free(buffer); return NULL; } @@ -72,10 +94,10 @@ SilcBuffer silc_sftp_packet_encode_vp(SilcSFTPPacket packet, uint32 len, SilcSFTPPacket silc_sftp_packet_decode(SilcBuffer packet, unsigned char **payload, - uint32 *payload_len) + SilcUInt32 *payload_len) { - uint32 len; - uint8 type; + SilcUInt32 len; + SilcUInt8 type; int ret; ret = silc_buffer_unformat(packet, @@ -111,7 +133,8 @@ SilcSFTPPacket silc_sftp_packet_decode(SilcBuffer packet, SilcBuffer silc_sftp_attr_encode(SilcSFTPAttributes attr) { SilcBuffer buffer; - int i, ret, len = 4; + int i, ret; + SilcUInt32 len = 4; if (attr->flags & SILC_SFTP_ATTR_SIZE) len += 8; @@ -130,8 +153,9 @@ SilcBuffer silc_sftp_attr_encode(SilcSFTPAttributes attr) } } - buffer = silc_buffer_alloc(len); - silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer)); + buffer = silc_buffer_alloc_size(len); + if (!buffer) + return NULL; silc_buffer_format(buffer, SILC_STR_UI_INT(attr->flags), @@ -201,6 +225,8 @@ SilcSFTPAttributes silc_sftp_attr_decode(SilcBuffer buffer) SilcSFTPAttributes attr; attr = silc_calloc(1, sizeof(*attr)); + if (!attr) + return NULL; if (silc_buffer_unformat(buffer, SILC_STR_UI_INT(&attr->flags), @@ -261,9 +287,12 @@ SilcSFTPAttributes silc_sftp_attr_decode(SilcBuffer buffer) sizeof(*attr->extended_type)); attr->extended_data = silc_calloc(attr->extended_count, sizeof(*attr->extended_data)); + if (!attr->extended_type || !attr->extended_data) + return NULL; + for (i = 0; i < attr->extended_count; i++) { unsigned char *tmp, *tmp2; - uint32 tmp_len, tmp2_len; + SilcUInt32 tmp_len, tmp2_len; if (silc_buffer_unformat(buffer, SILC_STR_UI32_NSTRING(&tmp, &tmp_len), @@ -273,6 +302,8 @@ SilcSFTPAttributes silc_sftp_attr_decode(SilcBuffer buffer) attr->extended_type[i] = silc_buffer_alloc(tmp_len); attr->extended_data[i] = silc_buffer_alloc(tmp2_len); + if (!attr->extended_type[i] || !attr->extended_data[i]) + return NULL; silc_buffer_put(attr->extended_type[i], tmp, tmp_len); silc_buffer_put(attr->extended_data[i], tmp2, tmp2_len); @@ -314,6 +345,8 @@ void silc_sftp_name_add(SilcSFTPName name, const char *short_name, (name->count + 1)); name->attrs = silc_realloc(name->attrs, sizeof(*name->attrs) * (name->count + 1)); + if (!name->filename || !name->long_filename || !name->attrs) + return; name->filename[name->count] = strdup(short_name); name->long_filename[name->count] = strdup(long_name); @@ -331,13 +364,20 @@ SilcBuffer silc_sftp_name_encode(SilcSFTPName name) SilcBuffer *attr_buf; attr_buf = silc_calloc(name->count, sizeof(*attr_buf)); + if (!attr_buf) + return NULL; + for (i = 0; i < name->count; i++) { len += (8 + strlen(name->filename[i]) + strlen(name->long_filename[i])); attr_buf[i] = silc_sftp_attr_encode(name->attrs[i]); + if (!attr_buf[i]) + return NULL; len += attr_buf[i]->len; } buffer = silc_buffer_alloc(len); + if (!buffer) + return NULL; silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer)); silc_buffer_format(buffer, @@ -370,16 +410,22 @@ SilcBuffer silc_sftp_name_encode(SilcSFTPName name) `count' many name, longname and attribute values. Returns the allocated structure or NULL on error. */ -SilcSFTPName silc_sftp_name_decode(uint32 count, SilcBuffer buffer) +SilcSFTPName silc_sftp_name_decode(SilcUInt32 count, SilcBuffer buffer) { SilcSFTPName name; int i; int ret; name = silc_calloc(1, sizeof(*name)); + if (!name) + return NULL; name->filename = silc_calloc(count, sizeof(*name->filename)); name->long_filename = silc_calloc(count, sizeof(*name->filename)); name->attrs = silc_calloc(count, sizeof(*name->attrs)); + if (!name->filename || !name->long_filename || !name->attrs) { + silc_sftp_name_free(name); + return NULL; + } name->count = count; for (i = 0; i < count; i++) { @@ -398,6 +444,10 @@ SilcSFTPName silc_sftp_name_decode(uint32 count, SilcBuffer buffer) /* Decode attributes, this will pull the `buffer' to correct place for next round automatically. */ name->attrs[i] = silc_sftp_attr_decode(buffer); + if (!name->attrs[i]) { + silc_sftp_name_free(name); + return NULL; + } } return name; @@ -434,7 +484,6 @@ SilcSFTPStatus silc_sftp_map_errno(int err) case ENOENT: case ENOTDIR: case EBADF: - case ELOOP: ret = SILC_SFTP_STATUS_NO_SUCH_FILE; break; case EPERM: