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);
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@xxxxxxxxxxx
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev