[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Bugfix patches + SFTP append support


Hi,

I attached some patches:

- The SSH_FXF_READ flag was always set when opening a file via SFTP
- I added support for opening files in append mode. Due to bad protocol
design I had to query the file size through the stat() function to get
the EOF offset, which makes opening a file in append mode non-atomic.
- The current master was not compilable on Windows since November.

Regards
Tilo
From d47a6b435a37bc811a77651891b768c41ee1afb4 Mon Sep 17 00:00:00 2001
From: Tilo Eckert <tilo.eckert@xxxxxxx>
Date: Thu, 30 Jun 2016 12:27:43 +0200
Subject: [PATCH 1/3] bug fix: SFTP flag SSH_FXF_READ was always set (even on
 O_WRONLY) because O_RDONLY == 0

Comparison ((flags & O_RDONLY) == O_RDONLY) is always true.
Also, O_RDWR, O_WRONLY and O_RDONLY are mutually exclusive => no need to check all of them

Signed-off-by: Tilo Eckert <tilo.eckert@xxxxxxx>
---
 src/sftp.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/sftp.c b/src/sftp.c
index f99683d..db5b088 100644
--- a/src/sftp.c
+++ b/src/sftp.c
@@ -1625,12 +1625,12 @@ sftp_file sftp_open(sftp_session sftp, const char *file, int flags,
   attr.permissions = mode;
   attr.flags = SSH_FILEXFER_ATTR_PERMISSIONS;
 
-  if ((flags & O_RDONLY) == O_RDONLY)
-    sftp_flags |= SSH_FXF_READ;
-  if ((flags & O_WRONLY) == O_WRONLY)
-    sftp_flags |= SSH_FXF_WRITE;
   if ((flags & O_RDWR) == O_RDWR)
     sftp_flags |= (SSH_FXF_WRITE | SSH_FXF_READ);
+  else if ((flags & O_WRONLY) == O_WRONLY)
+    sftp_flags |= SSH_FXF_WRITE;
+  else
+    sftp_flags |= SSH_FXF_READ;
   if ((flags & O_CREAT) == O_CREAT)
     sftp_flags |= SSH_FXF_CREAT;
   if ((flags & O_TRUNC) == O_TRUNC)
-- 
2.9.0

From a12d8c856a52cedba408e7817881e09411520b6b Mon Sep 17 00:00:00 2001
From: Tilo Eckert <tilo.eckert@xxxxxxx>
Date: Fri, 1 Jul 2016 10:57:38 +0200
Subject: [PATCH 2/3] add append support to sftp_open()

Signed-off-by: Tilo Eckert <tilo.eckert@xxxxxxx>
---
 src/sftp.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/src/sftp.c b/src/sftp.c
index db5b088..ae8418b 100644
--- a/src/sftp.c
+++ b/src/sftp.c
@@ -1605,6 +1605,7 @@ sftp_file sftp_open(sftp_session sftp, const char *file, int flags,
   sftp_file handle;
   ssh_string filename;
   ssh_buffer buffer;
+  sftp_attributes statData;
   uint32_t sftp_flags = 0;
   uint32_t id;
 
@@ -1637,6 +1638,8 @@ sftp_file sftp_open(sftp_session sftp, const char *file, int flags,
     sftp_flags |= SSH_FXF_TRUNC;
   if ((flags & O_EXCL) == O_EXCL)
     sftp_flags |= SSH_FXF_EXCL;
+  if ((flags & O_APPEND) == O_APPEND)
+    sftp_flags |= SSH_FXF_APPEND;
   SSH_LOG(SSH_LOG_PACKET,"Opening file %s with sftp flags %x",file,sftp_flags);
   id = sftp_get_new_id(sftp);
   if (ssh_buffer_add_u32(buffer, htonl(id)) < 0 ||
@@ -1684,6 +1687,19 @@ sftp_file sftp_open(sftp_session sftp, const char *file, int flags,
     case SSH_FXP_HANDLE:
       handle = parse_handle_msg(msg);
       sftp_message_free(msg);
+      if ((flags & O_APPEND) == O_APPEND) {
+        statData = sftp_stat(sftp, file);
+        if (statData==NULL) {
+          sftp_close(handle);
+          return NULL;
+        }
+        if ((statData->flags & SSH_FILEXFER_ATTR_SIZE) != SSH_FILEXFER_ATTR_SIZE) {
+          ssh_set_error(sftp->session, SSH_FATAL, "Cannot open in append mode. Unknown file size.");
+          sftp_close(handle);
+          return NULL;
+        }
+        handle->offset = statData->size;
+      }
       return handle;
     default:
       ssh_set_error(sftp->session, SSH_FATAL,
-- 
2.9.0

From b2b1c02f828d07082847f851e270cc37ad66ee9f Mon Sep 17 00:00:00 2001
From: Tilo Eckert <tilo.eckert@xxxxxxx>
Date: Fri, 1 Jul 2016 10:58:39 +0200
Subject: [PATCH 3/3] Add missing ifdef that prevented Windows builds

Signed-off-by: Tilo Eckert <tilo.eckert@xxxxxxx>
---
 src/session.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/session.c b/src/session.c
index 6885866..31bb2a7 100644
--- a/src/session.c
+++ b/src/session.c
@@ -270,7 +270,9 @@ void ssh_free(ssh_session session) {
       ssh_list_free(session->opts.identity);
   }
 
+#ifndef _WIN32
   ssh_agent_state_free (session->agent_state);
+#endif
   session->agent_state = NULL;
 
   SAFE_FREE(session->auth_auto_state);
-- 
2.9.0


Archive administrator: postmaster@lists.cynapses.org