-/* $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>
*
if ((r = sshbuf_get_u32(msg, &status)) != 0)
fatal_fr(r, "parse status");
if (quiet)
- debug("Couldn't stat remote file: %s", fx2txt(status));
+ debug("stat remote: %s", fx2txt(status));
else
- error("Couldn't stat remote file: %s", fx2txt(status));
+ error("stat remote: %s", fx2txt(status));
sshbuf_free(msg);
return(NULL);
} else if (type != SSH2_FXP_ATTRS) {
if ((r = sshbuf_get_u32(msg, &status)) != 0)
fatal_fr(r, "parse status");
if (quiet)
- debug("Couldn't statvfs: %s", fx2txt(status));
+ debug("remote statvfs: %s", fx2txt(status));
else
- error("Couldn't statvfs: %s", fx2txt(status));
+ error("remote statvfs: %s", fx2txt(status));
sshbuf_free(msg);
return -1;
} else if (type != SSH2_FXP_EXTENDED_REPLY) {
status = get_status(conn, id);
if (status != SSH2_FX_OK)
- error("Couldn't close file: %s", fx2txt(status));
+ error("close remote: %s", fx2txt(status));
sshbuf_free(msg);
send_string_request(conn, id, SSH2_FXP_REMOVE, path, strlen(path));
status = get_status(conn, id);
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;
}
{
u_int status, id;
+ debug2("Sending SSH2_FXP_MKDIR \"%s\"", path);
+
id = conn->msg_id++;
send_string_attrs_request(conn, id, SSH2_FXP_MKDIR, path,
strlen(path), a);
status = get_status(conn, id);
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;
}
{
u_int status, id;
+ debug2("Sending SSH2_FXP_RMDIR \"%s\"", path);
+
id = conn->msg_id++;
send_string_request(conn, id, SSH2_FXP_RMDIR, path,
strlen(path));
status = get_status(conn, id);
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;
}
{
u_int id;
+ debug2("Sending SSH2_FXP_STAT \"%s\"", path);
+
id = conn->msg_id++;
send_string_request(conn, id,
{
u_int id;
+ debug2("Sending SSH2_FXP_FSTAT \"%s\"");
+
id = conn->msg_id++;
send_string_request(conn, id, SSH2_FXP_FSTAT, handle,
handle_len);
{
u_int status, id;
+ debug2("Sending SSH2_FXP_SETSTAT \"%s\"", path);
+
id = conn->msg_id++;
send_string_attrs_request(conn, id, SSH2_FXP_SETSTAT, path,
strlen(path), a);
status = get_status(conn, id);
if (status != SSH2_FX_OK)
- error("Couldn't setstat on \"%s\": %s", path,
- fx2txt(status));
+ error("remote setstat \"%s\": %s", path, fx2txt(status));
return status == SSH2_FX_OK ? 0 : -1;
}
{
u_int status, id;
+ debug2("Sending SSH2_FXP_FSETSTAT");
+
id = conn->msg_id++;
send_string_attrs_request(conn, id, SSH2_FXP_FSETSTAT, handle,
handle_len, a);
status = get_status(conn, id);
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;
}
expected_id = id = conn->msg_id++;
if (expand) {
+ debug2("Sending SSH2_FXP_EXTENDED(expand-path@openssh.com) "
+ "\"%s\"", path);
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_cstring(msg,
fatal_fr(r, "compose %s", what);
send_msg(conn, msg);
} else {
+ debug2("Sending SSH2_FXP_REALPATH \"%s\"", path);
send_string_request(conn, id, SSH2_FXP_REALPATH,
path, strlen(path));
}
/* Send rename request */
id = conn->msg_id++;
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 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_cstring(msg,
"posix-rename@openssh.com")) != 0)
fatal_fr(r, "compose posix-rename");
} else {
+ debug2("Sending SSH2_FXP_RENAME \"%s\" to \"%s\"",
+ oldpath, newpath);
if ((r = sshbuf_put_u8(msg, SSH2_FXP_RENAME)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0)
fatal_fr(r, "compose rename");
status = get_status(conn, id);
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));
return status == SSH2_FX_OK ? 0 : -1;
error("Server does not support hardlink@openssh.com extension");
return -1;
}
+ debug2("Sending SSH2_FXP_EXTENDED(hardlink@openssh.com) "
+ "\"%s\" to \"%s\"", oldpath, newpath);
if ((msg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
status = get_status(conn, id);
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));
return status == SSH2_FX_OK ? 0 : -1;
error("This server does not support the symlink operation");
return(SSH2_FX_OP_UNSUPPORTED);
}
+ debug2("Sending SSH2_FXP_SYMLINK \"%s\" to \"%s\"", oldpath, newpath);
if ((msg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
status = get_status(conn, id);
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));
return status == SSH2_FX_OK ? 0 : -1;
/* Silently return if the extension is not supported */
if ((conn->exts & SFTP_EXT_FSYNC) == 0)
return -1;
+ debug2("Sending SSH2_FXP_EXTENDED(fsync@openssh.com)");
/* Send fsync request */
if ((msg = sshbuf_new()) == NULL)
status = get_status(conn, id);
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;
}
u_char type;
int r;
+ debug2("Sending SSH2_FXP_READLINK \"%s\"", path);
+
expected_id = id = conn->msg_id++;
send_string_request(conn, id, SSH2_FXP_READLINK, path, strlen(path));
return -1;
}
+ debug2("Sending SSH2_FXP_EXTENDED(statvfs@openssh.com) \"%s\"", path);
+
id = conn->msg_id++;
if ((msg = sshbuf_new()) == NULL)
return -1;
}
+ debug2("Sending SSH2_FXP_EXTENDED(fstatvfs@openssh.com)");
+
id = conn->msg_id++;
if ((msg = sshbuf_new()) == NULL)
return -1;
}
+ debug2("Sending SSH2_FXP_EXTENDED(lsetstat@openssh.com) \"%s\"", path);
+
id = conn->msg_id++;
if ((msg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
status = get_status(conn, id);
if (status != SSH2_FX_OK)
- error("Couldn't setstat on \"%s\": %s", path,
- fx2txt(status));
+ error("remote lsetstat \"%s\": %s", path, fx2txt(status));
return status == SSH2_FX_OK ? 0 : -1;
}
int r;
u_int id;
+ debug2("Sending SSH2_FXP_OPEN \"%s\"", path);
+
*handlep = NULL;
*handle_lenp = 0;
struct request *req;
u_char type;
+ debug2_f("download remote \"%s\" to local \"%s\"",
+ remote_path, local_path);
+
TAILQ_INIT(&requests);
if (a == NULL && (a = do_stat(conn, remote_path, 0)) == NULL)
if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
(!S_ISREG(a->perm))) {
- error("Cannot download non-regular file: %s", remote_path);
+ error("download %s: not a regular file", remote_path);
return(-1);
}
local_fd = open(local_path,
O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC), mode | S_IWUSR);
if (local_fd == -1) {
- error("Couldn't open local file \"%s\" for writing: %s",
- local_path, strerror(errno));
+ error("open local \"%s\": %s", local_path, strerror(errno));
goto fail;
}
offset = highwater = 0;
if (resume_flag) {
if (fstat(local_fd, &st) == -1) {
- error("Unable to stat local file \"%s\": %s",
+ error("stat local \"%s\": %s",
local_path, strerror(errno));
goto fail;
}
}
debug("truncating at %llu", (unsigned long long)highwater);
if (ftruncate(local_fd, highwater) == -1)
- error("ftruncate \"%s\": %s", local_path,
+ error("local ftruncate \"%s\": %s", local_path,
strerror(errno));
}
if (read_error) {
- error("Couldn't read from remote file \"%s\" : %s",
- remote_path, fx2txt(status));
+ error("read remote \"%s\" : %s", remote_path, fx2txt(status));
status = -1;
do_close(conn, handle, handle_len);
} else if (write_error) {
- error("Couldn't write to \"%s\": %s", local_path,
+ error("write local \"%s\": %s", local_path,
strerror(write_errno));
status = SSH2_FX_FAILURE;
do_close(conn, handle, handle_len);
status = SSH2_FX_OK;
/* Override umask and utimes if asked */
if (preserve_flag && fchmod(local_fd, mode) == -1)
- error("Couldn't set mode on \"%s\": %s", local_path,
+ error("local chmod \"%s\": %s", local_path,
strerror(errno));
if (preserve_flag &&
(a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) {
tv[1].tv_sec = a->mtime;
tv[0].tv_usec = tv[1].tv_usec = 0;
if (utimes(local_path, tv) == -1)
- error("Can't set times on \"%s\": %s",
+ error("local set times \"%s\": %s",
local_path, strerror(errno));
}
if (resume_flag && !lmodified)
else if (fsync_flag) {
debug("syncing \"%s\"", local_path);
if (fsync(local_fd) == -1)
- error("Couldn't sync file \"%s\": %s",
+ error("local sync \"%s\": %s",
local_path, strerror(errno));
}
}
return -1;
}
+ debug2_f("download dir remote \"%s\" to local \"%s\"", src, dst);
+
if (dirattrib == 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;
}
if (!S_ISDIR(dirattrib->perm)) {
mode = dirattrib->perm & 01777;
tmpmode = mode | (S_IWUSR|S_IXUSR);
} else {
- debug("Server did not send permissions for "
- "directory \"%s\"", dst);
+ debug("download remote \"%s\": server "
+ "did not send permissions", dst);
}
if (mkdir(dst, tmpmode) == -1 && errno != EEXIST) {
}
if (do_readdir(conn, src, &dir_entries) == -1) {
- error("%s: Failed to get directory contents", src);
+ error("remote readdir \"%s\" failed", src);
return -1;
}
ret = -1;
}
} else
- logit("%s: not a regular file\n", new_src);
+ logit("download \"%s\": not a regular file", new_src);
}
free(new_dst);
tv[1].tv_sec = dirattrib->mtime;
tv[0].tv_usec = tv[1].tv_usec = 0;
if (utimes(dst, tv) == -1)
- error("Can't set times on \"%s\": %s",
+ error("local set times on \"%s\": %s",
dst, strerror(errno));
} else
debug("Server did not send times for directory "
}
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));
free_sftp_dirents(dir_entries);
int ret;
if ((src_canon = do_realpath(conn, src)) == NULL) {
- error("Unable to canonicalize path \"%s\"", src);
+ error("download \"%s\": path canonicalization failed", src);
return -1;
}
struct requests acks;
size_t handle_len;
+ debug2_f("upload local \"%s\" to remote \"%s\"",
+ local_path, remote_path);
+
TAILQ_INIT(&acks);
if ((local_fd = open(local_path, O_RDONLY)) == -1) {
- error("Couldn't open local file \"%s\" for reading: %s",
- local_path, strerror(errno));
+ error("open local \"%s\": %s", local_path, strerror(errno));
return(-1);
}
if (fstat(local_fd, &sb) == -1) {
- error("Couldn't fstat local file \"%s\": %s",
- local_path, strerror(errno));
+ error("fstat local \"%s\": %s", local_path, strerror(errno));
close(local_fd);
return(-1);
}
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);
return(-1);
}
}
if ((off_t)c->size >= sb.st_size) {
- error("destination file bigger or same size as "
- "source file");
+ error("resume \"%s\": destination file "
+ "same size or larger", local_path);
close(local_fd);
return -1;
}
len = read(local_fd, data, conn->upload_buflen);
while ((len == -1) && (errno == EINTR || errno == EAGAIN));
- if (len == -1)
- fatal("Couldn't read from \"%s\": %s", local_path,
- strerror(errno));
-
- if (len != 0) {
+ if (len == -1) {
+ fatal("read local \"%s\": %s",
+ local_path, strerror(errno));
+ } else if (len != 0) {
ack = request_enqueue(&acks, ++id, len, offset);
sshbuf_reset(msg);
if ((r = sshbuf_put_u8(msg, SSH2_FXP_WRITE)) != 0 ||
free(data);
if (status != SSH2_FX_OK) {
- error("Couldn't write to remote file \"%s\": %s",
- remote_path, fx2txt(status));
+ error("write remote \"%s\": %s", remote_path, fx2txt(status));
status = SSH2_FX_FAILURE;
}
if (close(local_fd) == -1) {
- error("Couldn't close local file \"%s\": %s", local_path,
- strerror(errno));
+ error("close local \"%s\": %s", local_path, strerror(errno));
status = SSH2_FX_FAILURE;
}
Attrib a, *dirattrib;
u_int32_t saved_perm;
+ debug2_f("upload local dir \"%s\" to remote \"%s\"", src, dst);
+
if (depth >= MAX_DIR_DEPTH) {
error("Maximum directory depth exceeded: %d levels", depth);
return -1;
}
if (stat(src, &sb) == -1) {
- error("Couldn't stat directory \"%s\": %s",
- src, strerror(errno));
+ error("stat local \"%s\": %s", src, strerror(errno));
return -1;
}
if (!S_ISDIR(sb.st_mode)) {
a.perm = saved_perm;
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;
}
new_src = path_append(src, filename);
if (lstat(new_src, &sb) == -1) {
- logit("%s: lstat failed: %s", filename,
+ logit("local lstat \"%s\": %s", filename,
strerror(errno));
ret = -1;
} else if (S_ISDIR(sb.st_mode)) {
(follow_link_flag && S_ISLNK(sb.st_mode))) {
if (do_upload(conn, new_src, new_dst,
preserve_flag, resume, fsync_flag) == -1) {
- error("Uploading of file %s to %s failed!",
+ error("upload \"%s\" to \"%s\" failed",
new_src, new_dst);
ret = -1;
}
} else
- logit("%s: not a regular file\n", filename);
+ logit("%s: not a regular file", filename);
}
free(new_dst);
free(new_src);
int ret;
if ((dst_canon = do_realpath(conn, dst)) == NULL) {
- error("Unable to canonicalize path \"%s\"", dst);
+ error("upload \"%s\": path canonicalization failed", dst);
return -1;
}
struct request *req;
u_char type;
+ debug2_f("crossload src \"%s\" to dst \"%s\"", from_path, to_path);
+
TAILQ_INIT(&requests);
if (a == NULL && (a = do_stat(from, from_path, 0)) == NULL)
if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
(!S_ISREG(a->perm))) {
- error("Cannot download non-regular file: %s", from_path);
+ error("download \"%s\": not a regular file", from_path);
return(-1);
}
if (a->flags & SSH2_FILEXFER_ATTR_SIZE)
if (send_open(to, to_path, "dest",
SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC, a,
&to_handle, &to_handle_len) != 0) {
- error("truncation failed for \"%s\"", to_path);
+ error("dest truncate \"%s\" failed", to_path);
to_handle = NULL;
}
}
if (read_error) {
- error("Couldn't read from origin file \"%s\" : %s",
- from_path, fx2txt(status));
+ error("read origin \"%s\": %s", from_path, fx2txt(status));
status = -1;
do_close(from, from_handle, from_handle_len);
if (to_handle != NULL)
do_close(to, to_handle, to_handle_len);
} else if (write_error) {
- error("Couldn't write to \"%s\": %s",
- to_path, fx2txt(write_error));
+ error("write dest \"%s\": %s", to_path, fx2txt(write_error));
status = SSH2_FX_FAILURE;
do_close(from, from_handle, from_handle_len);
if (to_handle != NULL)
mode_t mode = 0777;
Attrib curdir;
+ debug2_f("crossload dir src \"%s\" to dst \"%s\"", from_path, to_path);
+
if (depth >= MAX_DIR_DEPTH) {
error("Maximum directory depth exceeded: %d levels", depth);
return -1;
if (dirattrib == 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;
}
if (!S_ISDIR(dirattrib->perm)) {
curdir.perm = mode;
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;
}
if (do_crossload(from, to, new_from_path, new_to_path,
S_ISLNK(dir_entries[i]->a.perm) ? NULL :
&(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);
ret = -1;
}
- } else
- logit("%s: not a regular file\n", new_from_path);
-
+ } else {
+ logit("origin \"%s\": not a regular file",
+ new_from_path);
+ }
}
free(new_to_path);
free(new_from_path);
int ret;
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;
}