summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/fileops.c10
-rw-r--r--test/test_e2e.py15
2 files changed, 21 insertions, 4 deletions
diff --git a/src/fileops.c b/src/fileops.c
index 5db7906..2c13436 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -323,12 +323,14 @@ int mscp_setstat(const char *path, struct stat *st, bool preserve_ts, sftp_sessi
ret = sftp_setstat(sftp, path, &attr);
sftp_err_to_errno(sftp);
} else {
- if ((ret = chmod(path, st->st_mode)) < 0)
- return ret;
if ((ret = truncate(path, st->st_size)) < 0)
return ret;
- if (preserve_ts)
- ret = setutimes(path, st->st_atim, st->st_mtim);
+ if (preserve_ts) {
+ if ((ret = setutimes(path, st->st_atim, st->st_mtim)) < 0)
+ return ret;
+ }
+ if ((ret = chmod(path, st->st_mode)) < 0)
+ return ret;
}
return ret;
diff --git a/test/test_e2e.py b/test/test_e2e.py
index e4dbe49..808558d 100644
--- a/test/test_e2e.py
+++ b/test/test_e2e.py
@@ -322,6 +322,21 @@ def test_dont_truncate_dst(mscp, src_prefix, dst_prefix):
f.cleanup()
@pytest.mark.parametrize("src_prefix, dst_prefix", param_remote_prefix)
+def test_copy_readonly_file(mscp, src_prefix, dst_prefix):
+ """When a source file permission is r--r--r--, if chmod(r--r--r--)
+ runs first on the remote side, following truncate() and setutime()
+ fail due to permission deneid. So, run chmod() after truncate()
+ and setutime()
+
+ """
+ src = File("src", size = 1024 * 1024 * 128, perm = 0o444).make()
+ dst = File("dst")
+ run2ok([mscp, "-H", "-vvv", src_prefix + src.path, dst_prefix + dst.path])
+ assert check_same_md5sum(src, dst)
+ src.cleanup()
+ dst.cleanup()
+
+@pytest.mark.parametrize("src_prefix, dst_prefix", param_remote_prefix)
def test_dont_make_conns_more_than_chunks(mscp, src_prefix, dst_prefix):
# copy 100 files with -n 20 -I 1 options. if mscp creates 20 SSH
# connections although all files have been copied, it is error.