upstream: make most of the sftp errors more idiomatic, following
the general form of "[local/remote] operation path: error message"; ok markus OpenBSD-Commit-ID: 61364cd5f3a9fecaf8d63b4c38a42c0c91f8b571
This commit is contained in:
parent
ac7c9ec894
commit
d5981b1883
182
sftp-client.c
182
sftp-client.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: sftp-client.c,v 1.160 2022/01/08 07:37:32 djm Exp $ */
|
/* $OpenBSD: sftp-client.c,v 1.161 2022/01/17 21:41:04 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
||||||
*
|
*
|
||||||
|
@ -367,9 +367,9 @@ get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet)
|
||||||
if ((r = sshbuf_get_u32(msg, &status)) != 0)
|
if ((r = sshbuf_get_u32(msg, &status)) != 0)
|
||||||
fatal_fr(r, "parse status");
|
fatal_fr(r, "parse status");
|
||||||
if (quiet)
|
if (quiet)
|
||||||
debug("Couldn't stat remote file: %s", fx2txt(status));
|
debug("stat remote: %s", fx2txt(status));
|
||||||
else
|
else
|
||||||
error("Couldn't stat remote file: %s", fx2txt(status));
|
error("stat remote: %s", fx2txt(status));
|
||||||
sshbuf_free(msg);
|
sshbuf_free(msg);
|
||||||
return(NULL);
|
return(NULL);
|
||||||
} else if (type != SSH2_FXP_ATTRS) {
|
} else if (type != SSH2_FXP_ATTRS) {
|
||||||
|
@ -415,9 +415,9 @@ get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st,
|
||||||
if ((r = sshbuf_get_u32(msg, &status)) != 0)
|
if ((r = sshbuf_get_u32(msg, &status)) != 0)
|
||||||
fatal_fr(r, "parse status");
|
fatal_fr(r, "parse status");
|
||||||
if (quiet)
|
if (quiet)
|
||||||
debug("Couldn't statvfs: %s", fx2txt(status));
|
debug("remote statvfs: %s", fx2txt(status));
|
||||||
else
|
else
|
||||||
error("Couldn't statvfs: %s", fx2txt(status));
|
error("remote statvfs: %s", fx2txt(status));
|
||||||
sshbuf_free(msg);
|
sshbuf_free(msg);
|
||||||
return -1;
|
return -1;
|
||||||
} else if (type != SSH2_FXP_EXTENDED_REPLY) {
|
} else if (type != SSH2_FXP_EXTENDED_REPLY) {
|
||||||
|
@ -668,7 +668,7 @@ do_close(struct sftp_conn *conn, const u_char *handle, u_int handle_len)
|
||||||
|
|
||||||
status = get_status(conn, id);
|
status = get_status(conn, id);
|
||||||
if (status != SSH2_FX_OK)
|
if (status != SSH2_FX_OK)
|
||||||
error("Couldn't close file: %s", fx2txt(status));
|
error("close remote: %s", fx2txt(status));
|
||||||
|
|
||||||
sshbuf_free(msg);
|
sshbuf_free(msg);
|
||||||
|
|
||||||
|
@ -850,7 +850,7 @@ do_rm(struct sftp_conn *conn, const char *path)
|
||||||
send_string_request(conn, id, SSH2_FXP_REMOVE, path, strlen(path));
|
send_string_request(conn, id, SSH2_FXP_REMOVE, path, strlen(path));
|
||||||
status = get_status(conn, id);
|
status = get_status(conn, id);
|
||||||
if (status != SSH2_FX_OK)
|
if (status != SSH2_FX_OK)
|
||||||
error("Couldn't delete file: %s", fx2txt(status));
|
error("remote delete %s: %s", path, fx2txt(status));
|
||||||
return status == SSH2_FX_OK ? 0 : -1;
|
return status == SSH2_FX_OK ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -859,13 +859,15 @@ do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int print_flag)
|
||||||
{
|
{
|
||||||
u_int status, id;
|
u_int status, id;
|
||||||
|
|
||||||
|
debug2("Sending SSH2_FXP_MKDIR \"%s\"", path);
|
||||||
|
|
||||||
id = conn->msg_id++;
|
id = conn->msg_id++;
|
||||||
send_string_attrs_request(conn, id, SSH2_FXP_MKDIR, path,
|
send_string_attrs_request(conn, id, SSH2_FXP_MKDIR, path,
|
||||||
strlen(path), a);
|
strlen(path), a);
|
||||||
|
|
||||||
status = get_status(conn, id);
|
status = get_status(conn, id);
|
||||||
if (status != SSH2_FX_OK && print_flag)
|
if (status != SSH2_FX_OK && print_flag)
|
||||||
error("Couldn't create directory: %s", fx2txt(status));
|
error("remote mkdir \"%s\": %s", path, fx2txt(status));
|
||||||
|
|
||||||
return status == SSH2_FX_OK ? 0 : -1;
|
return status == SSH2_FX_OK ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
@ -875,13 +877,15 @@ do_rmdir(struct sftp_conn *conn, const char *path)
|
||||||
{
|
{
|
||||||
u_int status, id;
|
u_int status, id;
|
||||||
|
|
||||||
|
debug2("Sending SSH2_FXP_RMDIR \"%s\"", path);
|
||||||
|
|
||||||
id = conn->msg_id++;
|
id = conn->msg_id++;
|
||||||
send_string_request(conn, id, SSH2_FXP_RMDIR, path,
|
send_string_request(conn, id, SSH2_FXP_RMDIR, path,
|
||||||
strlen(path));
|
strlen(path));
|
||||||
|
|
||||||
status = get_status(conn, id);
|
status = get_status(conn, id);
|
||||||
if (status != SSH2_FX_OK)
|
if (status != SSH2_FX_OK)
|
||||||
error("Couldn't remove directory: %s", fx2txt(status));
|
error("remote rmdir \"%s\": %s", path, fx2txt(status));
|
||||||
|
|
||||||
return status == SSH2_FX_OK ? 0 : -1;
|
return status == SSH2_FX_OK ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
@ -891,6 +895,8 @@ do_stat(struct sftp_conn *conn, const char *path, int quiet)
|
||||||
{
|
{
|
||||||
u_int id;
|
u_int id;
|
||||||
|
|
||||||
|
debug2("Sending SSH2_FXP_STAT \"%s\"", path);
|
||||||
|
|
||||||
id = conn->msg_id++;
|
id = conn->msg_id++;
|
||||||
|
|
||||||
send_string_request(conn, id,
|
send_string_request(conn, id,
|
||||||
|
@ -927,6 +933,8 @@ do_fstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
|
||||||
{
|
{
|
||||||
u_int id;
|
u_int id;
|
||||||
|
|
||||||
|
debug2("Sending SSH2_FXP_FSTAT \"%s\"");
|
||||||
|
|
||||||
id = conn->msg_id++;
|
id = conn->msg_id++;
|
||||||
send_string_request(conn, id, SSH2_FXP_FSTAT, handle,
|
send_string_request(conn, id, SSH2_FXP_FSTAT, handle,
|
||||||
handle_len);
|
handle_len);
|
||||||
|
@ -940,14 +948,15 @@ do_setstat(struct sftp_conn *conn, const char *path, Attrib *a)
|
||||||
{
|
{
|
||||||
u_int status, id;
|
u_int status, id;
|
||||||
|
|
||||||
|
debug2("Sending SSH2_FXP_SETSTAT \"%s\"", path);
|
||||||
|
|
||||||
id = conn->msg_id++;
|
id = conn->msg_id++;
|
||||||
send_string_attrs_request(conn, id, SSH2_FXP_SETSTAT, path,
|
send_string_attrs_request(conn, id, SSH2_FXP_SETSTAT, path,
|
||||||
strlen(path), a);
|
strlen(path), a);
|
||||||
|
|
||||||
status = get_status(conn, id);
|
status = get_status(conn, id);
|
||||||
if (status != SSH2_FX_OK)
|
if (status != SSH2_FX_OK)
|
||||||
error("Couldn't setstat on \"%s\": %s", path,
|
error("remote setstat \"%s\": %s", path, fx2txt(status));
|
||||||
fx2txt(status));
|
|
||||||
|
|
||||||
return status == SSH2_FX_OK ? 0 : -1;
|
return status == SSH2_FX_OK ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
@ -958,13 +967,15 @@ do_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
|
||||||
{
|
{
|
||||||
u_int status, id;
|
u_int status, id;
|
||||||
|
|
||||||
|
debug2("Sending SSH2_FXP_FSETSTAT");
|
||||||
|
|
||||||
id = conn->msg_id++;
|
id = conn->msg_id++;
|
||||||
send_string_attrs_request(conn, id, SSH2_FXP_FSETSTAT, handle,
|
send_string_attrs_request(conn, id, SSH2_FXP_FSETSTAT, handle,
|
||||||
handle_len, a);
|
handle_len, a);
|
||||||
|
|
||||||
status = get_status(conn, id);
|
status = get_status(conn, id);
|
||||||
if (status != SSH2_FX_OK)
|
if (status != SSH2_FX_OK)
|
||||||
error("Couldn't fsetstat: %s", fx2txt(status));
|
error("remote fsetstat: %s", fx2txt(status));
|
||||||
|
|
||||||
return status == SSH2_FX_OK ? 0 : -1;
|
return status == SSH2_FX_OK ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
@ -988,6 +999,8 @@ do_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
|
||||||
|
|
||||||
expected_id = id = conn->msg_id++;
|
expected_id = id = conn->msg_id++;
|
||||||
if (expand) {
|
if (expand) {
|
||||||
|
debug2("Sending SSH2_FXP_EXTENDED(expand-path@openssh.com) "
|
||||||
|
"\"%s\"", path);
|
||||||
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
|
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
|
||||||
(r = sshbuf_put_u32(msg, id)) != 0 ||
|
(r = sshbuf_put_u32(msg, id)) != 0 ||
|
||||||
(r = sshbuf_put_cstring(msg,
|
(r = sshbuf_put_cstring(msg,
|
||||||
|
@ -996,6 +1009,7 @@ do_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
|
||||||
fatal_fr(r, "compose %s", what);
|
fatal_fr(r, "compose %s", what);
|
||||||
send_msg(conn, msg);
|
send_msg(conn, msg);
|
||||||
} else {
|
} else {
|
||||||
|
debug2("Sending SSH2_FXP_REALPATH \"%s\"", path);
|
||||||
send_string_request(conn, id, SSH2_FXP_REALPATH,
|
send_string_request(conn, id, SSH2_FXP_REALPATH,
|
||||||
path, strlen(path));
|
path, strlen(path));
|
||||||
}
|
}
|
||||||
|
@ -1078,12 +1092,16 @@ do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath,
|
||||||
/* Send rename request */
|
/* Send rename request */
|
||||||
id = conn->msg_id++;
|
id = conn->msg_id++;
|
||||||
if (use_ext) {
|
if (use_ext) {
|
||||||
|
debug2("Sending SSH2_FXP_EXTENDED(posix-rename@openssh.com) "
|
||||||
|
"\"%s\" to \"%s\"", oldpath, newpath);
|
||||||
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
|
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
|
||||||
(r = sshbuf_put_u32(msg, id)) != 0 ||
|
(r = sshbuf_put_u32(msg, id)) != 0 ||
|
||||||
(r = sshbuf_put_cstring(msg,
|
(r = sshbuf_put_cstring(msg,
|
||||||
"posix-rename@openssh.com")) != 0)
|
"posix-rename@openssh.com")) != 0)
|
||||||
fatal_fr(r, "compose posix-rename");
|
fatal_fr(r, "compose posix-rename");
|
||||||
} else {
|
} else {
|
||||||
|
debug2("Sending SSH2_FXP_RENAME \"%s\" to \"%s\"",
|
||||||
|
oldpath, newpath);
|
||||||
if ((r = sshbuf_put_u8(msg, SSH2_FXP_RENAME)) != 0 ||
|
if ((r = sshbuf_put_u8(msg, SSH2_FXP_RENAME)) != 0 ||
|
||||||
(r = sshbuf_put_u32(msg, id)) != 0)
|
(r = sshbuf_put_u32(msg, id)) != 0)
|
||||||
fatal_fr(r, "compose rename");
|
fatal_fr(r, "compose rename");
|
||||||
|
@ -1099,7 +1117,7 @@ do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath,
|
||||||
|
|
||||||
status = get_status(conn, id);
|
status = get_status(conn, id);
|
||||||
if (status != SSH2_FX_OK)
|
if (status != SSH2_FX_OK)
|
||||||
error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath,
|
error("remote rename \"%s\" to \"%s\": %s", oldpath,
|
||||||
newpath, fx2txt(status));
|
newpath, fx2txt(status));
|
||||||
|
|
||||||
return status == SSH2_FX_OK ? 0 : -1;
|
return status == SSH2_FX_OK ? 0 : -1;
|
||||||
|
@ -1116,6 +1134,8 @@ do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
|
||||||
error("Server does not support hardlink@openssh.com extension");
|
error("Server does not support hardlink@openssh.com extension");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
debug2("Sending SSH2_FXP_EXTENDED(hardlink@openssh.com) "
|
||||||
|
"\"%s\" to \"%s\"", oldpath, newpath);
|
||||||
|
|
||||||
if ((msg = sshbuf_new()) == NULL)
|
if ((msg = sshbuf_new()) == NULL)
|
||||||
fatal_f("sshbuf_new failed");
|
fatal_f("sshbuf_new failed");
|
||||||
|
@ -1135,7 +1155,7 @@ do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
|
||||||
|
|
||||||
status = get_status(conn, id);
|
status = get_status(conn, id);
|
||||||
if (status != SSH2_FX_OK)
|
if (status != SSH2_FX_OK)
|
||||||
error("Couldn't link file \"%s\" to \"%s\": %s", oldpath,
|
error("remote link \"%s\" to \"%s\": %s", oldpath,
|
||||||
newpath, fx2txt(status));
|
newpath, fx2txt(status));
|
||||||
|
|
||||||
return status == SSH2_FX_OK ? 0 : -1;
|
return status == SSH2_FX_OK ? 0 : -1;
|
||||||
|
@ -1152,6 +1172,7 @@ do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
|
||||||
error("This server does not support the symlink operation");
|
error("This server does not support the symlink operation");
|
||||||
return(SSH2_FX_OP_UNSUPPORTED);
|
return(SSH2_FX_OP_UNSUPPORTED);
|
||||||
}
|
}
|
||||||
|
debug2("Sending SSH2_FXP_SYMLINK \"%s\" to \"%s\"", oldpath, newpath);
|
||||||
|
|
||||||
if ((msg = sshbuf_new()) == NULL)
|
if ((msg = sshbuf_new()) == NULL)
|
||||||
fatal_f("sshbuf_new failed");
|
fatal_f("sshbuf_new failed");
|
||||||
|
@ -1170,7 +1191,7 @@ do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
|
||||||
|
|
||||||
status = get_status(conn, id);
|
status = get_status(conn, id);
|
||||||
if (status != SSH2_FX_OK)
|
if (status != SSH2_FX_OK)
|
||||||
error("Couldn't symlink file \"%s\" to \"%s\": %s", oldpath,
|
error("remote symlink file \"%s\" to \"%s\": %s", oldpath,
|
||||||
newpath, fx2txt(status));
|
newpath, fx2txt(status));
|
||||||
|
|
||||||
return status == SSH2_FX_OK ? 0 : -1;
|
return status == SSH2_FX_OK ? 0 : -1;
|
||||||
|
@ -1186,6 +1207,7 @@ do_fsync(struct sftp_conn *conn, u_char *handle, u_int handle_len)
|
||||||
/* Silently return if the extension is not supported */
|
/* Silently return if the extension is not supported */
|
||||||
if ((conn->exts & SFTP_EXT_FSYNC) == 0)
|
if ((conn->exts & SFTP_EXT_FSYNC) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
debug2("Sending SSH2_FXP_EXTENDED(fsync@openssh.com)");
|
||||||
|
|
||||||
/* Send fsync request */
|
/* Send fsync request */
|
||||||
if ((msg = sshbuf_new()) == NULL)
|
if ((msg = sshbuf_new()) == NULL)
|
||||||
|
@ -1202,7 +1224,7 @@ do_fsync(struct sftp_conn *conn, u_char *handle, u_int handle_len)
|
||||||
|
|
||||||
status = get_status(conn, id);
|
status = get_status(conn, id);
|
||||||
if (status != SSH2_FX_OK)
|
if (status != SSH2_FX_OK)
|
||||||
error("Couldn't sync file: %s", fx2txt(status));
|
error("remote fsync: %s", fx2txt(status));
|
||||||
|
|
||||||
return status == SSH2_FX_OK ? 0 : -1;
|
return status == SSH2_FX_OK ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
@ -1218,6 +1240,8 @@ do_readlink(struct sftp_conn *conn, const char *path)
|
||||||
u_char type;
|
u_char type;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
debug2("Sending SSH2_FXP_READLINK \"%s\"", path);
|
||||||
|
|
||||||
expected_id = id = conn->msg_id++;
|
expected_id = id = conn->msg_id++;
|
||||||
send_string_request(conn, id, SSH2_FXP_READLINK, path, strlen(path));
|
send_string_request(conn, id, SSH2_FXP_READLINK, path, strlen(path));
|
||||||
|
|
||||||
|
@ -1277,6 +1301,8 @@ do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug2("Sending SSH2_FXP_EXTENDED(statvfs@openssh.com) \"%s\"", path);
|
||||||
|
|
||||||
id = conn->msg_id++;
|
id = conn->msg_id++;
|
||||||
|
|
||||||
if ((msg = sshbuf_new()) == NULL)
|
if ((msg = sshbuf_new()) == NULL)
|
||||||
|
@ -1305,6 +1331,8 @@ do_fstatvfs(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug2("Sending SSH2_FXP_EXTENDED(fstatvfs@openssh.com)");
|
||||||
|
|
||||||
id = conn->msg_id++;
|
id = conn->msg_id++;
|
||||||
|
|
||||||
if ((msg = sshbuf_new()) == NULL)
|
if ((msg = sshbuf_new()) == NULL)
|
||||||
|
@ -1333,6 +1361,8 @@ do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug2("Sending SSH2_FXP_EXTENDED(lsetstat@openssh.com) \"%s\"", path);
|
||||||
|
|
||||||
id = conn->msg_id++;
|
id = conn->msg_id++;
|
||||||
if ((msg = sshbuf_new()) == NULL)
|
if ((msg = sshbuf_new()) == NULL)
|
||||||
fatal_f("sshbuf_new failed");
|
fatal_f("sshbuf_new failed");
|
||||||
|
@ -1347,8 +1377,7 @@ do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a)
|
||||||
|
|
||||||
status = get_status(conn, id);
|
status = get_status(conn, id);
|
||||||
if (status != SSH2_FX_OK)
|
if (status != SSH2_FX_OK)
|
||||||
error("Couldn't setstat on \"%s\": %s", path,
|
error("remote lsetstat \"%s\": %s", path, fx2txt(status));
|
||||||
fx2txt(status));
|
|
||||||
|
|
||||||
return status == SSH2_FX_OK ? 0 : -1;
|
return status == SSH2_FX_OK ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
@ -1383,6 +1412,8 @@ send_open(struct sftp_conn *conn, const char *path, const char *tag,
|
||||||
int r;
|
int r;
|
||||||
u_int id;
|
u_int id;
|
||||||
|
|
||||||
|
debug2("Sending SSH2_FXP_OPEN \"%s\"", path);
|
||||||
|
|
||||||
*handlep = NULL;
|
*handlep = NULL;
|
||||||
*handle_lenp = 0;
|
*handle_lenp = 0;
|
||||||
|
|
||||||
|
@ -1444,6 +1475,9 @@ do_download(struct sftp_conn *conn, const char *remote_path,
|
||||||
struct request *req;
|
struct request *req;
|
||||||
u_char type;
|
u_char type;
|
||||||
|
|
||||||
|
debug2_f("download remote \"%s\" to local \"%s\"",
|
||||||
|
remote_path, local_path);
|
||||||
|
|
||||||
TAILQ_INIT(&requests);
|
TAILQ_INIT(&requests);
|
||||||
|
|
||||||
if (a == NULL && (a = do_stat(conn, remote_path, 0)) == NULL)
|
if (a == NULL && (a = do_stat(conn, remote_path, 0)) == NULL)
|
||||||
|
@ -1457,7 +1491,7 @@ do_download(struct sftp_conn *conn, const char *remote_path,
|
||||||
|
|
||||||
if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
|
if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
|
||||||
(!S_ISREG(a->perm))) {
|
(!S_ISREG(a->perm))) {
|
||||||
error("Cannot download non-regular file: %s", remote_path);
|
error("download %s: not a regular file", remote_path);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1476,14 +1510,13 @@ do_download(struct sftp_conn *conn, const char *remote_path,
|
||||||
local_fd = open(local_path,
|
local_fd = open(local_path,
|
||||||
O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC), mode | S_IWUSR);
|
O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC), mode | S_IWUSR);
|
||||||
if (local_fd == -1) {
|
if (local_fd == -1) {
|
||||||
error("Couldn't open local file \"%s\" for writing: %s",
|
error("open local \"%s\": %s", local_path, strerror(errno));
|
||||||
local_path, strerror(errno));
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
offset = highwater = 0;
|
offset = highwater = 0;
|
||||||
if (resume_flag) {
|
if (resume_flag) {
|
||||||
if (fstat(local_fd, &st) == -1) {
|
if (fstat(local_fd, &st) == -1) {
|
||||||
error("Unable to stat local file \"%s\": %s",
|
error("stat local \"%s\": %s",
|
||||||
local_path, strerror(errno));
|
local_path, strerror(errno));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -1644,16 +1677,16 @@ do_download(struct sftp_conn *conn, const char *remote_path,
|
||||||
}
|
}
|
||||||
debug("truncating at %llu", (unsigned long long)highwater);
|
debug("truncating at %llu", (unsigned long long)highwater);
|
||||||
if (ftruncate(local_fd, highwater) == -1)
|
if (ftruncate(local_fd, highwater) == -1)
|
||||||
error("ftruncate \"%s\": %s", local_path,
|
error("local ftruncate \"%s\": %s", local_path,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
if (read_error) {
|
if (read_error) {
|
||||||
error("Couldn't read from remote file \"%s\" : %s",
|
error("read remote \"%s\" : %s", remote_path, fx2txt(status));
|
||||||
remote_path, fx2txt(status));
|
remote_path, fx2txt(status));
|
||||||
status = -1;
|
status = -1;
|
||||||
do_close(conn, handle, handle_len);
|
do_close(conn, handle, handle_len);
|
||||||
} else if (write_error) {
|
} else if (write_error) {
|
||||||
error("Couldn't write to \"%s\": %s", local_path,
|
error("write local \"%s\": %s", local_path,
|
||||||
strerror(write_errno));
|
strerror(write_errno));
|
||||||
status = SSH2_FX_FAILURE;
|
status = SSH2_FX_FAILURE;
|
||||||
do_close(conn, handle, handle_len);
|
do_close(conn, handle, handle_len);
|
||||||
|
@ -1668,7 +1701,7 @@ do_download(struct sftp_conn *conn, const char *remote_path,
|
||||||
#else
|
#else
|
||||||
if (preserve_flag && chmod(local_path, mode) == -1)
|
if (preserve_flag && chmod(local_path, mode) == -1)
|
||||||
#endif /* HAVE_FCHMOD */
|
#endif /* HAVE_FCHMOD */
|
||||||
error("Couldn't set mode on \"%s\": %s", local_path,
|
error("local chmod \"%s\": %s", local_path,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
if (preserve_flag &&
|
if (preserve_flag &&
|
||||||
(a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) {
|
(a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) {
|
||||||
|
@ -1677,7 +1710,7 @@ do_download(struct sftp_conn *conn, const char *remote_path,
|
||||||
tv[1].tv_sec = a->mtime;
|
tv[1].tv_sec = a->mtime;
|
||||||
tv[0].tv_usec = tv[1].tv_usec = 0;
|
tv[0].tv_usec = tv[1].tv_usec = 0;
|
||||||
if (utimes(local_path, tv) == -1)
|
if (utimes(local_path, tv) == -1)
|
||||||
error("Can't set times on \"%s\": %s",
|
error("local set times \"%s\": %s",
|
||||||
local_path, strerror(errno));
|
local_path, strerror(errno));
|
||||||
}
|
}
|
||||||
if (resume_flag && !lmodified)
|
if (resume_flag && !lmodified)
|
||||||
|
@ -1685,7 +1718,7 @@ do_download(struct sftp_conn *conn, const char *remote_path,
|
||||||
else if (fsync_flag) {
|
else if (fsync_flag) {
|
||||||
debug("syncing \"%s\"", local_path);
|
debug("syncing \"%s\"", local_path);
|
||||||
if (fsync(local_fd) == -1)
|
if (fsync(local_fd) == -1)
|
||||||
error("Couldn't sync file \"%s\": %s",
|
error("local sync \"%s\": %s",
|
||||||
local_path, strerror(errno));
|
local_path, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1711,9 +1744,11 @@ download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug2_f("download dir remote \"%s\" to local \"%s\"", src, dst);
|
||||||
|
|
||||||
if (dirattrib == NULL &&
|
if (dirattrib == NULL &&
|
||||||
(dirattrib = do_stat(conn, src, 1)) == NULL) {
|
(dirattrib = do_stat(conn, src, 1)) == NULL) {
|
||||||
error("Unable to stat remote directory \"%s\"", src);
|
error("stat remote \"%s\" directory failed", src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!S_ISDIR(dirattrib->perm)) {
|
if (!S_ISDIR(dirattrib->perm)) {
|
||||||
|
@ -1727,8 +1762,8 @@ download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
|
||||||
mode = dirattrib->perm & 01777;
|
mode = dirattrib->perm & 01777;
|
||||||
tmpmode = mode | (S_IWUSR|S_IXUSR);
|
tmpmode = mode | (S_IWUSR|S_IXUSR);
|
||||||
} else {
|
} else {
|
||||||
debug("Server did not send permissions for "
|
debug("download remote \"%s\": server "
|
||||||
"directory \"%s\"", dst);
|
"did not send permissions", dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mkdir(dst, tmpmode) == -1 && errno != EEXIST) {
|
if (mkdir(dst, tmpmode) == -1 && errno != EEXIST) {
|
||||||
|
@ -1737,7 +1772,7 @@ download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (do_readdir(conn, src, &dir_entries) == -1) {
|
if (do_readdir(conn, src, &dir_entries) == -1) {
|
||||||
error("%s: Failed to get directory contents", src);
|
error("remote readdir \"%s\" failed", src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1774,7 +1809,7 @@ download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
logit("%s: not a regular file\n", new_src);
|
logit("download \"%s\": not a regular file", new_src);
|
||||||
|
|
||||||
}
|
}
|
||||||
free(new_dst);
|
free(new_dst);
|
||||||
|
@ -1787,7 +1822,7 @@ download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
|
||||||
tv[1].tv_sec = dirattrib->mtime;
|
tv[1].tv_sec = dirattrib->mtime;
|
||||||
tv[0].tv_usec = tv[1].tv_usec = 0;
|
tv[0].tv_usec = tv[1].tv_usec = 0;
|
||||||
if (utimes(dst, tv) == -1)
|
if (utimes(dst, tv) == -1)
|
||||||
error("Can't set times on \"%s\": %s",
|
error("local set times on \"%s\": %s",
|
||||||
dst, strerror(errno));
|
dst, strerror(errno));
|
||||||
} else
|
} else
|
||||||
debug("Server did not send times for directory "
|
debug("Server did not send times for directory "
|
||||||
|
@ -1795,7 +1830,7 @@ download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode != tmpmode && chmod(dst, mode) == -1)
|
if (mode != tmpmode && chmod(dst, mode) == -1)
|
||||||
error("Can't set final mode on \"%s\": %s", dst,
|
error("local chmod directory \"%s\": %s", dst,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
|
||||||
free_sftp_dirents(dir_entries);
|
free_sftp_dirents(dir_entries);
|
||||||
|
@ -1812,7 +1847,7 @@ download_dir(struct sftp_conn *conn, const char *src, const char *dst,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if ((src_canon = do_realpath(conn, src)) == NULL) {
|
if ((src_canon = do_realpath(conn, src)) == NULL) {
|
||||||
error("Unable to canonicalize path \"%s\"", src);
|
error("download \"%s\": path canonicalization failed", src);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1842,21 +1877,22 @@ do_upload(struct sftp_conn *conn, const char *local_path,
|
||||||
struct requests acks;
|
struct requests acks;
|
||||||
size_t handle_len;
|
size_t handle_len;
|
||||||
|
|
||||||
|
debug2_f("upload local \"%s\" to remote \"%s\"",
|
||||||
|
local_path, remote_path);
|
||||||
|
|
||||||
TAILQ_INIT(&acks);
|
TAILQ_INIT(&acks);
|
||||||
|
|
||||||
if ((local_fd = open(local_path, O_RDONLY)) == -1) {
|
if ((local_fd = open(local_path, O_RDONLY)) == -1) {
|
||||||
error("Couldn't open local file \"%s\" for reading: %s",
|
error("open local \"%s\": %s", local_path, strerror(errno));
|
||||||
local_path, strerror(errno));
|
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
if (fstat(local_fd, &sb) == -1) {
|
if (fstat(local_fd, &sb) == -1) {
|
||||||
error("Couldn't fstat local file \"%s\": %s",
|
error("fstat local \"%s\": %s", local_path, strerror(errno));
|
||||||
local_path, strerror(errno));
|
|
||||||
close(local_fd);
|
close(local_fd);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
if (!S_ISREG(sb.st_mode)) {
|
if (!S_ISREG(sb.st_mode)) {
|
||||||
error("%s is not a regular file", local_path);
|
error("local \"%s\" is not a regular file", local_path);
|
||||||
close(local_fd);
|
close(local_fd);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
@ -1876,8 +1912,8 @@ do_upload(struct sftp_conn *conn, const char *local_path,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((off_t)c->size >= sb.st_size) {
|
if ((off_t)c->size >= sb.st_size) {
|
||||||
error("destination file bigger or same size as "
|
error("resume \"%s\": destination file "
|
||||||
"source file");
|
"same size or larger", local_path);
|
||||||
close(local_fd);
|
close(local_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1925,11 +1961,10 @@ do_upload(struct sftp_conn *conn, const char *local_path,
|
||||||
while ((len == -1) &&
|
while ((len == -1) &&
|
||||||
(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
|
(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
|
||||||
|
|
||||||
if (len == -1)
|
if (len == -1) {
|
||||||
fatal("Couldn't read from \"%s\": %s", local_path,
|
fatal("read local \"%s\": %s",
|
||||||
strerror(errno));
|
local_path, strerror(errno));
|
||||||
|
} else if (len != 0) {
|
||||||
if (len != 0) {
|
|
||||||
ack = request_enqueue(&acks, ++id, len, offset);
|
ack = request_enqueue(&acks, ++id, len, offset);
|
||||||
sshbuf_reset(msg);
|
sshbuf_reset(msg);
|
||||||
if ((r = sshbuf_put_u8(msg, SSH2_FXP_WRITE)) != 0 ||
|
if ((r = sshbuf_put_u8(msg, SSH2_FXP_WRITE)) != 0 ||
|
||||||
|
@ -1987,14 +2022,12 @@ do_upload(struct sftp_conn *conn, const char *local_path,
|
||||||
free(data);
|
free(data);
|
||||||
|
|
||||||
if (status != SSH2_FX_OK) {
|
if (status != SSH2_FX_OK) {
|
||||||
error("Couldn't write to remote file \"%s\": %s",
|
error("write remote \"%s\": %s", remote_path, fx2txt(status));
|
||||||
remote_path, fx2txt(status));
|
|
||||||
status = SSH2_FX_FAILURE;
|
status = SSH2_FX_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (close(local_fd) == -1) {
|
if (close(local_fd) == -1) {
|
||||||
error("Couldn't close local file \"%s\": %s", local_path,
|
error("close local \"%s\": %s", local_path, strerror(errno));
|
||||||
strerror(errno));
|
|
||||||
status = SSH2_FX_FAILURE;
|
status = SSH2_FX_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2026,14 +2059,15 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
|
||||||
Attrib a, *dirattrib;
|
Attrib a, *dirattrib;
|
||||||
u_int32_t saved_perm;
|
u_int32_t saved_perm;
|
||||||
|
|
||||||
|
debug2_f("upload local dir \"%s\" to remote \"%s\"", src, dst);
|
||||||
|
|
||||||
if (depth >= MAX_DIR_DEPTH) {
|
if (depth >= MAX_DIR_DEPTH) {
|
||||||
error("Maximum directory depth exceeded: %d levels", depth);
|
error("Maximum directory depth exceeded: %d levels", depth);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stat(src, &sb) == -1) {
|
if (stat(src, &sb) == -1) {
|
||||||
error("Couldn't stat directory \"%s\": %s",
|
error("stat local \"%s\": %s", src, strerror(errno));
|
||||||
src, strerror(errno));
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!S_ISDIR(sb.st_mode)) {
|
if (!S_ISDIR(sb.st_mode)) {
|
||||||
|
@ -2069,7 +2103,7 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
|
||||||
a.perm = saved_perm;
|
a.perm = saved_perm;
|
||||||
|
|
||||||
if ((dirp = opendir(src)) == NULL) {
|
if ((dirp = opendir(src)) == NULL) {
|
||||||
error("Failed to open dir \"%s\": %s", src, strerror(errno));
|
error("local opendir \"%s\": %s", src, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2083,7 +2117,7 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
|
||||||
new_src = path_append(src, filename);
|
new_src = path_append(src, filename);
|
||||||
|
|
||||||
if (lstat(new_src, &sb) == -1) {
|
if (lstat(new_src, &sb) == -1) {
|
||||||
logit("%s: lstat failed: %s", filename,
|
logit("local lstat \"%s\": %s", filename,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
ret = -1;
|
ret = -1;
|
||||||
} else if (S_ISDIR(sb.st_mode)) {
|
} else if (S_ISDIR(sb.st_mode)) {
|
||||||
|
@ -2099,12 +2133,12 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
|
||||||
(follow_link_flag && S_ISLNK(sb.st_mode))) {
|
(follow_link_flag && S_ISLNK(sb.st_mode))) {
|
||||||
if (do_upload(conn, new_src, new_dst,
|
if (do_upload(conn, new_src, new_dst,
|
||||||
preserve_flag, resume, fsync_flag) == -1) {
|
preserve_flag, resume, fsync_flag) == -1) {
|
||||||
error("Uploading of file %s to %s failed!",
|
error("upload \"%s\" to \"%s\" failed",
|
||||||
new_src, new_dst);
|
new_src, new_dst);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
logit("%s: not a regular file\n", filename);
|
logit("%s: not a regular file", filename);
|
||||||
}
|
}
|
||||||
free(new_dst);
|
free(new_dst);
|
||||||
free(new_src);
|
free(new_src);
|
||||||
|
@ -2124,7 +2158,7 @@ upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if ((dst_canon = do_realpath(conn, dst)) == NULL) {
|
if ((dst_canon = do_realpath(conn, dst)) == NULL) {
|
||||||
error("Unable to canonicalize path \"%s\"", dst);
|
error("upload \"%s\": path canonicalization failed", dst);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2219,6 +2253,8 @@ do_crossload(struct sftp_conn *from, struct sftp_conn *to,
|
||||||
struct request *req;
|
struct request *req;
|
||||||
u_char type;
|
u_char type;
|
||||||
|
|
||||||
|
debug2_f("crossload src \"%s\" to dst \"%s\"", from_path, to_path);
|
||||||
|
|
||||||
TAILQ_INIT(&requests);
|
TAILQ_INIT(&requests);
|
||||||
|
|
||||||
if (a == NULL && (a = do_stat(from, from_path, 0)) == NULL)
|
if (a == NULL && (a = do_stat(from, from_path, 0)) == NULL)
|
||||||
|
@ -2226,7 +2262,7 @@ do_crossload(struct sftp_conn *from, struct sftp_conn *to,
|
||||||
|
|
||||||
if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
|
if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
|
||||||
(!S_ISREG(a->perm))) {
|
(!S_ISREG(a->perm))) {
|
||||||
error("Cannot download non-regular file: %s", from_path);
|
error("download \"%s\": not a regular file", from_path);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
if (a->flags & SSH2_FILEXFER_ATTR_SIZE)
|
if (a->flags & SSH2_FILEXFER_ATTR_SIZE)
|
||||||
|
@ -2407,20 +2443,18 @@ do_crossload(struct sftp_conn *from, struct sftp_conn *to,
|
||||||
if (send_open(to, to_path, "dest",
|
if (send_open(to, to_path, "dest",
|
||||||
SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC, a,
|
SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC, a,
|
||||||
&to_handle, &to_handle_len) != 0) {
|
&to_handle, &to_handle_len) != 0) {
|
||||||
error("truncation failed for \"%s\"", to_path);
|
error("dest truncate \"%s\" failed", to_path);
|
||||||
to_handle = NULL;
|
to_handle = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (read_error) {
|
if (read_error) {
|
||||||
error("Couldn't read from origin file \"%s\" : %s",
|
error("read origin \"%s\": %s", from_path, fx2txt(status));
|
||||||
from_path, fx2txt(status));
|
|
||||||
status = -1;
|
status = -1;
|
||||||
do_close(from, from_handle, from_handle_len);
|
do_close(from, from_handle, from_handle_len);
|
||||||
if (to_handle != NULL)
|
if (to_handle != NULL)
|
||||||
do_close(to, to_handle, to_handle_len);
|
do_close(to, to_handle, to_handle_len);
|
||||||
} else if (write_error) {
|
} else if (write_error) {
|
||||||
error("Couldn't write to \"%s\": %s",
|
error("write dest \"%s\": %s", to_path, fx2txt(write_error));
|
||||||
to_path, fx2txt(write_error));
|
|
||||||
status = SSH2_FX_FAILURE;
|
status = SSH2_FX_FAILURE;
|
||||||
do_close(from, from_handle, from_handle_len);
|
do_close(from, from_handle, from_handle_len);
|
||||||
if (to_handle != NULL)
|
if (to_handle != NULL)
|
||||||
|
@ -2457,6 +2491,8 @@ crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to,
|
||||||
mode_t mode = 0777;
|
mode_t mode = 0777;
|
||||||
Attrib curdir;
|
Attrib curdir;
|
||||||
|
|
||||||
|
debug2_f("crossload dir src \"%s\" to dst \"%s\"", from_path, to_path);
|
||||||
|
|
||||||
if (depth >= MAX_DIR_DEPTH) {
|
if (depth >= MAX_DIR_DEPTH) {
|
||||||
error("Maximum directory depth exceeded: %d levels", depth);
|
error("Maximum directory depth exceeded: %d levels", depth);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -2464,7 +2500,7 @@ crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to,
|
||||||
|
|
||||||
if (dirattrib == NULL &&
|
if (dirattrib == NULL &&
|
||||||
(dirattrib = do_stat(from, from_path, 1)) == NULL) {
|
(dirattrib = do_stat(from, from_path, 1)) == NULL) {
|
||||||
error("Unable to stat remote directory \"%s\"", from_path);
|
error("stat remote \"%s\" failed", from_path);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!S_ISDIR(dirattrib->perm)) {
|
if (!S_ISDIR(dirattrib->perm)) {
|
||||||
|
@ -2504,7 +2540,7 @@ crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to,
|
||||||
curdir.perm = mode;
|
curdir.perm = mode;
|
||||||
|
|
||||||
if (do_readdir(from, from_path, &dir_entries) == -1) {
|
if (do_readdir(from, from_path, &dir_entries) == -1) {
|
||||||
error("%s: Failed to get directory contents", from_path);
|
error("origin readdir \"%s\" failed", from_path);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2535,13 +2571,14 @@ crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to,
|
||||||
if (do_crossload(from, to, new_from_path, new_to_path,
|
if (do_crossload(from, to, new_from_path, new_to_path,
|
||||||
S_ISLNK(dir_entries[i]->a.perm) ? NULL :
|
S_ISLNK(dir_entries[i]->a.perm) ? NULL :
|
||||||
&(dir_entries[i]->a), preserve_flag) == -1) {
|
&(dir_entries[i]->a), preserve_flag) == -1) {
|
||||||
error("Transfer of file %s to %s failed",
|
error("crossload \"%s\" to \"%s\" failed",
|
||||||
new_from_path, new_to_path);
|
new_from_path, new_to_path);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
logit("%s: not a regular file\n", new_from_path);
|
logit("origin \"%s\": not a regular file",
|
||||||
|
new_from_path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free(new_to_path);
|
free(new_to_path);
|
||||||
free(new_from_path);
|
free(new_from_path);
|
||||||
|
@ -2562,7 +2599,8 @@ crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if ((from_path_canon = do_realpath(from, from_path)) == NULL) {
|
if ((from_path_canon = do_realpath(from, from_path)) == NULL) {
|
||||||
error("Unable to canonicalize path \"%s\"", from_path);
|
error("crossload \"%s\": path canonicalization failed",
|
||||||
|
from_path);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue