mirror of
https://github.com/upa/mscp.git
synced 2026-02-04 03:24:58 +08:00
refactor error message-related functions
split message print fuctions (mpr_*), strerrno, and mscp_get/set_error into print.c/h and strerrno.c/h. ToDo: revise usages of priv_set_errv and pr_* functions.
This commit is contained in:
@@ -98,7 +98,8 @@ list(APPEND MSCP_BUILD_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||
|
||||
# libmscp.a
|
||||
set(LIBMSCP_SRC
|
||||
src/mscp.c src/ssh.c src/fileops.c src/path.c src/platform.c src/message.c
|
||||
src/mscp.c src/ssh.c src/fileops.c src/path.c src/platform.c
|
||||
src/print.c src/strerrno.c
|
||||
${OPENBSD_COMPAT_SRC})
|
||||
add_library(mscp-static STATIC ${LIBMSCP_SRC})
|
||||
target_include_directories(mscp-static
|
||||
|
||||
@@ -120,7 +120,6 @@ struct mscp *mscp_init(const char *remote_host, int direction,
|
||||
* @param m mscp instance.
|
||||
*
|
||||
* @return 0 on success, < 0 if an error occured.
|
||||
* mscp_get_error() can be used to retrieve error message.
|
||||
*/
|
||||
int mscp_connect(struct mscp *m);
|
||||
|
||||
@@ -136,7 +135,6 @@ int mscp_connect(struct mscp *m);
|
||||
* @param src_path source file path to be copied.
|
||||
*
|
||||
* @return 0 on success, < 0 if an error occured.
|
||||
* mscp_get_error() can be used to retrieve error message.
|
||||
*/
|
||||
int mscp_add_src_path(struct mscp *m, const char *src_path);
|
||||
|
||||
@@ -150,7 +148,6 @@ int mscp_add_src_path(struct mscp *m, const char *src_path);
|
||||
* @param dst_path destination path to which source files copied.
|
||||
*
|
||||
* @return 0 on success, < 0 if an error occured.
|
||||
* mscp_get_error() can be used to retrieve error message.
|
||||
*/
|
||||
int mscp_set_dst_path(struct mscp *m, const char *dst_path);
|
||||
|
||||
@@ -165,7 +162,6 @@ int mscp_set_dst_path(struct mscp *m, const char *dst_path);
|
||||
* @param m mscp instance.
|
||||
*
|
||||
* @return 0 on success, < 0 if an error occured.
|
||||
* mscp_get_error() can be used to retrieve error message.
|
||||
*/
|
||||
int mscp_scan(struct mscp *m);
|
||||
|
||||
@@ -176,7 +172,6 @@ int mscp_scan(struct mscp *m);
|
||||
*
|
||||
* @param m mscp instance.
|
||||
* @return 0 on success, < 0 if an error occured.
|
||||
* mscp_get_error() can be used to retrieve error message.
|
||||
*/
|
||||
int mscp_scan_join(struct mscp *m);
|
||||
|
||||
@@ -189,7 +184,6 @@ int mscp_scan_join(struct mscp *m);
|
||||
* @param m mscp instance.
|
||||
*
|
||||
* @return number of threads on success, < 0 if an error occured.
|
||||
* mscp_get_error() can be used to retrieve error message.
|
||||
*
|
||||
* @see mscp_join()
|
||||
*/
|
||||
@@ -211,7 +205,6 @@ void mscp_stop(struct mscp *m);
|
||||
* @param m mscp instance.
|
||||
*
|
||||
* @return 0 on success, < 0 if an error occured.
|
||||
* mscp_get_error() can be used to retrieve error message.
|
||||
*/
|
||||
int mscp_join(struct mscp *m);
|
||||
|
||||
@@ -261,15 +254,4 @@ enum {
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the recent error message from libmscp. Note that this
|
||||
* function is not thread-safe.
|
||||
*
|
||||
* @return pointer to the message.
|
||||
*/
|
||||
const char *mscp_get_error(void);
|
||||
|
||||
|
||||
|
||||
#endif /* _MSCP_H_ */
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <message.h>
|
||||
|
||||
typedef int refcnt;
|
||||
|
||||
static inline void refcnt_inc(refcnt *cnt)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#include <fileops.h>
|
||||
#include <ssh.h>
|
||||
#include <message.h>
|
||||
#include <print.h>
|
||||
#include <platform.h>
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ static void sftp_err_to_errno(sftp_session sftp)
|
||||
errno = ENODEV;
|
||||
break;
|
||||
default:
|
||||
mpr_warn("unkown SSH_FX response %d", sftperr);
|
||||
pr_warn("unkown SSH_FX response %d", sftperr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ static void sftp_attr_to_stat(sftp_attributes attr, struct stat *st)
|
||||
st->st_mode |= S_IFIFO; /* really? */
|
||||
break;
|
||||
default:
|
||||
mpr_warn("unkown SSH_FILEXFER_TYPE %d", attr->type);
|
||||
pr_warn("unkown SSH_FILEXFER_TYPE %d", attr->type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
36
src/main.c
36
src/main.c
@@ -12,7 +12,10 @@
|
||||
#include <pthread.h>
|
||||
|
||||
#include <mscp.h>
|
||||
#include <util.h>
|
||||
#include <minmax.h>
|
||||
#include <strerrno.h>
|
||||
#include <print.h>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
@@ -79,7 +82,7 @@ char *split_user_host_path(const char *s, char **userp, char **hostp, char **pat
|
||||
bool inbrackets = false;
|
||||
|
||||
if (!(tmp = strdup(s))) {
|
||||
fprintf(stderr, "stdrup: %s\n", strerror(errno));
|
||||
pr_err("stdrup: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -174,7 +177,7 @@ struct target *validate_targets(char **arg, int len)
|
||||
int n;
|
||||
|
||||
if ((t = calloc(len, sizeof(struct target))) == NULL) {
|
||||
fprintf(stderr, "calloc: %s\n", strerror(errno));
|
||||
pr_err("calloc: %s", strerrno());
|
||||
return NULL;
|
||||
}
|
||||
memset(t, 0, len * sizeof(struct target));
|
||||
@@ -198,19 +201,19 @@ struct target *validate_targets(char **arg, int len)
|
||||
|
||||
/* check inconsistent remote position in args */
|
||||
if (t[0].host == NULL && t[len - 1].host == NULL) {
|
||||
fprintf(stderr, "no remote host given\n");
|
||||
pr_err("no remote host given");
|
||||
goto free_split_out;
|
||||
}
|
||||
|
||||
if (t[0].host != NULL && t[len - 1].host != NULL) {
|
||||
fprintf(stderr, "no local path given\n");
|
||||
pr_err("no local path given");
|
||||
goto free_split_out;
|
||||
}
|
||||
|
||||
return t;
|
||||
|
||||
invalid_remotes:
|
||||
fprintf(stderr, "invalid remote host notation\n");
|
||||
pr_err("invalid remote host notation");
|
||||
|
||||
free_split_out:
|
||||
for (n = 0; n < len; n++)
|
||||
@@ -263,8 +266,7 @@ int main(int argc, char **argv)
|
||||
case 'n':
|
||||
o.nr_threads = atoi(optarg);
|
||||
if (o.nr_threads < 1) {
|
||||
fprintf(stderr, "invalid number of connections: %s\n",
|
||||
optarg);
|
||||
pr_err( "invalid number of connections: %s", optarg);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
@@ -373,29 +375,29 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
if ((m = mscp_init(remote, direction, &o, &s)) == NULL) {
|
||||
fprintf(stderr, "mscp_init: %s\n", mscp_get_error());
|
||||
pr_err("mscp_init: %s", priv_get_err());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mscp_connect(m) < 0) {
|
||||
fprintf(stderr, "mscp_connect: %s\n", mscp_get_error());
|
||||
pr_err("mscp_connect: %s", priv_get_err());
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (n = 0; n < i - 1; n++) {
|
||||
if (mscp_add_src_path(m, t[n].path) < 0) {
|
||||
fprintf(stderr, "mscp_add_src_path: %s\n", mscp_get_error());
|
||||
pr_err("mscp_add_src_path: %s", priv_get_err());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (mscp_set_dst_path(m, t[i - 1].path) < 0) {
|
||||
fprintf(stderr, "mscp_set_dst_path: %s\n", mscp_get_error());
|
||||
pr_err("mscp_set_dst_path: %s", priv_get_err());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mscp_scan(m) < 0) {
|
||||
fprintf(stderr, "mscp_scan: %s\n", mscp_get_error());
|
||||
pr_err("mscp_scan: %s", priv_get_err());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -405,22 +407,22 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (pthread_create(&tid_stat, NULL, print_stat_thread, NULL) < 0) {
|
||||
fprintf(stderr, "pthread_create: %s\n", strerror(errno));
|
||||
pr_err("pthread_create: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (signal(SIGINT, sigint_handler) == SIG_ERR) {
|
||||
fprintf(stderr, "signal: %s\n", strerror(errno));
|
||||
pr_err("signal: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = mscp_start(m);
|
||||
if (ret < 0)
|
||||
fprintf(stderr, "mscp_start: %s\n", mscp_get_error());
|
||||
pr_err("mscp_start: %s", priv_get_err());
|
||||
|
||||
ret = mscp_join(m);
|
||||
if (ret != 0)
|
||||
fprintf(stderr, "mscp_join: %s\n", mscp_get_error());
|
||||
pr_err("mscp_join: %s", priv_get_err());
|
||||
|
||||
pthread_cancel(tid_stat);
|
||||
pthread_join(tid_stat, NULL);
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-only */
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <util.h>
|
||||
#include <message.h>
|
||||
|
||||
/* strerror_r wrapper */
|
||||
__thread char thread_strerror[128];
|
||||
|
||||
/* mscp error message buffer */
|
||||
#define MSCP_ERRMSG_SIZE (PATH_MAX * 2)
|
||||
|
||||
static char errmsg[MSCP_ERRMSG_SIZE];
|
||||
|
||||
void _mscp_set_error(const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
memset(errmsg, 0, sizeof(errmsg));
|
||||
va_start(va, fmt);
|
||||
vsnprintf(errmsg, sizeof(errmsg) - 1, fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
const char *mscp_get_error()
|
||||
{
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
|
||||
/* message print functions */
|
||||
|
||||
static int mprint_severity = MSCP_SEVERITY_WARN;
|
||||
|
||||
void mprint_set_severity(int serverity)
|
||||
{
|
||||
if (serverity < 0)
|
||||
mprint_severity = -1; /* no print */
|
||||
mprint_severity = serverity;
|
||||
}
|
||||
|
||||
int mprint_get_severity()
|
||||
{
|
||||
return mprint_severity;
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-only */
|
||||
#ifndef _MESSAGE_H_
|
||||
#define _MESSAGE_H_
|
||||
|
||||
#include <libgen.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <mscp.h>
|
||||
|
||||
/* message print. printed messages are passed to application via msg_fd */
|
||||
void mprint_set_severity(int severity);
|
||||
int mprint_get_severity();
|
||||
|
||||
#define mprint(fp, severity, fmt, ...) \
|
||||
do { \
|
||||
if (severity <= mprint_get_severity()) { \
|
||||
fprintf(fp, "\r\033[K" fmt "\n", ##__VA_ARGS__); \
|
||||
fflush(fp); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define mpr_err(fmt, ...) \
|
||||
mprint(stderr, MSCP_SEVERITY_ERR, fmt, ##__VA_ARGS__)
|
||||
#define mpr_warn(fmt, ...) \
|
||||
mprint(stderr, MSCP_SEVERITY_WARN, fmt, ##__VA_ARGS__)
|
||||
#define mpr_notice(fmt, ...) \
|
||||
mprint(stdout, MSCP_SEVERITY_NOTICE, fmt, ##__VA_ARGS__)
|
||||
#define mpr_info(fmt, ...) \
|
||||
mprint(stdout, MSCP_SEVERITY_INFO, fmt, ##__VA_ARGS__)
|
||||
#define mpr_debug(fmt, ...) \
|
||||
mprint(stdout, MSCP_SEVERITY_DEBUG, fmt, ##__VA_ARGS__)
|
||||
|
||||
|
||||
/* errorno wrapper */
|
||||
extern __thread char thread_strerror[128];
|
||||
|
||||
#ifdef _GNU_SOURCE
|
||||
/* GNU strerror_r */
|
||||
#define strerrno() \
|
||||
strerror_r(errno, thread_strerror, sizeof(thread_strerror))
|
||||
#else
|
||||
/* this macro assumes that strerror_r never fails. any good way? */
|
||||
#define strerrno() \
|
||||
(strerror_r(errno, thread_strerror, sizeof(thread_strerror)) \
|
||||
? thread_strerror : thread_strerror)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* error message buffer */
|
||||
#define mscp_set_error(fmt, ...) \
|
||||
_mscp_set_error("%s:%d:%s: " fmt "\0", \
|
||||
basename(__FILE__), __LINE__, __func__, ##__VA_ARGS__)
|
||||
|
||||
void _mscp_set_error(const char *fmt, ...);
|
||||
|
||||
#endif /* _MESSAGE_H_ */
|
||||
8
src/minmax.h
Normal file
8
src/minmax.h
Normal file
@@ -0,0 +1,8 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-only */
|
||||
#ifndef _MINMAX_H_
|
||||
#define _MINMAX_H_
|
||||
|
||||
#define min(a, b) (((a) > (b)) ? (b) : (a))
|
||||
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
#endif /* _MINMAX_H_ */
|
||||
88
src/mscp.c
88
src/mscp.c
@@ -7,13 +7,14 @@
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <list.h>
|
||||
#include <util.h>
|
||||
#include <ssh.h>
|
||||
#include <minmax.h>
|
||||
#include <ssh.h>
|
||||
#include <path.h>
|
||||
#include <fileops.h>
|
||||
#include <atomic.h>
|
||||
#include <atomic.h>
|
||||
#include <platform.h>
|
||||
#include <message.h>
|
||||
#include <print.h>
|
||||
#include <strerrno.h>
|
||||
#include <mscp.h>
|
||||
|
||||
#include <openbsd-compat/openbsd-compat.h>
|
||||
@@ -101,7 +102,7 @@ static int expand_coremask(const char *coremask, int **cores, int *nr_cores)
|
||||
|
||||
core_list = realloc(NULL, sizeof(int) * 64);
|
||||
if (!core_list) {
|
||||
mscp_set_error("failed to realloc: %s", strerrno());
|
||||
priv_set_errv("failed to realloc: %s", strerrno());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -111,7 +112,7 @@ static int expand_coremask(const char *coremask, int **cores, int *nr_cores)
|
||||
c[0] = _coremask[n];
|
||||
v = strtol(c, NULL, 16);
|
||||
if (v == LONG_MIN || v == LONG_MAX) {
|
||||
mscp_set_error("invalid coremask: %s", coremask);
|
||||
priv_set_errv("invalid coremask: %s", coremask);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -123,7 +124,7 @@ static int expand_coremask(const char *coremask, int **cores, int *nr_cores)
|
||||
nr_usable++;
|
||||
core_list = realloc(core_list, sizeof(int) * nr_usable);
|
||||
if (!core_list) {
|
||||
mscp_set_error("realloc: %s", strerrno());
|
||||
priv_set_errv("realloc: %s", strerrno());
|
||||
return -1;
|
||||
}
|
||||
core_list[nr_usable - 1] = nr_all - 1;
|
||||
@@ -132,7 +133,7 @@ static int expand_coremask(const char *coremask, int **cores, int *nr_cores)
|
||||
}
|
||||
|
||||
if (nr_usable < 1) {
|
||||
mscp_set_error("invalid core mask: %s", coremask);
|
||||
priv_set_errv("invalid core mask: %s", coremask);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -149,13 +150,13 @@ static int default_nr_threads()
|
||||
static int validate_and_set_defaut_params(struct mscp_opts *o)
|
||||
{
|
||||
if (o->nr_threads < 0) {
|
||||
mscp_set_error("invalid nr_threads: %d", o->nr_threads);
|
||||
priv_set_errv("invalid nr_threads: %d", o->nr_threads);
|
||||
return -1;
|
||||
} else if (o->nr_threads == 0)
|
||||
o->nr_threads = default_nr_threads();
|
||||
|
||||
if (o->nr_ahead < 0) {
|
||||
mscp_set_error("invalid nr_ahead: %d", o->nr_ahead);
|
||||
priv_set_errv("invalid nr_ahead: %d", o->nr_ahead);
|
||||
return -1;
|
||||
} else if (o->nr_ahead == 0)
|
||||
o->nr_ahead = DEFAULT_NR_AHEAD;
|
||||
@@ -165,7 +166,7 @@ static int validate_and_set_defaut_params(struct mscp_opts *o)
|
||||
else {
|
||||
if (o->min_chunk_sz < getpagesize() ||
|
||||
o->min_chunk_sz % getpagesize() != 0) {
|
||||
mscp_set_error("min chunk size must be "
|
||||
priv_set_errv("min chunk size must be "
|
||||
"larget than and multiple of page size %d: %lu",
|
||||
getpagesize(), o->min_chunk_sz);
|
||||
return -1;
|
||||
@@ -175,12 +176,12 @@ static int validate_and_set_defaut_params(struct mscp_opts *o)
|
||||
if (o->max_chunk_sz) {
|
||||
if (o->max_chunk_sz < getpagesize() ||
|
||||
o->max_chunk_sz % getpagesize() != 0) {
|
||||
mscp_set_error("min chunk size must be larget than and "
|
||||
priv_set_errv("min chunk size must be larget than and "
|
||||
"multiple of page size %d: %lu",
|
||||
getpagesize(), o->max_chunk_sz);
|
||||
}
|
||||
if (o->min_chunk_sz > o->max_chunk_sz) {
|
||||
mscp_set_error("smaller max chunk size than "
|
||||
priv_set_errv("smaller max chunk size than "
|
||||
"min chunk size: %lu < %lu",
|
||||
o->max_chunk_sz, o->min_chunk_sz);
|
||||
return -1;
|
||||
@@ -190,14 +191,14 @@ static int validate_and_set_defaut_params(struct mscp_opts *o)
|
||||
if (o->buf_sz == 0)
|
||||
o->buf_sz = DEFAULT_BUF_SZ;
|
||||
else if (o->buf_sz == 0) {
|
||||
mscp_set_error("invalid buf size: %lu", o->buf_sz);
|
||||
priv_set_errv("invalid buf size: %lu", o->buf_sz);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (o->max_startups == 0)
|
||||
o->max_startups = DEFAULT_MAX_STARTUPS;
|
||||
else if (o->max_startups < 0) {
|
||||
mscp_set_error("invalid max_startups: %d", o->max_startups);
|
||||
priv_set_errv("invalid max_startups: %d", o->max_startups);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -216,17 +217,17 @@ struct mscp *mscp_init(const char *remote_host, int direction,
|
||||
int n;
|
||||
|
||||
if (!remote_host) {
|
||||
mscp_set_error("empty remote host");
|
||||
priv_set_errv("empty remote host");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(direction == MSCP_DIRECTION_L2R ||
|
||||
direction == MSCP_DIRECTION_R2L)) {
|
||||
mscp_set_error("invalid copy direction: %d", direction);
|
||||
priv_set_errv("invalid copy direction: %d", direction);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mprint_set_severity(o->severity);
|
||||
set_print_severity(o->severity);
|
||||
|
||||
if (validate_and_set_defaut_params(o) < 0) {
|
||||
return NULL;
|
||||
@@ -234,7 +235,7 @@ struct mscp *mscp_init(const char *remote_host, int direction,
|
||||
|
||||
m = malloc(sizeof(*m));
|
||||
if (!m) {
|
||||
mscp_set_error("failed to allocate memory: %s", strerrno());
|
||||
priv_set_errv("failed to allocate memory: %s", strerrno());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -247,13 +248,13 @@ struct mscp *mscp_init(const char *remote_host, int direction,
|
||||
rwlock_init(&m->thread_rwlock);
|
||||
|
||||
if ((m->sem = sem_create(o->max_startups)) == NULL) {
|
||||
mscp_set_error("sem_create: %s", strerrno());
|
||||
priv_set_errv("sem_create: %s", strerrno());
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
m->remote = strdup(remote_host);
|
||||
if (!m->remote) {
|
||||
mscp_set_error("failed to allocate memory: %s", strerrno());
|
||||
priv_set_errv("failed to allocate memory: %s", strerrno());
|
||||
goto free_out;
|
||||
}
|
||||
m->direction = direction;
|
||||
@@ -267,7 +268,7 @@ struct mscp *mscp_init(const char *remote_host, int direction,
|
||||
snprintf(c, sizeof(c) - 1, " %d", m->cores[n]);
|
||||
strlcat(b, c, sizeof(b));
|
||||
}
|
||||
mpr_notice("usable cpu cores:%s", b);
|
||||
pr_notice("usable cpu cores:%s", b);
|
||||
}
|
||||
|
||||
m->opts = o;
|
||||
@@ -295,14 +296,14 @@ int mscp_add_src_path(struct mscp *m, const char *src_path)
|
||||
|
||||
s = malloc(sizeof(*s));
|
||||
if (!s) {
|
||||
mscp_set_error("failed to allocate memory: %s", strerrno());
|
||||
priv_set_errv("failed to allocate memory: %s", strerrno());
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->path = strdup(src_path);
|
||||
if (!s->path) {
|
||||
mscp_set_error("failed to allocate memory: %s", strerrno());
|
||||
priv_set_errv("failed to allocate memory: %s", strerrno());
|
||||
free(s);
|
||||
return -1;
|
||||
}
|
||||
@@ -314,7 +315,7 @@ int mscp_add_src_path(struct mscp *m, const char *src_path)
|
||||
int mscp_set_dst_path(struct mscp *m, const char *dst_path)
|
||||
{
|
||||
if (strlen(dst_path) + 1 >= PATH_MAX) {
|
||||
mscp_set_error("too long dst path: %s", dst_path);
|
||||
priv_set_errv("too long dst path: %s", dst_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -388,7 +389,7 @@ void *mscp_scan_thread(void *arg)
|
||||
dst_sftp = NULL;
|
||||
break;
|
||||
default:
|
||||
mscp_set_error("invalid copy direction: %d", m->direction);
|
||||
priv_set_errv("invalid copy direction: %d", m->direction);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
@@ -410,19 +411,19 @@ void *mscp_scan_thread(void *arg)
|
||||
a.max_chunk_sz = m->opts->max_chunk_sz;
|
||||
a.chunk_align = get_page_mask();
|
||||
|
||||
mpr_info("start to walk source path(s)");
|
||||
pr_info("start to walk source path(s)");
|
||||
|
||||
/* walk a src_path recusively, and resolve path->dst_path for each src */
|
||||
list_for_each_entry(s, &m->src_list, list) {
|
||||
memset(&pglob, 0, sizeof(pglob));
|
||||
if (mscp_glob(s->path, GLOB_NOCHECK, &pglob, src_sftp) < 0) {
|
||||
mscp_set_error("mscp_glob: %s", strerrno());
|
||||
priv_set_errv("mscp_glob: %s", strerrno());
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
for (n = 0; n < pglob.gl_pathc; n++) {
|
||||
if (mscp_stat(pglob.gl_pathv[n], &ss, src_sftp) < 0) {
|
||||
mscp_set_error("stat: %s %s", s->path, strerrno());
|
||||
priv_set_errv("stat: %s %s", s->path, strerrno());
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
@@ -443,7 +444,7 @@ void *mscp_scan_thread(void *arg)
|
||||
mscp_globfree(&pglob);
|
||||
}
|
||||
|
||||
mpr_info("walk source path(s) done");
|
||||
pr_info("walk source path(s) done");
|
||||
chunk_pool_set_filled(&m->cp);
|
||||
m->ret_scan = 0;
|
||||
return NULL;
|
||||
@@ -458,7 +459,7 @@ int mscp_scan(struct mscp *m)
|
||||
{
|
||||
int ret = pthread_create(&m->tid_scan, NULL, mscp_scan_thread, m);
|
||||
if (ret < 0) {
|
||||
mscp_set_error("pthread_create_error: %d", ret);
|
||||
priv_set_errv("pthread_create_error: %d", ret);
|
||||
m->tid_scan = 0;
|
||||
mscp_stop(m);
|
||||
return -1;
|
||||
@@ -497,7 +498,7 @@ static struct mscp_thread *mscp_copy_thread_spawn(struct mscp *m, int id)
|
||||
|
||||
t = malloc(sizeof(*t));
|
||||
if (!t){
|
||||
mscp_set_error("malloc: %s,", strerrno());
|
||||
priv_set_errv("malloc: %s,", strerrno());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -511,7 +512,7 @@ static struct mscp_thread *mscp_copy_thread_spawn(struct mscp *m, int id)
|
||||
|
||||
ret = pthread_create(&t->tid, NULL, mscp_copy_thread, t);
|
||||
if (ret < 0) {
|
||||
mscp_set_error("pthread_create error: %d", ret);
|
||||
priv_set_errv("pthread_create error: %d", ret);
|
||||
free(t);
|
||||
return NULL;
|
||||
}
|
||||
@@ -526,7 +527,7 @@ int mscp_start(struct mscp *m)
|
||||
int n, ret = 0;
|
||||
|
||||
if ((n = chunk_pool_size(&m->cp)) < m->opts->nr_threads) {
|
||||
mpr_notice("we have only %d chunk(s). "
|
||||
pr_notice("we have only %d chunk(s). "
|
||||
"set number of connections to %d", n, n);
|
||||
m->opts->nr_threads = n;
|
||||
}
|
||||
@@ -534,7 +535,7 @@ int mscp_start(struct mscp *m)
|
||||
for (n = 0; n < m->opts->nr_threads; n++) {
|
||||
t = mscp_copy_thread_spawn(m, n);
|
||||
if (!t) {
|
||||
mpr_err("failed to spawn copy thread");
|
||||
pr_err("failed to spawn copy thread");
|
||||
break;
|
||||
}
|
||||
RWLOCK_WRITE_ACQUIRE(&m->thread_rwlock);
|
||||
@@ -582,7 +583,7 @@ int mscp_join(struct mscp *m)
|
||||
}
|
||||
}
|
||||
|
||||
mpr_notice("%lu/%lu bytes copied for %lu/%lu files",
|
||||
pr_notice("%lu/%lu bytes copied for %lu/%lu files",
|
||||
done, m->total_bytes, nr_copied, nr_tobe_copied);
|
||||
|
||||
return ret;
|
||||
@@ -627,29 +628,29 @@ void *mscp_copy_thread(void *arg)
|
||||
}
|
||||
|
||||
if (sem_wait(m->sem) < 0) {
|
||||
mpr_err("sem_wait: %s", strerrno());
|
||||
pr_err("sem_wait: %s", strerrno());
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (!(nomore = chunk_pool_is_empty(&m->cp))) {
|
||||
if (m->opts->interval > 0)
|
||||
wait_for_interval(m->opts->interval);
|
||||
mpr_notice("thread:%d connecting to %s", t->id, m->remote);
|
||||
pr_notice("thread:%d connecting to %s", t->id, m->remote);
|
||||
t->sftp = ssh_init_sftp_session(m->remote, m->ssh_opts);
|
||||
}
|
||||
|
||||
if (sem_post(m->sem) < 0) {
|
||||
mpr_err("sem_post: %s", strerrno());
|
||||
pr_err("sem_post: %s", strerrno());
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (nomore) {
|
||||
mpr_notice("thread:%d no more connections needed", t->id);
|
||||
pr_notice("thread:%d no more connections needed", t->id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!t->sftp) {
|
||||
mpr_err("thread:%d: %s", t->id, mscp_get_error());
|
||||
pr_err("thread:%d: %s", t->id, priv_get_err());
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
@@ -685,8 +686,8 @@ void *mscp_copy_thread(void *arg)
|
||||
pthread_cleanup_pop(1);
|
||||
|
||||
if (t->ret < 0)
|
||||
mpr_err("thread:%d copy failed: %s 0x%010lx-0x%010lx",
|
||||
t->id, c->p->path, c->off, c->off + c->len);
|
||||
pr_err("thread:%d copy failed: %s 0x%010lx-0x%010lx",
|
||||
t->id, c->p->path, c->off, c->off + c->len);
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -777,3 +778,4 @@ void mscp_get_stats(struct mscp *m, struct mscp_stats *s)
|
||||
|
||||
s->finished = nr_threads > 0 ? (nr_finished == nr_threads) : false;
|
||||
}
|
||||
|
||||
|
||||
67
src/path.c
67
src/path.c
@@ -7,12 +7,13 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include <ssh.h>
|
||||
#include <util.h>
|
||||
#include <minmax.h>
|
||||
#include <fileops.h>
|
||||
#include <list.h>
|
||||
#include <atomic.h>
|
||||
#include <path.h>
|
||||
#include <message.h>
|
||||
#include <strerrno.h>
|
||||
#include <print.h>
|
||||
|
||||
/* chunk pool operations */
|
||||
#define CHUNK_POOL_STATE_FILLING 0
|
||||
@@ -103,7 +104,7 @@ static char *resolve_dst_path(const char *src_file_path, struct path_resolve_arg
|
||||
strncpy(copy, a->src_path, PATH_MAX);
|
||||
prefix = dirname(copy);
|
||||
if (!prefix) {
|
||||
mscp_set_error("dirname: %s", strerrno());
|
||||
priv_set_errv("dirname: %s", strerrno());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -146,11 +147,11 @@ static char *resolve_dst_path(const char *src_file_path, struct path_resolve_arg
|
||||
a->dst_path, src_file_path + strlen(a->src_path) + 1);
|
||||
|
||||
if (ret >= PATH_MAX) {
|
||||
mpr_warn("Too long path: %s", dst_file_path);
|
||||
pr_warn("Too long path: %s", dst_file_path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mpr_debug("file: %s -> %s", src_file_path, dst_file_path);
|
||||
pr_debug("file: %s -> %s", src_file_path, dst_file_path);
|
||||
|
||||
return strndup(dst_file_path, PATH_MAX);
|
||||
}
|
||||
@@ -161,7 +162,7 @@ static struct chunk *alloc_chunk(struct path *p)
|
||||
struct chunk *c;
|
||||
|
||||
if (!(c = malloc(sizeof(*c)))) {
|
||||
mscp_set_error("malloc %s", strerrno());
|
||||
priv_set_errv("malloc %s", strerrno());
|
||||
return NULL;
|
||||
}
|
||||
memset(c, 0, sizeof(*c));
|
||||
@@ -223,7 +224,7 @@ static int append_path(sftp_session sftp, const char *path, struct stat st,
|
||||
struct path *p;
|
||||
|
||||
if (!(p = malloc(sizeof(*p)))) {
|
||||
mscp_set_error("failed to allocate memory: %s", strerrno());
|
||||
priv_set_errv("failed to allocate memory: %s", strerrno());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -275,7 +276,7 @@ static int walk_path_recursive(sftp_session sftp, const char *path,
|
||||
int ret;
|
||||
|
||||
if (mscp_stat(path, &st, sftp) < 0) {
|
||||
mpr_err("stat: %s: %s", path, strerrno());
|
||||
pr_err("stat: %s: %s", path, strerrno());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -289,7 +290,7 @@ static int walk_path_recursive(sftp_session sftp, const char *path,
|
||||
|
||||
/* ok, this path is a directory. walk through it. */
|
||||
if (!(d = mscp_opendir(path, sftp))) {
|
||||
mpr_err("opendir: %s: %s", path, strerrno());
|
||||
pr_err("opendir: %s: %s", path, strerrno());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -299,7 +300,7 @@ static int walk_path_recursive(sftp_session sftp, const char *path,
|
||||
|
||||
ret = snprintf(next_path, PATH_MAX, "%s/%s", path, e->d_name);
|
||||
if (ret >= PATH_MAX) {
|
||||
mpr_warn("Too long path: %s/%s", path, e->d_name);
|
||||
pr_warn("Too long path: %s/%s", path, e->d_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -354,7 +355,7 @@ static int touch_dst_path(struct path *p, sftp_session sftp)
|
||||
if (S_ISDIR(st.st_mode))
|
||||
goto next; /* directory exists. go deeper */
|
||||
else {
|
||||
mscp_set_error("mscp_stat %s: not a directory", path);
|
||||
priv_set_errv("mscp_stat %s: not a directory", path);
|
||||
return -1; /* path exists, but not directory. */
|
||||
}
|
||||
}
|
||||
@@ -362,7 +363,7 @@ static int touch_dst_path(struct path *p, sftp_session sftp)
|
||||
if (errno == ENOENT) {
|
||||
/* no file on the path. create directory. */
|
||||
if (mscp_mkdir(path, mode, sftp) < 0) {
|
||||
mscp_set_error("mscp_mkdir %s: %s", path, strerrno());
|
||||
priv_set_errv("mscp_mkdir %s: %s", path, strerrno());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -374,7 +375,7 @@ static int touch_dst_path(struct path *p, sftp_session sftp)
|
||||
* end. see https://bugzilla.mindrot.org/show_bug.cgi?id=3431 */
|
||||
f = mscp_open(p->dst_path, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR, sftp);
|
||||
if (!f) {
|
||||
mscp_set_error("mscp_open %s: %s\n", p->dst_path, strerrno());
|
||||
priv_set_errv("mscp_open %s: %s\n", p->dst_path, strerrno());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -391,11 +392,11 @@ static int prepare_dst_path(struct path *p, sftp_session dst_sftp)
|
||||
if (p->state == FILE_STATE_INIT) {
|
||||
if (touch_dst_path(p, dst_sftp) < 0) {
|
||||
ret = -1;
|
||||
mpr_err("failed to prepare dst path: %s", mscp_get_error());
|
||||
pr_err("failed to prepare dst path: %s", priv_get_err());
|
||||
goto out;
|
||||
}
|
||||
p->state = FILE_STATE_OPENED;
|
||||
mpr_info("copy start: %s", p->path);
|
||||
pr_info("copy start: %s", p->path);
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -431,7 +432,7 @@ static int copy_chunk_l2r(struct chunk *c, int fd, sftp_file sf,
|
||||
reqs[idx].len = sftp_async_write(sf, read_to_buf, reqs[idx].len, &fd,
|
||||
&reqs[idx].id);
|
||||
if (reqs[idx].len < 0) {
|
||||
mscp_set_error("sftp_async_write: %s or %s",
|
||||
priv_set_errv("sftp_async_write: %s or %s",
|
||||
sftp_get_ssh_error(sf->sftp), strerrno());
|
||||
return -1;
|
||||
}
|
||||
@@ -441,7 +442,7 @@ static int copy_chunk_l2r(struct chunk *c, int fd, sftp_file sf,
|
||||
for (idx = 0; remaind > 0; idx = (idx + 1) % nr_ahead) {
|
||||
ret = sftp_async_write_end(sf, reqs[idx].id, 1);
|
||||
if (ret != SSH_OK) {
|
||||
mscp_set_error("sftp_async_write_end: %s",
|
||||
priv_set_errv("sftp_async_write_end: %s",
|
||||
sftp_get_ssh_error(sf->sftp));
|
||||
return -1;
|
||||
}
|
||||
@@ -459,7 +460,7 @@ static int copy_chunk_l2r(struct chunk *c, int fd, sftp_file sf,
|
||||
reqs[idx].len = sftp_async_write(sf, read_to_buf, reqs[idx].len, &fd,
|
||||
&reqs[idx].id);
|
||||
if (reqs[idx].len < 0) {
|
||||
mscp_set_error("sftp_async_write: %s or %s",
|
||||
priv_set_errv("sftp_async_write: %s or %s",
|
||||
sftp_get_ssh_error(sf->sftp), strerrno());
|
||||
return -1;
|
||||
}
|
||||
@@ -467,7 +468,7 @@ static int copy_chunk_l2r(struct chunk *c, int fd, sftp_file sf,
|
||||
}
|
||||
|
||||
if (remaind < 0) {
|
||||
mscp_set_error("invalid remaind bytes %ld. "
|
||||
priv_set_errv("invalid remaind bytes %ld. "
|
||||
"last async_write_end bytes %lu.",
|
||||
remaind, reqs[idx].len);
|
||||
return -1;
|
||||
@@ -497,7 +498,7 @@ static int copy_chunk_r2l(struct chunk *c, sftp_file sf, int fd,
|
||||
reqs[idx].len = min(thrown, sizeof(buf));
|
||||
reqs[idx].id = sftp_async_read_begin(sf, reqs[idx].len);
|
||||
if (reqs[idx].id < 0) {
|
||||
mscp_set_error("sftp_async_read_begin: %d",
|
||||
priv_set_errv("sftp_async_read_begin: %d",
|
||||
sftp_get_error(sf->sftp));
|
||||
return -1;
|
||||
}
|
||||
@@ -507,7 +508,7 @@ static int copy_chunk_r2l(struct chunk *c, sftp_file sf, int fd,
|
||||
for (idx = 0; remaind > 0; idx = (idx + 1) % nr_ahead) {
|
||||
read_bytes = sftp_async_read(sf, buf, reqs[idx].len, reqs[idx].id);
|
||||
if (read_bytes == SSH_ERROR) {
|
||||
mscp_set_error("sftp_async_read: %d",
|
||||
priv_set_errv("sftp_async_read: %d",
|
||||
sftp_get_error(sf->sftp));
|
||||
return -1;
|
||||
}
|
||||
@@ -520,12 +521,12 @@ static int copy_chunk_r2l(struct chunk *c, sftp_file sf, int fd,
|
||||
|
||||
write_bytes = write(fd, buf, read_bytes);
|
||||
if (write_bytes < 0) {
|
||||
mscp_set_error("write: %s", strerrno());
|
||||
priv_set_errv("write: %s", strerrno());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (write_bytes < read_bytes) {
|
||||
mscp_set_error("failed to write full bytes");
|
||||
priv_set_errv("failed to write full bytes");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -534,7 +535,7 @@ static int copy_chunk_r2l(struct chunk *c, sftp_file sf, int fd,
|
||||
}
|
||||
|
||||
if (remaind < 0) {
|
||||
mscp_set_error("invalid remaind bytes %ld. last async_read bytes %ld. "
|
||||
priv_set_errv("invalid remaind bytes %ld. last async_read bytes %ld. "
|
||||
"last write bytes %ld",
|
||||
remaind, read_bytes, write_bytes);
|
||||
return -1;
|
||||
@@ -573,11 +574,11 @@ int copy_chunk(struct chunk *c, sftp_session src_sftp, sftp_session dst_sftp,
|
||||
mode = S_IRUSR;
|
||||
s = mscp_open(c->p->path, flags, mode, src_sftp);
|
||||
if (!s) {
|
||||
mscp_set_error("mscp_open: %s: %s", c->p->path, strerrno());
|
||||
priv_set_errv("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());
|
||||
priv_set_errv("mscp_lseek: %s: %s", c->p->path, strerrno());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -587,20 +588,20 @@ int copy_chunk(struct chunk *c, sftp_session src_sftp, sftp_session dst_sftp,
|
||||
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());
|
||||
priv_set_errv("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());
|
||||
priv_set_errv("mscp_lseek: %s: %s", c->p->dst_path, strerrno());
|
||||
return -1;
|
||||
}
|
||||
|
||||
mpr_debug("copy chunk start: %s 0x%lx-0x%lx",
|
||||
pr_debug("copy chunk start: %s 0x%lx-0x%lx",
|
||||
c->p->path, c->off, c->off + c->len);
|
||||
|
||||
ret = _copy_chunk(c, s, d, nr_ahead, buf_sz, counter);
|
||||
|
||||
mpr_debug("copy chunk done: %s 0x%lx-0x%lx",
|
||||
pr_debug("copy chunk done: %s 0x%lx-0x%lx",
|
||||
c->p->path, c->off, c->off + c->len);
|
||||
|
||||
|
||||
@@ -615,14 +616,14 @@ int copy_chunk(struct chunk *c, sftp_session src_sftp, sftp_session dst_sftp,
|
||||
|
||||
/* sync stat */
|
||||
if (mscp_stat(c->p->path, &st, src_sftp) < 0) {
|
||||
mpr_err("mscp_stat: %s: %s", c->p->path, strerrno());
|
||||
pr_err("mscp_stat: %s: %s", c->p->path, strerrno());
|
||||
return -1;
|
||||
}
|
||||
if (mscp_setstat(c->p->dst_path, &st, preserve_ts, dst_sftp) < 0) {
|
||||
mpr_err("mscp_setstat: %s: %s", c->p->path, strerrno());
|
||||
pr_err("mscp_setstat: %s: %s", c->p->path, strerrno());
|
||||
return -1;
|
||||
}
|
||||
mpr_info("copy done: %s", c->p->path);
|
||||
pr_info("copy done: %s", c->p->path);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <list.h>
|
||||
#include <atomic.h>
|
||||
#include <ssh.h>
|
||||
#include <message.h>
|
||||
|
||||
struct path {
|
||||
struct list_head list; /* mscp->path_list */
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
#error unsupported platform
|
||||
#endif
|
||||
|
||||
#include <util.h>
|
||||
#include <platform.h>
|
||||
#include <message.h>
|
||||
#include <strerrno.h>
|
||||
#include <print.h>
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
@@ -34,7 +34,7 @@ int nr_cpus()
|
||||
size_t size = sizeof(n);
|
||||
|
||||
if (sysctlbyname("machdep.cpu.core_count", &n, &size, NULL, 0) != 0) {
|
||||
mscp_set_error("failed to get number of cpu cores: %s", strerrno());
|
||||
priv_set_errv("failed to get number of cpu cores: %s", strerrno());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ int nr_cpus()
|
||||
|
||||
int set_thread_affinity(pthread_t tid, int core)
|
||||
{
|
||||
pr_warn("setting thread afinity is not implemented on apple\n");
|
||||
pr_warn("setting thread afinity is not implemented on apple");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -124,8 +124,8 @@ int set_thread_affinity(pthread_t tid, int core)
|
||||
CPU_SET(core, &target_cpu_set);
|
||||
ret = pthread_setaffinity_np(tid, sizeof(target_cpu_set), &target_cpu_set);
|
||||
if (ret < 0)
|
||||
mscp_set_error("failed to set thread/cpu affinity for core %d: %s",
|
||||
core, strerrno());
|
||||
priv_set_errv("failed to set thread/cpu affinity for core %d: %s",
|
||||
core, strerrno());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
19
src/print.c
Normal file
19
src/print.c
Normal file
@@ -0,0 +1,19 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-only */
|
||||
|
||||
#include <print.h>
|
||||
|
||||
/* message print functions */
|
||||
static int __print_severity = MSCP_SEVERITY_WARN;
|
||||
|
||||
void set_print_severity(int serverity)
|
||||
{
|
||||
if (serverity < 0)
|
||||
__print_severity = -1; /* no print */
|
||||
__print_severity = serverity;
|
||||
}
|
||||
|
||||
int get_print_severity()
|
||||
{
|
||||
return __print_severity;
|
||||
}
|
||||
|
||||
35
src/print.h
Normal file
35
src/print.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-only */
|
||||
#ifndef _PRINT_H_
|
||||
#define _PRINT_H_
|
||||
|
||||
#include <libgen.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <mscp.h>
|
||||
|
||||
/* message print. printed messages are passed to application via msg_fd */
|
||||
void set_print_severity(int severity);
|
||||
int get_print_severity();
|
||||
|
||||
#define __print(fp, severity, fmt, ...) \
|
||||
do { \
|
||||
if (severity <= get_print_severity()) { \
|
||||
fprintf(fp, "\r\033[K" fmt "\n", ##__VA_ARGS__); \
|
||||
fflush(fp); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define pr_err(fmt, ...) \
|
||||
__print(stderr, MSCP_SEVERITY_ERR, fmt, ##__VA_ARGS__)
|
||||
#define pr_warn(fmt, ...) \
|
||||
__print(stderr, MSCP_SEVERITY_WARN, fmt, ##__VA_ARGS__)
|
||||
#define pr_notice(fmt, ...) \
|
||||
__print(stdout, MSCP_SEVERITY_NOTICE, fmt, ##__VA_ARGS__)
|
||||
#define pr_info(fmt, ...) \
|
||||
__print(stdout, MSCP_SEVERITY_INFO, fmt, ##__VA_ARGS__)
|
||||
#define pr_debug(fmt, ...) \
|
||||
__print(stdout, MSCP_SEVERITY_DEBUG, fmt, ##__VA_ARGS__)
|
||||
|
||||
#endif /* _PRINT_H_ */
|
||||
45
src/ssh.c
45
src/ssh.c
@@ -7,8 +7,8 @@
|
||||
#include "libssh/callbacks.h"
|
||||
|
||||
#include <ssh.h>
|
||||
#include <util.h>
|
||||
#include <message.h>
|
||||
#include <mscp.h>
|
||||
#include <strerrno.h>
|
||||
|
||||
static int ssh_verify_known_hosts(ssh_session session);
|
||||
|
||||
@@ -18,53 +18,53 @@ static int ssh_set_opts(ssh_session ssh, struct mscp_ssh_opts *opts)
|
||||
|
||||
if (opts->login_name &&
|
||||
ssh_options_set(ssh, SSH_OPTIONS_USER, opts->login_name) < 0) {
|
||||
mscp_set_error("failed to set login name");
|
||||
priv_set_errv("failed to set login name");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (opts->port &&
|
||||
ssh_options_set(ssh, SSH_OPTIONS_PORT_STR, opts->port) < 0) {
|
||||
mscp_set_error("failed to set port number");
|
||||
priv_set_errv("failed to set port number");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (opts->identity &&
|
||||
ssh_options_set(ssh, SSH_OPTIONS_IDENTITY, opts->identity) < 0) {
|
||||
mscp_set_error("failed to set identity");
|
||||
priv_set_errv("failed to set identity");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (opts->cipher) {
|
||||
if (ssh_options_set(ssh, SSH_OPTIONS_CIPHERS_C_S, opts->cipher) < 0) {
|
||||
mscp_set_error("failed to set cipher for client to server");
|
||||
priv_set_errv("failed to set cipher for client to server");
|
||||
return -1;
|
||||
}
|
||||
if (ssh_options_set(ssh, SSH_OPTIONS_CIPHERS_S_C, opts->cipher) < 0) {
|
||||
mscp_set_error("failed to set cipher for server to client");
|
||||
priv_set_errv("failed to set cipher for server to client");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (opts->hmac) {
|
||||
if (ssh_options_set(ssh, SSH_OPTIONS_HMAC_C_S, opts->hmac) < 0) {
|
||||
mscp_set_error("failed to set hmac for client to server");
|
||||
priv_set_errv("failed to set hmac for client to server");
|
||||
return -1;
|
||||
}
|
||||
if (ssh_options_set(ssh, SSH_OPTIONS_HMAC_S_C, opts->hmac) < 0) {
|
||||
mscp_set_error("failed to set hmac for server to client");
|
||||
priv_set_errv("failed to set hmac for server to client");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (opts->compress &&
|
||||
ssh_options_set(ssh, SSH_OPTIONS_COMPRESSION, opts->compress) < 0) {
|
||||
mscp_set_error("failed to enable ssh compression");
|
||||
priv_set_errv("failed to enable ssh compression");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (opts->ccalgo &&
|
||||
ssh_options_set(ssh, SSH_OPTIONS_CCALGO, opts->ccalgo) < 0) {
|
||||
mscp_set_error("failed to set cclago");
|
||||
priv_set_errv("failed to set cclago");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -72,14 +72,14 @@ static int ssh_set_opts(ssh_session ssh, struct mscp_ssh_opts *opts)
|
||||
if (!opts->enable_nagle) {
|
||||
int v = 1;
|
||||
if (ssh_options_set(ssh, SSH_OPTIONS_NODELAY, &v) < 0) {
|
||||
mscp_set_error("failed to set TCP_NODELAY");
|
||||
priv_set_errv("failed to set TCP_NODELAY");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (opts->config &&
|
||||
ssh_options_parse_config(ssh, opts->config) < 0) {
|
||||
mscp_set_error("failed to parse ssh_config: %s", opts->config);
|
||||
priv_set_errv("failed to parse ssh_config: %s", opts->config);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -112,10 +112,11 @@ static int ssh_authenticate(ssh_session ssh, struct mscp_ssh_opts *opts)
|
||||
if (!opts->password) {
|
||||
char buf[128] = {};
|
||||
if (ssh_getpass("Password: ", buf, sizeof(buf), 0, 0) < 0) {
|
||||
priv_set_errv("ssh_getpass failed");
|
||||
return -1;
|
||||
}
|
||||
if (!(opts->password = strndup(buf, sizeof(buf)))) {
|
||||
mpr_err("strndup: %s", strerrno());
|
||||
priv_set_errv("strndup: %s", strerrno());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -149,7 +150,7 @@ static int ssh_cache_passphrase(const char *prompt, char *buf, size_t len, int e
|
||||
free(opts->passphrase);
|
||||
|
||||
if (!(opts->passphrase = strndup(buf, len))) {
|
||||
mpr_err("strndup: %s", strerrno());
|
||||
priv_set_errv("strndup: %s", strerrno());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -171,7 +172,7 @@ static ssh_session ssh_init_session(const char *sshdst, struct mscp_ssh_opts *op
|
||||
ssh_set_callbacks(ssh, &cb);
|
||||
|
||||
if (ssh_options_set(ssh, SSH_OPTIONS_HOST, sshdst) != SSH_OK) {
|
||||
mscp_set_error("failed to set destination host");
|
||||
priv_set_errv("failed to set destination host");
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
@@ -179,12 +180,12 @@ static ssh_session ssh_init_session(const char *sshdst, struct mscp_ssh_opts *op
|
||||
goto free_out;
|
||||
|
||||
if (ssh_connect(ssh) != SSH_OK) {
|
||||
mscp_set_error("failed to connect ssh server: %s", ssh_get_error(ssh));
|
||||
priv_set_errv("failed to connect ssh server: %s", ssh_get_error(ssh));
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
if (ssh_authenticate(ssh, opts) != 0) {
|
||||
mscp_set_error("authentication failed: %s", ssh_get_error(ssh));
|
||||
priv_set_errv("authentication failed: %s", ssh_get_error(ssh));
|
||||
goto disconnect_out;
|
||||
}
|
||||
|
||||
@@ -212,13 +213,13 @@ sftp_session ssh_init_sftp_session(const char *sshdst, struct mscp_ssh_opts *opt
|
||||
|
||||
sftp = sftp_new(ssh);
|
||||
if (!sftp) {
|
||||
mscp_set_error("failed to allocate sftp session: %s",
|
||||
priv_set_errv("failed to allocate sftp session: %s",
|
||||
ssh_get_error(ssh));
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (sftp_init(sftp) != SSH_OK) {
|
||||
mscp_set_error("failed to initialize sftp session: err code %d",
|
||||
priv_set_errv("failed to initialize sftp session: err code %d",
|
||||
sftp_get_error(sftp));
|
||||
goto err_out;
|
||||
}
|
||||
@@ -305,13 +306,13 @@ static int ssh_verify_known_hosts(ssh_session session)
|
||||
|
||||
rc = ssh_session_update_known_hosts(session);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Error %s\n", strerror(errno));
|
||||
priv_set_errv("%s", ssh_get_error(session));
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
case SSH_KNOWN_HOSTS_ERROR:
|
||||
fprintf(stderr, "Error %s", ssh_get_error(session));
|
||||
priv_set_errv("known hosts error: %s", ssh_get_error(session));
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return -1;
|
||||
}
|
||||
|
||||
41
src/strerrno.c
Normal file
41
src/strerrno.c
Normal file
@@ -0,0 +1,41 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-only */
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <strerrno.h>
|
||||
|
||||
#define STRERRNO_TLS_BUFSIZ 128
|
||||
__thread char tls_strerrno_buf[STRERRNO_TLS_BUFSIZ];
|
||||
|
||||
const char *strerrno(void)
|
||||
{
|
||||
snprintf(tls_strerrno_buf, sizeof(tls_strerrno_buf), "%s", "strerror_r error");
|
||||
strerror_r(errno, tls_strerrno_buf, sizeof(tls_strerrno_buf));
|
||||
return tls_strerrno_buf;
|
||||
}
|
||||
|
||||
#define PRIV_ERR_BUFSIZ (1 << 12)
|
||||
static char priv_err_buf[PRIV_ERR_BUFSIZ], internal[PRIV_ERR_BUFSIZ];
|
||||
|
||||
void priv_set_err(const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
/* arguments may contains priv_err_buf. Thus, we build the
|
||||
* string in a internal buffer, and then copy it to
|
||||
* priv_err_buf. */
|
||||
memset(internal, 0, sizeof(internal));
|
||||
va_start(va, fmt);
|
||||
vsnprintf(internal, sizeof(internal), fmt, va);
|
||||
va_end(va);
|
||||
|
||||
snprintf(priv_err_buf, sizeof(priv_err_buf), "%s", internal);
|
||||
}
|
||||
|
||||
const char *priv_get_err()
|
||||
{
|
||||
return priv_err_buf;
|
||||
}
|
||||
33
src/strerrno.h
Normal file
33
src/strerrno.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-only */
|
||||
#ifndef _STRERRNO_
|
||||
#define _STRERRNO_
|
||||
|
||||
#include <libgen.h> /* basename() */
|
||||
|
||||
/**
|
||||
* strerrno() returns error message string corresponding to errno.
|
||||
* strerrno() is thread safe.
|
||||
*/
|
||||
const char *strerrno(void);
|
||||
|
||||
/**
|
||||
* priv_set_err() sets an error message into a private buffer. This
|
||||
* error message set by priv_set_err() can be accessed via
|
||||
* priv_get_err(). priv_*_err functions are not thread safe.
|
||||
*/
|
||||
void priv_set_err(const char *fmt, ...);
|
||||
|
||||
/**
|
||||
* priv_set_errv(), a wrapper for priv_set_err(), just adds filename,
|
||||
* line, and function name to the error message.
|
||||
*/
|
||||
#define priv_set_errv(fmt, ...) \
|
||||
priv_set_err("[%s:%d:%s] " fmt "\0", \
|
||||
basename(__FILE__), __LINE__, __func__, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* priv_get_err() gets the error message sotred in a private buffer.
|
||||
*/
|
||||
const char *priv_get_err();
|
||||
|
||||
#endif /* _STRERRNO_ */
|
||||
39
src/util.h
39
src/util.h
@@ -1,39 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-only */
|
||||
#ifndef _UTIL_H_
|
||||
#define _UTIL_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#define likely(x) __builtin_expect(!!(x), 1)
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
|
||||
#define pr(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
|
||||
|
||||
#define pr_info(fmt, ...) fprintf(stderr, "INFO:%s(): " fmt, \
|
||||
__func__, ##__VA_ARGS__)
|
||||
|
||||
#define pr_warn(fmt, ...) fprintf(stderr, "\x1b[1m\x1b[33m" \
|
||||
"WARN:%s():\x1b[0m " fmt, \
|
||||
__func__, ##__VA_ARGS__)
|
||||
|
||||
#define pr_err(fmt, ...) fprintf(stderr, "\x1b[1m\x1b[31m" \
|
||||
"ERR:%s:%d:%s():\x1b[0m " fmt, \
|
||||
basename(__FILE__), __LINE__, __func__, ##__VA_ARGS__)
|
||||
|
||||
#ifdef DEBUG
|
||||
#define pr_debug(fmt, ...) fprintf(stderr, "\x1b[1m\x1b[33m" \
|
||||
"DEBUG:%s():\x1b[0m " fmt, \
|
||||
__func__, ##__VA_ARGS__);
|
||||
#else
|
||||
#define pr_debug(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
#define min(a, b) (((a) > (b)) ? (b) : (a))
|
||||
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
#endif /* _UTIL_H_ */
|
||||
Reference in New Issue
Block a user