summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/file.c29
-rw-r--r--src/file.h3
-rw-r--r--test/test_e2e.py8
3 files changed, 37 insertions, 3 deletions
diff --git a/src/file.c b/src/file.c
index 02d73cf..90cd97d 100644
--- a/src/file.c
+++ b/src/file.c
@@ -367,6 +367,7 @@ static int file_dst_prepare(struct file *f, sftp_session sftp)
pr_debug("prepare for %s\n", path);
+ /* mkdir -p */
for (p = strchr(path + 1, '/'); p; p = strchr(p + 1, '/')) {
*p = '\0';
@@ -398,6 +399,30 @@ static int file_dst_prepare(struct file *f, sftp_session sftp)
*p = '/';
}
+ /* open file with O_TRUNC to set file size 0 */
+ mode = O_WRONLY|O_CREAT|O_TRUNC;
+ if (sftp) {
+ sftp_file sf;
+ if ((sf = sftp_open(sftp, f->dst_path, mode, S_IRUSR|S_IWUSR)) == NULL) {
+ pr_err("sftp_open: %s\n", sftp_get_ssh_error(sftp));
+ return -1;
+ }
+ if (sftp_close(sf) < 0) {
+ pr_err("sftp_close: %s\n", sftp_get_ssh_error(sftp));
+ return -1;
+ }
+ } else {
+ int fd;
+ if ((fd = open(f->dst_path, mode, S_IRUSR|S_IWUSR)) < 0) {
+ pr_err("open: %s\n", strerrno());
+ return -1;
+ }
+ if (close(fd) < 0) {
+ pr_err("close: %s\n", strerrno());
+ return -1;
+ }
+ }
+
return 0;
}
@@ -824,7 +849,7 @@ static int chunk_copy_local_to_remote(struct chunk *c, sftp_session sftp,
goto out;
}
- flags = O_WRONLY|O_CREAT;
+ flags = O_WRONLY;
mode = S_IRUSR|S_IWUSR;
if (!(sf = chunk_open_remote(f->dst_path, flags, mode, c->off, sftp))) {
ret = -1;
@@ -866,7 +891,7 @@ static int chunk_copy_remote_to_local(struct chunk *c, sftp_session sftp,
int fd = 0;
int ret = 0;
- flags = O_WRONLY|O_CREAT;
+ flags = O_WRONLY;
mode = S_IRUSR|S_IWUSR;
if ((fd = chunk_open_local(f->dst_path, flags, mode, c->off)) < 0) {
ret = -1;
diff --git a/src/file.h b/src/file.h
index 57cd2c2..883cb32 100644
--- a/src/file.h
+++ b/src/file.h
@@ -37,7 +37,8 @@ struct file {
* if the file state of the chunk is INIT:
* acquire the file lock
* * if file state is INIT:
- * create destination file and directory if necessary
+ * create directory if necessary
+ * open file with O_TRUNC and close.
* set file state OPENED.
* // only the first thread in the lock open the destination file
* release the file lock
diff --git a/test/test_e2e.py b/test/test_e2e.py
index 61a3532..515717f 100644
--- a/test/test_e2e.py
+++ b/test/test_e2e.py
@@ -174,3 +174,11 @@ def test_transfer_zero_bytes(mscp, src_prefix, dst_prefix):
src.cleanup()
dst.cleanup()
+@pytest.mark.parametrize("src_prefix, dst_prefix", param_remote_prefix)
+def test_override_dst_having_larger_size(mscp, src_prefix, dst_prefix):
+ src = File("src", size = 1024 * 1024).make()
+ dst = File("dst", size = 1024 * 1024 * 2).make()
+ run2ok([mscp, "-H", src_prefix + src.path, dst_prefix + "dst"])
+ assert check_same_md5sum(src, dst)
+ src.cleanup()
+ dst.cleanup()