Ported SFTP library to new util library.
authorPekka Riikonen <priikone@silcnet.org>
Wed, 3 Jan 2007 17:45:58 +0000 (17:45 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Wed, 3 Jan 2007 17:45:58 +0000 (17:45 +0000)
13 files changed:
CHANGES
TODO
configure.ad
distdir/client
lib/Makefile.ad
lib/silcsftp/sftp_client.c
lib/silcsftp/sftp_fs_memory.c
lib/silcsftp/sftp_server.c
lib/silcsftp/sftp_util.c
lib/silcsftp/silcsftp.h
lib/silcsftp/tests/Makefile.am
lib/silcsftp/tests/sftp_client.c
lib/silcsftp/tests/sftp_server.c

diff --git a/CHANGES b/CHANGES
index a650ed1b8c2ae52b239a815fba8fe324d123a6f0..2728fef9af9c4f9afb7f3eae0e1bbfff9ce9af6f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,9 @@ Wed Jan  3 18:06:33 EET 2007  Pekka Riikonen <priikone@silcnet.org>
        * Fixed %p formatting from silc_snprintf.  Affected file is
          lib/silcutil/silcsnprintf.c.
 
+       * Ported SFTP library to new utility library.  Ported also
+         the SFTP testers.  Affected files in lib/silcsftp/.
+
 Tue Jan  2 17:18:46 EET 2007  Pekka Riikonen <priikone@silcnet.org>
 
        * Added lib/silcutil/silcsnprintf.[ch].  Added in addition
diff --git a/TODO b/TODO
index dac81c5aea808ae8af14c878064352d7809e30be..39edc027bd6ec5c8aa15c0f93a72badc3dfa0b57 100644 (file)
--- a/TODO
+++ b/TODO
@@ -76,10 +76,10 @@ lib/silcclient, The Client Library  ***PARTLY DONE****
  o All packet waiting timeout tests and error condition tests.
 
 
-lib/silcsftp
+lib/silcsftp                   ****DONE****
 ============
 
- o Porting to use the new util library.
+ o Porting to use the new util library. (***DONE)
 
 
 lib/silccore/silcpacket.[ch]   ****DONE****
index 5f0141834d31316f5557e74661a21a7768fe0d3c..2dbd9bdd11e15b80dc50ab4b42acea09b014b0a7 100644 (file)
@@ -135,6 +135,8 @@ AC_CHECK_SIZEOF(char, 0)
 AC_SUBST(SILC_SIZEOF_CHAR, $ac_cv_sizeof_char)
 AC_CHECK_SIZEOF(void *, 0)
 AC_SUBST(SILC_SIZEOF_VOID_P, $ac_cv_sizeof_void_p)
+AC_CHECK_TYPES(long long)
+AC_CHECK_TYPES(long double)
 
 # Function to check if compiler flag works
 # Usage: SILC_ADD_CFLAGS(FLAGS, [ACTION-IF-FAILED])
index c6ea8099fb93a8bfd628d3a85ae980311878de45..13f35fefcf47a67b51450cdcf1378a583754e621 100644 (file)
@@ -6,9 +6,6 @@ inherit common
 define SILC_DIST_CLIENT
 define SILC_DIST_CLIENTLIB
 
-# XXX
-undef SILC_DIST_SFTP
-
 pre-hook distdir/pre-run
 post-process-dist-hook distdir/post-process-dist
 post-dist-hook distdir/post-dist
index fbcaca3a6435d9f4c05be09a7617d98f0f5e98eb..b12b9dc44ab57059b2304e5d1ec54d5fa0f4c224 100644 (file)
 
 AUTOMAKE_OPTIONS = 1.0 no-dependencies foreign
 
-#ifdef SILC_DIST_SFTP
-#      silcsftp
-#endif SILC_DIST_SFTP
-
 # SILC Library dirs
 SILCLIB_DIRS =                 \
        contrib         \
@@ -44,6 +40,9 @@ SILCLIB_DIRS =                \
 #ifdef SILC_DIST_HTTP
        silchttp        \
 #endif SILC_DIST_HTTP
+#ifdef SILC_DIST_SFTP
+       silcsftp
+#endif SILC_DIST_SFTP
 #ifdef SILC_DIST_IDCACHE
        silcvcard       \
 #endif SILC_DIST_IDCACHE
index a60437235562fe9baa86484eb4cd634a314cd6f5..7227d33c596e3f043efb0e4489b2140292146f72 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2001 - 2005 Pekka Riikonen
+  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
@@ -25,8 +25,7 @@
 /* Request context. Every request will allocate this context and set
    the correct callback function according the `type' field. */
 typedef struct SilcSFTPRequestStruct {
-  SilcUInt32 id;
-  SilcSFTPPacket type;
+  struct SilcSFTPRequestStruct *next;
   SilcSFTPStatusCallback status;
   SilcSFTPHandleCallback handle;
   SilcSFTPDataCallback data;
@@ -34,17 +33,19 @@ typedef struct SilcSFTPRequestStruct {
   SilcSFTPAttrCallback attr;
   SilcSFTPExtendedCallback extended;
   void *context;
-  struct SilcSFTPRequestStruct *next;
+  SilcUInt32 id;
+  SilcSFTPPacket type;
 } *SilcSFTPRequest;
 
 /* SFTP client context */
 typedef struct {
   SilcStream stream;
   SilcSFTPVersionCallback version;
-  void *version_context;
-  SilcUInt32 id;
+  SilcSFTPErrorCallback error;
+  void *context;
   SilcList requests;
   SilcBuffer packet;
+  SilcUInt32 id;
 } *SilcSFTPClient;
 
 /* File handle */
@@ -54,7 +55,7 @@ struct SilcSFTPHandleStruct {
 };
 
 static void silc_sftp_client_receive_process(SilcSFTP context,
-                                            SilcBuffer buffer)
+                                            SilcBuffer buffer);
 
 /* Creates SilcSFTPHandle and returns pointer to it. The caller must free
    the context. */
@@ -94,7 +95,7 @@ static void silc_sftp_handle_get(SilcSFTPHandle handle,
   *data_len = handle->data_len;
 }
 
-/* General routine to send SFTP packet to the SFTP server. */
+/* Generic routine to send SFTP packet to the SFTP server. */
 
 static void silc_sftp_send_packet(SilcSFTPClient sftp,
                                  SilcSFTPPacket type,
@@ -102,6 +103,7 @@ static void silc_sftp_send_packet(SilcSFTPClient sftp,
 {
   SilcBuffer tmp;
   va_list vp;
+  int ret;
 
   va_start(vp, len);
   tmp = silc_sftp_packet_encode_vp(type, sftp->packet, len, vp);
@@ -114,8 +116,17 @@ static void silc_sftp_send_packet(SilcSFTPClient sftp,
                   silc_buffer_len(sftp->packet));
 
   /* Send the packet */
-  silc_stream_write(sftp->stream, sftp->packet->data,
-                   silc_buffer_len(sftp->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));
+      break;
+    }
+    if (ret <= 0)
+      break;
+    silc_buffer_pull(sftp->packet, ret);
+  }
 
   /* Clear packet */
   silc_buffer_reset(sftp->packet);
@@ -136,7 +147,7 @@ static SilcSFTPRequest silc_sftp_find_request(SilcSFTPClient sftp,
       return req;
   }
 
-  SILC_LOG_DEBUG(("Unknown request ID"));
+  SILC_LOG_DEBUG(("Unknown request ID %d", id));
 
   return NULL;
 }
@@ -302,17 +313,37 @@ static void silc_sftp_call_request(SilcSFTPClient sftp,
   va_end(vp);
 }
 
-/* Handles stream IO */
+/* Handles stream I/O */
 
 static void silc_sftp_client_io(SilcStream stream, SilcStreamStatus status,
                                void *context)
 {
   SilcSFTPClient sftp = context;
+  unsigned char inbuf[30720];
+  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_client_receive_process(context, &packet);
+    break;
 
   case SILC_STREAM_CAN_WRITE:
-    if (!silc_buffer_headlen(&sftp->packet))
+    if (!silc_buffer_headlen(sftp->packet))
       return;
 
     SILC_LOG_DEBUG(("Writing pending data to stream"));
@@ -323,70 +354,25 @@ static void silc_sftp_client_io(SilcStream stream, SilcStreamStatus status,
       ret = silc_stream_write(stream, sftp->packet->data,
                              silc_buffer_len(sftp->packet));
       if (ret == 0) {
-       /* EOS */
-       /* XXX */
+       sftp->error(context, SILC_SFTP_STATUS_EOF, sftp->context);
        silc_buffer_reset(sftp->packet);
        return;
       }
 
-      if (i == -2) {
-       /* Error */
-       /* XXX */
+      if (ret == -2) {
+       sftp->error(context, SILC_SFTP_STATUS_NO_CONNECTION, sftp->context);
        silc_buffer_reset(sftp->packet);
-       return FALSE;
+       return;
       }
 
-      if (ret == -1) {
-       /* Cannot write now, write later. */
-       silc_buffer_pull(sftp->packet, silc_buffer_len(sftp->packet));
+      if (ret == -1)
        return;
-      }
 
       /* Wrote data */
       silc_buffer_pull(sftp->packet, ret);
     }
     break;
 
-  case SILC_STREAM_CAN_READ:
-    SILC_LOG_DEBUG(("Reading data from stream"));
-
-    /* Make sure we have fair amount of free space in inbuf */
-    if (silc_buffer_taillen(&ps->inbuf) < SILC_PACKET_DEFAULT_SIZE)
-      if (!silc_buffer_realloc(&ps->inbuf, silc_buffer_truelen(&ps->inbuf) +
-                              SILC_PACKET_DEFAULT_SIZE * 2))
-       return;
-
-    /* Read data from stream */
-    ret = silc_stream_read(ps->stream, &ps->inbuf.tail,
-                          silc_buffer_taillen(&ps->inbuf));
-
-    if (ret == 0) {
-      /* EOS */
-      SILC_PACKET_CALLBACK_EOS(ps);
-      silc_buffer_reset(&ps->inbuf);
-      return;
-    }
-
-    if (ret == -2) {
-      /* Error */
-      SILC_PACKET_CALLBACK_ERROR(ps, SILC_PACKET_ERR_READ);
-      silc_buffer_reset(&ps->inbuf);
-      return;
-    }
-
-    if (ret == -1) {
-      /* Cannot read now, do it later. */
-      silc_buffer_pull(&ps->inbuf, silc_buffer_len(&ps->inbuf));
-      return;
-    }
-
-    /* Read some data */
-    silc_buffer_pull_tail(&ps->inbuf, ret);
-
-    /* Now process the data */
-    silc_sftp_client_receive_process(sftp);
-    break;
-
   default:
     break;
   }
@@ -395,11 +381,15 @@ static void silc_sftp_client_io(SilcStream stream, SilcStreamStatus status,
 /* Starts SFTP client and returns context for it. */
 
 SilcSFTP silc_sftp_client_start(SilcStream stream,
-                               SilcSFTPVersionCallback callback,
+                               SilcSchedule schedule,
+                               SilcSFTPVersionCallback version_cb,
+                               SilcSFTPErrorCallback error_cb,
                                void *context)
 {
   SilcSFTPClient sftp;
 
+  SILC_LOG_DEBUG(("Starting SFTP client"));
+
   if (!stream)
     return NULL;
 
@@ -407,12 +397,13 @@ SilcSFTP silc_sftp_client_start(SilcStream stream,
   if (!sftp)
     return NULL;
   sftp->stream = stream;
-  sftp->version = callback;
-  sftp->version_context = context;
+  sftp->version = version_cb;
+  sftp->error = error_cb;
+  sftp->context = context;
   silc_list_init(sftp->requests, struct SilcSFTPRequestStruct, next);
 
   /* We handle the stream now */
-  silc_stream_set_notifier(stream, silc_sftp_client_io, sftp);
+  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,
@@ -430,6 +421,7 @@ void silc_sftp_client_shutdown(SilcSFTP context)
 {
   SilcSFTPClient sftp = (SilcSFTPClient)context;
 
+  silc_stream_set_notifier(sftp->stream, NULL, NULL, NULL);
   if (sftp->packet)
     silc_buffer_free(sftp->packet);
   silc_free(sftp);
@@ -448,10 +440,10 @@ void silc_sftp_client_receive_process(SilcSFTP context, SilcBuffer buffer)
   SilcBufferStruct buf;
   SilcUInt32 id;
 
-  SILC_LOG_DEBUG(("Start"));
+  SILC_LOG_DEBUG(("Process SFTP packet"));
 
   /* Parse the packet */
-  type = silc_sftp_packet_decode(packet->buffer, (unsigned char **)&payload,
+  type = silc_sftp_packet_decode(buffer, (unsigned char **)&payload,
                                 &payload_len);
   if (!type)
     return;
@@ -459,6 +451,31 @@ void silc_sftp_client_receive_process(SilcSFTP context, SilcBuffer buffer)
   silc_buffer_set(&buf, (unsigned char *)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;
@@ -470,13 +487,13 @@ void silc_sftp_client_receive_process(SilcSFTP context, SilcBuffer buffer)
                                 SILC_STR_END);
       if (ret < 0) {
        (*sftp->version)((SilcSFTP)sftp, SILC_SFTP_STATUS_FAILURE, 0,
-                        sftp->version_context);
+                        sftp->context);
        break;
       }
 
       /* Call the callback */
       (*sftp->version)((SilcSFTP)sftp, SILC_SFTP_STATUS_OK, version,
-                      sftp->version_context);
+                      sftp->context);
     }
     break;
 
@@ -548,31 +565,6 @@ void silc_sftp_client_receive_process(SilcSFTP context, SilcBuffer buffer)
     }
     break;
 
-  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_NAME:
     {
       SilcUInt32 count;
index 66d393ace550649aa2ce95b3d685320db593b928..d23b7d2a9c26788ffdb6932295620832520d30e0 100644 (file)
@@ -775,7 +775,7 @@ void mem_readdir(void *context, SilcSFTP sftp,
     filesize = sizeof(*entry);
     memset(long_name, 0, sizeof(long_name));
 
-    date = (char *)silc_get_time(entry->created);
+    date = (char *)silc_time_string(entry->created);
     if (strrchr(date, ':'))
       *strrchr(date, ':') = '\0';
 
index de0b52ef9d7eaade18f4a1ac0b4418af93a4d1f6..41e049eee05e1f67580b012c27ac8978715ada82 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2001 - 2004 Pekka Riikonen
+  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
 
 /* SFTP Server context */
 typedef struct {
-  SilcSFTPSendPacketCallback send_packet;
-  void *send_context;
+  SilcStream stream;
   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,
@@ -42,6 +45,7 @@ static void silc_sftp_send_packet(SilcSFTPServer sftp,
 {
   SilcBuffer tmp;
   va_list vp;
+  int ret;
 
   va_start(vp, len);
   tmp = silc_sftp_packet_encode_vp(type, sftp->packet, len, vp);
@@ -50,15 +54,89 @@ static void silc_sftp_send_packet(SilcSFTPServer sftp,
     return;
   sftp->packet = tmp;
 
-  SILC_LOG_HEXDUMP(("SFTP packet to client"), sftp->packet->data,
-                  sftp->packet->len);
+  SILC_LOG_HEXDUMP(("SFTP packet to client"), silc_buffer_data(sftp->packet),
+                  silc_buffer_len(sftp->packet));
 
   /* Send the packet */
-  (*sftp->send_packet)(sftp->packet, sftp->send_context);
+  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));
+      break;
+    }
+    if (ret <= 0)
+      break;
+    silc_buffer_pull(sftp->packet, ret);
+  }
 
   /* Clear packet */
-  sftp->packet->data = sftp->packet->tail = sftp->packet->head;
-  sftp->packet->len = 0;
+  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[30720];
+  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 */
@@ -194,9 +272,10 @@ static void silc_sftp_server_name(SilcSFTP sftp,
     return;
   }
 
-  silc_sftp_send_packet(server, SILC_SFTP_NAME, 4 + namebuf->len,
+  silc_sftp_send_packet(server, SILC_SFTP_NAME, 4 + silc_buffer_len(namebuf),
                        SILC_STR_UI_INT(id),
-                       SILC_STR_UI_XNSTRING(namebuf->data, namebuf->len),
+                       SILC_STR_DATA(silc_buffer_data(namebuf),
+                                     silc_buffer_len(namebuf)),
                        SILC_STR_END);
 }
 
@@ -225,9 +304,10 @@ static void silc_sftp_server_attr(SilcSFTP sftp,
     return;
   }
 
-  silc_sftp_send_packet(server, SILC_SFTP_ATTRS, 4 + attr_buf->len,
+  silc_sftp_send_packet(server, SILC_SFTP_ATTRS, 4 + silc_buffer_len(attr_buf),
                        SILC_STR_UI_INT(id),
-                       SILC_STR_UI_XNSTRING(attr_buf->data, attr_buf->len),
+                       SILC_STR_DATA(silc_buffer_data(attr_buf),
+                                     silc_buffer_len(attr_buf)),
                        SILC_STR_END);
 
   silc_buffer_free(attr_buf);
@@ -263,8 +343,10 @@ static void silc_sftp_server_extended(SilcSFTP sftp,
    by the library when it needs to send a packet. The `fs' is the
    structure containing filesystem access callbacks. */
 
-SilcSFTP silc_sftp_server_start(SilcSFTPSendPacketCallback send_packet,
-                               void *send_context,
+SilcSFTP silc_sftp_server_start(SilcStream stream,
+                               SilcSchedule schedule,
+                               SilcSFTPErrorCallback error_cb,
+                               void *context,
                                SilcSFTPFilesystem fs)
 {
   SilcSFTPServer server;
@@ -272,10 +354,14 @@ SilcSFTP silc_sftp_server_start(SilcSFTPSendPacketCallback send_packet,
   server = silc_calloc(1, sizeof(*server));
   if (!server)
     return NULL;
-  server->send_packet = send_packet;
-  server->send_context = send_context;
+  server->stream = stream;
+  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;
@@ -313,9 +399,7 @@ void silc_sftp_server_set_monitor(SilcSFTP sftp,
 /* XXX Some day this will go away and we have automatic receive callbacks
    for SilcSocketConnection API or SilcPacketContext API. */
 
-void silc_sftp_server_receive_process(SilcSFTP sftp,
-                                     SilcSocketConnection sock,
-                                     SilcPacketContext *packet)
+static void silc_sftp_server_receive_process(SilcSFTP sftp, SilcBuffer buffer)
 {
   SilcSFTPServer server = (SilcSFTPServer)sftp;
   SilcSFTPPacket type;
@@ -332,7 +416,7 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
   SILC_LOG_DEBUG(("Start"));
 
   /* Parse the packet */
-  type = silc_sftp_packet_decode(packet->buffer, (unsigned char **)&payload,
+  type = silc_sftp_packet_decode(buffer, (unsigned char **)&payload,
                                 &payload_len);
   if (!type)
     return;
@@ -1017,11 +1101,11 @@ void silc_sftp_server_receive_process(SilcSFTP sftp,
       data_len = 8 + strlen(request);
       silc_buffer_pull(&buf, data_len);
       ret = silc_buffer_unformat(&buf,
-                                SILC_STR_UI_XNSTRING(&data, buf.len),
+                                SILC_STR_DATA(&data, silc_buffer_len(&buf)),
                                 SILC_STR_END);
       if (ret < 0)
        goto failure;
-      data_len = buf.len;
+      data_len = silc_buffer_len(&buf);
 
       /* Call monitor */
       if (server->monitors & SILC_SFTP_MONITOR_EXTENDED && server->monitor) {
index b3f79d5a87d978f8f69267714e46960c69d1a719..6aa40dbe9aff2dd28db61a40ac91df48ac0442ad 100644 (file)
@@ -1,10 +1,10 @@
 /*
 
-  sftp_util.c 
+  sftp_util.c
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2001 - 2002 Pekka Riikonen
+  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
@@ -29,7 +29,7 @@
    to that buffer instead of allocating new one.  If the new data cannot
    fit to `packet_buf' will be reallocated. */
 
-SilcBuffer silc_sftp_packet_encode(SilcSFTPPacket packet, 
+SilcBuffer silc_sftp_packet_encode(SilcSFTPPacket packet,
                                   SilcBuffer packet_buf, SilcUInt32 len, ...)
 {
   SilcBuffer buffer;
@@ -45,8 +45,8 @@ SilcBuffer silc_sftp_packet_encode(SilcSFTPPacket packet,
 /* Same as silc_sftp_packet_encode but takes the variable argument list
    pointer as argument. */
 
-SilcBuffer silc_sftp_packet_encode_vp(SilcSFTPPacket packet, 
-                                     SilcBuffer packet_buf, SilcUInt32 len, 
+SilcBuffer silc_sftp_packet_encode_vp(SilcSFTPPacket packet,
+                                     SilcBuffer packet_buf, SilcUInt32 len,
                                      va_list vp)
 {
   SilcBuffer buffer;
@@ -54,7 +54,7 @@ SilcBuffer silc_sftp_packet_encode_vp(SilcSFTPPacket packet,
   int ret;
 
   if (packet_buf) {
-    if (packet_buf->truelen < 4 + 1 + len) {
+    if (silc_buffer_truelen(packet_buf) < 4 + 1 + len) {
       packet_buf = silc_buffer_realloc(packet_buf, 4 + 1 + len);
       if (!packet_buf)
        return NULL;
@@ -69,8 +69,8 @@ SilcBuffer silc_sftp_packet_encode_vp(SilcSFTPPacket packet,
     dyn = TRUE;
   }
 
-  silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
-  silc_buffer_format(buffer, 
+  silc_buffer_pull_tail(buffer, 4 + 1 + len);
+  silc_buffer_format(buffer,
                     SILC_STR_UI_INT(len),
                     SILC_STR_UI_CHAR(packet),
                     SILC_STR_END);
@@ -110,11 +110,11 @@ SilcSFTPPacket silc_sftp_packet_decode(SilcBuffer packet,
   if (type < SILC_SFTP_INIT || type > SILC_SFTP_EXTENDED_REPLY)
     return 0;
 
-  if (len > (packet->len - 5))
+  if (len > (silc_buffer_len(packet) - 5))
     return 0;
 
   silc_buffer_pull(packet, 5);
-  ret = silc_buffer_unformat(packet, 
+  ret = silc_buffer_unformat(packet,
                             SILC_STR_UI_XNSTRING(payload, len),
                             SILC_STR_END);
   if (ret < 0)
@@ -148,8 +148,8 @@ SilcBuffer silc_sftp_attr_encode(SilcSFTPAttributes attr)
     len += 4;
     for (i = 0; i < attr->extended_count; i++) {
       len += 8;
-      len += attr->extended_type[i]->len;
-      len += attr->extended_data[i]->len;
+      len += silc_buffer_len(attr->extended_type[i]);
+      len += silc_buffer_len(attr->extended_data[i]);
     }
   }
 
@@ -157,57 +157,58 @@ SilcBuffer silc_sftp_attr_encode(SilcSFTPAttributes attr)
   if (!buffer)
     return NULL;
 
-  silc_buffer_format(buffer, 
-                    SILC_STR_UI_INT(attr->flags), 
+  silc_buffer_format(buffer,
+                    SILC_STR_UI_INT(attr->flags),
                     SILC_STR_END);
   silc_buffer_pull(buffer, 4);
 
   if (attr->flags & SILC_SFTP_ATTR_SIZE) {
-    silc_buffer_format(buffer, 
-                      SILC_STR_UI_INT64(attr->size), 
+    silc_buffer_format(buffer,
+                      SILC_STR_UI_INT64(attr->size),
                       SILC_STR_END);
     silc_buffer_pull(buffer, 8);
   }
 
   if (attr->flags & SILC_SFTP_ATTR_UIDGID) {
-    silc_buffer_format(buffer, 
-                      SILC_STR_UI_INT(attr->uid), 
-                      SILC_STR_UI_INT(attr->gid), 
+    silc_buffer_format(buffer,
+                      SILC_STR_UI_INT(attr->uid),
+                      SILC_STR_UI_INT(attr->gid),
                       SILC_STR_END);
     silc_buffer_pull(buffer, 8);
   }
 
   if (attr->flags & SILC_SFTP_ATTR_PERMISSIONS) {
-    silc_buffer_format(buffer, 
-                      SILC_STR_UI_INT(attr->permissions), 
+    silc_buffer_format(buffer,
+                      SILC_STR_UI_INT(attr->permissions),
                       SILC_STR_END);
     silc_buffer_pull(buffer, 4);
   }
 
   if (attr->flags & SILC_SFTP_ATTR_ACMODTIME) {
-    silc_buffer_format(buffer, 
-                      SILC_STR_UI_INT(attr->atime), 
-                      SILC_STR_UI_INT(attr->mtime), 
+    silc_buffer_format(buffer,
+                      SILC_STR_UI_INT(attr->atime),
+                      SILC_STR_UI_INT(attr->mtime),
                       SILC_STR_END);
     silc_buffer_pull(buffer, 8);
   }
 
   if (attr->flags & SILC_SFTP_ATTR_EXTENDED) {
-    silc_buffer_format(buffer, 
-                      SILC_STR_UI_INT(attr->extended_count), 
+    silc_buffer_format(buffer,
+                      SILC_STR_UI_INT(attr->extended_count),
                       SILC_STR_END);
     silc_buffer_pull(buffer, 4);
 
     for (i = 0; i < attr->extended_count; i++) {
-      ret = 
-       silc_buffer_format(buffer, 
-                          SILC_STR_UI_INT(attr->extended_type[i]->len),
-                          SILC_STR_UI_XNSTRING(attr->extended_type[i]->data,
-                                               attr->extended_type[i]->len),
-                          SILC_STR_UI_INT(attr->extended_data[i]->len),
-                          SILC_STR_UI_XNSTRING(attr->extended_data[i]->data,
-                                               attr->extended_data[i]->len),
-                          SILC_STR_END);
+      ret =
+       silc_buffer_format(
+                  buffer,
+                  SILC_STR_UI_INT(silc_buffer_len(attr->extended_type[i])),
+                  SILC_STR_DATA(silc_buffer_data(attr->extended_type[i]),
+                                silc_buffer_len(attr->extended_type[i])),
+                  SILC_STR_UI_INT(silc_buffer_len(attr->extended_data[i])),
+                  SILC_STR_DATA(silc_buffer_data(attr->extended_data[i]),
+                                silc_buffer_len(attr->extended_data[i])),
+                  SILC_STR_END);
       silc_buffer_pull(buffer, ret);
     }
   }
@@ -228,16 +229,16 @@ SilcSFTPAttributes silc_sftp_attr_decode(SilcBuffer buffer)
   if (!attr)
     return NULL;
 
-  if (silc_buffer_unformat(buffer, 
-                          SILC_STR_UI_INT(&attr->flags), 
+  if (silc_buffer_unformat(buffer,
+                          SILC_STR_UI_INT(&attr->flags),
                           SILC_STR_END) < 0)
     goto out;
 
   silc_buffer_pull(buffer, 4);
 
   if (attr->flags & SILC_SFTP_ATTR_SIZE) {
-    if (silc_buffer_unformat(buffer, 
-                            SILC_STR_UI_INT64(&attr->size), 
+    if (silc_buffer_unformat(buffer,
+                            SILC_STR_UI_INT64(&attr->size),
                             SILC_STR_END) < 0)
       goto out;
 
@@ -245,9 +246,9 @@ SilcSFTPAttributes silc_sftp_attr_decode(SilcBuffer buffer)
   }
 
   if (attr->flags & SILC_SFTP_ATTR_UIDGID) {
-    if (silc_buffer_unformat(buffer, 
-                            SILC_STR_UI_INT(&attr->uid), 
-                            SILC_STR_UI_INT(&attr->gid), 
+    if (silc_buffer_unformat(buffer,
+                            SILC_STR_UI_INT(&attr->uid),
+                            SILC_STR_UI_INT(&attr->gid),
                             SILC_STR_END) < 0)
       goto out;
 
@@ -255,8 +256,8 @@ SilcSFTPAttributes silc_sftp_attr_decode(SilcBuffer buffer)
   }
 
   if (attr->flags & SILC_SFTP_ATTR_PERMISSIONS) {
-    if (silc_buffer_unformat(buffer, 
-                            SILC_STR_UI_INT(&attr->permissions), 
+    if (silc_buffer_unformat(buffer,
+                            SILC_STR_UI_INT(&attr->permissions),
                             SILC_STR_END) < 0)
       goto out;
 
@@ -264,9 +265,9 @@ SilcSFTPAttributes silc_sftp_attr_decode(SilcBuffer buffer)
   }
 
   if (attr->flags & SILC_SFTP_ATTR_ACMODTIME) {
-    if (silc_buffer_unformat(buffer, 
-                            SILC_STR_UI_INT(&attr->atime), 
-                            SILC_STR_UI_INT(&attr->mtime), 
+    if (silc_buffer_unformat(buffer,
+                            SILC_STR_UI_INT(&attr->atime),
+                            SILC_STR_UI_INT(&attr->mtime),
                             SILC_STR_END) < 0)
       goto out;
 
@@ -276,16 +277,16 @@ SilcSFTPAttributes silc_sftp_attr_decode(SilcBuffer buffer)
   if (attr->flags & SILC_SFTP_ATTR_EXTENDED) {
     int i;
 
-    if (silc_buffer_unformat(buffer, 
-                            SILC_STR_UI_INT(&attr->extended_count), 
+    if (silc_buffer_unformat(buffer,
+                            SILC_STR_UI_INT(&attr->extended_count),
                             SILC_STR_END) < 0)
       goto out;
 
     silc_buffer_pull(buffer, 4);
 
-    attr->extended_type = silc_calloc(attr->extended_count, 
+    attr->extended_type = silc_calloc(attr->extended_count,
                                      sizeof(*attr->extended_type));
-    attr->extended_data = silc_calloc(attr->extended_count, 
+    attr->extended_data = silc_calloc(attr->extended_count,
                                      sizeof(*attr->extended_data));
     if (!attr->extended_type || !attr->extended_data)
       return NULL;
@@ -294,7 +295,7 @@ SilcSFTPAttributes silc_sftp_attr_decode(SilcBuffer buffer)
       unsigned char *tmp, *tmp2;
       SilcUInt32 tmp_len, tmp2_len;
 
-      if (silc_buffer_unformat(buffer, 
+      if (silc_buffer_unformat(buffer,
                               SILC_STR_UI32_NSTRING(&tmp, &tmp_len),
                               SILC_STR_UI32_NSTRING(&tmp2, &tmp2_len),
                               SILC_STR_END) < 0)
@@ -340,7 +341,7 @@ void silc_sftp_name_add(SilcSFTPName name, const char *short_name,
 {
   name->filename = silc_realloc(name->filename, sizeof(*name->filename) *
                                (name->count + 1));
-  name->long_filename = silc_realloc(name->long_filename, 
+  name->long_filename = silc_realloc(name->long_filename,
                                     sizeof(*name->long_filename) *
                                     (name->count + 1));
   name->attrs = silc_realloc(name->attrs, sizeof(*name->attrs) *
@@ -354,7 +355,7 @@ void silc_sftp_name_add(SilcSFTPName name, const char *short_name,
   name->count++;
 }
 
-/* Encodes the SilcSFTPName to a buffer and returns the allocated buffer. 
+/* Encodes the SilcSFTPName to a buffer and returns the allocated buffer.
    The caller must free the buffer. */
 
 SilcBuffer silc_sftp_name_encode(SilcSFTPName name)
@@ -372,13 +373,13 @@ SilcBuffer silc_sftp_name_encode(SilcSFTPName name)
     attr_buf[i] = silc_sftp_attr_encode(name->attrs[i]);
     if (!attr_buf[i])
       return NULL;
-    len += attr_buf[i]->len;
+    len += silc_buffer_len(attr_buf[i]);
   }
 
   buffer = silc_buffer_alloc(len);
   if (!buffer)
     return NULL;
-  silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
+  silc_buffer_end(buffer);
 
   silc_buffer_format(buffer,
                     SILC_STR_UI_INT(name->count),
@@ -392,8 +393,8 @@ SilcBuffer silc_sftp_name_encode(SilcSFTPName name)
                         SILC_STR_UI32_STRING(name->filename[i]),
                         SILC_STR_UI_INT(strlen(name->long_filename[i])),
                         SILC_STR_UI32_STRING(name->long_filename[i]),
-                        SILC_STR_UI_XNSTRING(attr_buf[i]->data,
-                                             attr_buf[i]->len),
+                        SILC_STR_DATA(silc_buffer_data(attr_buf[i]),
+                                      silc_buffer_len(attr_buf[i])),
                         SILC_STR_END);
 
     silc_buffer_pull(buffer, len);
@@ -429,7 +430,7 @@ SilcSFTPName silc_sftp_name_decode(SilcUInt32 count, SilcBuffer buffer)
   name->count = count;
 
   for (i = 0; i < count; i++) {
-    ret = 
+    ret =
       silc_buffer_unformat(buffer,
                           SILC_STR_UI32_STRING_ALLOC(&name->filename[i]),
                           SILC_STR_UI32_STRING_ALLOC(&name->long_filename[i]),
index b7036a95fe47cf9875c734c8599a422a2500232f..87ee70397ce1dc9a849a43bad1fe6855d0c215ae 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2001 - 2005 Pekka Riikonen
+  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
  *
  * DESCRIPTION
  *
- *    SILC SFTP Interface is the implementation of the Secure File Transfer
- *    Protocol.  The interface defines the SFTP client and the SFTP server.
- *    The SFTP is the mandatory file transfer protocol in the SILC protocol.
- *    The SFTP server implementation is filesystem independent and generic
- *    interface is defined to represent filesystem access.
+ * SILC SFTP Interface is the implementation of the Secure File Transfer
+ * Protocol (or SSH File Transfer Protocol).  The interface defines the SFTP
+ * client and the SFTP server.  The SFTP is the mandatory file transfer
+ * protocol in the SILC protocol, and when used in SILC the SFTP packets are
+ * encapsulated into SILC packets.  The SFTP server implementation is
+ * filesystem independent and generic interface is defined to represent
+ * filesystem access.
  *
- *    The SilcSFTP context is the actual SFTP client or SFTP server, and
- *    each SFTP session (associated to a socket connection) must create
- *    own SFTP context.
+ * The SilcSFTP context is the actual SFTP client or SFTP server, and each
+ * SFTP session should create its own SFTP context.
+ *
+ * The SILC SFTP library is a generic SFTP implementation and not directly
+ * related to either SILC or SSH.  It could be used for any general purpose
+ * SFTP application.
  *
  ***/
 
@@ -92,7 +97,7 @@ typedef enum {
   SILC_SFTP_STATUS_PERMISSION_DENIED   = 3,  /* No sufficient permissions */
   SILC_SFTP_STATUS_FAILURE             = 4,  /* Operation failed */
   SILC_SFTP_STATUS_BAD_MESSAGE         = 5,  /* Bad message received */
-  SILC_SFTP_STATUS_NO_CONNECTION       = 6,  /* No connection to server */
+  SILC_SFTP_STATUS_NO_CONNECTION       = 6,  /* No connection to remote */
   SILC_SFTP_STATUS_CONNECTION_LOST     = 7,  /* Connection lost to server */
   SILC_SFTP_STATUS_OP_UNSUPPORTED      = 8,  /* Operation unsupported */
   SILC_SFTP_STATUS_INVALID_HANDLE      = 9,  /* Invalid file handle */
@@ -205,22 +210,6 @@ typedef struct {
  ***/
 typedef struct SilcSFTPHandleStruct *SilcSFTPHandle;
 
-/****f* silcsftp/SilcSFTPAPI/SilcSFTPSendPacketCallback
- *
- * SYNOPSIS
- *
- *    typedef void (*SilcSFTPSendPacketCallback)(SilcBuffer packet,
- *                                               void *context);
- *
- * DESCRIPTION
- *
- *    Packet sending callback. The caller of this interface will provide this
- *    function for the library. The libary will call this function everytime
- *    it needs to send a packet to the remote host.
- *
- ***/
-typedef void (*SilcSFTPSendPacketCallback)(SilcBuffer packet, void *context);
-
 /****f* silcsftp/SilcSFTPAPI/SilcSFTPVersionCallback
  *
  * SYNOPSIS
@@ -242,6 +231,25 @@ typedef void (*SilcSFTPVersionCallback)(SilcSFTP sftp,
                                        SilcSFTPVersion version,
                                        void *context);
 
+/****f* silcsftp/SilcSFTPAPI/SilcSFTPErrorCallback
+ *
+ * SYNOPSIS
+ *
+ *    typedef void (*SilcSFTPErrorCallback)(SilcSFTP sftp,
+ *                                          SilcSFTPStatus status,
+ *                                          void *context);
+ *
+ * DESCRIPTION
+ *
+ *    Error callback is called if a connection error occurs during SFTP
+ *    session.  If the connection or stream is closed this callback is
+ *    called.  Other errors are delivered in other callbacks.
+ *
+ ***/
+typedef void (*SilcSFTPErrorCallback)(SilcSFTP sftp,
+                                     SilcSFTPStatus status,
+                                     void *context);
+
 /****f* silcsftp/SilcSFTPAPI/SilcSFTPStatusCallback
  *
  * SYNOPSIS
@@ -387,7 +395,9 @@ typedef void (*SilcSFTPExtendedCallback)(SilcSFTP sftp,
  * SYNOPSIS
  *
  *    SilcSFTP silc_sftp_client_start(SilcStream stream,
- *                                    SilcSFTPVersionCallback callback,
+ *                                    SilcSchedule schedule,
+ *                                    SilcSFTPVersionCallback version_cb,
+ *                                    SilcSFTPErrorCallback error_cb,
  *                                    void *context);
  *
  * DESCRIPTION
@@ -397,11 +407,13 @@ typedef void (*SilcSFTPExtendedCallback)(SilcSFTP sftp,
  *    been started and server has returned the version of the protocol.  The
  *    SFTP client context is returned in the callback too.  This returns the
  *    allocated SFTP client context or NULL on error.  The `stream' will be
- *    used to read from and write to the SFTP packets.
+ *    used to read and write the SFTP packets.
  *
  ***/
 SilcSFTP silc_sftp_client_start(SilcStream stream,
-                               SilcSFTPVersionCallback callback,
+                               SilcSchedule schedule,
+                               SilcSFTPVersionCallback version_cb,
+                               SilcSFTPErrorCallback error_cb,
                                void *context);
 
 /****f* silcsftp/SilcSFTPAPI/silc_sftp_client_shutdown
@@ -846,8 +858,10 @@ void silc_sftp_extended(SilcSFTP sftp,
  *
  * SYNOPSIS
  *
- *    SilcSFTP silc_sftp_server_start(SilcSFTPSendPacketCallback send_packet,
- *                                    void *send_context,
+ *    SilcSFTP silc_sftp_server_start(SilcStream stream,
+ *                                    SilcSchedule schedule,
+ *                                    SilcSFTPErrorCallback error_cb,
+ *                                    void *context,
  *                                    SilcSFTPFilesystem fs);
  *
  * DESCRIPTION
@@ -859,8 +873,10 @@ void silc_sftp_extended(SilcSFTP sftp,
  *    should start its own server by calling this function.
  *
  ***/
-SilcSFTP silc_sftp_server_start(SilcSFTPSendPacketCallback send_packet,
-                               void *send_context,
+SilcSFTP silc_sftp_server_start(SilcStream stream,
+                               SilcSchedule schedule,
+                               SilcSFTPErrorCallback error_cb,
+                               void *context,
                                SilcSFTPFilesystem fs);
 
 /****f* silcsftp/SilcSFTPAPI/silc_sftp_server_shutdown
index 4df05655af413da49d385c8ca7e3f227bd598340..6dbf79a8ada7370a5f4c87228e0e4255cd4c6d6a 100644 (file)
@@ -18,7 +18,7 @@
 
 AUTOMAKE_OPTIONS = 1.0 no-dependencies foreign
 
-bin_PROGRAMS = sftp_server sftp_client
+bin_PROGRAMS = sftp_client sftp_server 
 sftp_server_SOURCES = sftp_server.c
 sftp_client_SOURCES = sftp_client.c
 
index e181403d0fba3134dced0b5b397ada47d1098020..71ec8982979eaf6def1425d3858a438db8a8f53e 100644 (file)
@@ -1,10 +1,10 @@
 /*
 
-  sftp_client.c 
+  sftp_client.c
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2001 Pekka Riikonen
+  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
@@ -34,7 +34,7 @@
 
 typedef struct {
   SilcSchedule schedule;
-  SilcSocketConnection sock;
+  SilcStream stream;
   SilcSFTP sftp;
 } *Client;
 
@@ -55,81 +55,6 @@ static void sftp_data(SilcSFTP sftp, SilcSFTPStatus status,
                      void *context);
 static void end_test(void);
 
-static void send_packet(SilcBuffer packet, void *context)
-{
-  Client client = (Client)context;
-  SilcSocketConnection sock = client->sock;
-  SilcPacketContext packetdata;
-  const SilcBufferStruct p;
-  int ret;
-
-  memset(&packetdata, 0, sizeof(packetdata));
-  packetdata.type = SILC_PACKET_FTP;
-  packetdata.truelen = packet->len + SILC_PACKET_HEADER_LEN;
-  SILC_PACKET_PADLEN(packetdata.truelen, 0, packetdata.padlen);
-  silc_packet_assemble(&packetdata, NULL, NULL, NULL, sock,
-                      packet->data, packet->len, (const SilcBuffer)&p);
-  ret = silc_packet_send(sock, TRUE);
-  if (ret != -2)
-    return;
-  
-  silc_schedule_set_listen_fd(client->schedule, sock->sock, 
-                             (SILC_TASK_READ | SILC_TASK_WRITE), FALSE);
-  SILC_SET_OUTBUF_PENDING(sock);
-}
-
-static bool packet_parse(SilcPacketParserContext *parser, void *context)
-{
-  Client client = (Client)parser->context;
-  SilcSocketConnection sock = parser->sock;
-  SilcPacketContext *packet = parser->packet;
-  int ret;
-  
-  ret = silc_packet_parse(packet, NULL);
-  assert(packet->type == SILC_PACKET_FTP);
-
-  silc_sftp_client_receive_process(client->sftp, sock, packet);
-    
-  return TRUE;
-}
-
-SILC_TASK_CALLBACK(packet_process)
-{
-  Client client = (Client)context;
-  SilcSocketConnection sock = client->sock;
-  int ret;
-
-  if (type == SILC_TASK_WRITE) {
-    if (sock->outbuf->data - sock->outbuf->head)
-      silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head);
-
-    ret = silc_packet_send(sock, TRUE);
-    if (ret < 0)
-      return;
-      
-    silc_schedule_set_listen_fd(client->schedule, fd, SILC_TASK_READ, FALSE);
-    SILC_UNSET_OUTBUF_PENDING(sock);
-    silc_buffer_clear(sock->outbuf);
-    return;
-    
-  }
-
-  if (type == SILC_TASK_READ) {
-    ret = silc_packet_receive(sock);
-    if (ret < 0)
-      return;
-  
-    if (ret == 0) {
-      silc_net_close_connection(sock->sock);
-      silc_socket_free(sock);
-      exit(0);
-    }
-
-    silc_packet_receive_process(sock, FALSE, NULL, NULL, 0, 
-                               packet_parse, client);
-  }
-}
-
 static void sftp_status(SilcSFTP sftp, SilcSFTPStatus status,
                        const char *message, const char *lang_tag,
                        void *context)
@@ -150,9 +75,8 @@ static void sftp_attr(SilcSFTP sftp, SilcSFTPStatus status,
                      const SilcSFTPAttributes attrs, void *context)
 {
   SilcSFTPHandle handle = (SilcSFTPHandle)context;
-  int debug = silc_debug;
   int i;
-  
+
   fprintf(stderr, "Status %d\n", status);
   if (status != SILC_SFTP_STATUS_OK) {
     SILC_LOG_DEBUG(("Error status"));
@@ -160,9 +84,7 @@ static void sftp_attr(SilcSFTP sftp, SilcSFTPStatus status,
     end_test();
     return;
   }
-    
-  if (!debug)
-    silc_debug = 1;
+
 
   SILC_LOG_DEBUG(("Attr.flags: %d", attrs->flags));
   SILC_LOG_DEBUG(("Attr.size: %lu", attrs->size));
@@ -175,21 +97,19 @@ static void sftp_attr(SilcSFTP sftp, SilcSFTPStatus status,
   for (i = 0; i < attrs->extended_count; i++) {
     SILC_LOG_HEXDUMP(("Attr.extended_type[i]:", i),
                     attrs->extended_type[i]->data,
-                    attrs->extended_type[i]->len);
+                    silc_buffer_len(attrs->extended_type[i]));
     SILC_LOG_HEXDUMP(("Attr.extended_data[i]:", i),
                     attrs->extended_data[i]->data,
-                    attrs->extended_data[i]->len);
+                    silc_buffer_len(attrs->extended_data[i]));
   }
-    
-  silc_debug = debug;
 
   if (!file) {
-    fprintf(stderr, "Closing file\n"); 
+    fprintf(stderr, "Closing file\n");
     silc_sftp_close(sftp, handle, sftp_status, context);
     return;
   }
-  
-  fprintf(stderr, "LStatting file %s\n", file); 
+
+  fprintf(stderr, "LStatting file %s\n", file);
   silc_sftp_lstat(sftp, file, sftp_attr, context);
   file = NULL;
 }
@@ -199,7 +119,6 @@ static void sftp_data(SilcSFTP sftp, SilcSFTPStatus status,
                      void *context)
 {
   SilcSFTPHandle handle = (SilcSFTPHandle)context;
-  int debug = silc_debug;
 
   if (status != SILC_SFTP_STATUS_OK) {
     SilcSFTPAttributesStruct attrs;
@@ -212,13 +131,13 @@ static void sftp_data(SilcSFTP sftp, SilcSFTPStatus status,
       end_test();
       return;
     }
-    
+
     if (!strcmp(file, "/sftp/sftp_server.c")) {
-      fprintf(stderr, "FStatting file handle %s\n", file); 
+      fprintf(stderr, "FStatting file handle %s\n", file);
       silc_sftp_fstat(sftp, handle, sftp_attr, context);
       return;
     }
-      
+
     /* Open another file */
     opendir = FALSE;
     memset(&attrs, 0, sizeof(attrs));
@@ -230,10 +149,7 @@ static void sftp_data(SilcSFTP sftp, SilcSFTPStatus status,
     return;
   }
 
-  if (!debug)
-    silc_debug = 1;
   SILC_LOG_HEXDUMP(("data"), (unsigned char *)data, data_len);
-  silc_debug = debug;
 
   offset += data_len;
 
@@ -257,7 +173,7 @@ static void sftp_name(SilcSFTP sftp, SilcSFTPStatus status,
     end_test();
     return;
   }
-  
+
   fprintf(stderr, "Directory: %s\n", dir);
   for (i = 0; i < name->count; i++) {
     fprintf(stderr, "%s\n", name->long_filename[i]);
@@ -300,7 +216,7 @@ static void sftp_handle(SilcSFTP sftp, SilcSFTPStatus status,
     end_test();
     return;
   }
-  
+
   if (opendir) {
     fprintf(stderr, "Reading %s\n", dir);
     /* Readdir */
@@ -335,35 +251,58 @@ static void sftp_version(SilcSFTP sftp, SilcSFTPStatus status,
   silc_sftp_opendir(sftp, dir, sftp_handle, client);
 }
 
+static void sftp_error(SilcSFTP sftp, SilcSFTPStatus status,
+                      void *context)
+{
+  Client client = context;
+  SILC_LOG_DEBUG(("Error %d", status));
+  silc_stream_destroy(client->stream);
+  success = FALSE;
+  end_test();
+}
+
+static void connect_callback(SilcNetStatus status, SilcStream stream,
+                            void *context)
+{
+  Client client = context;
+
+  if (!stream) {
+    SILC_LOG_DEBUG(("Connect error"));
+    success = FALSE;
+    end_test();
+  }
+
+  /* Start SFTP session */
+  client->stream = stream;
+  client->sftp = silc_sftp_client_start(stream, client->schedule, sftp_version,
+                                       sftp_error, client);
+  if (!client->sftp) {
+    success = FALSE;
+    end_test();
+  }
+}
+
 int main(int argc, char **argv)
 {
   Client client = silc_calloc(1, sizeof(*client));
-  int sock;
 
   gclient = client;
 
-  if (argc > 1 && !strcmp(argv[1], "-d")) {
-    silc_debug = 1;
-    silc_debug_hexdump = 1;
-    silc_log_set_debug_string("*sftp*");
+  if (argc > 1) {
+    if (!strcmp(argv[1], "-d"))
+      silc_log_debug(TRUE);
+    if (argc > 2 && !strcmp(argv[2], "-x"))
+      silc_log_debug_hexdump(TRUE);
+    silc_log_set_debug_string("*");
   }
 
-  client->schedule = silc_schedule_init(100, NULL);
+  client->schedule = silc_schedule_init(0, NULL);
   if (!client->schedule)
     return -1;
 
   /* Connecto to server */
-  sock = silc_net_create_connection(NULL, 5000, "127.0.0.1");
-  if (sock < 0)
-    return -1;
-  silc_socket_alloc(sock, 0, NULL, &client->sock);
-  silc_schedule_task_add(client->schedule, sock,
-                        packet_process, client, 0, 0,
-                        SILC_TASK_GENERIC, SILC_TASK_PRI_NORMAL);
-
-  /* Start SFTP session */
-  client->sftp = silc_sftp_client_start(send_packet, client,
-                                       sftp_version, client);
+  silc_net_tcp_connect(NULL, "127.0.0.1", 5000, client->schedule,
+                      connect_callback, client);
 
   silc_schedule(client->schedule);
   return 0;
index 9510e53e24776dcd58dbcb636b62d1a475e31ce5..294c293340770e76dbb719e84eb0897cd433cc10 100644 (file)
@@ -1,10 +1,10 @@
 /*
 
-  sprp_server.c 
+  sprp_server.c
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2001 Pekka Riikonen
+  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
 #include "silc.h"
 #include "silcsftp.h"
 
-typedef struct {
-  SilcSocketConnection sock;
-  void *server;
+typedef struct ServerSessionStruct {
+  SilcStream stream;
+  SilcSFTP sftp;
 } *ServerSession;
 
 typedef struct {
   SilcSchedule schedule;
-  int sock;
+  SilcNetListener listener;
   SilcSFTPFilesystem fs;
-  ServerSession sessions[100];
-  SilcSFTP sftp[100];
 } *Server;
 
-static void send_packet(SilcBuffer packet, void *context)
+static void error_cb(SilcSFTP sftp, SilcSFTPStatus status, void *context)
 {
   ServerSession session = context;
-  Server server = session->server;
-  SilcPacketContext packetdata;
-  const SilcBufferStruct p;
-  int ret;
-
-  memset(&packetdata, 0, sizeof(packetdata));
-  packetdata.type = SILC_PACKET_FTP;
-  packetdata.truelen = packet->len + SILC_PACKET_HEADER_LEN;
-  SILC_PACKET_PADLEN(packetdata.truelen, 0, packetdata.padlen);
-  silc_packet_assemble(&packetdata, NULL, NULL, NULL, session->sock,
-                      packet->data, packet->len, (const SilcBuffer)&p);
-  ret = silc_packet_send(session->sock, TRUE);
-  if (ret != -2)
-    return;
 
-  silc_schedule_set_listen_fd(server->schedule, session->sock->sock, 
-                             (SILC_TASK_READ | SILC_TASK_WRITE), FALSE);
-  SILC_SET_OUTBUF_PENDING(session->sock);
-}
-
-static bool packet_parse(SilcPacketParserContext *parser, void *context)
-{
-  Server server = (Server)parser->context;
-  SilcSocketConnection sock = parser->sock;
-  SilcPacketContext *packet = parser->packet;
-  int ret;
-  
-  ret = silc_packet_parse(packet, NULL);
-  assert(packet->type == SILC_PACKET_FTP);
-
-  silc_sftp_server_receive_process(server->sftp[sock->sock], sock, packet);
+  if (status == SILC_SFTP_STATUS_EOF) {
+    SILC_LOG_DEBUG(("Eof"));
+    silc_stream_destroy(session->stream);
+    silc_free(session);
+  }
 
-  return TRUE;
+  SILC_LOG_DEBUG(("Error %d", status));
 }
 
-SILC_TASK_CALLBACK(packet_process)
+static void net_callback(SilcNetStatus status, SilcStream stream,
+                        void *context)
 {
   Server server = context;
-  ServerSession session = server->sessions[fd];
-  SilcSocketConnection sock;
-  int ret;
-
-  if (!session)
-    return;
-  sock = session->sock;
-
-  if (type == SILC_TASK_WRITE) {
-    if (sock->outbuf->data - sock->outbuf->head)
-      silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head);
+  ServerSession session;
 
-    ret = silc_packet_send(sock, TRUE);
-    if (ret < 0)
-      return;
+  SILC_LOG_DEBUG(("New connection"));
 
-    silc_schedule_set_listen_fd(server->schedule, fd, SILC_TASK_READ, FALSE);
-    SILC_UNSET_OUTBUF_PENDING(sock);
-    silc_buffer_clear(sock->outbuf);
+  session = silc_calloc(1, sizeof(*session));
+  if (!session)
     return;
-  }
+  session->stream = stream;
+  session->sftp = silc_sftp_server_start(stream, server->schedule, error_cb,
+                                        session, server->fs);
 
-  if (type == SILC_TASK_READ) {
-    ret = silc_packet_receive(sock);
-    if (ret < 0)
-      return;
-
-    if (ret == 0) {
-      silc_net_close_connection(sock->sock);
-      silc_schedule_unset_listen_fd(server->schedule, sock->sock);
-      silc_free(server->sessions[sock->sock]);
-      server->sessions[sock->sock] = NULL;
-      silc_socket_free(sock);
-      return;
-    }
-
-    silc_packet_receive_process(sock, FALSE, NULL, NULL, 0, packet_parse, 
-                               server);
-  }
-}
-
-SILC_TASK_CALLBACK(accept_connection)
-{
-  Server server = (Server)context;
-  SilcSocketConnection sc;
-  int sock;
-
-  sock = silc_net_accept_connection(server->sock);
-  if (sock < 0)
-    exit(1);
-
-  silc_net_set_socket_nonblock(sock);
-  silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
-
-  silc_socket_alloc(sock, 0, NULL, &sc);
-  server->sessions[sock] = silc_calloc(1, sizeof(server->sessions[0]));
-  server->sessions[sock]->sock = sc;
-  server->sessions[sock]->server = server;
-  server->sftp[sock] = 
-    silc_sftp_server_start(send_packet, server->sessions[sock],
-                          server->fs);
-  silc_schedule_task_add(server->schedule, sock, packet_process,
-                        server, 0, 0, SILC_TASK_GENERIC,
-                        SILC_TASK_PRI_NORMAL);
 }
 
 int main()
 {
   Server server = silc_calloc(1, sizeof(*server));
   void *dir;
+  const char *ip = "127.0.0.1";
 
-  silc_debug = 1;
-  silc_debug_hexdump = 1;
+  silc_log_debug(TRUE);
+  silc_log_debug_hexdump(TRUE);
   silc_log_set_debug_string("*sftp*");
-  
-  server->schedule = silc_schedule_init(100, NULL);
+
+  server->schedule = silc_schedule_init(0, NULL);
   if (!server->schedule)
     return -1;
 
-  server->sock = silc_net_create_server(5000, NULL);
-  if (server->sock < 0)
+  server->listener = silc_net_tcp_create_listener(&ip, 1, 5000, FALSE,
+                                                 FALSE, server->schedule,
+                                                 net_callback, server);
+  if (!server->listener)
     return -1;
 
   /* Make test filesystem hierarchy */
@@ -182,9 +106,6 @@ int main()
   silc_sftp_fs_memory_add_file(server->fs, NULL, SILC_SFTP_FS_PERM_EXEC,
                               "testi", "file://sftp_client.c");
 
-  silc_schedule_task_add(server->schedule, server->sock, 
-                        accept_connection, server, 0, 0,
-                        SILC_TASK_FD, SILC_TASK_PRI_NORMAL);
   silc_schedule(server->schedule);
 
   return 0;