Created SILC Crypto Toolkit git repository.
[crypto.git] / lib / silcsftp / sftp_client.c
diff --git a/lib/silcsftp/sftp_client.c b/lib/silcsftp/sftp_client.c
deleted file mode 100644 (file)
index 10eb160..0000000
+++ /dev/null
@@ -1,1301 +0,0 @@
-/*
-
-  sftp_client.c
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2001 - 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; 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
-  GNU General Public License for more details.
-
-*/
-/* $Id$ */
-
-#include "silc.h"
-#include "silcsftp.h"
-#include "sftp_util.h"
-
-/* Request context. Every request will allocate this context and set
-   the correct callback function according the `type' field. */
-typedef struct SilcSFTPRequestStruct {
-  struct SilcSFTPRequestStruct *next;
-  SilcSFTPStatusCallback status;
-  SilcSFTPHandleCallback handle;
-  SilcSFTPDataCallback data;
-  SilcSFTPNameCallback name;
-  SilcSFTPAttrCallback attr;
-  SilcSFTPExtendedCallback extended;
-  void *context;
-  SilcUInt32 id;
-  SilcSFTPPacket type;
-} *SilcSFTPRequest;
-
-/* SFTP client context */
-typedef struct {
-  SilcStream stream;
-  SilcSchedule schedule;
-  SilcSFTPVersionCallback version;
-  SilcSFTPErrorCallback error;
-  void *context;
-  SilcList requests;
-  SilcBuffer packet;
-  SilcUInt32 id;
-} *SilcSFTPClient;
-
-/* File handle */
-struct SilcSFTPHandleStruct {
-  unsigned char *data;
-  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. */
-
-static SilcSFTPHandle silc_sftp_handle_create(unsigned char *data,
-                                             SilcUInt32 data_len)
-{
-  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;
-
-  return handle;
-}
-
-/* Deletes the handle indicated by the `handle'. */
-
-static void silc_sftp_handle_delete(SilcSFTPHandle handle)
-{
-  silc_free(handle->data);
-  silc_free(handle);
-}
-
-/* Returns the handle data of the `handle' to the `data' pointer. */
-
-static void silc_sftp_handle_get(SilcSFTPHandle handle,
-                                const unsigned char **data,
-                                SilcUInt32 *data_len)
-{
-  *data = (const unsigned char *)handle->data;
-  *data_len = handle->data_len;
-}
-
-/* Generic routine to send SFTP packet to the SFTP server. */
-
-static void silc_sftp_send_packet(SilcSFTPClient sftp,
-                                 SilcSFTPPacket type,
-                                 SilcUInt32 len, ...)
-{
-  SilcBuffer tmp;
-  va_list vp;
-  int ret;
-
-  va_start(vp, len);
-  tmp = silc_sftp_packet_encode_vp(type, sftp->packet, len, vp);
-  va_end(vp);
-  if (!tmp)
-    return;
-  sftp->packet = tmp;
-
-  SILC_LOG_HEXDUMP(("SFTP packet to server"), sftp->packet->data,
-                  silc_buffer_len(sftp->packet));
-
-  /* Send the packet */
-  while (silc_buffer_len(sftp->packet) > 0) {
-    ret = silc_stream_write(sftp->stream, silc_buffer_data(sftp->packet),
-                           silc_buffer_len(sftp->packet));
-    if (ret == -2) {
-      SILC_LOG_ERROR(("Error sending SFTP packet type %d", type));
-      sftp->error((SilcSFTP)sftp, SILC_SFTP_STATUS_NO_CONNECTION,
-                 sftp->context);
-      silc_buffer_reset(sftp->packet);
-      return;
-    }
-    if (ret == 0) {
-      sftp->error((SilcSFTP)sftp, SILC_SFTP_STATUS_EOF, sftp->context);
-      silc_buffer_reset(sftp->packet);
-      return;
-    }
-    if (ret == -1)
-      return;
-
-    silc_buffer_pull(sftp->packet, ret);
-  }
-
-  /* Clear packet */
-  silc_buffer_reset(sftp->packet);
-}
-
-/* Finds request by request ID. */
-
-static SilcSFTPRequest silc_sftp_find_request(SilcSFTPClient sftp,
-                                             SilcUInt32 id)
-{
-  SilcSFTPRequest req;
-
-  SILC_LOG_DEBUG(("Finding request ID: %d", id));
-
-  silc_list_start(sftp->requests);
-  while ((req = silc_list_get(sftp->requests)) != SILC_LIST_END) {
-    if (req->id == id)
-      return req;
-  }
-
-  SILC_LOG_DEBUG(("Unknown request ID %d", id));
-
-  return NULL;
-}
-
-/* Function used to call the request callback indicated by the `req'. The
-   `status' will be sent to the callback function as the status of the
-   operation. The variable argument list includes the status and req->type
-   specific data. */
-
-static void silc_sftp_call_request(SilcSFTPClient sftp,
-                                  SilcSFTPRequest req,
-                                  SilcSFTPPacket type,
-                                  SilcSFTPStatus status, ...)
-{
-  va_list vp;
-
-  SILC_LOG_DEBUG(("Start"));
-
-  va_start(vp, status);
-
-  switch (req->type) {
-  case SILC_SFTP_READ:
-    {
-      /* Data returned */
-      unsigned char *data;
-      SilcUInt32 data_len;
-
-      if (status != SILC_SFTP_STATUS_OK) {
-       if (req->data)
-         (*req->data)((SilcSFTP)sftp, status, NULL, 0, req->context);
-       break;
-      }
-
-      data = (unsigned char *)va_arg(vp, unsigned char *);
-      data_len = (SilcUInt32)va_arg(vp, SilcUInt32);
-
-      if (req->data)
-       (*req->data)((SilcSFTP)sftp, status, (const unsigned char *)data,
-                    data_len, req->context);
-    }
-    break;
-
-  case SILC_SFTP_OPEN:
-  case SILC_SFTP_OPENDIR:
-    {
-      /* Handle returned */
-      SilcSFTPHandle handle;
-      unsigned char *hdata;
-      SilcUInt32 hdata_len;
-
-      if (status != SILC_SFTP_STATUS_OK) {
-       if (req->handle)
-         (*req->handle)((SilcSFTP)sftp, status, NULL, req->context);
-       break;
-      }
-
-      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);
-    }
-    break;
-
-  case SILC_SFTP_CLOSE:
-  case SILC_SFTP_WRITE:
-  case SILC_SFTP_REMOVE:
-  case SILC_SFTP_RENAME:
-  case SILC_SFTP_MKDIR:
-  case SILC_SFTP_RMDIR:
-  case SILC_SFTP_SETSTAT:
-  case SILC_SFTP_FSETSTAT:
-  case SILC_SFTP_SYMLINK:
-    {
-      /* Status returned */
-      char *message, *language_tag;
-
-      message = (char *)va_arg(vp, char *);
-      language_tag = (char *)va_arg(vp, char *);
-
-      if (req->status)
-       (*req->status)((SilcSFTP)sftp, status, (const char *)message,
-                      (const char *)language_tag, req->context);
-    }
-    break;
-
-  case SILC_SFTP_STAT:
-  case SILC_SFTP_LSTAT:
-  case SILC_SFTP_FSTAT:
-    {
-      /* Attributes returned */
-      SilcSFTPAttributes attr;
-
-      if (status != SILC_SFTP_STATUS_OK) {
-       if (req->attr)
-         (*req->attr)((SilcSFTP)sftp, status, NULL, req->context);
-       break;
-      }
-
-      attr = (SilcSFTPAttributes)va_arg(vp, SilcSFTPAttributes);
-
-      if (req->attr)
-       (*req->attr)((SilcSFTP)sftp, status, (const SilcSFTPAttributes)attr,
-                    req->context);
-    }
-    break;
-
-  case SILC_SFTP_READDIR:
-  case SILC_SFTP_REALPATH:
-  case SILC_SFTP_READLINK:
-    {
-      /* Name(s) returned */
-      SilcSFTPName name;
-
-      if (status != SILC_SFTP_STATUS_OK) {
-       if (req->name)
-         (*req->name)((SilcSFTP)sftp, status, NULL, req->context);
-       break;
-      }
-
-      name = (SilcSFTPName)va_arg(vp, SilcSFTPName);
-
-      if (req->name)
-       (*req->name)((SilcSFTP)sftp, status, name, req->context);
-    }
-    break;
-
-  case SILC_SFTP_EXTENDED:
-    {
-      /* Extended reply returned */
-      unsigned char *data;
-      SilcUInt32 data_len;
-
-      if (status != SILC_SFTP_STATUS_OK) {
-       if (req->extended)
-         (*req->extended)((SilcSFTP)sftp, status, NULL, 0, req->context);
-       break;
-      }
-
-      data = (unsigned char *)va_arg(vp, unsigned char *);
-      data_len = (SilcUInt32)va_arg(vp, SilcUInt32);
-
-      if (req->extended)
-       (*req->extended)((SilcSFTP)sftp, status, (const unsigned char *)data,
-                        data_len, req->context);
-    }
-    break;
-
-  default:
-    SILC_LOG_DEBUG(("Unknown request type %d", req->type));
-    break;
-  }
-
-  /* Remove this request */
-  silc_list_del(sftp->requests, req);
-  silc_free(req);
-
-  va_end(vp);
-}
-
-/* Handles stream I/O */
-
-static void silc_sftp_client_io(SilcStream stream, SilcStreamStatus status,
-                               void *context)
-{
-  SilcSFTPClient sftp = context;
-  unsigned char inbuf[65536];
-  SilcBufferStruct packet;
-  int ret;
-
-  switch (status) {
-  case SILC_STREAM_CAN_READ:
-    SILC_LOG_DEBUG(("Reading data from stream"));
-
-    /* Read data from stream */
-    ret = silc_stream_read(stream, inbuf, sizeof(inbuf));
-    if (ret <= 0) {
-      if (ret == 0)
-       sftp->error(context, SILC_SFTP_STATUS_EOF, sftp->context);
-      if (ret == -2)
-       sftp->error(context, SILC_SFTP_STATUS_NO_CONNECTION, sftp->context);
-      return;
-    }
-
-    SILC_LOG_DEBUG(("Read %d bytes", ret));
-
-    /* Now process the SFTP packet */
-    silc_buffer_set(&packet, inbuf, ret);
-    silc_sftp_client_receive_process(context, &packet);
-    break;
-
-  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) {
-       sftp->error(context, SILC_SFTP_STATUS_EOF, sftp->context);
-       silc_buffer_reset(sftp->packet);
-       return;
-      }
-
-      if (ret == -2) {
-       sftp->error(context, SILC_SFTP_STATUS_NO_CONNECTION, sftp->context);
-       silc_buffer_reset(sftp->packet);
-       return;
-      }
-
-      if (ret == -1)
-       return;
-
-      /* Wrote data */
-      silc_buffer_pull(sftp->packet, ret);
-    }
-    break;
-
-  default:
-    break;
-  }
-}
-
-/* Starts SFTP client and returns context for it. */
-
-SilcSFTP silc_sftp_client_start(SilcStream stream,
-                               SilcSchedule schedule,
-                               SilcSFTPVersionCallback version_cb,
-                               SilcSFTPErrorCallback error_cb,
-                               void *context)
-{
-  SilcSFTPClient sftp;
-
-  SILC_LOG_DEBUG(("Starting SFTP client"));
-
-  if (!schedule)
-    schedule = silc_schedule_get_global();
-
-  if (!stream)
-    return NULL;
-
-  sftp = silc_calloc(1, sizeof(*sftp));
-  if (!sftp)
-    return NULL;
-  sftp->stream = stream;
-  sftp->version = version_cb;
-  sftp->error = error_cb;
-  sftp->context = context;
-  sftp->schedule = schedule;
-  silc_list_init(sftp->requests, struct SilcSFTPRequestStruct, next);
-
-  /* We handle the stream now */
-  silc_stream_set_notifier(stream, schedule, silc_sftp_client_io, sftp);
-
-  /* Send the SFTP session initialization to the server */
-  silc_sftp_send_packet(sftp, SILC_SFTP_INIT, 4,
-                       SILC_STR_UI_INT(SILC_SFTP_PROTOCOL_VERSION),
-                       SILC_STR_END);
-
-  return (SilcSFTP)sftp;
-}
-
-/* Shutdown's the SFTP client.  The caller is responsible of closing
-   the associated socket connection.  The SFTP context is freed and is
-   invalid after this function returns. */
-
-void silc_sftp_client_shutdown(SilcSFTP context)
-{
-  SilcSFTPClient sftp = (SilcSFTPClient)context;
-
-  silc_stream_set_notifier(sftp->stream, sftp->schedule, NULL, NULL);
-  if (sftp->packet)
-    silc_buffer_free(sftp->packet);
-  silc_free(sftp);
-}
-
-/* Function that is called to process the incmoing SFTP packet. */
-
-void silc_sftp_client_receive_process(SilcSFTP context, SilcBuffer buffer)
-{
-  SilcSFTPClient sftp = (SilcSFTPClient)context;
-  SilcSFTPRequest req;
-  SilcSFTPPacket type;
-  unsigned char *payload = NULL;
-  SilcUInt32 payload_len;
-  int ret;
-  SilcBufferStruct buf;
-  SilcUInt32 id;
-
-  SILC_LOG_DEBUG(("Process SFTP packet"));
-
-  /* Parse the packet */
-  type = silc_sftp_packet_decode(buffer, &payload, &payload_len);
-  if (type <= 0)
-    return;
-
-  silc_buffer_set(&buf, payload, payload_len);
-
-  switch (type) {
-  case SILC_SFTP_DATA:
-    {
-      unsigned char *data = NULL;
-      SilcUInt32 data_len = 0;
-
-      SILC_LOG_DEBUG(("Data packet"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_NSTRING(&data, &data_len),
-                                SILC_STR_END);
-      if (ret < 0)
-       break;
-
-      /* Get request */
-      req = silc_sftp_find_request(sftp, id);
-      if (!req)
-       break;
-
-      /* Call the callback */
-      silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK,
-                            data, data_len);
-    }
-    break;
-
-  case SILC_SFTP_VERSION:
-    {
-      SilcSFTPVersion version;
-
-      SILC_LOG_DEBUG(("Version packet"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&version),
-                                SILC_STR_END);
-      if (ret < 0) {
-       (*sftp->version)((SilcSFTP)sftp, SILC_SFTP_STATUS_FAILURE, 0,
-                        sftp->context);
-       break;
-      }
-
-      /* Call the callback */
-      (*sftp->version)((SilcSFTP)sftp, SILC_SFTP_STATUS_OK, version,
-                      sftp->context);
-    }
-    break;
-
-  case SILC_SFTP_STATUS:
-    {
-      SilcUInt32 status;
-      char *message = NULL, *language_tag = NULL;
-
-      SILC_LOG_DEBUG(("Status packet"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI_INT(&status),
-                                SILC_STR_END);
-      if (ret < 0)
-       break;
-
-      if (status != SILC_SFTP_STATUS_OK) {
-       silc_buffer_pull(&buf, 8);
-       ret = silc_buffer_unformat(&buf,
-                                  SILC_STR_UI32_STRING_ALLOC(&message),
-                                  SILC_STR_UI32_STRING_ALLOC(&language_tag),
-                                  SILC_STR_END);
-       if (ret < 0)
-         break;
-
-       silc_buffer_push(&buf, 8);
-      }
-
-      /* Get request */
-      req = silc_sftp_find_request(sftp, id);
-      if (!req) {
-       silc_free(message);
-       silc_free(language_tag);
-       break;
-      }
-
-      /* Call the callback */
-      silc_sftp_call_request(sftp, req, type, status, message, language_tag);
-
-      silc_free(message);
-      silc_free(language_tag);
-    }
-    break;
-
-  case SILC_SFTP_HANDLE:
-    {
-      unsigned char *handle = NULL;
-      SilcUInt32 handle_len;
-
-      SILC_LOG_DEBUG(("Handle packet"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_NSTRING(&handle,
-                                                      &handle_len),
-                                SILC_STR_END);
-      if (ret < 0)
-       break;
-
-      /* Get request */
-      req = silc_sftp_find_request(sftp, id);
-      if (!req)
-       break;
-
-      /* Call the callback */
-      silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK,
-                            handle, handle_len);
-    }
-    break;
-
-  case SILC_SFTP_NAME:
-    {
-      SilcUInt32 count;
-      SilcSFTPName name = NULL;
-
-      SILC_LOG_DEBUG(("Name packet"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI_INT(&count),
-                                SILC_STR_END);
-      if (ret < 0)
-       break;
-
-      /* Get request */
-      req = silc_sftp_find_request(sftp, id);
-      if (!req)
-       break;
-
-      silc_buffer_pull(&buf, 8);
-      name = silc_sftp_name_decode(count, &buf);
-      if (!name)
-       break;
-      silc_buffer_push(&buf, 8);
-
-      /* Call the callback */
-      silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK, name);
-      silc_sftp_name_free(name);
-    }
-    break;
-
-  case SILC_SFTP_ATTRS:
-    {
-      SilcSFTPAttributes attr = NULL;
-      unsigned char *data;
-      SilcBufferStruct tmpbuf;
-
-      SILC_LOG_DEBUG(("Attributes packet"));
-
-      ret =
-       silc_buffer_unformat(&buf,
-                            SILC_STR_UI_INT(&id),
-                            SILC_STR_DATA(&data, silc_buffer_len(&buf) - 4),
-                            SILC_STR_END);
-      if (ret < 0)
-       break;
-
-      /* Get request */
-      req = silc_sftp_find_request(sftp, id);
-      if (!req)
-       break;
-
-      silc_buffer_set(&tmpbuf, data, silc_buffer_len(&buf) - 4);
-      attr = silc_sftp_attr_decode(&tmpbuf);
-      if (!attr)
-       break;
-
-      /* Call the callback */
-      silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK, attr);
-    }
-    break;
-
-  case SILC_SFTP_EXTENDED_REPLY:
-    {
-      unsigned char *data = NULL;
-
-      SILC_LOG_DEBUG(("Extended reply packet"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_DATA(&data,
-                                              silc_buffer_len(&buf) - 4),
-                                SILC_STR_END);
-      if (ret < 0)
-       break;
-
-      /* Get request */
-      req = silc_sftp_find_request(sftp, id);
-      if (!req)
-       break;
-
-      /* Call the callback */
-      silc_sftp_call_request(sftp, req, type, SILC_SFTP_STATUS_OK,
-                            data, silc_buffer_len(&buf) - 4);
-    }
-    break;
-
-  default:
-    break;
-  }
-}
-
-void silc_sftp_open(SilcSFTP sftp,
-                   const char *filename,
-                   SilcSFTPFileOperation pflags,
-                   SilcSFTPAttributes attrs,
-                   SilcSFTPHandleCallback callback,
-                   void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcBuffer attrs_buf;
-  SilcUInt32 len = 0;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  attrs_buf = silc_sftp_attr_encode(attrs);
-  if (!attrs_buf)
-    return;
-  len = 4 + 4 + strlen(filename) + 4 + silc_buffer_len(attrs_buf);
-
-  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,
-                                            silc_buffer_len(attrs_buf)),
-                       SILC_STR_END);
-
-  silc_buffer_free(attrs_buf);
-}
-
-void silc_sftp_close(SilcSFTP sftp,
-                    SilcSFTPHandle handle,
-                    SilcSFTPStatusCallback callback,
-                    void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcUInt32 len = 0;
-  const unsigned char *hdata;
-  SilcUInt32 hdata_len;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  silc_sftp_handle_get(handle, &hdata, &hdata_len);
-  len = 4 + 4 + hdata_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,
-                   SilcUInt32 len,
-                   SilcSFTPDataCallback callback,
-                   void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcUInt32 len2 = 0;
-  const unsigned char *hdata;
-  SilcUInt32 hdata_len;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  silc_sftp_handle_get(handle, &hdata, &hdata_len);
-  len2 = 4 + 4 + hdata_len + 8 + 4;
-
-  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),
-                       SILC_STR_UI_INT64(offset),
-                       SILC_STR_UI_INT(len),
-                       SILC_STR_END);
-}
-
-void silc_sftp_write(SilcSFTP sftp,
-                    SilcSFTPHandle handle,
-                    SilcUInt64 offset,
-                    const unsigned char *data,
-                    SilcUInt32 data_len,
-                    SilcSFTPStatusCallback callback,
-                    void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcUInt32 len = 0;
-  const unsigned char *hdata;
-  SilcUInt32 hdata_len;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  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_STR_UI_INT(req->id),
-                       SILC_STR_UI_INT(hdata_len),
-                       SILC_STR_UI_XNSTRING(hdata, hdata_len),
-                       SILC_STR_UI_INT64(offset),
-                       SILC_STR_UI_INT(data_len),
-                       SILC_STR_UI_XNSTRING(data, data_len),
-                       SILC_STR_END);
-}
-
-void silc_sftp_remove(SilcSFTP sftp,
-                     const char *filename,
-                     SilcSFTPStatusCallback callback,
-                     void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcUInt32 len = 0;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  len = 4 + 4 + strlen(filename);
-
-  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_END);
-}
-
-void silc_sftp_rename(SilcSFTP sftp,
-                     const char *oldname,
-                     const char *newname,
-                     SilcSFTPStatusCallback callback,
-                     void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcUInt32 len = 0;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  len = 4 + 4 + strlen(oldname) + 4 + strlen(newname);
-
-  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),
-                       SILC_STR_UI_INT(strlen(newname)),
-                       SILC_STR_UI32_STRING(newname),
-                       SILC_STR_END);
-}
-
-void silc_sftp_mkdir(SilcSFTP sftp,
-                    const char *path,
-                    SilcSFTPAttributes attrs,
-                    SilcSFTPStatusCallback callback,
-                    void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcUInt32 len = 0;
-  SilcBuffer attrs_buf;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  attrs_buf = silc_sftp_attr_encode(attrs);
-  if (!attrs_buf)
-    return;
-  len = 4 + 4 + strlen(path) + silc_buffer_len(attrs_buf);
-
-  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,
-                                            silc_buffer_len(attrs_buf)),
-                       SILC_STR_END);
-
-  silc_buffer_free(attrs_buf);
-}
-
-void silc_sftp_rmdir(SilcSFTP sftp,
-                    const char *path,
-                    SilcSFTPStatusCallback callback,
-                    void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcUInt32 len = 0;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  len = 4 + 4 + strlen(path);
-
-  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_END);
-}
-
-void silc_sftp_opendir(SilcSFTP sftp,
-                      const char *path,
-                      SilcSFTPHandleCallback callback,
-                      void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcUInt32 len = 0;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  len = 4 + 4 + strlen(path);
-
-  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_END);
-}
-
-void silc_sftp_readdir(SilcSFTP sftp,
-                      SilcSFTPHandle handle,
-                      SilcSFTPNameCallback callback,
-                      void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcUInt32 len = 0;
-  const unsigned char *hdata;
-  SilcUInt32 hdata_len;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  silc_sftp_handle_get(handle, &hdata, &hdata_len);
-  len = 4 + 4 + hdata_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);
-}
-
-void silc_sftp_stat(SilcSFTP sftp,
-                   const char *path,
-                   SilcSFTPAttrCallback callback,
-                   void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcUInt32 len = 0;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  len = 4 + 4 + strlen(path);
-
-  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_END);
-}
-
-void silc_sftp_lstat(SilcSFTP sftp,
-                    const char *path,
-                    SilcSFTPAttrCallback callback,
-                    void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcUInt32 len = 0;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  len = 4 + 4 + strlen(path);
-
-  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_END);
-}
-
-void silc_sftp_fstat(SilcSFTP sftp,
-                    SilcSFTPHandle handle,
-                    SilcSFTPAttrCallback callback,
-                    void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcUInt32 len = 0;
-  const unsigned char *hdata;
-  SilcUInt32 hdata_len;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  silc_sftp_handle_get(handle, &hdata, &hdata_len);
-  len = 4 + 4 + hdata_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);
-}
-
-void silc_sftp_setstat(SilcSFTP sftp,
-                      const char *path,
-                      SilcSFTPAttributes attrs,
-                      SilcSFTPStatusCallback callback,
-                      void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcUInt32 len = 0;
-  SilcBuffer attrs_buf;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  attrs_buf = silc_sftp_attr_encode(attrs);
-  if (!attrs_buf)
-    return;
-  len = 4 + 4 + strlen(path) + silc_buffer_len(attrs_buf);
-
-  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,
-                                            silc_buffer_len(attrs_buf)),
-                       SILC_STR_END);
-
-  silc_buffer_free(attrs_buf);
-}
-
-void silc_sftp_fsetstat(SilcSFTP sftp,
-                       SilcSFTPHandle handle,
-                       SilcSFTPAttributes attrs,
-                       SilcSFTPStatusCallback callback,
-                       void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcUInt32 len = 0;
-  SilcBuffer attrs_buf;
-  const unsigned char *hdata;
-  SilcUInt32 hdata_len;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  silc_sftp_handle_get(handle, &hdata, &hdata_len);
-  attrs_buf = silc_sftp_attr_encode(attrs);
-  if (!attrs_buf)
-    return;
-  len = 4 + 4 + hdata_len + silc_buffer_len(attrs_buf);
-
-  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,
-                                            silc_buffer_len(attrs_buf)),
-                       SILC_STR_END);
-
-  silc_buffer_free(attrs_buf);
-}
-
-void silc_sftp_readlink(SilcSFTP sftp,
-                       const char *path,
-                       SilcSFTPNameCallback callback,
-                       void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcUInt32 len = 0;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  len = 4 + 4 + strlen(path);
-
-  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_END);
-}
-
-void silc_sftp_symlink(SilcSFTP sftp,
-                      const char *linkpath,
-                      const char *targetpath,
-                      SilcSFTPStatusCallback callback,
-                      void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcUInt32 len = 0;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  len = 4 + 4 + strlen(linkpath) + 4 + strlen(targetpath);
-
-  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),
-                       SILC_STR_UI_INT(strlen(targetpath)),
-                       SILC_STR_UI32_STRING(targetpath),
-                       SILC_STR_END);
-}
-
-void silc_sftp_realpath(SilcSFTP sftp,
-                       const char *path,
-                       SilcSFTPNameCallback callback,
-                       void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcUInt32 len = 0;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  len = 4 + 4 + strlen(path);
-
-  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_END);
-}
-
-void silc_sftp_extended(SilcSFTP sftp,
-                       const char *request,
-                       const unsigned char *data,
-                       SilcUInt32 data_len,
-                       SilcSFTPExtendedCallback callback,
-                       void *context)
-{
-  SilcSFTPClient client = (SilcSFTPClient)sftp;
-  SilcSFTPRequest req;
-  SilcUInt32 len = 0;
-
-  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;
-  req->context = context;
-  silc_list_add(client->requests, req);
-
-  len = 4 + 4 + strlen(request) + data_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),
-                       SILC_STR_UI_XNSTRING(data, data_len),
-                       SILC_STR_END);
-}