Author: Pekka Riikonen <priikone@silcnet.org>
- 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
*/
/* $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;
/* 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),
ret = silc_buffer_format_vp(buffer, vp);
if (ret < 0) {
- silc_buffer_free(buffer);
+ if (dyn)
+ silc_buffer_free(buffer);
return NULL;
}
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,
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;
}
}
- 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),
SilcSFTPAttributes attr;
attr = silc_calloc(1, sizeof(*attr));
+ if (!attr)
+ return NULL;
if (silc_buffer_unformat(buffer,
SILC_STR_UI_INT(&attr->flags),
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),
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);
(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);
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,
`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++) {
/* 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;