mirror of
https://github.com/upa/mscp.git
synced 2026-03-12 11:07:42 +08:00
Merge branch 'main' of github.com:upa/mscp
This commit is contained in:
71
src/file.c
71
src/file.c
@@ -135,7 +135,7 @@ int file_directory_exists(char *path, sftp_session sftp)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct file *file_alloc(char *path, size_t size, bool remote)
|
static struct file *file_alloc(char *src_path, size_t size, bool src_is_remote)
|
||||||
{
|
{
|
||||||
struct file *f;
|
struct file *f;
|
||||||
|
|
||||||
@@ -146,16 +146,16 @@ static struct file *file_alloc(char *path, size_t size, bool remote)
|
|||||||
}
|
}
|
||||||
memset(f, 0, sizeof(*f));
|
memset(f, 0, sizeof(*f));
|
||||||
|
|
||||||
strncpy(f->path, path, PATH_MAX - 1);
|
strncpy(f->src_path, src_path, PATH_MAX - 1);
|
||||||
f->size = size;
|
f->size = size;
|
||||||
f->remote = remote;
|
f->src_is_remote = src_is_remote;
|
||||||
f->dst_remote = !remote;
|
f->dst_is_remote = !src_is_remote;
|
||||||
lock_init(&f->lock);
|
lock_init(&f->lock);
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool file_should_skip(char *path)
|
static bool check_file_should_skip(char *path)
|
||||||
{
|
{
|
||||||
int len = strlen(path);
|
int len = strlen(path);
|
||||||
if ((len == 1 && strncmp(path, ".", 1) == 0) ||
|
if ((len == 1 && strncmp(path, ".", 1) == 0) ||
|
||||||
@@ -203,6 +203,15 @@ static int check_file_tobe_copied(char *path, sftp_session sftp, size_t *size)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int check_pathlen(const char *src, const char *dst)
|
||||||
|
{
|
||||||
|
if ((strlen(src) + strlen(dst) + 1) > PATH_MAX) {
|
||||||
|
pr_err("too long path: %s/%s\n", src, dst);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int file_fill_recursive(struct list_head *file_list,
|
static int file_fill_recursive(struct list_head *file_list,
|
||||||
bool dst_is_remote, sftp_session sftp, char *src_path,
|
bool dst_is_remote, sftp_session sftp, char *src_path,
|
||||||
char *rel_path, char *dst_path, bool dst_should_dir)
|
char *rel_path, char *dst_path, bool dst_should_dir)
|
||||||
@@ -236,7 +245,7 @@ static int file_fill_recursive(struct list_head *file_list,
|
|||||||
|
|
||||||
list_add_tail(&f->list, file_list);
|
list_add_tail(&f->list, file_list);
|
||||||
pprint2("file %s %s -> %s %s %luB\n",
|
pprint2("file %s %s -> %s %s %luB\n",
|
||||||
f->path, dst_is_remote ? "(local)" : "(remote)",
|
f->src_path, dst_is_remote ? "(local)" : "(remote)",
|
||||||
f->dst_path, dst_is_remote ? "(remote)" : "(local)",
|
f->dst_path, dst_is_remote ? "(remote)" : "(local)",
|
||||||
f->size);
|
f->size);
|
||||||
|
|
||||||
@@ -253,8 +262,11 @@ static int file_fill_recursive(struct list_head *file_list,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
while ((de = readdir(dir)) != NULL) {
|
while ((de = readdir(dir)) != NULL) {
|
||||||
if (file_should_skip(de->d_name))
|
if (check_file_should_skip(de->d_name))
|
||||||
continue;
|
continue;
|
||||||
|
if (check_pathlen(src_path, de->d_name) < 0 ||
|
||||||
|
check_pathlen(rel_path, basename(src_path)) < 0)
|
||||||
|
return -1;
|
||||||
snprintf(next_src_path, sizeof(next_src_path),
|
snprintf(next_src_path, sizeof(next_src_path),
|
||||||
"%s/%s", src_path, de->d_name);
|
"%s/%s", src_path, de->d_name);
|
||||||
snprintf(next_rel_path, sizeof(next_rel_path),
|
snprintf(next_rel_path, sizeof(next_rel_path),
|
||||||
@@ -275,8 +287,11 @@ static int file_fill_recursive(struct list_head *file_list,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
while ((attr = sftp_readdir(sftp, dir)) != NULL) {
|
while ((attr = sftp_readdir(sftp, dir)) != NULL) {
|
||||||
if (file_should_skip(attr->name))
|
if (check_file_should_skip(attr->name))
|
||||||
continue;
|
continue;
|
||||||
|
if (check_pathlen(src_path, attr->name) < 0 ||
|
||||||
|
check_pathlen(rel_path, basename(src_path)) < 0)
|
||||||
|
return -1;
|
||||||
snprintf(next_src_path, sizeof(next_src_path),
|
snprintf(next_src_path, sizeof(next_src_path),
|
||||||
"%s/%s", src_path, attr->name);
|
"%s/%s", src_path, attr->name);
|
||||||
snprintf(next_rel_path, sizeof(next_rel_path),
|
snprintf(next_rel_path, sizeof(next_rel_path),
|
||||||
@@ -381,8 +396,8 @@ void file_dump(struct list_head *file_list)
|
|||||||
|
|
||||||
list_for_each_entry(f, file_list, list) {
|
list_for_each_entry(f, file_list, list) {
|
||||||
pr_debug("%s %s -> %s %s %lu-byte\n",
|
pr_debug("%s %s -> %s %s %lu-byte\n",
|
||||||
f->path, f->remote ? "(remote)" : "(local)",
|
f->src_path, strloc(f->src_is_remote),
|
||||||
f->dst_path, f->dst_remote ? "(remote)" : "(local)",
|
f->dst_path, strloc(f->dst_is_remote),
|
||||||
f->size);
|
f->size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -444,7 +459,7 @@ int chunk_fill(struct list_head *file_list, struct list_head *chunk_list,
|
|||||||
chunk_sz = min_chunk_sz;
|
chunk_sz = min_chunk_sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_debug("%s chunk_sz %lu-byte\n", f->path, chunk_sz);
|
pr_debug("%s chunk_sz %lu-byte\n", f->src_path, chunk_sz);
|
||||||
|
|
||||||
for (size = f->size; size > 0;) {
|
for (size = f->size; size > 0;) {
|
||||||
c = chunk_alloc(f);
|
c = chunk_alloc(f);
|
||||||
@@ -455,7 +470,7 @@ int chunk_fill(struct list_head *file_list, struct list_head *chunk_list,
|
|||||||
size -= c->len;
|
size -= c->len;
|
||||||
list_add_tail(&c->list, chunk_list);
|
list_add_tail(&c->list, chunk_list);
|
||||||
pprint4("chunk %s 0x%010lx-0x%010lx %luB\n",
|
pprint4("chunk %s 0x%010lx-0x%010lx %luB\n",
|
||||||
c->f->path, c->off, c->off + c->len, c->len);
|
c->f->src_path, c->off, c->off + c->len, c->len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -469,7 +484,7 @@ void chunk_dump(struct list_head *chunk_list)
|
|||||||
|
|
||||||
list_for_each_entry(c, chunk_list, list) {
|
list_for_each_entry(c, chunk_list, list) {
|
||||||
pr_debug("%s %s 0x%010lx-0x%010lx %lu-byte\n",
|
pr_debug("%s %s 0x%010lx-0x%010lx %lu-byte\n",
|
||||||
c->f->path, c->f->remote ? "(remote)" : "(local)",
|
c->f->src_path, strloc(f->src_is_remote),
|
||||||
c->off, c->off + c->len, c->len);
|
c->off, c->off + c->len, c->len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -498,12 +513,12 @@ int chunk_prepare(struct chunk *c, sftp_session sftp)
|
|||||||
|
|
||||||
lock_acquire(&f->lock); /* XXX: is always acquiring lock per-chunk heavy? */
|
lock_acquire(&f->lock); /* XXX: is always acquiring lock per-chunk heavy? */
|
||||||
if (f->state == FILE_STATE_INIT) {
|
if (f->state == FILE_STATE_INIT) {
|
||||||
if (file_dst_prepare(f, f->dst_remote ? sftp : NULL) < 0) {
|
if (file_dst_prepare(f, f->dst_is_remote ? sftp : NULL) < 0) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
f->state = FILE_STATE_OPENED;
|
f->state = FILE_STATE_OPENED;
|
||||||
pprint2("copy start: %s\n", f->path);
|
pprint2("copy start: %s\n", f->src_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -593,7 +608,7 @@ static int chunk_copy_internal(struct chunk *c, int fd, sftp_file sf,
|
|||||||
size_t sftp_buf_sz, size_t io_buf_sz,
|
size_t sftp_buf_sz, size_t io_buf_sz,
|
||||||
bool reverse, size_t *counter)
|
bool reverse, size_t *counter)
|
||||||
{
|
{
|
||||||
int remaind, read_bytes, write_bytes;
|
size_t remaind, read_bytes, write_bytes;
|
||||||
char buf[io_buf_sz];
|
char buf[io_buf_sz];
|
||||||
|
|
||||||
/* if reverse is false, copy fd->sf (local to remote).
|
/* if reverse is false, copy fd->sf (local to remote).
|
||||||
@@ -650,7 +665,7 @@ static int chunk_copy_local_to_remote(struct chunk *c, sftp_session sftp,
|
|||||||
|
|
||||||
flags = O_RDONLY;
|
flags = O_RDONLY;
|
||||||
mode = S_IRUSR;
|
mode = S_IRUSR;
|
||||||
if ((fd = chunk_open_local(f->path, flags, mode, c->off)) < 0) {
|
if ((fd = chunk_open_local(f->src_path, flags, mode, c->off)) < 0) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -663,10 +678,10 @@ static int chunk_copy_local_to_remote(struct chunk *c, sftp_session sftp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = chunk_copy_internal(c, fd, sf, sftp_buf_sz, io_buf_sz, false, counter);
|
ret = chunk_copy_internal(c, fd, sf, sftp_buf_sz, io_buf_sz, false, counter);
|
||||||
if (ret< 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if ((mode = chunk_get_mode(f->path, NULL)) < 0) {
|
if ((mode = chunk_get_mode(f->src_path, NULL)) < 0) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -702,7 +717,7 @@ static int chunk_copy_remote_to_local(struct chunk *c, sftp_session sftp,
|
|||||||
|
|
||||||
flags = O_RDONLY;
|
flags = O_RDONLY;
|
||||||
mode = S_IRUSR;
|
mode = S_IRUSR;
|
||||||
if (!(sf = chunk_open_remote(f->path, flags, mode, c->off, sftp))) {
|
if (!(sf = chunk_open_remote(f->src_path, flags, mode, c->off, sftp))) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -729,14 +744,14 @@ int chunk_copy(struct chunk *c, sftp_session sftp, size_t sftp_buf_sz, size_t io
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
pr_debug("copy %s %s -> %s %s off=0x%010lx\n",
|
pr_debug("copy %s %s -> %s %s off=0x%010lx\n",
|
||||||
f->path, f->remote ? "(remote)" : "(local)",
|
f->src_path, strloc(f->src_is_remote),
|
||||||
f->dst_path, f->dst_remote ? "(remote)" : "(local)", c->off);
|
f->dst_path, strloc(f->dst_is_remote), c->off);
|
||||||
|
|
||||||
pprint4("copy start: chunk %s 0x%010lx-0x%010lx %luB\n",
|
pprint4("copy start: chunk %s 0x%010lx-0x%010lx %luB\n",
|
||||||
c->f->path, c->off, c->off + c->len, c->len);
|
c->f->src_path, c->off, c->off + c->len, c->len);
|
||||||
|
|
||||||
|
|
||||||
if (f->dst_remote)
|
if (f->dst_is_remote)
|
||||||
ret = chunk_copy_local_to_remote(c, sftp,
|
ret = chunk_copy_local_to_remote(c, sftp,
|
||||||
sftp_buf_sz, io_buf_sz, counter);
|
sftp_buf_sz, io_buf_sz, counter);
|
||||||
else
|
else
|
||||||
@@ -747,15 +762,15 @@ int chunk_copy(struct chunk *c, sftp_session sftp, size_t sftp_buf_sz, size_t io
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
pr_debug("done %s %s -> %s %s off=0x%010lx\n",
|
pr_debug("done %s %s -> %s %s off=0x%010lx\n",
|
||||||
f->path, f->remote ? "(remote)" : "(local)",
|
f->src_path, strloc(f->src_is_remote),
|
||||||
f->dst_path, f->dst_remote ? "(remote)" : "(local)", c->off);
|
f->dst_path, strloc(f->dst_is_remote), c->off);
|
||||||
|
|
||||||
pprint4("copy done: chunk %s 0x%010lx-0x%010lx %luB\n",
|
pprint4("copy done: chunk %s 0x%010lx-0x%010lx %luB\n",
|
||||||
c->f->path, c->off, c->off + c->len, c->len);
|
c->f->src_path, c->off, c->off + c->len, c->len);
|
||||||
|
|
||||||
if (refcnt_dec(&f->refcnt) == 0) {
|
if (refcnt_dec(&f->refcnt) == 0) {
|
||||||
f->state = FILE_STATE_DONE;
|
f->state = FILE_STATE_DONE;
|
||||||
pprint2("copy done: %s\n", f->path);
|
pprint2("copy done: %s\n", f->src_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
12
src/file.h
12
src/file.h
@@ -12,12 +12,12 @@
|
|||||||
struct file {
|
struct file {
|
||||||
struct list_head list; /* mscp->file_list */
|
struct list_head list; /* mscp->file_list */
|
||||||
|
|
||||||
char path[PATH_MAX]; /* copy source path */
|
char src_path[PATH_MAX]; /* copy source path */
|
||||||
bool remote; /* source is remote */
|
bool src_is_remote; /* source is remote */
|
||||||
size_t size; /* size of this file */
|
size_t size; /* size of this file */
|
||||||
|
|
||||||
char dst_path[PATH_MAX]; /* copy destination path */
|
char dst_path[PATH_MAX]; /* copy destination path */
|
||||||
bool dst_remote; /* destination is remote */
|
bool dst_is_remote; /* destination is remote */
|
||||||
|
|
||||||
int state; /* destination file state */
|
int state; /* destination file state */
|
||||||
lock lock; /* mutex to protect state */
|
lock lock; /* mutex to protect state */
|
||||||
@@ -27,6 +27,8 @@ struct file {
|
|||||||
#define FILE_STATE_OPENED 1
|
#define FILE_STATE_OPENED 1
|
||||||
#define FILE_STATE_DONE 2
|
#define FILE_STATE_DONE 2
|
||||||
|
|
||||||
|
#define strloc(is_remote) is_remote ? "(remote)" : "(local)"
|
||||||
|
|
||||||
/* Allocating chunk increments refcnt of the associating file.
|
/* Allocating chunk increments refcnt of the associating file.
|
||||||
* Multiple threads copying files follows:
|
* Multiple threads copying files follows:
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -425,9 +425,9 @@ static void print_progress_bar(double percent, char *suffix)
|
|||||||
struct winsize ws;
|
struct winsize ws;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* [=======> ] XX.X% SUFFIX
|
* [=======> ] XX.X% SUFFIX
|
||||||
*/
|
*/
|
||||||
|
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ static int ssh_authenticate(ssh_session ssh, struct ssh_opts *opts)
|
|||||||
int auth_bit_mask;
|
int auth_bit_mask;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* none method */
|
/* none method */
|
||||||
ret = ssh_userauth_none(ssh, NULL);
|
ret = ssh_userauth_none(ssh, NULL);
|
||||||
if (ret == SSH_AUTH_SUCCESS)
|
if (ret == SSH_AUTH_SUCCESS)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -178,12 +178,12 @@ static int ssh_verify_known_hosts(ssh_session session)
|
|||||||
state = ssh_session_is_known_server(session);
|
state = ssh_session_is_known_server(session);
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case SSH_KNOWN_HOSTS_OK:
|
case SSH_KNOWN_HOSTS_OK:
|
||||||
/* OK */
|
/* OK */
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case SSH_KNOWN_HOSTS_CHANGED:
|
case SSH_KNOWN_HOSTS_CHANGED:
|
||||||
fprintf(stderr, "Host key for server changed: it is now:\n");
|
fprintf(stderr, "Host key for server changed: it is now:\n");
|
||||||
//ssh_print_hexa("Public key hash", hash, hlen);
|
//ssh_print_hexa("Public key hash", hash, hlen);
|
||||||
fprintf(stderr, "For security reasons, connection will be stopped\n");
|
fprintf(stderr, "For security reasons, connection will be stopped\n");
|
||||||
ssh_clean_pubkey_hash(&hash);
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
|
||||||
@@ -201,12 +201,13 @@ static int ssh_verify_known_hosts(ssh_session session)
|
|||||||
fprintf(stderr, "If you accept the host key here, the file will be"
|
fprintf(stderr, "If you accept the host key here, the file will be"
|
||||||
"automatically created.\n");
|
"automatically created.\n");
|
||||||
|
|
||||||
/* FALL THROUGH to SSH_SERVER_NOT_KNOWN behavior */
|
/* FALL THROUGH to SSH_SERVER_NOT_KNOWN behavior */
|
||||||
|
|
||||||
case SSH_KNOWN_HOSTS_UNKNOWN:
|
case SSH_KNOWN_HOSTS_UNKNOWN:
|
||||||
hexa = ssh_get_hexa(hash, hlen);
|
hexa = ssh_get_hexa(hash, hlen);
|
||||||
fprintf(stderr,"The server is unknown. Do you trust the host key?\n");
|
fprintf(stderr,"The server is unknown. Do you trust the host key?\n");
|
||||||
fprintf(stderr, "Public key hash: %s\n", hexa);
|
fprintf(stderr, "Public key hash: %s\n", hexa);
|
||||||
|
fprintf(stderr, "(yes/no): ");
|
||||||
ssh_string_free_char(hexa);
|
ssh_string_free_char(hexa);
|
||||||
ssh_clean_pubkey_hash(&hash);
|
ssh_clean_pubkey_hash(&hash);
|
||||||
p = fgets(buf, sizeof(buf), stdin);
|
p = fgets(buf, sizeof(buf), stdin);
|
||||||
|
|||||||
Reference in New Issue
Block a user