Created SILC Crypto Toolkit git repository.
[crypto.git] / lib / silcsftp / sftp_server.c
diff --git a/lib/silcsftp/sftp_server.c b/lib/silcsftp/sftp_server.c
deleted file mode 100644 (file)
index b22e21f..0000000
+++ /dev/null
@@ -1,1148 +0,0 @@
-/*
-
-  sftp_server.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 "silcsftp_fs.h"
-#include "sftp_util.h"
-
-/* SFTP Server context */
-typedef struct {
-  SilcStream stream;
-  SilcSchedule schedule;
-  SilcSFTPMonitors monitors;
-  SilcSFTPMonitor monitor;
-  void *monitor_context;
-  SilcSFTPFilesystem fs;
-  SilcBuffer packet;
-  SilcSFTPErrorCallback error;
-  void *context;
-} *SilcSFTPServer;
-
-static void silc_sftp_server_receive_process(SilcSFTP sftp, SilcBuffer buffer);
-
-/* General routine to send SFTP packet to the SFTP client. */
-
-static void silc_sftp_send_packet(SilcSFTPServer 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 client"), silc_buffer_data(sftp->packet),
-                  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);
-}
-
-/* Handles stream I/O */
-
-static void silc_sftp_server_io(SilcStream stream, SilcStreamStatus status,
-                               void *context)
-{
-  SilcSFTPServer sftp = context;
-  unsigned char inbuf[33792];
-  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;
-    }
-
-    /* Now process the SFTP packet */
-    silc_buffer_set(&packet, inbuf, ret);
-    silc_sftp_server_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;
-  }
-}
-
-/* Sends error to the client */
-
-static void silc_sftp_send_error(SilcSFTPServer sftp,
-                                SilcSFTPStatus status,
-                                SilcUInt32 id)
-{
-  SILC_LOG_DEBUG(("Send error %d", status));
-
-  silc_sftp_send_packet(sftp, SILC_SFTP_STATUS, 16,
-                       SILC_STR_UI_INT(id),
-                       SILC_STR_UI_INT(status),
-                       SILC_STR_UI_INT(0),      /* Error */
-                       SILC_STR_UI_INT(0),      /* Language tag */
-                       SILC_STR_END);
-}
-
-/* Status callback */
-
-static void silc_sftp_server_status(SilcSFTP sftp,
-                                   SilcSFTPStatus status,
-                                   const char *message,
-                                   const char *language_tag,
-                                   void *context)
-{
-  SilcSFTPServer server = (SilcSFTPServer)sftp;
-  SilcUInt32 id = SILC_PTR_TO_32(context);
-  int mlen, llen;
-
-  SILC_LOG_DEBUG(("Status callback"));
-  SILC_LOG_DEBUG(("Request ID: %d", id));
-
-  if (!message)
-    message = "";
-  if (!language_tag)
-    language_tag = "";
-  mlen = strlen(message);
-  llen = strlen(language_tag);
-
-  silc_sftp_send_packet(server, SILC_SFTP_STATUS, 16 + mlen + llen,
-                       SILC_STR_UI_INT(id),
-                       SILC_STR_UI_INT(status),
-                       SILC_STR_UI_INT(mlen),
-                       SILC_STR_UI32_STRING(message),
-                       SILC_STR_UI_INT(llen),
-                       SILC_STR_UI32_STRING(language_tag),
-                       SILC_STR_END);
-}
-
-/* Handle callback */
-
-static void silc_sftp_server_handle(SilcSFTP sftp,
-                                   SilcSFTPStatus status,
-                                   SilcSFTPHandle handle,
-                                   void *context)
-{
-  SilcSFTPServer server = (SilcSFTPServer)sftp;
-  SilcUInt32 id = SILC_PTR_TO_32(context);
-  unsigned char *hdata;
-  SilcUInt32 hdata_len;
-
-  SILC_LOG_DEBUG(("Handle callback"));
-  SILC_LOG_DEBUG(("Request ID: %d", id));
-
-  if (status != SILC_SFTP_STATUS_OK) {
-    silc_sftp_send_error(server, status, id);
-    return;
-  }
-
-  hdata = server->fs->fs->sftp_encode_handle(server->fs->fs_context, sftp,
-                                            handle, &hdata_len);
-  if (!hdata) {
-    silc_sftp_send_error(server, SILC_SFTP_STATUS_FAILURE, id);
-    return;
-  }
-
-  silc_sftp_send_packet(server, SILC_SFTP_HANDLE, 8 + hdata_len,
-                       SILC_STR_UI_INT(id),
-                       SILC_STR_UI_INT(hdata_len),
-                       SILC_STR_UI_XNSTRING(hdata, hdata_len),
-                       SILC_STR_END);
-}
-
-/* Data callback */
-
-static void silc_sftp_server_data(SilcSFTP sftp,
-                                 SilcSFTPStatus status,
-                                 const unsigned char *data,
-                                 SilcUInt32 data_len,
-                                 void *context)
-{
-  SilcSFTPServer server = (SilcSFTPServer)sftp;
-  SilcUInt32 id = SILC_PTR_TO_32(context);
-
-  SILC_LOG_DEBUG(("Data callback"));
-  SILC_LOG_DEBUG(("Request ID: %d", id));
-
-  if (status != SILC_SFTP_STATUS_OK) {
-    silc_sftp_send_error(server, status, id);
-    return;
-  }
-
-  silc_sftp_send_packet(server, SILC_SFTP_DATA, 8 + data_len,
-                       SILC_STR_UI_INT(id),
-                       SILC_STR_UI_INT(data_len),
-                       SILC_STR_UI_XNSTRING(data, data_len),
-                       SILC_STR_END);
-}
-
-/* Name callback */
-
-static void silc_sftp_server_name(SilcSFTP sftp,
-                                 SilcSFTPStatus status,
-                                 const SilcSFTPName name,
-                                 void *context)
-{
-  SilcSFTPServer server = (SilcSFTPServer)sftp;
-  SilcUInt32 id = SILC_PTR_TO_32(context);
-  SilcBuffer namebuf;
-
-  SILC_LOG_DEBUG(("Name callback"));
-  SILC_LOG_DEBUG(("Request ID: %d", id));
-
-  if (status != SILC_SFTP_STATUS_OK) {
-    silc_sftp_send_error(server, status, id);
-    return;
-  }
-
-  namebuf = silc_sftp_name_encode(name);
-  if (!namebuf) {
-    silc_sftp_send_error(server, SILC_SFTP_STATUS_FAILURE, id);
-    return;
-  }
-
-  silc_sftp_send_packet(server, SILC_SFTP_NAME, 4 + silc_buffer_len(namebuf),
-                       SILC_STR_UI_INT(id),
-                       SILC_STR_DATA(silc_buffer_data(namebuf),
-                                     silc_buffer_len(namebuf)),
-                       SILC_STR_END);
-}
-
-/* Attributes callback */
-
-static void silc_sftp_server_attr(SilcSFTP sftp,
-                                 SilcSFTPStatus status,
-                                 const SilcSFTPAttributes attrs,
-                                 void *context)
-{
-  SilcSFTPServer server = (SilcSFTPServer)sftp;
-  SilcUInt32 id = SILC_PTR_TO_32(context);
-  SilcBuffer attr_buf;
-
-  SILC_LOG_DEBUG(("Attr callback"));
-  SILC_LOG_DEBUG(("Request ID: %d", id));
-
-  if (status != SILC_SFTP_STATUS_OK) {
-    silc_sftp_send_error(server, status, id);
-    return;
-  }
-
-  attr_buf = silc_sftp_attr_encode(attrs);
-  if (!attr_buf) {
-    silc_sftp_send_error(server, SILC_SFTP_STATUS_FAILURE, id);
-    return;
-  }
-
-  silc_sftp_send_packet(server, SILC_SFTP_ATTRS, 4 + silc_buffer_len(attr_buf),
-                       SILC_STR_UI_INT(id),
-                       SILC_STR_DATA(silc_buffer_data(attr_buf),
-                                     silc_buffer_len(attr_buf)),
-                       SILC_STR_END);
-
-  silc_buffer_free(attr_buf);
-}
-
-/* Extended callback */
-
-static void silc_sftp_server_extended(SilcSFTP sftp,
-                                     SilcSFTPStatus status,
-                                     const unsigned char *data,
-                                     SilcUInt32 data_len,
-                                     void *context)
-{
-  SilcSFTPServer server = (SilcSFTPServer)sftp;
-  SilcUInt32 id = SILC_PTR_TO_32(context);
-
-  SILC_LOG_DEBUG(("Extended callback"));
-  SILC_LOG_DEBUG(("Request ID: %d", id));
-
-  if (status != SILC_SFTP_STATUS_OK) {
-    silc_sftp_send_error(server, status, id);
-    return;
-  }
-
-  silc_sftp_send_packet(server, SILC_SFTP_EXTENDED, 4 + data_len,
-                       SILC_STR_UI_INT(id),
-                       SILC_STR_UI_XNSTRING(data, data_len),
-                       SILC_STR_END);
-}
-
-/* Starts SFTP server and returns context to it.  This function returns the
-   allocated SFTP client context or NULL on error. The `send_packet' is called
-   by the library when it needs to send a packet. The `fs' is the
-   structure containing filesystem access callbacks. */
-
-SilcSFTP silc_sftp_server_start(SilcStream stream,
-                               SilcSchedule schedule,
-                               SilcSFTPErrorCallback error_cb,
-                               void *context,
-                               SilcSFTPFilesystem fs)
-{
-  SilcSFTPServer server;
-
-  if (!schedule)
-    schedule = silc_schedule_get_global();
-
-  server = silc_calloc(1, sizeof(*server));
-  if (!server)
-    return NULL;
-  server->stream = stream;
-  server->schedule = schedule;
-  server->error = error_cb;
-  server->context = context;
-  server->fs = fs;
-
-  /* We handle the stream now */
-  silc_stream_set_notifier(stream, schedule, silc_sftp_server_io, server);
-
-  SILC_LOG_DEBUG(("Starting SFTP server %p", server));
-
-  return (SilcSFTP)server;
-}
-
-/* Shutdown's the SFTP server.  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_server_shutdown(SilcSFTP sftp)
-{
-  SilcSFTPServer server = (SilcSFTPServer)sftp;
-
-  SILC_LOG_DEBUG(("Stopping SFTP server %p", server));
-
-  silc_stream_set_notifier(server->stream, server->schedule, NULL, NULL);
-  if (server->packet)
-    silc_buffer_free(server->packet);
-  silc_free(server);
-}
-
-/* Sets monitor callback */
-
-void silc_sftp_server_set_monitor(SilcSFTP sftp,
-                                 SilcSFTPMonitors monitors,
-                                 SilcSFTPMonitor monitor,
-                                 void *context)
-{
-  SilcSFTPServer server = (SilcSFTPServer)sftp;
-  server->monitors = monitors;
-  server->monitor = monitor;
-  server->monitor_context = context;
-}
-
-/* Function that is called to process the incmoing SFTP packet. */
-
-static void silc_sftp_server_receive_process(SilcSFTP sftp, SilcBuffer buffer)
-{
-  SilcSFTPServer server = (SilcSFTPServer)sftp;
-  SilcSFTPPacket type;
-  char *filename = NULL, *path = NULL;
-  unsigned char *payload = NULL;
-  SilcUInt32 payload_len;
-  int ret;
-  SilcBufferStruct buf;
-  SilcUInt32 id;
-  SilcSFTPAttributes attrs;
-  SilcSFTPHandle handle;
-  SilcSFTPMonitorDataStruct mdata;
-
-  SILC_LOG_DEBUG(("Start"));
-
-  /* Parse the packet */
-  type = silc_sftp_packet_decode(buffer, &payload, &payload_len);
-  if (type <= 0)
-    return;
-
-  silc_buffer_set(&buf, payload, payload_len);
-
-  memset(&mdata, 0, sizeof(mdata));
-
-  switch (type) {
-  case SILC_SFTP_READ:
-    {
-      unsigned char *hdata;
-      SilcUInt32 hdata_len;
-      SilcUInt64 offset;
-      SilcUInt32 len;
-
-      SILC_LOG_DEBUG(("Read request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_NSTRING(&hdata,
-                                                      &hdata_len),
-                                SILC_STR_UI_INT64(&offset),
-                                SILC_STR_UI_INT(&len),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      /* Get the handle */
-      handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp,
-                                              (const unsigned char *)hdata,
-                                              hdata_len);
-      if (!handle) {
-       silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id);
-       break;
-      }
-
-      /* Read operation */
-      server->fs->fs->sftp_read(server->fs->fs_context, sftp,
-                               handle, offset, len,
-                               silc_sftp_server_data, SILC_32_TO_PTR(id));
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_READ && server->monitor) {
-       mdata.offset = offset;
-       mdata.data_len = len;
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_READ, &mdata,
-                          server->monitor_context);
-      }
-    }
-    break;
-
-  case SILC_SFTP_WRITE:
-    {
-      unsigned char *hdata;
-      SilcUInt32 hdata_len;
-      SilcUInt64 offset;
-      unsigned char *data;
-      SilcUInt32 data_len;
-
-      SILC_LOG_DEBUG(("Read request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_NSTRING(&hdata,
-                                                      &hdata_len),
-                                SILC_STR_UI_INT64(&offset),
-                                SILC_STR_UI32_NSTRING(&data,
-                                                      &data_len),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      /* Get the handle */
-      handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp,
-                                              (const unsigned char *)hdata,
-                                              hdata_len);
-      if (!handle) {
-       silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id);
-       break;
-      }
-
-      /* Write operation */
-      server->fs->fs->sftp_write(server->fs->fs_context, sftp, handle, offset,
-                                (const unsigned char *)data, data_len,
-                                silc_sftp_server_status, SILC_32_TO_PTR(id));
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_WRITE && server->monitor) {
-       mdata.offset = offset;
-       mdata.data_len = data_len;
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_WRITE, &mdata,
-                          server->monitor_context);
-      }
-    }
-    break;
-
-  case SILC_SFTP_INIT:
-    {
-      SilcSFTPVersion version;
-
-      SILC_LOG_DEBUG(("Init request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&version),
-                                SILC_STR_END);
-      if (ret < 0)
-       break;
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_INIT && server->monitor) {
-       mdata.version = version;
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_INIT, &mdata,
-                          server->monitor_context);
-      }
-
-      silc_sftp_send_packet(server, SILC_SFTP_VERSION, 4,
-                           SILC_STR_UI_INT(SILC_SFTP_PROTOCOL_VERSION),
-                           SILC_STR_END);
-    }
-    break;
-
-  case SILC_SFTP_OPEN:
-    {
-      SilcSFTPFileOperation pflags;
-      unsigned char *attr_buf;
-      SilcUInt32 attr_len = 0;
-      SilcBufferStruct tmpbuf;
-
-      SILC_LOG_DEBUG(("Open request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_STRING_ALLOC(&filename),
-                                SILC_STR_UI_INT(&pflags),
-                                SILC_STR_UI32_NSTRING(&attr_buf,
-                                                      &attr_len),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      if (attr_len) {
-       silc_buffer_set(&tmpbuf, attr_buf, attr_len);
-       attrs = silc_sftp_attr_decode(&tmpbuf);
-       if (!attrs)
-         goto failure;
-      } else {
-       attrs = silc_calloc(1, sizeof(*attrs));
-       if (!attrs)
-         goto failure;
-      }
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_OPEN && server->monitor) {
-       mdata.name = filename;
-       mdata.pflags = pflags;
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_OPEN, &mdata,
-                          server->monitor_context);
-      }
-
-      /* Open operation */
-      server->fs->fs->sftp_open(server->fs->fs_context, sftp, filename, pflags,
-                               attrs, silc_sftp_server_handle,
-                               SILC_32_TO_PTR(id));
-
-      silc_free(filename);
-      silc_sftp_attr_free(attrs);
-    }
-    break;
-
-  case SILC_SFTP_CLOSE:
-    {
-      unsigned char *hdata;
-      SilcUInt32 hdata_len;
-
-      SILC_LOG_DEBUG(("Close request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_NSTRING(&hdata,
-                                                      &hdata_len),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      /* Get the handle */
-      handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp,
-                                              (const unsigned char *)hdata,
-                                              hdata_len);
-      if (!handle) {
-       silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id);
-       break;
-      }
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_CLOSE && server->monitor) {
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_CLOSE, &mdata,
-                          server->monitor_context);
-      }
-
-      /* Close operation */
-      server->fs->fs->sftp_close(server->fs->fs_context, sftp, handle,
-                                silc_sftp_server_status, SILC_32_TO_PTR(id));
-
-    }
-    break;
-
-  case SILC_SFTP_REMOVE:
-    {
-      SILC_LOG_DEBUG(("Remove request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_STRING_ALLOC(&filename),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_REMOVE && server->monitor) {
-       mdata.name = filename;
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_REMOVE, &mdata,
-                          server->monitor_context);
-      }
-
-      /* Remove operation */
-      server->fs->fs->sftp_remove(server->fs->fs_context, sftp, filename,
-                                 silc_sftp_server_status, SILC_32_TO_PTR(id));
-
-      silc_free(filename);
-    }
-    break;
-
-  case SILC_SFTP_RENAME:
-    {
-      char *newname = NULL;
-
-      SILC_LOG_DEBUG(("Rename request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_STRING_ALLOC(&filename),
-                                SILC_STR_UI32_STRING_ALLOC(&newname),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_RENAME && server->monitor) {
-       mdata.name = filename;
-       mdata.name2 = newname;
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_RENAME, &mdata,
-                          server->monitor_context);
-      }
-
-      /* Rename operation */
-      server->fs->fs->sftp_rename(server->fs->fs_context, sftp,
-                                 filename, newname,
-                                 silc_sftp_server_status, SILC_32_TO_PTR(id));
-
-      silc_free(filename);
-      silc_free(newname);
-    }
-    break;
-
-  case SILC_SFTP_MKDIR:
-    {
-      unsigned char *attr_buf;
-      SilcUInt32 attr_len = 0;
-      SilcBufferStruct tmpbuf;
-
-      SILC_LOG_DEBUG(("Mkdir request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_STRING_ALLOC(&path),
-                                SILC_STR_UI32_NSTRING(&attr_buf,
-                                                      &attr_len),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      if (attr_len) {
-       silc_buffer_set(&tmpbuf, attr_buf, attr_len);
-       attrs = silc_sftp_attr_decode(&tmpbuf);
-       if (!attrs)
-         goto failure;
-      } else {
-       attrs = silc_calloc(1, sizeof(*attrs));
-       if (!attrs)
-         goto failure;
-      }
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_MKDIR && server->monitor) {
-       mdata.name = path;
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_MKDIR, &mdata,
-                          server->monitor_context);
-      }
-
-      /* Mkdir operation */
-      server->fs->fs->sftp_mkdir(server->fs->fs_context, sftp, path, attrs,
-                                silc_sftp_server_status, SILC_32_TO_PTR(id));
-
-      silc_sftp_attr_free(attrs);
-      silc_free(path);
-    }
-    break;
-
-  case SILC_SFTP_RMDIR:
-    {
-      SILC_LOG_DEBUG(("Rmdir request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_STRING_ALLOC(&path),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_RMDIR && server->monitor) {
-       mdata.name = path;
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_RMDIR, &mdata,
-                          server->monitor_context);
-      }
-
-      /* Rmdir operation */
-      server->fs->fs->sftp_rmdir(server->fs->fs_context, sftp, path,
-                                silc_sftp_server_status, SILC_32_TO_PTR(id));
-
-      silc_free(path);
-    }
-    break;
-
-  case SILC_SFTP_OPENDIR:
-    {
-      SILC_LOG_DEBUG(("Opendir request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_STRING_ALLOC(&path),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_OPENDIR && server->monitor) {
-       mdata.name = path;
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_OPENDIR, &mdata,
-                          server->monitor_context);
-      }
-
-      /* Opendir operation */
-      server->fs->fs->sftp_opendir(server->fs->fs_context, sftp, path,
-                                  silc_sftp_server_handle, SILC_32_TO_PTR(id));
-
-      silc_free(path);
-    }
-    break;
-
-  case SILC_SFTP_READDIR:
-    {
-      unsigned char *hdata;
-      SilcUInt32 hdata_len;
-
-      SILC_LOG_DEBUG(("Readdir request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_NSTRING(&hdata,
-                                                      &hdata_len),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      /* Get the handle */
-      handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp,
-                                              (const unsigned char *)hdata,
-                                              hdata_len);
-      if (!handle) {
-       silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id);
-       break;
-      }
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_READDIR && server->monitor) {
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_READDIR, &mdata,
-                          server->monitor_context);
-      }
-
-      /* Readdir operation */
-      server->fs->fs->sftp_readdir(server->fs->fs_context, sftp, handle,
-                                  silc_sftp_server_name, SILC_32_TO_PTR(id));
-    }
-    break;
-
-  case SILC_SFTP_STAT:
-    {
-      SILC_LOG_DEBUG(("Stat request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_STRING_ALLOC(&path),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_STAT && server->monitor) {
-       mdata.name = path;
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_STAT, &mdata,
-                          server->monitor_context);
-      }
-
-      /* Stat operation */
-      server->fs->fs->sftp_stat(server->fs->fs_context, sftp, path,
-                               silc_sftp_server_attr, SILC_32_TO_PTR(id));
-
-      silc_free(path);
-    }
-    break;
-
-  case SILC_SFTP_LSTAT:
-    {
-      SILC_LOG_DEBUG(("Lstat request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_STRING_ALLOC(&path),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_LSTAT && server->monitor) {
-       mdata.name = path;
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_LSTAT, &mdata,
-                          server->monitor_context);
-      }
-
-      /* Lstat operation */
-      server->fs->fs->sftp_lstat(server->fs->fs_context, sftp, path,
-                                silc_sftp_server_attr, SILC_32_TO_PTR(id));
-
-      silc_free(path);
-    }
-    break;
-
-  case SILC_SFTP_FSTAT:
-    {
-      unsigned char *hdata;
-      SilcUInt32 hdata_len;
-
-      SILC_LOG_DEBUG(("Fstat request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_NSTRING(&hdata,
-                                                      &hdata_len),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      /* Get the handle */
-      handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp,
-                                              (const unsigned char *)hdata,
-                                              hdata_len);
-      if (!handle) {
-       silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id);
-       break;
-      }
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_FSTAT && server->monitor) {
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_FSTAT, &mdata,
-                          server->monitor_context);
-      }
-
-      /* Fstat operation */
-      server->fs->fs->sftp_fstat(server->fs->fs_context, sftp, handle,
-                                silc_sftp_server_attr, SILC_32_TO_PTR(id));
-    }
-    break;
-
-  case SILC_SFTP_SETSTAT:
-    {
-      unsigned char *attr_buf;
-      SilcUInt32 attr_len = 0;
-      SilcBufferStruct tmpbuf;
-
-      SILC_LOG_DEBUG(("Setstat request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_STRING_ALLOC(&path),
-                                SILC_STR_UI32_NSTRING(&attr_buf,
-                                                      &attr_len),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      if (attr_len) {
-       silc_buffer_set(&tmpbuf, attr_buf, attr_len);
-       attrs = silc_sftp_attr_decode(&tmpbuf);
-       if (!attrs)
-         goto failure;
-      } else {
-       attrs = silc_calloc(1, sizeof(*attrs));
-       if (!attrs)
-         goto failure;
-      }
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_SETSTAT && server->monitor) {
-       mdata.name = path;
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_SETSTAT, &mdata,
-                          server->monitor_context);
-      }
-
-      /* Setstat operation */
-      server->fs->fs->sftp_setstat(server->fs->fs_context, sftp, path, attrs,
-                                  silc_sftp_server_status,
-                                  SILC_32_TO_PTR(id));
-
-      silc_sftp_attr_free(attrs);
-      silc_free(path);
-    }
-    break;
-
-  case SILC_SFTP_FSETSTAT:
-    {
-      unsigned char *hdata, *attr_buf;
-      SilcUInt32 hdata_len, attr_len = 0;
-      SilcBufferStruct tmpbuf;
-
-      SILC_LOG_DEBUG(("Fsetstat request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_NSTRING(&hdata,
-                                                      &hdata_len),
-                                SILC_STR_UI32_NSTRING(&attr_buf,
-                                                      &attr_len),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      if (attr_len) {
-       silc_buffer_set(&tmpbuf, attr_buf, attr_len);
-       attrs = silc_sftp_attr_decode(&tmpbuf);
-       if (!attrs)
-         goto failure;
-      } else {
-       attrs = silc_calloc(1, sizeof(*attrs));
-       if (!attrs)
-         goto failure;
-      }
-
-      /* Get the handle */
-      handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp,
-                                              (const unsigned char *)hdata,
-                                              hdata_len);
-      if (!handle) {
-       silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id);
-       break;
-      }
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_FSETSTAT && server->monitor) {
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_FSETSTAT, &mdata,
-                          server->monitor_context);
-      }
-
-      /* Fsetstat operation */
-      server->fs->fs->sftp_fsetstat(server->fs->fs_context, sftp,
-                                   handle, attrs,
-                                   silc_sftp_server_status,
-                                   SILC_32_TO_PTR(id));
-
-      silc_sftp_attr_free(attrs);
-    }
-    break;
-
-  case SILC_SFTP_READLINK:
-    {
-      SILC_LOG_DEBUG(("Readlink request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_STRING_ALLOC(&path),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_READLINK && server->monitor) {
-       mdata.name = path;
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_READLINK, &mdata,
-                          server->monitor_context);
-      }
-
-      /* Readlink operation */
-      server->fs->fs->sftp_readlink(server->fs->fs_context, sftp, path,
-                                   silc_sftp_server_name, SILC_32_TO_PTR(id));
-
-      silc_free(path);
-    }
-    break;
-
-  case SILC_SFTP_SYMLINK:
-    {
-      char *target = NULL;
-
-      SILC_LOG_DEBUG(("Symlink request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_STRING_ALLOC(&path),
-                                SILC_STR_UI32_STRING_ALLOC(&target),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_SYMLINK && server->monitor) {
-       mdata.name = path;
-       mdata.name2 = target;
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_SYMLINK, &mdata,
-                          server->monitor_context);
-      }
-
-      /* Symlink operation */
-      server->fs->fs->sftp_symlink(server->fs->fs_context, sftp, path, target,
-                                  silc_sftp_server_status,
-                                  SILC_32_TO_PTR(id));
-
-      silc_free(path);
-      silc_free(target);
-    }
-    break;
-
-  case SILC_SFTP_REALPATH:
-    {
-      SILC_LOG_DEBUG(("Realpath request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_STRING_ALLOC(&path),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_REALPATH && server->monitor) {
-       mdata.name = path;
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_REALPATH, &mdata,
-                          server->monitor_context);
-      }
-
-      /* Realpath operation */
-      server->fs->fs->sftp_realpath(server->fs->fs_context, sftp, path,
-                                   silc_sftp_server_name, SILC_32_TO_PTR(id));
-
-      silc_free(path);
-    }
-    break;
-
-  case SILC_SFTP_EXTENDED:
-    {
-      char *request = NULL;
-      unsigned char *data;
-      SilcUInt32 data_len;
-
-      SILC_LOG_DEBUG(("Extended request"));
-
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_INT(&id),
-                                SILC_STR_UI32_STRING_ALLOC(&request),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-
-      data_len = 8 + strlen(request);
-      silc_buffer_pull(&buf, data_len);
-      ret = silc_buffer_unformat(&buf,
-                                SILC_STR_DATA(&data, silc_buffer_len(&buf)),
-                                SILC_STR_END);
-      if (ret < 0)
-       goto failure;
-      data_len = silc_buffer_len(&buf);
-
-      /* Call monitor */
-      if (server->monitors & SILC_SFTP_MONITOR_EXTENDED && server->monitor) {
-       (*server->monitor)(sftp, SILC_SFTP_MONITOR_EXTENDED, &mdata,
-                          server->monitor_context);
-      }
-
-      /* Extended operation */
-      server->fs->fs->sftp_extended(server->fs->fs_context, sftp,
-                                   request, data, data_len,
-                                   silc_sftp_server_extended,
-                                   SILC_32_TO_PTR(id));
-
-      silc_free(request);
-    }
-    break;
-
-  default:
-    break;
-  }
-
-  return;
-
- failure:
-  silc_sftp_send_error(server, SILC_SFTP_STATUS_FAILURE, id);
-}