[PATCH] Bug 2150: Recursive upload expects target directory to already exist

Michael Grauvogl Michael.Grauvogl at klinik.uni-regensburg.de
Mon Jan 30 00:00:21 AEDT 2017


Hi,

below is a patch for bug 2150 (Recursive upload expects target directory 
to already exist, https://bugzilla.mindrot.org/show_bug.cgi?id=2150).

The problem is that function upload_dir calls do_realpath which will 
fail if the destination directory does not already exist and therefore 
upload_dir_internal never gets called. I used some code from 
upload_dir_internal to create the destination directory if it does not 
already exist.


Cheers,

Michael


diff --git a/sftp-client.c b/sftp-client.c
index d47be0e..f02ecd7 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -1869,6 +1869,33 @@ upload_dir(struct sftp_conn *conn, const char 
*src, const char *dst,
  {
         char *dst_canon;
         int ret;
+       struct stat sb;
+       Attrib a, *dirattrib;
+
+       /* check if dst exists */
+       if (stat(src, &sb) == -1) {
+           error("Couldn't stat directory \"%s\": %s",
+               src, strerror(errno));
+           return -1;
+       }
+
+       attrib_clear(&a);
+       stat_to_attrib(&sb, &a);
+       a.flags &= ~SSH2_FILEXFER_ATTR_SIZE;
+       a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
+       a.perm &= 01777;
+       if (!preserve_flag)
+           a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME;
+
+       /*
+        * sftp lacks a portable status value to match errno EEXIST,
+        * so if we get a failure back then we must check whether
+        * the path already existed and is a directory.
+        */
+       if (do_mkdir(conn, dst, &a, 0) != 0) {
+           if ((dirattrib = do_stat(conn, dst, 0)) == NULL)
+               return -1;
+       }

         if ((dst_canon = do_realpath(conn, dst)) == NULL) {
                 error("Unable to canonicalize path \"%s\"", dst);




More information about the openssh-unix-dev mailing list