Integer type name change.
[silc.git] / lib / silcsftp / sftp_server.c
index 2286457fc9f8443472b9cf48ff4d0332dae5a49b..f3bda1d64642d4dcdf1f100be04b07b6272efc4e 100644 (file)
   GNU General Public License for more details.
 
 */
+/* $Id$ */
 
 #include "silcincludes.h"
 #include "silcsftp.h"
+#include "silcsftp_fs.h"
 #include "sftp_util.h"
 
 /* SFTP Server context */
@@ -26,39 +28,45 @@ typedef struct {
   SilcSocketConnection sock;
   SilcSFTPSendPacketCallback send_packet;
   void *send_context;
+  SilcSFTPMonitors monitors;
+  SilcSFTPMonitor monitor;
+  void *monitor_context;
   SilcSFTPFilesystem fs;
-  void *fs_context;
+  SilcBuffer packet;
 } *SilcSFTPServer;
 
 /* General routine to send SFTP packet to the SFTP client. */
 
 static void silc_sftp_send_packet(SilcSFTPServer sftp,
                                  SilcSFTPPacket type, 
-                                 uint32 len, ...)
+                                 SilcUInt32 len, ...)
 {
-  SilcBuffer packet;
+  SilcBuffer tmp;
   va_list vp;
 
   va_start(vp, len);
-  packet = silc_sftp_packet_encode_vp(type, len, vp);
+  tmp = silc_sftp_packet_encode_vp(type, sftp->packet, len, vp);
   va_end(vp);
-
-  if (!packet)
+  if (!tmp)
     return;
+  sftp->packet = tmp;
 
-  SILC_LOG_HEXDUMP(("SFTP packet to client"), packet->data, packet->len);
+  SILC_LOG_HEXDUMP(("SFTP packet to client"), sftp->packet->data, 
+                  sftp->packet->len);
 
   /* Send the packet */
-  (*sftp->send_packet)(sftp->sock, packet, sftp->send_context);
+  (*sftp->send_packet)(sftp->sock, sftp->packet, sftp->send_context);
 
-  silc_buffer_free(packet);
+  /* Clear packet */
+  sftp->packet->data = sftp->packet->tail = sftp->packet->head;
+  sftp->packet->len = 0;
 }
 
 /* Sends error to the client */
 
 static void silc_sftp_send_error(SilcSFTPServer sftp,
                                 SilcSFTPStatus status,
-                                uint32 id)
+                                SilcUInt32 id)
 {
   SILC_LOG_DEBUG(("Send error %d", status));
 
@@ -79,7 +87,7 @@ static void silc_sftp_server_status(SilcSFTP sftp,
                                    void *context)
 {
   SilcSFTPServer server = (SilcSFTPServer)sftp;
-  uint32 id = (uint32)context;
+  SilcUInt32 id = (SilcUInt32)context;
   int mlen, llen;
 
   SILC_LOG_DEBUG(("Status callback"));
@@ -110,9 +118,9 @@ static void silc_sftp_server_handle(SilcSFTP sftp,
                                    void *context)
 {
   SilcSFTPServer server = (SilcSFTPServer)sftp;
-  uint32 id = (uint32)context;
+  SilcUInt32 id = (SilcUInt32)context;
   unsigned char *hdata;
-  uint32 hdata_len;
+  SilcUInt32 hdata_len;
 
   SILC_LOG_DEBUG(("Handle callback"));
   SILC_LOG_DEBUG(("Request ID: %d", id));
@@ -122,8 +130,8 @@ static void silc_sftp_server_handle(SilcSFTP sftp,
     return;
   }
 
-  hdata = server->fs->sftp_encode_handle(server->fs_context, sftp,
-                                        handle, &hdata_len);
+  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;
@@ -141,11 +149,11 @@ static void silc_sftp_server_handle(SilcSFTP sftp,
 static void silc_sftp_server_data(SilcSFTP sftp,
                                  SilcSFTPStatus status,
                                  const unsigned char *data,
-                                 uint32 data_len,
+                                 SilcUInt32 data_len,
                                  void *context)
 {
   SilcSFTPServer server = (SilcSFTPServer)sftp;
-  uint32 id = (uint32)context;
+  SilcUInt32 id = (SilcUInt32)context;
 
   SILC_LOG_DEBUG(("Data callback"));
   SILC_LOG_DEBUG(("Request ID: %d", id));
@@ -170,7 +178,7 @@ static void silc_sftp_server_name(SilcSFTP sftp,
                                  void *context)
 {
   SilcSFTPServer server = (SilcSFTPServer)sftp;
-  uint32 id = (uint32)context;
+  SilcUInt32 id = (SilcUInt32)context;
   SilcBuffer namebuf;
 
   SILC_LOG_DEBUG(("Name callback"));
@@ -201,7 +209,7 @@ static void silc_sftp_server_attr(SilcSFTP sftp,
                                  void *context)
 {
   SilcSFTPServer server = (SilcSFTPServer)sftp;
-  uint32 id = (uint32)context;
+  SilcUInt32 id = (SilcUInt32)context;
   SilcBuffer attr_buf;
 
   SILC_LOG_DEBUG(("Attr callback"));
@@ -227,11 +235,11 @@ static void silc_sftp_server_attr(SilcSFTP sftp,
 static void silc_sftp_server_extended(SilcSFTP sftp,
                                      SilcSFTPStatus status,
                                      const unsigned char *data,
-                                     uint32 data_len,
+                                     SilcUInt32 data_len,
                                      void *context)
 {
   SilcSFTPServer server = (SilcSFTPServer)sftp;
-  uint32 id = (uint32)context;
+  SilcUInt32 id = (SilcUInt32)context;
 
   SILC_LOG_DEBUG(("Extended callback"));
   SILC_LOG_DEBUG(("Request ID: %d", id));
@@ -256,8 +264,7 @@ static void silc_sftp_server_extended(SilcSFTP sftp,
 SilcSFTP silc_sftp_server_start(SilcSocketConnection sock,
                                SilcSFTPSendPacketCallback send_packet,
                                void *send_context,
-                               SilcSFTPFilesystem fs,
-                               void *fs_context)
+                               SilcSFTPFilesystem fs)
 {
   SilcSFTPServer server;
 
@@ -266,7 +273,6 @@ SilcSFTP silc_sftp_server_start(SilcSocketConnection sock,
   server->send_packet = send_packet;
   server->send_context = send_context;
   server->fs = fs;
-  server->fs_context = fs_context;
 
   SILC_LOG_DEBUG(("Starting SFTP server %p", server));
 
@@ -283,9 +289,24 @@ void silc_sftp_server_shutdown(SilcSFTP sftp)
 
   SILC_LOG_DEBUG(("Stopping SFTP server %p", server));
 
+  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. */
 /* XXX Some day this will go away and we have automatic receive callbacks
    for SilcSocketConnection API or SilcPacketContext API. */
@@ -298,12 +319,13 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
   SilcSFTPPacket type;
   char *filename = NULL, *path = NULL;
   const unsigned char *payload = NULL;
-  uint32 payload_len;
+  SilcUInt32 payload_len;
   int ret;
   SilcBufferStruct buf;
-  uint32 id;
+  SilcUInt32 id;
   SilcSFTPAttributes attrs;
   SilcSFTPHandle handle;
+  SilcSFTPMonitorDataStruct mdata;
 
   SILC_LOG_DEBUG(("Start"));
 
@@ -315,6 +337,8 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
 
   silc_buffer_set(&buf, (unsigned char *)payload, payload_len);
 
+  memset(&mdata, 0, sizeof(mdata));
+
   switch (type) {
   case SILC_SFTP_INIT:
     {
@@ -328,6 +352,13 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
       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);
@@ -338,7 +369,7 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
     {
       SilcSFTPFileOperation pflags;
       unsigned char *attr_buf;
-      uint32 attr_len = 0;
+      SilcUInt32 attr_len = 0;
       SilcBufferStruct tmpbuf;
 
       SILC_LOG_DEBUG(("Open request"));
@@ -360,9 +391,17 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
        attrs = silc_calloc(1, sizeof(*attrs));
       }
 
+      /* 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->sftp_open(server->fs_context, sftp, filename, pflags,
-                           attrs, silc_sftp_server_handle, (void *)id);
+      server->fs->fs->sftp_open(server->fs->fs_context, sftp, filename, pflags,
+                               attrs, silc_sftp_server_handle, (void *)id);
 
       silc_free(filename);
       silc_sftp_attr_free(attrs);
@@ -372,7 +411,7 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
   case SILC_SFTP_CLOSE:
     {
       unsigned char *hdata;
-      uint32 hdata_len;
+      SilcUInt32 hdata_len;
 
       SILC_LOG_DEBUG(("Close request"));
 
@@ -385,26 +424,32 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
        goto failure;
 
       /* Get the handle */
-      handle = server->fs->sftp_get_handle(server->fs_context, sftp,
-                                          (const unsigned char *)hdata,
-                                          hdata_len);
+      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->sftp_close(server->fs_context, sftp, handle,
-                            silc_sftp_server_status, (void *)id);
+      server->fs->fs->sftp_close(server->fs->fs_context, sftp, handle,
+                                silc_sftp_server_status, (void *)id);
     }
     break;
 
   case SILC_SFTP_READ:
     {
       unsigned char *hdata;
-      uint32 hdata_len;
-      uint64 offset;
-      uint32 len;
+      SilcUInt32 hdata_len;
+      SilcUInt64 offset;
+      SilcUInt32 len;
 
       SILC_LOG_DEBUG(("Read request"));
 
@@ -419,27 +464,36 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
        goto failure;
 
       /* Get the handle */
-      handle = server->fs->sftp_get_handle(server->fs_context, sftp,
-                                          (const unsigned char *)hdata,
-                                          hdata_len);
+      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_READ && server->monitor) {
+       mdata.offset = offset;
+       mdata.data_len = len;
+       (*server->monitor)(sftp, SILC_SFTP_MONITOR_READ, &mdata,
+                          server->monitor_context);
+      }
+
       /* Read operation */
-      server->fs->sftp_read(server->fs_context, sftp, handle, offset, len,
-                           silc_sftp_server_data, (void *)id);
+      server->fs->fs->sftp_read(server->fs->fs_context, sftp, 
+                               handle, offset, len,
+                               silc_sftp_server_data, (void *)id);
     }
     break;
 
   case SILC_SFTP_WRITE:
     {
       unsigned char *hdata;
-      uint32 hdata_len;
-      uint64 offset;
+      SilcUInt32 hdata_len;
+      SilcUInt64 offset;
       unsigned char *data;
-      uint32 data_len;
+      SilcUInt32 data_len;
 
       SILC_LOG_DEBUG(("Read request"));
 
@@ -455,18 +509,26 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
        goto failure;
 
       /* Get the handle */
-      handle = server->fs->sftp_get_handle(server->fs_context, sftp,
-                                          (const unsigned char *)hdata,
-                                          hdata_len);
+      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_WRITE && server->monitor) {
+       mdata.offset = offset;
+       mdata.data_len = data_len;
+       (*server->monitor)(sftp, SILC_SFTP_MONITOR_WRITE, &mdata,
+                          server->monitor_context);
+      }
+
       /* Write operation */
-      server->fs->sftp_write(server->fs_context, sftp, handle, offset, 
-                            (const unsigned char *)data, data_len,
-                            silc_sftp_server_status, (void *)id);
+      server->fs->fs->sftp_write(server->fs->fs_context, sftp, handle, offset, 
+                                (const unsigned char *)data, data_len,
+                                silc_sftp_server_status, (void *)id);
     }
     break;
 
@@ -481,9 +543,16 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
       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->sftp_remove(server->fs_context, sftp, filename,
-                             silc_sftp_server_status, (void *)id);
+      server->fs->fs->sftp_remove(server->fs->fs_context, sftp, filename,
+                                 silc_sftp_server_status, (void *)id);
 
       silc_free(filename);
     }
@@ -503,9 +572,18 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
       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->sftp_rename(server->fs_context, sftp, filename, newname,
-                             silc_sftp_server_status, (void *)id);
+      server->fs->fs->sftp_rename(server->fs->fs_context, sftp, 
+                                 filename, newname,
+                                 silc_sftp_server_status, (void *)id);
 
       silc_free(filename);
       silc_free(newname);
@@ -515,7 +593,7 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
   case SILC_SFTP_MKDIR:
     {
       unsigned char *attr_buf;
-      uint32 attr_len = 0;
+      SilcUInt32 attr_len = 0;
       SilcBufferStruct tmpbuf;
 
       SILC_LOG_DEBUG(("Mkdir request"));
@@ -536,9 +614,16 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
        attrs = silc_calloc(1, sizeof(*attrs));
       }
 
+      /* 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->sftp_mkdir(server->fs_context, sftp, path, attrs,
-                            silc_sftp_server_status, (void *)id);
+      server->fs->fs->sftp_mkdir(server->fs->fs_context, sftp, path, attrs,
+                                silc_sftp_server_status, (void *)id);
 
       silc_sftp_attr_free(attrs);
       silc_free(path);
@@ -556,9 +641,16 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
       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->sftp_rmdir(server->fs_context, sftp, path,
-                            silc_sftp_server_status, (void *)id);
+      server->fs->fs->sftp_rmdir(server->fs->fs_context, sftp, path,
+                                silc_sftp_server_status, (void *)id);
 
       silc_free(path);
     }
@@ -575,9 +667,16 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
       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->sftp_opendir(server->fs_context, sftp, path,
-                              silc_sftp_server_handle, (void *)id);
+      server->fs->fs->sftp_opendir(server->fs->fs_context, sftp, path,
+                                  silc_sftp_server_handle, (void *)id);
 
       silc_free(path);
     }
@@ -586,7 +685,7 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
   case SILC_SFTP_READDIR:
     {
       unsigned char *hdata;
-      uint32 hdata_len;
+      SilcUInt32 hdata_len;
 
       SILC_LOG_DEBUG(("Readdir request"));
 
@@ -599,17 +698,23 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
        goto failure;
 
       /* Get the handle */
-      handle = server->fs->sftp_get_handle(server->fs_context, sftp,
-                                          (const unsigned char *)hdata,
-                                          hdata_len);
+      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->sftp_readdir(server->fs_context, sftp, handle,
-                              silc_sftp_server_name, (void *)id);
+      server->fs->fs->sftp_readdir(server->fs->fs_context, sftp, handle,
+                                  silc_sftp_server_name, (void *)id);
     }
     break;
 
@@ -624,9 +729,16 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
       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->sftp_stat(server->fs_context, sftp, path,
-                           silc_sftp_server_attr, (void *)id);
+      server->fs->fs->sftp_stat(server->fs->fs_context, sftp, path,
+                               silc_sftp_server_attr, (void *)id);
 
       silc_free(path);
     }
@@ -643,9 +755,16 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
       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->sftp_lstat(server->fs_context, sftp, path,
-                            silc_sftp_server_attr, (void *)id);
+      server->fs->fs->sftp_lstat(server->fs->fs_context, sftp, path,
+                                silc_sftp_server_attr, (void *)id);
 
       silc_free(path);
     }
@@ -654,7 +773,7 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
   case SILC_SFTP_FSTAT:
     {
       unsigned char *hdata;
-      uint32 hdata_len;
+      SilcUInt32 hdata_len;
 
       SILC_LOG_DEBUG(("Fstat request"));
 
@@ -667,24 +786,30 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
        goto failure;
 
       /* Get the handle */
-      handle = server->fs->sftp_get_handle(server->fs_context, sftp,
-                                          (const unsigned char *)hdata,
-                                          hdata_len);
+      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->sftp_fstat(server->fs_context, sftp, handle,
-                            silc_sftp_server_attr, (void *)id);
+      server->fs->fs->sftp_fstat(server->fs->fs_context, sftp, handle,
+                                silc_sftp_server_attr, (void *)id);
     }
     break;
 
   case SILC_SFTP_SETSTAT:
     {
       unsigned char *attr_buf;
-      uint32 attr_len = 0;
+      SilcUInt32 attr_len = 0;
       SilcBufferStruct tmpbuf;
 
       SILC_LOG_DEBUG(("Setstat request"));
@@ -705,9 +830,16 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
        attrs = silc_calloc(1, sizeof(*attrs));
       }
 
+      /* 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->sftp_setstat(server->fs_context, sftp, path, attrs,
-                              silc_sftp_server_status, (void *)id);
+      server->fs->fs->sftp_setstat(server->fs->fs_context, sftp, path, attrs,
+                                  silc_sftp_server_status, (void *)id);
 
       silc_sftp_attr_free(attrs);
       silc_free(path);
@@ -717,7 +849,7 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
   case SILC_SFTP_FSETSTAT:
     {
       unsigned char *hdata, *attr_buf;
-      uint32 hdata_len, attr_len = 0;
+      SilcUInt32 hdata_len, attr_len = 0;
       SilcBufferStruct tmpbuf;
 
       SILC_LOG_DEBUG(("Fsetstat request"));
@@ -740,17 +872,24 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
       }
 
       /* Get the handle */
-      handle = server->fs->sftp_get_handle(server->fs_context, sftp,
-                                          (const unsigned char *)hdata,
-                                          hdata_len);
+      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->sftp_fsetstat(server->fs_context, sftp, handle, attrs,
-                               silc_sftp_server_status, (void *)id);
+      server->fs->fs->sftp_fsetstat(server->fs->fs_context, sftp, 
+                                   handle, attrs,
+                                   silc_sftp_server_status, (void *)id);
 
       silc_sftp_attr_free(attrs);
     }
@@ -767,9 +906,16 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
       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->sftp_readlink(server->fs_context, sftp, path,
-                               silc_sftp_server_name, (void *)id);
+      server->fs->fs->sftp_readlink(server->fs->fs_context, sftp, path,
+                                   silc_sftp_server_name, (void *)id);
 
       silc_free(path);
     }
@@ -789,9 +935,17 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
       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->sftp_symlink(server->fs_context, sftp, path, target,
-                              silc_sftp_server_status, (void *)id);
+      server->fs->fs->sftp_symlink(server->fs->fs_context, sftp, path, target,
+                                  silc_sftp_server_status, (void *)id);
 
       silc_free(path);
       silc_free(target);
@@ -809,9 +963,16 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
       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->sftp_realpath(server->fs_context, sftp, path,
-                               silc_sftp_server_name, (void *)id);
+      server->fs->fs->sftp_realpath(server->fs->fs_context, sftp, path,
+                                   silc_sftp_server_name, (void *)id);
 
       silc_free(path);
     }
@@ -821,7 +982,7 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
     {
       char *request = NULL;
       unsigned char *data;
-      uint32 data_len;
+      SilcUInt32 data_len;
 
       SILC_LOG_DEBUG(("Extended request"));
 
@@ -841,10 +1002,16 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
        goto failure;
       data_len = buf.len;
 
+      /* 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->sftp_extended(server->fs_context, sftp, 
-                               request, data, data_len,
-                               silc_sftp_server_extended, (void *)id);
+      server->fs->fs->sftp_extended(server->fs->fs_context, sftp, 
+                                   request, data, data_len,
+                                   silc_sftp_server_extended, (void *)id);
 
       silc_free(request);
     }