X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilcsftp%2Fsftp_client.c;h=a60437235562fe9baa86484eb4cd634a314cd6f5;hp=0b4ee1647345499ecdd2f39a847b02f2f8d05fce;hb=40f8443d8d3a6577336ee66d18e04d9ac4d956bb;hpb=030955992dd0663ddb907a06fd92af62afb9a015 diff --git a/lib/silcsftp/sftp_client.c b/lib/silcsftp/sftp_client.c index 0b4ee164..a6043723 100644 --- a/lib/silcsftp/sftp_client.c +++ b/lib/silcsftp/sftp_client.c @@ -1,10 +1,10 @@ /* - sftp_client.c + sftp_client.c Author: Pekka Riikonen - Copyright (C) 2001 Pekka Riikonen + Copyright (C) 2001 - 2005 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 @@ -18,7 +18,7 @@ */ /* $Id$ */ -#include "silcincludes.h" +#include "silc.h" #include "silcsftp.h" #include "sftp_util.h" @@ -39,8 +39,7 @@ typedef struct SilcSFTPRequestStruct { /* SFTP client context */ typedef struct { - SilcSFTPSendPacketCallback send_packet; - void *send_context; + SilcStream stream; SilcSFTPVersionCallback version; void *version_context; SilcUInt32 id; @@ -54,6 +53,9 @@ struct SilcSFTPHandleStruct { SilcUInt32 data_len; }; +static void silc_sftp_client_receive_process(SilcSFTP context, + SilcBuffer buffer) + /* Creates SilcSFTPHandle and returns pointer to it. The caller must free the context. */ @@ -63,7 +65,11 @@ static SilcSFTPHandle silc_sftp_handle_create(unsigned char *data, SilcSFTPHandle handle; handle = silc_calloc(1, sizeof(*handle)); + if (!handle) + return NULL; handle->data = silc_calloc(data_len, sizeof(*handle->data)); + if (!handle->data) + return NULL; memcpy(handle->data, data, data_len); handle->data_len = data_len; @@ -80,7 +86,7 @@ static void silc_sftp_handle_delete(SilcSFTPHandle handle) /* Returns the handle data of the `handle' to the `data' pointer. */ -static void silc_sftp_handle_get(SilcSFTPHandle handle, +static void silc_sftp_handle_get(SilcSFTPHandle handle, const unsigned char **data, SilcUInt32 *data_len) { @@ -91,7 +97,7 @@ static void silc_sftp_handle_get(SilcSFTPHandle handle, /* General routine to send SFTP packet to the SFTP server. */ static void silc_sftp_send_packet(SilcSFTPClient sftp, - SilcSFTPPacket type, + SilcSFTPPacket type, SilcUInt32 len, ...) { SilcBuffer tmp; @@ -104,20 +110,21 @@ static void silc_sftp_send_packet(SilcSFTPClient sftp, return; sftp->packet = tmp; - SILC_LOG_HEXDUMP(("SFTP packet to server"), sftp->packet->data, - sftp->packet->len); + SILC_LOG_HEXDUMP(("SFTP packet to server"), sftp->packet->data, + silc_buffer_len(sftp->packet)); /* Send the packet */ - (*sftp->send_packet)(sftp->packet, sftp->send_context); + silc_stream_write(sftp->stream, sftp->packet->data, + silc_buffer_len(sftp->packet)); /* Clear packet */ - sftp->packet->data = sftp->packet->tail = sftp->packet->head; - sftp->packet->len = 0; + silc_buffer_reset(sftp->packet); } /* Finds request by request ID. */ -static SilcSFTPRequest silc_sftp_find_request(SilcSFTPClient sftp, SilcUInt32 id) +static SilcSFTPRequest silc_sftp_find_request(SilcSFTPClient sftp, + SilcUInt32 id) { SilcSFTPRequest req; @@ -139,8 +146,8 @@ static SilcSFTPRequest silc_sftp_find_request(SilcSFTPClient sftp, SilcUInt32 id operation. The variable argument list includes the status and req->type specific data. */ -static void silc_sftp_call_request(SilcSFTPClient sftp, - SilcSFTPRequest req, +static void silc_sftp_call_request(SilcSFTPClient sftp, + SilcSFTPRequest req, SilcSFTPPacket type, SilcSFTPStatus status, ...) { @@ -167,9 +174,9 @@ static void silc_sftp_call_request(SilcSFTPClient sftp, data_len = (SilcUInt32)va_arg(vp, SilcUInt32); if (req->data) - (*req->data)((SilcSFTP)sftp, status, (const unsigned char *)data, + (*req->data)((SilcSFTP)sftp, status, (const unsigned char *)data, data_len, req->context); - } + } break; case SILC_SFTP_OPEN: @@ -189,6 +196,11 @@ static void silc_sftp_call_request(SilcSFTPClient sftp, hdata = (unsigned char *)va_arg(vp, unsigned char *); hdata_len = (SilcUInt32)va_arg(vp, SilcUInt32); handle = silc_sftp_handle_create(hdata, hdata_len); + if (!handle) { + if (req->handle) + (*req->handle)((SilcSFTP)sftp, status, NULL, req->context); + break; + } if (req->handle) (*req->handle)((SilcSFTP)sftp, status, handle, req->context); @@ -212,7 +224,7 @@ static void silc_sftp_call_request(SilcSFTPClient sftp, language_tag = (char *)va_arg(vp, char *); if (req->status) - (*req->status)((SilcSFTP)sftp, status, (const char *)message, + (*req->status)((SilcSFTP)sftp, status, (const char *)message, (const char *)language_tag, req->context); } break; @@ -233,7 +245,7 @@ static void silc_sftp_call_request(SilcSFTPClient sftp, attr = (SilcSFTPAttributes)va_arg(vp, SilcSFTPAttributes); if (req->attr) - (*req->attr)((SilcSFTP)sftp, status, (const SilcSFTPAttributes)attr, + (*req->attr)((SilcSFTP)sftp, status, (const SilcSFTPAttributes)attr, req->context); } break; @@ -274,7 +286,7 @@ static void silc_sftp_call_request(SilcSFTPClient sftp, data_len = (SilcUInt32)va_arg(vp, SilcUInt32); if (req->extended) - (*req->extended)((SilcSFTP)sftp, status, (const unsigned char *)data, + (*req->extended)((SilcSFTP)sftp, status, (const unsigned char *)data, data_len, req->context); } break; @@ -290,31 +302,120 @@ static void silc_sftp_call_request(SilcSFTPClient sftp, va_end(vp); } -/* Starts SFTP client and returns context for it. The version callback - indicated by the `callback' will be called after the SFTP session has - been started and server has returned the version of the protocol. The - SFTP client context is returned in the callback too. This returns - allocated SFTP client context or NULL on error. */ +/* Handles stream IO */ + +static void silc_sftp_client_io(SilcStream stream, SilcStreamStatus status, + void *context) +{ + SilcSFTPClient sftp = context; + + switch (status) { + + case SILC_STREAM_CAN_WRITE: + if (!silc_buffer_headlen(&sftp->packet)) + return; + + SILC_LOG_DEBUG(("Writing pending data to stream")); + + /* Write pending data to stream */ + silc_buffer_push(sftp->packet, silc_buffer_headlen(sftp->packet)); + while (silc_buffer_len(sftp->packet) > 0) { + ret = silc_stream_write(stream, sftp->packet->data, + silc_buffer_len(sftp->packet)); + if (ret == 0) { + /* EOS */ + /* XXX */ + silc_buffer_reset(sftp->packet); + return; + } + + if (i == -2) { + /* Error */ + /* XXX */ + silc_buffer_reset(sftp->packet); + return FALSE; + } + + if (ret == -1) { + /* Cannot write now, write later. */ + silc_buffer_pull(sftp->packet, silc_buffer_len(sftp->packet)); + return; + } + + /* Wrote data */ + silc_buffer_pull(sftp->packet, ret); + } + break; + + case SILC_STREAM_CAN_READ: + SILC_LOG_DEBUG(("Reading data from stream")); + + /* Make sure we have fair amount of free space in inbuf */ + if (silc_buffer_taillen(&ps->inbuf) < SILC_PACKET_DEFAULT_SIZE) + if (!silc_buffer_realloc(&ps->inbuf, silc_buffer_truelen(&ps->inbuf) + + SILC_PACKET_DEFAULT_SIZE * 2)) + return; + + /* Read data from stream */ + ret = silc_stream_read(ps->stream, &ps->inbuf.tail, + silc_buffer_taillen(&ps->inbuf)); + + if (ret == 0) { + /* EOS */ + SILC_PACKET_CALLBACK_EOS(ps); + silc_buffer_reset(&ps->inbuf); + return; + } + + if (ret == -2) { + /* Error */ + SILC_PACKET_CALLBACK_ERROR(ps, SILC_PACKET_ERR_READ); + silc_buffer_reset(&ps->inbuf); + return; + } + + if (ret == -1) { + /* Cannot read now, do it later. */ + silc_buffer_pull(&ps->inbuf, silc_buffer_len(&ps->inbuf)); + return; + } + + /* Read some data */ + silc_buffer_pull_tail(&ps->inbuf, ret); + + /* Now process the data */ + silc_sftp_client_receive_process(sftp); + break; + + default: + break; + } +} + +/* Starts SFTP client and returns context for it. */ -SilcSFTP silc_sftp_client_start(SilcSFTPSendPacketCallback send_packet, - void *send_context, +SilcSFTP silc_sftp_client_start(SilcStream stream, SilcSFTPVersionCallback callback, void *context) { SilcSFTPClient sftp; - if (!send_packet) + if (!stream) return NULL; sftp = silc_calloc(1, sizeof(*sftp)); - sftp->send_packet = send_packet; - sftp->send_context = send_context; + if (!sftp) + return NULL; + sftp->stream = stream; sftp->version = callback; sftp->version_context = context; silc_list_init(sftp->requests, struct SilcSFTPRequestStruct, next); + /* We handle the stream now */ + silc_stream_set_notifier(stream, silc_sftp_client_io, sftp); + /* Send the SFTP session initialization to the server */ - silc_sftp_send_packet(sftp, SILC_SFTP_INIT, 4, + silc_sftp_send_packet(sftp, SILC_SFTP_INIT, 4, SILC_STR_UI_INT(SILC_SFTP_PROTOCOL_VERSION), SILC_STR_END); @@ -335,12 +436,8 @@ void silc_sftp_client_shutdown(SilcSFTP context) } /* Function that is called to process the incmoing SFTP packet. */ -/* XXX Some day this will go away and we have automatic receive callbacks - for SilcSocketConnection API or SilcPacketContext API. */ -void silc_sftp_client_receive_process(SilcSFTP context, - SilcSocketConnection sock, - SilcPacketContext *packet) +void silc_sftp_client_receive_process(SilcSFTP context, SilcBuffer buffer) { SilcSFTPClient sftp = (SilcSFTPClient)context; SilcSFTPRequest req; @@ -354,7 +451,7 @@ void silc_sftp_client_receive_process(SilcSFTP context, SILC_LOG_DEBUG(("Start")); /* Parse the packet */ - type = silc_sftp_packet_decode(packet->buffer, (unsigned char **)&payload, + type = silc_sftp_packet_decode(packet->buffer, (unsigned char **)&payload, &payload_len); if (!type) return; @@ -372,13 +469,13 @@ void silc_sftp_client_receive_process(SilcSFTP context, SILC_STR_UI_INT(&version), SILC_STR_END); if (ret < 0) { - (*sftp->version)((SilcSFTP)sftp, SILC_SFTP_STATUS_FAILURE, 0, + (*sftp->version)((SilcSFTP)sftp, SILC_SFTP_STATUS_FAILURE, 0, sftp->version_context); break; } /* Call the callback */ - (*sftp->version)((SilcSFTP)sftp, SILC_SFTP_STATUS_OK, version, + (*sftp->version)((SilcSFTP)sftp, SILC_SFTP_STATUS_OK, version, sftp->version_context); } break; @@ -390,7 +487,7 @@ void silc_sftp_client_receive_process(SilcSFTP context, SILC_LOG_DEBUG(("Status packet")); - ret = silc_buffer_unformat(&buf, + ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI_INT(&status), SILC_STR_END); @@ -432,9 +529,9 @@ void silc_sftp_client_receive_process(SilcSFTP context, SILC_LOG_DEBUG(("Handle packet")); - ret = silc_buffer_unformat(&buf, + ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), - SILC_STR_UI32_NSTRING(&handle, + SILC_STR_UI32_NSTRING(&handle, &handle_len), SILC_STR_END); if (ret < 0) @@ -446,7 +543,7 @@ void silc_sftp_client_receive_process(SilcSFTP context, break; /* Call the callback */ - silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK, + silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK, handle, handle_len); } break; @@ -458,7 +555,7 @@ void silc_sftp_client_receive_process(SilcSFTP context, SILC_LOG_DEBUG(("Data packet")); - ret = silc_buffer_unformat(&buf, + ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_NSTRING(&data, &data_len), SILC_STR_END); @@ -471,7 +568,7 @@ void silc_sftp_client_receive_process(SilcSFTP context, break; /* Call the callback */ - silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK, + silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK, data, data_len); } break; @@ -483,7 +580,7 @@ void silc_sftp_client_receive_process(SilcSFTP context, SILC_LOG_DEBUG(("Name packet")); - ret = silc_buffer_unformat(&buf, + ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI_INT(&count), SILC_STR_END); @@ -515,10 +612,12 @@ void silc_sftp_client_receive_process(SilcSFTP context, SILC_LOG_DEBUG(("Attributes packet")); - ret = silc_buffer_unformat(&buf, - SILC_STR_UI_INT(&id), - SILC_STR_UI_XNSTRING(&data, buf.len - 4), - SILC_STR_END); + ret = + silc_buffer_unformat(&buf, + SILC_STR_UI_INT(&id), + SILC_STR_UI_XNSTRING(&data, + silc_buffer_len(&buf) - 4), + SILC_STR_END); if (ret < 0) break; @@ -527,7 +626,7 @@ void silc_sftp_client_receive_process(SilcSFTP context, if (!req) break; - silc_buffer_set(&tmpbuf, data, buf.len - 4); + silc_buffer_set(&tmpbuf, data, silc_buffer_len(&buf) - 4); attr = silc_sftp_attr_decode(&tmpbuf); if (!attr) break; @@ -543,9 +642,9 @@ void silc_sftp_client_receive_process(SilcSFTP context, SILC_LOG_DEBUG(("Extended reply packet")); - ret = silc_buffer_unformat(&buf, + ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), - SILC_STR_UI_XNSTRING(&data, buf.len - 4), + SILC_STR_UI_XNSTRING(&data, silc_buffer_len(&buf) - 4), SILC_STR_END); if (ret < 0) break; @@ -556,8 +655,8 @@ void silc_sftp_client_receive_process(SilcSFTP context, break; /* Call the callback */ - silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK, - data, buf.len - 4); + silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK, + data, silc_buffer_len(&buf) - 4); } break; @@ -566,7 +665,7 @@ void silc_sftp_client_receive_process(SilcSFTP context, } } -void silc_sftp_open(SilcSFTP sftp, +void silc_sftp_open(SilcSFTP sftp, const char *filename, SilcSFTPFileOperation pflags, SilcSFTPAttributes attrs, @@ -581,6 +680,8 @@ void silc_sftp_open(SilcSFTP sftp, SILC_LOG_DEBUG(("Open request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_OPEN; req->handle = callback; @@ -588,15 +689,17 @@ void silc_sftp_open(SilcSFTP sftp, silc_list_add(client->requests, req); attrs_buf = silc_sftp_attr_encode(attrs); - len = 4 + 4 + strlen(filename) + 4 + attrs_buf->len; + if (!attrs_buf) + return; + len = 4 + 4 + strlen(filename) + 4 + silc_buffer_len(attrs_buf); - silc_sftp_send_packet(client, req->type, len, + silc_sftp_send_packet(client, req->type, len, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(strlen(filename)), SILC_STR_UI32_STRING(filename), SILC_STR_UI_INT(pflags), - SILC_STR_UI_XNSTRING(attrs_buf->data, - attrs_buf->len), + SILC_STR_UI_XNSTRING(attrs_buf->data, + silc_buffer_len(attrs_buf)), SILC_STR_END); silc_buffer_free(attrs_buf); @@ -616,6 +719,8 @@ void silc_sftp_close(SilcSFTP sftp, SILC_LOG_DEBUG(("Close request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_CLOSE; req->status = callback; @@ -625,16 +730,17 @@ void silc_sftp_close(SilcSFTP sftp, silc_sftp_handle_get(handle, &hdata, &hdata_len); len = 4 + 4 + hdata_len; - silc_sftp_send_packet(client, req->type, len, + silc_sftp_send_packet(client, req->type, len, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(hdata_len), SILC_STR_UI_XNSTRING(hdata, hdata_len), SILC_STR_END); + silc_sftp_handle_delete(handle); } void silc_sftp_read(SilcSFTP sftp, SilcSFTPHandle handle, - SilcUInt64 offset, + SilcUInt64 offset, SilcUInt32 len, SilcSFTPDataCallback callback, void *context) @@ -648,6 +754,8 @@ void silc_sftp_read(SilcSFTP sftp, SILC_LOG_DEBUG(("Read request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_READ; req->data = callback; @@ -657,7 +765,7 @@ void silc_sftp_read(SilcSFTP sftp, silc_sftp_handle_get(handle, &hdata, &hdata_len); len2 = 4 + 4 + hdata_len + 8 + 4; - silc_sftp_send_packet(client, req->type, len2, + silc_sftp_send_packet(client, req->type, len2, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(hdata_len), SILC_STR_UI_XNSTRING(hdata, hdata_len), @@ -683,6 +791,8 @@ void silc_sftp_write(SilcSFTP sftp, SILC_LOG_DEBUG(("Write request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_WRITE; req->status = callback; @@ -692,7 +802,7 @@ void silc_sftp_write(SilcSFTP sftp, silc_sftp_handle_get(handle, &hdata, &hdata_len); len = 4 + 4 + hdata_len + 8 + 4 + data_len; - silc_sftp_send_packet(client, req->type, len, + silc_sftp_send_packet(client, req->type, len, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(hdata_len), SILC_STR_UI_XNSTRING(hdata, hdata_len), @@ -714,6 +824,8 @@ void silc_sftp_remove(SilcSFTP sftp, SILC_LOG_DEBUG(("Remove request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_REMOVE; req->status = callback; @@ -722,7 +834,7 @@ void silc_sftp_remove(SilcSFTP sftp, len = 4 + 4 + strlen(filename); - silc_sftp_send_packet(client, req->type, len, + silc_sftp_send_packet(client, req->type, len, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(strlen(filename)), SILC_STR_UI32_STRING(filename), @@ -742,6 +854,8 @@ void silc_sftp_rename(SilcSFTP sftp, SILC_LOG_DEBUG(("Rename request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_RENAME; req->status = callback; @@ -750,7 +864,7 @@ void silc_sftp_rename(SilcSFTP sftp, len = 4 + 4 + strlen(oldname) + 4 + strlen(newname); - silc_sftp_send_packet(client, req->type, len, + silc_sftp_send_packet(client, req->type, len, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(strlen(oldname)), SILC_STR_UI32_STRING(oldname), @@ -773,6 +887,8 @@ void silc_sftp_mkdir(SilcSFTP sftp, SILC_LOG_DEBUG(("Mkdir request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_MKDIR; req->status = callback; @@ -780,14 +896,16 @@ void silc_sftp_mkdir(SilcSFTP sftp, silc_list_add(client->requests, req); attrs_buf = silc_sftp_attr_encode(attrs); - len = 4 + 4 + strlen(path) + attrs_buf->len; + if (!attrs_buf) + return; + len = 4 + 4 + strlen(path) + silc_buffer_len(attrs_buf); - silc_sftp_send_packet(client, req->type, len, + silc_sftp_send_packet(client, req->type, len, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(strlen(path)), SILC_STR_UI32_STRING(path), SILC_STR_UI_XNSTRING(attrs_buf->data, - attrs_buf->len), + silc_buffer_len(attrs_buf)), SILC_STR_END); silc_buffer_free(attrs_buf); @@ -805,6 +923,8 @@ void silc_sftp_rmdir(SilcSFTP sftp, SILC_LOG_DEBUG(("Rmdir request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_RMDIR; req->status = callback; @@ -813,7 +933,7 @@ void silc_sftp_rmdir(SilcSFTP sftp, len = 4 + 4 + strlen(path); - silc_sftp_send_packet(client, req->type, len, + silc_sftp_send_packet(client, req->type, len, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(strlen(path)), SILC_STR_UI32_STRING(path), @@ -832,6 +952,8 @@ void silc_sftp_opendir(SilcSFTP sftp, SILC_LOG_DEBUG(("Opendir request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_OPENDIR; req->handle = callback; @@ -840,7 +962,7 @@ void silc_sftp_opendir(SilcSFTP sftp, len = 4 + 4 + strlen(path); - silc_sftp_send_packet(client, req->type, len, + silc_sftp_send_packet(client, req->type, len, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(strlen(path)), SILC_STR_UI32_STRING(path), @@ -861,6 +983,8 @@ void silc_sftp_readdir(SilcSFTP sftp, SILC_LOG_DEBUG(("Readdir request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_READDIR; req->name = callback; @@ -870,7 +994,7 @@ void silc_sftp_readdir(SilcSFTP sftp, silc_sftp_handle_get(handle, &hdata, &hdata_len); len = 4 + 4 + hdata_len; - silc_sftp_send_packet(client, req->type, len, + silc_sftp_send_packet(client, req->type, len, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(hdata_len), SILC_STR_UI_XNSTRING(hdata, hdata_len), @@ -889,6 +1013,8 @@ void silc_sftp_stat(SilcSFTP sftp, SILC_LOG_DEBUG(("Stat request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_STAT; req->attr = callback; @@ -897,7 +1023,7 @@ void silc_sftp_stat(SilcSFTP sftp, len = 4 + 4 + strlen(path); - silc_sftp_send_packet(client, req->type, len, + silc_sftp_send_packet(client, req->type, len, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(strlen(path)), SILC_STR_UI32_STRING(path), @@ -916,6 +1042,8 @@ void silc_sftp_lstat(SilcSFTP sftp, SILC_LOG_DEBUG(("Lstat request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_LSTAT; req->attr = callback; @@ -924,7 +1052,7 @@ void silc_sftp_lstat(SilcSFTP sftp, len = 4 + 4 + strlen(path); - silc_sftp_send_packet(client, req->type, len, + silc_sftp_send_packet(client, req->type, len, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(strlen(path)), SILC_STR_UI32_STRING(path), @@ -945,6 +1073,8 @@ void silc_sftp_fstat(SilcSFTP sftp, SILC_LOG_DEBUG(("Fstat request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_FSTAT; req->attr = callback; @@ -954,7 +1084,7 @@ void silc_sftp_fstat(SilcSFTP sftp, silc_sftp_handle_get(handle, &hdata, &hdata_len); len = 4 + 4 + hdata_len; - silc_sftp_send_packet(client, req->type, len, + silc_sftp_send_packet(client, req->type, len, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(hdata_len), SILC_STR_UI_XNSTRING(hdata, hdata_len), @@ -975,6 +1105,8 @@ void silc_sftp_setstat(SilcSFTP sftp, SILC_LOG_DEBUG(("Setstat request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_SETSTAT; req->status = callback; @@ -982,14 +1114,16 @@ void silc_sftp_setstat(SilcSFTP sftp, silc_list_add(client->requests, req); attrs_buf = silc_sftp_attr_encode(attrs); - len = 4 + 4 + strlen(path) + attrs_buf->len; + if (!attrs_buf) + return; + len = 4 + 4 + strlen(path) + silc_buffer_len(attrs_buf); - silc_sftp_send_packet(client, req->type, len, + silc_sftp_send_packet(client, req->type, len, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(strlen(path)), SILC_STR_UI32_STRING(path), SILC_STR_UI_XNSTRING(attrs_buf->data, - attrs_buf->len), + silc_buffer_len(attrs_buf)), SILC_STR_END); silc_buffer_free(attrs_buf); @@ -1011,6 +1145,8 @@ void silc_sftp_fsetstat(SilcSFTP sftp, SILC_LOG_DEBUG(("Fsetstat request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_FSETSTAT; req->status = callback; @@ -1019,14 +1155,16 @@ void silc_sftp_fsetstat(SilcSFTP sftp, silc_sftp_handle_get(handle, &hdata, &hdata_len); attrs_buf = silc_sftp_attr_encode(attrs); - len = 4 + 4 + hdata_len + attrs_buf->len; + if (!attrs_buf) + return; + len = 4 + 4 + hdata_len + silc_buffer_len(attrs_buf); - silc_sftp_send_packet(client, req->type, len, + silc_sftp_send_packet(client, req->type, len, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(hdata_len), SILC_STR_UI_XNSTRING(hdata, hdata_len), SILC_STR_UI_XNSTRING(attrs_buf->data, - attrs_buf->len), + silc_buffer_len(attrs_buf)), SILC_STR_END); silc_buffer_free(attrs_buf); @@ -1044,6 +1182,8 @@ void silc_sftp_readlink(SilcSFTP sftp, SILC_LOG_DEBUG(("Readlink request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_READLINK; req->name = callback; @@ -1052,7 +1192,7 @@ void silc_sftp_readlink(SilcSFTP sftp, len = 4 + 4 + strlen(path); - silc_sftp_send_packet(client, req->type, len, + silc_sftp_send_packet(client, req->type, len, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(strlen(path)), SILC_STR_UI32_STRING(path), @@ -1072,6 +1212,8 @@ void silc_sftp_symlink(SilcSFTP sftp, SILC_LOG_DEBUG(("Symlink request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_SYMLINK; req->status = callback; @@ -1080,7 +1222,7 @@ void silc_sftp_symlink(SilcSFTP sftp, len = 4 + 4 + strlen(linkpath) + 4 + strlen(targetpath); - silc_sftp_send_packet(client, req->type, len, + silc_sftp_send_packet(client, req->type, len, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(strlen(linkpath)), SILC_STR_UI32_STRING(linkpath), @@ -1101,6 +1243,8 @@ void silc_sftp_realpath(SilcSFTP sftp, SILC_LOG_DEBUG(("Realpath request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_REALPATH; req->name = callback; @@ -1109,7 +1253,7 @@ void silc_sftp_realpath(SilcSFTP sftp, len = 4 + 4 + strlen(path); - silc_sftp_send_packet(client, req->type, len, + silc_sftp_send_packet(client, req->type, len, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(strlen(path)), SILC_STR_UI32_STRING(path), @@ -1130,6 +1274,8 @@ void silc_sftp_extended(SilcSFTP sftp, SILC_LOG_DEBUG(("Extended request")); req = silc_calloc(1, sizeof(*req)); + if (!req) + return; req->id = client->id++; req->type = SILC_SFTP_WRITE; req->extended = callback; @@ -1138,7 +1284,7 @@ void silc_sftp_extended(SilcSFTP sftp, len = 4 + 4 + strlen(request) + data_len; - silc_sftp_send_packet(client, req->type, len, + silc_sftp_send_packet(client, req->type, len, SILC_STR_UI_INT(req->id), SILC_STR_UI_INT(strlen(request)), SILC_STR_UI32_STRING(request),