summaryrefslogtreecommitdiff
path: root/src/path.c
diff options
context:
space:
mode:
authorRyo Nakamura <upa@haeena.net>2023-08-03 17:07:39 +0900
committerRyo Nakamura <upa@haeena.net>2023-08-03 17:07:39 +0900
commit9f7c135b1515ae297b839f54ea08c1fd16c9521e (patch)
tree74dc98867f35b76e458939f7846f9fa0c7625eff /src/path.c
parent8ab06c95319d4da360e3ca1c98876902736243b8 (diff)
cleanup wrappers for file operations
Previously wrapper functions for open(), opendir(), and stat(), etc, are implemneted in path.h, and now they are in fileops.h and fileops.c. This commit is a reparation for remote glob.
Diffstat (limited to 'src/path.c')
-rw-r--r--src/path.c109
1 files changed, 54 insertions, 55 deletions
diff --git a/src/path.c b/src/path.c
index 7dbb9da..e35ff06 100644
--- a/src/path.c
+++ b/src/path.c
@@ -7,6 +7,7 @@
#include <ssh.h>
#include <util.h>
+#include <fileops.h>
#include <list.h>
#include <atomic.h>
#include <path.h>
@@ -190,7 +191,7 @@ static int resolve_chunk(struct path *p, struct path_resolve_args *a)
return 0;
}
-static int append_path(sftp_session sftp, const char *path, mstat s,
+static int append_path(sftp_session sftp, const char *path, struct stat st,
struct list_head *path_list, struct path_resolve_args *a)
{
struct path *p;
@@ -203,8 +204,8 @@ static int append_path(sftp_session sftp, const char *path, mstat s,
memset(p, 0, sizeof(*p));
INIT_LIST_HEAD(&p->list);
strncpy(p->path, path, PATH_MAX - 1);
- p->size = mstat_size(s);
- p->mode = mstat_mode(s);
+ p->size = st.st_size;
+ p->mode = st.st_mode;
p->state = FILE_STATE_INIT;
lock_init(&p->lock);
@@ -239,48 +240,36 @@ static int walk_path_recursive(sftp_session sftp, const char *path,
struct list_head *path_list, struct path_resolve_args *a)
{
char next_path[PATH_MAX];
- mdirent *e;
- mdir *d;
- mstat s;
+ struct dirent *e;
+ struct stat st;
+ MDIR *d;
int ret;
- if (mscp_stat(path, &s, sftp) < 0)
+ if (mscp_stat(path, &st, sftp) < 0)
return -1;
- if (mstat_is_regular(s)) {
+ if (S_ISREG(st.st_mode)) {
/* this path is regular file. it is to be copied */
- ret = append_path(sftp, path, s, path_list, a);
- mscp_stat_free(s);
- return ret;
- }
-
- if (!mstat_is_dir(s)) {
- /* not regular file and not directory, skip it. */
- mscp_stat_free(s);
- return 0;
+ return append_path(sftp, path, st, path_list, a);
}
- mscp_stat_free(s);
-
+ if (!S_ISDIR(st.st_mode))
+ return 0; /* not a regular file and not a directory, skip it. */
/* ok, this path is directory. walk it. */
if (!(d = mscp_opendir(path, sftp)))
return -1;
- for (e = mscp_readdir(d); !mdirent_is_null(e); e = mscp_readdir(d)) {
- if (check_path_should_skip(mdirent_name(e))) {
- mscp_dirent_free(e);
+ for (e = mscp_readdir(d); e; e = mscp_readdir(d)) {
+ if (check_path_should_skip(e->d_name))
continue;
- }
- if (strlen(path) + 1 + strlen(mdirent_name(e)) > PATH_MAX) {
- mscp_set_error("too long path: %s/%s", path, mdirent_name(e));
- mscp_dirent_free(e);
+ if (strlen(path) + 1 + strlen(e->d_name) > PATH_MAX) {
+ mscp_set_error("too long path: %s/%s", path, e->d_name);
return -1;
}
- snprintf(next_path, sizeof(next_path), "%s/%s", path, mdirent_name(e));
+ snprintf(next_path, sizeof(next_path), "%s/%s", path, e->d_name);
ret = walk_path_recursive(sftp, next_path, path_list, a);
- mscp_dirent_free(e);
if (ret < 0)
return ret;
}
@@ -314,10 +303,11 @@ static int touch_dst_path(struct path *p, sftp_session sftp)
{
/* XXX: should reflect the permission of the original directory? */
mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
+ struct stat st;
char path[PATH_MAX];
char *needle;
int ret;
- mfh h;
+ mf *f;
strncpy(path, p->dst_path, sizeof(path));
@@ -326,22 +316,17 @@ static int touch_dst_path(struct path *p, sftp_session sftp)
for (needle = strchr(path + 1, '/'); needle; needle = strchr(needle + 1, '/')) {
*needle = '\0';
- mstat s;
- if (mscp_stat(path, &s, sftp) == 0) {
- if (mstat_is_dir(s)) {
- mscp_stat_free(s);
+ if (mscp_stat(path, &st, sftp) == 0) {
+ if (S_ISDIR(st.st_mode))
goto next; /* directory exists. go deeper */
- } else {
- mscp_stat_free(s);
+ else
return -1; /* path exists, but not directory. */
- }
}
- if (mscp_stat_check_err_noent(sftp) == 0) {
+ if (errno == ENOENT) {
/* no file on the path. create directory. */
if (mscp_mkdir(path, mode, sftp) < 0) {
- mscp_set_error("mkdir %s: %s", path,
- mscp_strerror(sftp));
+ mscp_set_error("mscp_mkdir %s: %s", path, strerrno());
return -1;
}
}
@@ -350,11 +335,13 @@ static int touch_dst_path(struct path *p, sftp_session sftp)
}
/* open file with O_TRUNC to set file size 0 */
- h = mscp_open(p->dst_path, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR, 0, sftp);
- if (mscp_open_is_failed(h))
+ f = mscp_open(p->dst_path, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR, sftp);
+ if (!f) {
+ mscp_set_error("mscp_open %s: %s\n", p->dst_path, strerrno());
return -1;
+ }
- mscp_close(h);
+ mscp_close(f);
return 0;
}
@@ -518,16 +505,16 @@ static int copy_chunk_r2l(struct chunk *c, sftp_file sf, int fd,
return 0;
}
-static int _copy_chunk(struct chunk *c, mfh s, mfh d,
+static int _copy_chunk(struct chunk *c, mf *s, mf *d,
int nr_ahead, int buf_sz, size_t *counter)
{
- if (s.fd > 0 && d.sf) /* local to remote copy */
- return copy_chunk_l2r(c, s.fd, d.sf, nr_ahead, buf_sz, counter);
- else if (s.sf && d.fd > 0) /* remote to local copy */
- return copy_chunk_r2l(c, s.sf, d.fd, nr_ahead, buf_sz, counter);
+ if (s->local && d->remote) /* local to remote copy */
+ return copy_chunk_l2r(c, s->local, d->remote, nr_ahead, buf_sz, counter);
+ else if (s->remote && d->local) /* remote to local copy */
+ return copy_chunk_r2l(c, s->remote, d->local, nr_ahead, buf_sz, counter);
- assert(true); /* not reached */
- return -1;
+ assert(false);
+ return -1; /* not reached */
}
int copy_chunk(FILE *msg_fp, struct chunk *c,
@@ -536,7 +523,7 @@ int copy_chunk(FILE *msg_fp, struct chunk *c,
{
mode_t mode;
int flags;
- mfh s, d;
+ mf *s, *d;
int ret;
assert((src_sftp && !dst_sftp) || (!src_sftp && dst_sftp));
@@ -547,21 +534,33 @@ int copy_chunk(FILE *msg_fp, struct chunk *c,
/* open src */
flags = O_RDONLY;
mode = S_IRUSR;
- s = mscp_open(c->p->path, flags, mode, c->off, src_sftp);
- if (mscp_open_is_failed(s)) {
- mscp_close(d);
+ s = mscp_open(c->p->path, flags, mode, src_sftp);
+ if (!s) {
+ mscp_set_error("mscp_open: %s: %s", c->p->path, strerrno());
+ return -1;
+ }
+ if (mscp_lseek(s, c->off) < 0) {
+ mscp_set_error("mscp_lseek: %s: %s", c->p->path, strerrno());
return -1;
}
/* open dst */
flags = O_WRONLY;
mode = S_IRUSR|S_IWUSR;
- d = mscp_open(c->p->dst_path, flags, mode, c->off, dst_sftp);
- if (mscp_open_is_failed(d))
+ d = mscp_open(c->p->dst_path, flags, mode, dst_sftp);
+ if (!d) {
+ mscp_close(s);
+ mscp_set_error("mscp_open: %s: %s", c->p->dst_path, strerrno());
return -1;
+ }
+ if (mscp_lseek(d, c->off) < 0) {
+ mscp_set_error("mscp_lseek: %s: %s", c->p->dst_path, strerrno());
+ return -1;
+ }
mpr_debug(msg_fp, "copy chunk start: %s 0x%lx-0x%lx\n",
c->p->path, c->off, c->off + c->len);
+
ret = _copy_chunk(c, s, d, nr_ahead, buf_sz, counter);
mpr_debug(msg_fp, "copy chunk done: %s 0x%lx-0x%lx\n",