diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mscp.c | 11 | ||||
-rw-r--r-- | src/path.c | 23 | ||||
-rw-r--r-- | src/path.h | 3 |
3 files changed, 27 insertions, 10 deletions
@@ -297,7 +297,7 @@ int mscp_set_dst_path(struct mscp *m, const char *dst_path) int mscp_prepare(struct mscp *m) { sftp_session src_sftp = NULL, dst_sftp = NULL; - bool src_path_is_dir, dst_path_is_dir; + bool src_path_is_dir, dst_path_is_dir, dst_path_should_dir = false; struct list_head tmp; struct src *s; mstat ss, ds; @@ -316,6 +316,9 @@ int mscp_prepare(struct mscp *m) return -1; } + if (list_count(&m->src_list) > 1) + dst_path_should_dir = true; + if (mscp_stat(m->dst_path, &ds, dst_sftp) == 0) { if (mstat_is_dir(ds)) dst_path_is_dir = true; @@ -336,8 +339,12 @@ int mscp_prepare(struct mscp *m) if (walk_src_path(src_sftp, s->path, &tmp) < 0) return -1; + if (list_count(&tmp) > 1) + dst_path_should_dir = true; + if (resolve_dst_path(s->path, m->dst_path, &tmp, - src_path_is_dir, dst_path_is_dir) < 0) + src_path_is_dir, dst_path_is_dir, + dst_path_should_dir) < 0) return -1; list_splice_tail(&tmp, m->path_list.prev); @@ -104,7 +104,8 @@ int walk_src_path(sftp_session src_sftp, const char *src_path, static int src2dst_path(const char *src_path, const char *src_file_path, const char *dst_path, char *dst_file_path, size_t len, - bool src_path_is_dir, bool dst_path_is_dir) + bool src_path_is_dir, bool dst_path_is_dir, + bool dst_path_should_dir) { char copy[PATH_MAX]; char *prefix; @@ -121,10 +122,16 @@ static int src2dst_path(const char *src_path, const char *src_file_path, else offset = strlen(prefix) + 1; - - /* both are file */ - if (!src_path_is_dir && !dst_path_is_dir) - strncpy(dst_file_path, dst_path, len); + if (!src_path_is_dir && !dst_path_is_dir) { + /* src path is file. dst path is (1) file, or (2) does not exist. + * In the second case, we need to put src under the dst. + */ + if (dst_path_should_dir) + snprintf(dst_file_path, len, "%s/%s", + dst_path, src_path + offset); + else + strncpy(dst_file_path, dst_path, len); + } /* src is file, and dst is dir */ if (!src_path_is_dir && dst_path_is_dir) @@ -145,13 +152,15 @@ static int src2dst_path(const char *src_path, const char *src_file_path, } int resolve_dst_path(const char *src_path, const char *dst_path, - struct list_head *path_list, bool src_is_dir, bool dst_is_dir) + struct list_head *path_list, bool src_path_is_dir, + bool dst_path_is_dir, bool dst_path_should_dir) { struct path *p; list_for_each_entry(p, path_list, list) { if (src2dst_path(src_path, p->path, dst_path, p->dst_path, PATH_MAX, - src_is_dir, dst_is_dir) < 0) + src_path_is_dir, dst_path_is_dir, + dst_path_should_dir) < 0) return -1; } @@ -45,7 +45,8 @@ int walk_src_path(sftp_session src_sftp, const char *src_path, /* fill path->dst_path for all files */ int resolve_dst_path(const char *src_path, const char *dst_path, struct list_head *path_list, - bool src_path_is_dir, bool dst_path_is_dir); + bool src_path_is_dir, bool dst_path_is_dir, + bool dst_path_should_dir); /* resolve chunks from files in the path_list */ int resolve_chunk(struct list_head *path_list, struct list_head *chunk_list, |