updates.
[crypto.git] / lib / silcclient / client_ftp.c
index 90642aa251d1f8fa4e9cf4ea34d59e72f3992368..1f19f94567e106c4bfa5a39a9cdffba9be2cd3f4 100644 (file)
@@ -18,7 +18,8 @@
 */
 /* $Id$ */
 
-#include "clientlibincludes.h"
+#include "silcincludes.h"
+#include "silcclient.h"
 #include "client_internal.h"
 
 static int
@@ -33,7 +34,7 @@ static void silc_client_ftp_start_key_agreement(SilcClientFtpSession session,
 
 /* File transmission session */
 struct SilcClientFtpSessionStruct {
-  uint32 session_id;
+  SilcUInt32 session_id;
   SilcClient client;
   SilcClientConnection conn;
   SilcClientEntry client_entry;
@@ -42,12 +43,13 @@ struct SilcClientFtpSessionStruct {
   SilcBuffer packet;
 
   char *hostname;
-  uint16 port;
+  SilcUInt16 port;
   int listener;
 
   SilcClientFileMonitor monitor;
   void *monitor_context;
   char *filepath;
+  char *path;
 
   SilcSFTP sftp;
   SilcSFTPFilesystem fs;
@@ -55,8 +57,8 @@ struct SilcClientFtpSessionStruct {
 
   SilcSFTPHandle dir_handle;
   SilcSFTPHandle read_handle;
-  uint64 filesize;
-  uint64 read_offset;
+  SilcUInt64 filesize;
+  SilcUInt64 read_offset;
   int fd;
 };
 
@@ -158,8 +160,7 @@ silc_client_connect_to_client(SilcClient client,
 /* SFTP packet send callback. This will use preallocated buffer to avoid
    reallocation of outgoing data buffer everytime. */
 
-static void silc_client_ftp_send_packet(SilcSocketConnection sock,
-                                       SilcBuffer packet, void *context)
+static void silc_client_ftp_send_packet(SilcBuffer packet, void *context)
 {
   SilcClientFtpSession session = (SilcClientFtpSession)context;
   SilcClient client = session->client;
@@ -182,8 +183,9 @@ static void silc_client_ftp_send_packet(SilcSocketConnection sock,
                     SILC_STR_END);
 
   /* Send the packet immediately */
-  silc_client_packet_send(client, sock, SILC_PACKET_FTP, NULL, 0, NULL, NULL,
-                         session->packet->data, session->packet->len, TRUE);
+  silc_client_packet_send(client, session->sock, SILC_PACKET_FTP, NULL, 
+                         0, NULL, NULL, session->packet->data, 
+                         session->packet->len, TRUE);
 
   /* Clear buffer */
   session->packet->data = session->packet->tail = session->packet->head;
@@ -221,7 +223,7 @@ static void silc_client_ftp_monitor(SilcSFTP sftp,
 static void silc_client_ftp_data(SilcSFTP sftp,
                                 SilcSFTPStatus status,
                                 const unsigned char *data,
-                                uint32 data_len,
+                                SilcUInt32 data_len,
                                 void *context)
 {
   SilcClientFtpSession session = (SilcClientFtpSession)context;
@@ -264,7 +266,8 @@ static void silc_client_ftp_data(SilcSFTP sftp,
 
   /* Read more, until EOF is received */
   session->read_offset += data_len;
-  silc_sftp_read(sftp, session->read_handle, session->read_offset, 64512,
+  silc_sftp_read(sftp, session->read_handle, session->read_offset, 
+                 SILC_PACKET_MAX_LEN - 1024,
                 silc_client_ftp_data, session);
 
   /* Call monitor callback */
@@ -289,6 +292,7 @@ static void silc_client_ftp_open_handle(SilcSFTP sftp,
                                        void *context)
 {
   SilcClientFtpSession session = (SilcClientFtpSession)context;
+  char path[512];
 
   SILC_LOG_DEBUG(("Start"));
 
@@ -308,8 +312,10 @@ static void silc_client_ftp_open_handle(SilcSFTP sftp,
   }
 
   /* Open the actual local file */
-  session->fd = silc_file_open(session->filepath, 
-                              O_RDWR | O_CREAT | O_EXCL);
+  memset(path, 0, sizeof(path));
+  snprintf(path, sizeof(path) - 1, "%s%s", session->path ?
+          session->path : "", session->filepath);
+  session->fd = silc_file_open(path, O_RDWR | O_CREAT | O_EXCL);
   if (session->fd < 0) {
     /* Call monitor callback */
     session->client->internal->ops->say(session->client, session->conn, 
@@ -330,7 +336,8 @@ static void silc_client_ftp_open_handle(SilcSFTP sftp,
   session->read_handle = handle;
 
   /* Now, start reading the file */
-  silc_sftp_read(sftp, session->read_handle, session->read_offset, 64512,
+  silc_sftp_read(sftp, session->read_handle, session->read_offset,
+                 SILC_PACKET_MAX_LEN - 1024,
                 silc_client_ftp_data, session);
 
   /* Call monitor callback */
@@ -376,7 +383,7 @@ static void silc_client_ftp_readdir_name(SilcSFTP sftp,
   silc_sftp_open(sftp, name->filename[0], SILC_SFTP_FXF_READ, &attr,
                 silc_client_ftp_open_handle, session);
 
-  /* Save the important attributes */
+  /* Save the important attributes like filename and file size */
   session->filepath = strdup(name->filename[0]);
   session->filesize = name->attrs[0]->size;
 
@@ -489,14 +496,12 @@ SILC_TASK_CALLBACK(silc_client_ftp_key_agreement_final)
   if (!session->server) {
     /* If we are the SFTP client then start the SFTP session and retrieve
        the info about the file available for download. */
-    session->sftp = silc_sftp_client_start(conn->sock,
-                                          silc_client_ftp_send_packet,
-                                          session, 
-                                          silc_client_ftp_version, session);
+    session->sftp = silc_sftp_client_start(silc_client_ftp_send_packet,
+                                          session, silc_client_ftp_version, 
+                                          session);
   } else {
     /* Start SFTP server */
-    session->sftp = silc_sftp_server_start(conn->sock,
-                                          silc_client_ftp_send_packet,
+    session->sftp = silc_sftp_server_start(silc_client_ftp_send_packet,
                                           session, session->fs);
 
     /* Monitor transmission */
@@ -541,7 +546,7 @@ static void silc_client_ftp_start_key_agreement(SilcClientFtpSession session,
                        NULL, session->monitor_context);
 
   /* Add new connection for this session */
-  conn = silc_client_add_connection(client, session->hostname,
+  conn = silc_client_add_connection(client, NULL, session->hostname,
                                    session->port, session);
 
   /* Allocate new socket connection object */
@@ -639,7 +644,7 @@ SILC_TASK_CALLBACK(silc_client_ftp_process_key_agreement)
                        NULL, session->monitor_context);
 
   /* Add new connection for this session */
-  conn = silc_client_add_connection(client, newsocket->hostname,
+  conn = silc_client_add_connection(client, NULL, newsocket->hostname,
                                    newsocket->port, session);
   conn->sock = newsocket;
   conn->sock->user_data = conn;
@@ -753,7 +758,7 @@ void silc_client_ftp_session_free(SilcClientFtpSession session)
       if (conn->active_session == session)
        conn->active_session = NULL;
 
-      silc_client_close_connection(session->client, session->sock, conn);
+      silc_client_close_connection_real(session->client, session->sock, conn);
     } else {
       silc_socket_free(session->sock);
     }
@@ -779,10 +784,10 @@ silc_client_file_send(SilcClient client,
                      SilcClientFileMonitor monitor,
                      void *monitor_context,
                      const char *local_ip,
-                     uint32 local_port,
+                     SilcUInt32 local_port,
                      SilcClientEntry client_entry,
                      const char *filepath,
-                     uint32 *session_id)
+                     SilcUInt32 *session_id)
 {
   SilcClientFtpSession session;
   SilcBuffer keyagr, ftp;
@@ -890,7 +895,8 @@ silc_client_file_receive(SilcClient client,
                         SilcClientConnection conn,
                         SilcClientFileMonitor monitor,
                         void *monitor_context,
-                        uint32 session_id)
+                        const char *path,
+                        SilcUInt32 session_id)
 {
   SilcClientFtpSession session;
   SilcBuffer keyagr, ftp;
@@ -919,6 +925,7 @@ silc_client_file_receive(SilcClient client,
   session->monitor = monitor;
   session->monitor_context = monitor_context;
   session->conn = conn;
+  session->path = path ? strdup(path) : NULL;
 
   /* If the hostname and port already exists then the remote client did
      provide the connection point to us and we won't create listener, but
@@ -972,7 +979,7 @@ silc_client_file_receive(SilcClient client,
 
 SilcClientFileError silc_client_file_close(SilcClient client,
                                           SilcClientConnection conn,
-                                          uint32 session_id)
+                                          SilcUInt32 session_id)
 {
   SilcClientFtpSession session;
 
@@ -1004,7 +1011,7 @@ SilcClientFileError silc_client_file_close(SilcClient client,
 static void silc_client_ftp_resolve_cb(SilcClient client,
                                       SilcClientConnection conn,
                                       SilcClientEntry *clients,
-                                      uint32 clients_count,
+                                      SilcUInt32 clients_count,
                                       void *context)
 {
   SilcPacketContext *packet = (SilcPacketContext *)context;
@@ -1012,7 +1019,7 @@ static void silc_client_ftp_resolve_cb(SilcClient client,
   SilcKeyAgreementPayload payload = NULL;
   SilcClientEntry client_entry;
   char *hostname;
-  uint16 port;
+  SilcUInt16 port;
 
   SILC_LOG_DEBUG(("Start"));
 
@@ -1093,7 +1100,7 @@ void silc_client_ftp(SilcClient client,
                     SilcPacketContext *packet)
 {
   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
-  uint8 type;
+  SilcUInt8 type;
   int ret;
 
   SILC_LOG_DEBUG(("Start"));