diff options
author | djm@openbsd.org <djm@openbsd.org> | 2016-02-11 02:21:34 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2016-02-11 13:22:05 +1100 |
commit | e30cabfa4ab456a30b3224f7f545f1bdfc4a2517 (patch) | |
tree | d8aa55b71effee3fa925624fc4a461e93161db88 | |
parent | 714e367226ded4dc3897078be48b961637350b05 (diff) |
upstream commit
fix regression in openssh-6.8 sftp client: existing
destination directories would incorrectly terminate recursive uploads;
bz#2528
Upstream-ID: 3306be469f41f26758e3d447987ac6d662623e18
-rw-r--r-- | sftp-client.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/sftp-client.c b/sftp-client.c index 5dbeb47c0..d49bfaaba 100644 --- a/sftp-client.c +++ b/sftp-client.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sftp-client.c,v 1.120 2015/05/28 04:50:53 djm Exp $ */ | 1 | /* $OpenBSD: sftp-client.c,v 1.121 2016/02/11 02:21:34 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> | 3 | * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> |
4 | * | 4 | * |
@@ -1760,7 +1760,7 @@ do_upload(struct sftp_conn *conn, const char *local_path, | |||
1760 | if (fsync_flag) | 1760 | if (fsync_flag) |
1761 | (void)do_fsync(conn, handle, handle_len); | 1761 | (void)do_fsync(conn, handle, handle_len); |
1762 | 1762 | ||
1763 | if (do_close(conn, handle, handle_len) != SSH2_FX_OK) | 1763 | if (do_close(conn, handle, handle_len) != 0) |
1764 | status = SSH2_FX_FAILURE; | 1764 | status = SSH2_FX_FAILURE; |
1765 | 1765 | ||
1766 | free(handle); | 1766 | free(handle); |
@@ -1773,12 +1773,11 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, | |||
1773 | int depth, int preserve_flag, int print_flag, int resume, int fsync_flag) | 1773 | int depth, int preserve_flag, int print_flag, int resume, int fsync_flag) |
1774 | { | 1774 | { |
1775 | int ret = 0; | 1775 | int ret = 0; |
1776 | u_int status; | ||
1777 | DIR *dirp; | 1776 | DIR *dirp; |
1778 | struct dirent *dp; | 1777 | struct dirent *dp; |
1779 | char *filename, *new_src, *new_dst; | 1778 | char *filename, *new_src, *new_dst; |
1780 | struct stat sb; | 1779 | struct stat sb; |
1781 | Attrib a; | 1780 | Attrib a, *dirattrib; |
1782 | 1781 | ||
1783 | if (depth >= MAX_DIR_DEPTH) { | 1782 | if (depth >= MAX_DIR_DEPTH) { |
1784 | error("Maximum directory depth exceeded: %d levels", depth); | 1783 | error("Maximum directory depth exceeded: %d levels", depth); |
@@ -1805,17 +1804,18 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, | |||
1805 | if (!preserve_flag) | 1804 | if (!preserve_flag) |
1806 | a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME; | 1805 | a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME; |
1807 | 1806 | ||
1808 | status = do_mkdir(conn, dst, &a, 0); | ||
1809 | /* | 1807 | /* |
1810 | * we lack a portable status for errno EEXIST, | 1808 | * sftp lacks a portable status value to match errno EEXIST, |
1811 | * so if we get a SSH2_FX_FAILURE back we must check | 1809 | * so if we get a failure back then we must check whether |
1812 | * if it was created successfully. | 1810 | * the path already existed and is a directory. |
1813 | */ | 1811 | */ |
1814 | if (status != SSH2_FX_OK) { | 1812 | if (do_mkdir(conn, dst, &a, 0) != 0) { |
1815 | if (status != SSH2_FX_FAILURE) | 1813 | if ((dirattrib = do_stat(conn, dst, 0)) == NULL) |
1816 | return -1; | 1814 | return -1; |
1817 | if (do_stat(conn, dst, 0) == NULL) | 1815 | if (!S_ISDIR(dirattrib->perm)) { |
1816 | error("\"%s\" exists but is not a directory", dst); | ||
1818 | return -1; | 1817 | return -1; |
1818 | } | ||
1819 | } | 1819 | } |
1820 | 1820 | ||
1821 | if ((dirp = opendir(src)) == NULL) { | 1821 | if ((dirp = opendir(src)) == NULL) { |