summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/mscp.1.in12
-rw-r--r--doc/mscp.rst33
-rw-r--r--src/checkpoint.c42
3 files changed, 48 insertions, 39 deletions
diff --git a/doc/mscp.1.in b/doc/mscp.1.in
index a56e26c..b50d6bc 100644
--- a/doc/mscp.1.in
+++ b/doc/mscp.1.in
@@ -139,7 +139,7 @@ determined as an attack. The default value is 0.
.TP
.B \-W \fICHECKPOINT\fR
-Specifies a checkpoint file path to save the state of a failed
+Specifies a checkpoint file to save the state of a failed
transfer. When transferring fails due to, for example, connection
disruption or user interrupt,
.B mscp
@@ -153,7 +153,7 @@ option with
.TP
.B \-R \fICHECKPOINT\fR
-Specifies a checkpoint file path to resume a transfer. When this
+Specifies a checkpoint file to resume a transfer. When this
option with a checkpoint file is passed,
.B mscp
loads a remote host, copy direction, and files and their chunks to be
@@ -163,14 +163,12 @@ can resume a past failed transfer from the checkpoint. Resumeing with
a checkpoint does not require
.I source ... target
arguments. Other options for establishing SSH connections, for
-example, username, port number, config file, should be specified as
+example, login_name, port number, config file, should be specified as
with the failed run. In addition, checkpoint files contain files as
relative paths. Thus, you must run
.B mscp
-in the same working directory as the failed run.
-
-
-You can see contents of a checkpoint file with
+in the same working directory as the failed run. You can see contents
+of a checkpoint file with
.B mscp
.I \-vvv \-D \-R CHECKOPOINT
command.
diff --git a/doc/mscp.rst b/doc/mscp.rst
index a183dde..99dabfd 100644
--- a/doc/mscp.rst
+++ b/doc/mscp.rst
@@ -2,7 +2,7 @@
MSCP
====
-:Date: v0.1.4-19-g5f628b6
+:Date: v0.1.4-20-g19c73af
NAME
====
@@ -71,27 +71,24 @@ OPTIONS
determined as an attack. The default value is 0.
**-W CHECKPOINT**
- Specifies a checkpoint file path to save the state of a failed
- transfer. When transferring fails due to, for example, connection
- disruption or user interrupt, **mscp** writes the information about
- remaining files and chunks to the specified checkpoint file. **-W**
- option with **-D** (dry-run mode) only writes a checkpoint file and
- exits.
+ Specifies a checkpoint file to save the state of a failed transfer.
+ When transferring fails due to, for example, connection disruption or
+ user interrupt, **mscp** writes the information about remaining files
+ and chunks to the specified checkpoint file. **-W** option with
+ **-D** (dry-run mode) only writes a checkpoint file and exits.
**-R CHECKPOINT**
- Specifies a checkpoint file path to resume a transfer. When this
- option with a checkpoint file is passed, **mscp** loads a remote
- host, copy direction, and files and their chunks to be transferred
- from the checkpoint file. Namely, **mscp** can resume a past failed
- transfer from the checkpoint. Resumeing with a checkpoint does not
- require *source ... target* arguments. Other options for establishing
- SSH connections, for example, username, port number, config file,
+ Specifies a checkpoint file to resume a transfer. When this option
+ with a checkpoint file is passed, **mscp** loads a remote host, copy
+ direction, and files and their chunks to be transferred from the
+ checkpoint file. Namely, **mscp** can resume a past failed transfer
+ from the checkpoint. Resumeing with a checkpoint does not require
+ *source ... target* arguments. Other options for establishing SSH
+ connections, for example, login_name, port number, config file,
should be specified as with the failed run. In addition, checkpoint
files contain files as relative paths. Thus, you must run **mscp** in
- the same working directory as the failed run.
-
-You can see contents of a checkpoint file with **mscp** *-vvv -D -R
-CHECKOPOINT* command.
+ the same working directory as the failed run. You can see contents of
+ a checkpoint file with **mscp** *-vvv -D -R CHECKOPOINT* command.
**-s MIN_CHUNK_SIZE**
Specifies the minimum chunk size. **mscp** divides a file into chunks
diff --git a/src/checkpoint.c b/src/checkpoint.c
index efa1926..906b02f 100644
--- a/src/checkpoint.c
+++ b/src/checkpoint.c
@@ -11,6 +11,10 @@
#include <checkpoint.h>
+#define MSCP_CHECKPOINT_MAGIC 0x6d736370UL /* mscp in UTF-8 */
+#define MSCP_CHECKPOINT_VERSION 0x1
+
+
enum {
OBJ_TYPE_META = 0x0A,
OBJ_TYPE_PATH = 0x0B,
@@ -23,8 +27,6 @@ struct checkpoint_obj_hdr {
uint16_t len; /* length of an object including this hdr */
} __attribute__((packed));
-#define MSCP_CHECKPOINT_MAGIC 0x6d736370UL /* mscp in UTF-8 */
-#define MSCP_CHECKPOINT_VERSION 0x1
struct checkpoint_obj_meta {
struct checkpoint_obj_hdr hdr;
@@ -41,17 +43,24 @@ struct checkpoint_obj_path {
struct checkpoint_obj_hdr hdr;
uint32_t idx;
- uint16_t src_off; /* offset to the src path
- * string (including \0) from
- * the head of this object. */
-
- uint16_t dst_off; /* offset to the dst path
- * string (including \0) from
- * the head of this object */
+ uint16_t src_off; /* offset to the src path string (including
+ * \0) from the head of this object. */
+ uint16_t dst_off; /* offset to the dst path string (including
+ * \0) from the head of this object */
} __attribute__((packed));
-#define obj_path_src(obj) ((char *)(obj) + ntohs(obj->src_off))
-#define obj_path_dst(obj) ((char *)(obj) + ntohs(obj->dst_off))
+#define obj_path_src(o) ((char *)(o) + ntohs(o->src_off))
+#define obj_path_dst(o) ((char *)(o) + ntohs(o->dst_off))
+
+#define obj_path_src_len(o) (ntohs(o->dst_off) - ntohs(o->src_off))
+#define obj_path_dst_len(o) (ntohs(o->hdr.len) - ntohs(o->dst_off))
+
+#define obj_path_validate(o) \
+ ((ntohs(o->hdr.len) > ntohs(o->dst_off)) && \
+ (ntohs(o->dst_off) > ntohs(o->src_off)) && \
+ (obj_path_src_len(o) < PATH_MAX) && \
+ (obj_path_dst_len(o) < PATH_MAX)) \
+
struct checkpoint_obj_chunk {
struct checkpoint_obj_hdr hdr;
@@ -213,12 +222,17 @@ static int checkpoint_load_path(struct checkpoint_obj_hdr *hdr, pool *path_pool)
struct path *p;
char *s, *d;
- if (!(s = strdup(obj_path_src(path)))) {
+ if (!obj_path_validate(path)) {
+ priv_set_errv("invalid path object");
+ return -1;
+ }
+
+ if (!(s = strndup(obj_path_src(path), obj_path_src_len(path)))) {
priv_set_errv("strdup: %s", strerrno());
return -1;
}
- if (!(d = strdup(obj_path_dst(path)))) {
+ if (!(d = strndup(obj_path_dst(path), obj_path_dst_len(path)))) {
priv_set_errv("strdup: %s", strerrno());
free(s);
return -1;
@@ -235,7 +249,7 @@ static int checkpoint_load_path(struct checkpoint_obj_hdr *hdr, pool *path_pool)
return -1;
}
- pr_info("checkpoint:path: %s -> %s", p->path, p->dst_path);
+ pr_info("checkpoint:file: %s -> %s", p->path, p->dst_path);
return 0;
}