summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mscp.c11
-rw-r--r--src/path.c23
-rw-r--r--src/path.h3
3 files changed, 27 insertions, 10 deletions
diff --git a/src/mscp.c b/src/mscp.c
index f1af1b7..2fe9703 100644
--- a/src/mscp.c
+++ b/src/mscp.c
@@ -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);
diff --git a/src/path.c b/src/path.c
index dc6cac3..1d6e708 100644
--- a/src/path.c
+++ b/src/path.c
@@ -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;
}
diff --git a/src/path.h b/src/path.h
index 2672f51..7ad4f9e 100644
--- a/src/path.h
+++ b/src/path.h
@@ -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,