mirror of
https://github.com/upa/mscp.git
synced 2026-02-04 03:24:58 +08:00
do not set O_TRUNC when opening destination file.
It prevents `mscp localhost:hoge ~/hoge` from truncating the source file. See https://bugzilla.mindrot.org/show_bug.cgi?id=3431. https://github.com/upa/mscp/issues/1
This commit is contained in:
@@ -293,15 +293,24 @@ int mscp_lseek(mf *f, size_t off)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mscp_chmod(const char *path, mode_t mode, sftp_session sftp)
|
||||
int mscp_setstat(const char *path, mode_t mode, size_t size, sftp_session sftp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (sftp) {
|
||||
ret = sftp_chmod(sftp, path, mode);
|
||||
struct sftp_attributes_struct attr;
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
attr.permissions = mode;
|
||||
attr.size = size;
|
||||
attr.flags = (SSH_FILEXFER_ATTR_PERMISSIONS|SSH_FILEXFER_ATTR_SIZE);
|
||||
ret = sftp_setstat(sftp, path, &attr);
|
||||
sftp_err_to_errno(sftp);
|
||||
} else
|
||||
ret = chmod(path, mode);
|
||||
} else {
|
||||
if ((ret = chmod(path, mode)) < 0)
|
||||
return ret;
|
||||
if ((ret = truncate(path, size)) < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,11 @@ typedef struct mf_struct mf;
|
||||
mf *mscp_open(const char *path, int flags, mode_t mode, sftp_session sftp);
|
||||
void mscp_close(mf *f);
|
||||
int mscp_lseek(mf *f, size_t off);
|
||||
int mscp_chmod(const char *path, mode_t mode, sftp_session sftp);
|
||||
|
||||
/* mscp_setstat() involves chmod and truncate. It executes both at
|
||||
* once via a single SFTP command (sftp_setstat()).
|
||||
*/
|
||||
int mscp_setstat(const char *path, mode_t mode, size_t size, sftp_session sftp);
|
||||
|
||||
/* remote glob */
|
||||
int mscp_glob(const char *pattern, int flags, glob_t *pglob, sftp_session sftp);
|
||||
|
||||
@@ -334,8 +334,9 @@ static int touch_dst_path(struct path *p, sftp_session sftp)
|
||||
*needle = '/';
|
||||
}
|
||||
|
||||
/* open file with O_TRUNC to set file size 0 */
|
||||
f = mscp_open(p->dst_path, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR, sftp);
|
||||
/* Do not set O_TRUNC here. Instead, do mscp_setstat() at the
|
||||
* end. see https://bugzilla.mindrot.org/show_bug.cgi?id=3431 */
|
||||
f = mscp_open(p->dst_path, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR, sftp);
|
||||
if (!f) {
|
||||
mscp_set_error("mscp_open %s: %s\n", p->dst_path, strerrno());
|
||||
return -1;
|
||||
@@ -574,7 +575,9 @@ int copy_chunk(FILE *msg_fp, struct chunk *c,
|
||||
|
||||
if (refcnt_dec(&c->p->refcnt) == 0) {
|
||||
c->p->state = FILE_STATE_DONE;
|
||||
mscp_chmod(c->p->dst_path, c->p->mode, dst_sftp);
|
||||
if (mscp_setstat(c->p->dst_path, c->p->mode, c->p->size, dst_sftp) < 0)
|
||||
mpr_err(msg_fp, "failed to chmod and truncate %s: %s\n",
|
||||
c->p->path, strerrno());
|
||||
mpr_info(msg_fp, "copy done: %s\n", c->p->path);
|
||||
}
|
||||
|
||||
|
||||
@@ -227,6 +227,15 @@ def test_override_dst_having_larger_size(mscp, src_prefix, dst_prefix):
|
||||
src.cleanup()
|
||||
dst.cleanup()
|
||||
|
||||
@pytest.mark.parametrize("src_prefix, dst_prefix", param_remote_prefix)
|
||||
def test_dont_truncate_dst(mscp, src_prefix, dst_prefix):
|
||||
f = File("srcanddst", size = 1024 * 1024 * 128).make()
|
||||
md5_before = f.md5sum()
|
||||
run2ok([mscp, "-H", "-vvv", src_prefix + f.path, dst_prefix + f.path])
|
||||
md5_after = f.md5sum()
|
||||
assert md5_before == md5_after
|
||||
f.cleanup()
|
||||
|
||||
compressions = ["yes", "no", "none"]
|
||||
@pytest.mark.parametrize("src_prefix, dst_prefix", param_remote_prefix)
|
||||
@pytest.mark.parametrize("compress", compressions)
|
||||
|
||||
Reference in New Issue
Block a user