-/* $OpenBSD: sftp-client.c,v 1.172 2023/09/08 05:50:12 djm Exp $ */
+/* $OpenBSD: sftp-client.c,v 1.173 2023/09/08 05:56:13 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
return handle;
}
-/* XXX returning &static is error-prone. Refactor to fill *Attrib argument */
-static Attrib *
-get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet)
+static int
+get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet, Attrib *a)
{
struct sshbuf *msg;
u_int id;
u_char type;
int r;
- static Attrib a;
+ Attrib attr;
+ if (a != NULL)
+ memset(a, '\0', sizeof(*a));
if ((msg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
get_msg(conn, msg);
else
error("stat remote: %s", fx2txt(status));
sshbuf_free(msg);
- return(NULL);
+ return -1;
} else if (type != SSH2_FXP_ATTRS) {
fatal("Expected SSH2_FXP_ATTRS(%u) packet, got %u",
SSH2_FXP_ATTRS, type);
}
- if ((r = decode_attrib(msg, &a)) != 0) {
+ if ((r = decode_attrib(msg, &attr)) != 0) {
error_fr(r, "decode_attrib");
sshbuf_free(msg);
- return NULL;
+ return -1;
}
+ /* success */
+ if (a != NULL)
+ *a = attr;
debug3("Received stat reply T:%u I:%u F:0x%04x M:%05o",
- type, id, a.flags, a.perm);
+ type, id, attr.flags, attr.perm);
sshbuf_free(msg);
- return &a;
+ return 0;
}
static int
}
struct sftp_conn *
-do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests,
+sftp_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests,
u_int64_t limit_kbps)
{
u_char type;
/* Query the server for its limits */
if (ret->exts & SFTP_EXT_LIMITS) {
struct sftp_limits limits;
- if (do_limits(ret, &limits) != 0)
+ if (sftp_get_limits(ret, &limits) != 0)
fatal_f("limits failed");
/* If the caller did not specify, find a good value */
}
int
-do_limits(struct sftp_conn *conn, struct sftp_limits *limits)
+sftp_get_limits(struct sftp_conn *conn, struct sftp_limits *limits)
{
u_int id, msg_id;
u_char type;
}
int
-do_close(struct sftp_conn *conn, const u_char *handle, u_int handle_len)
+sftp_close(struct sftp_conn *conn, const u_char *handle, u_int handle_len)
{
u_int id, status;
struct sshbuf *msg;
static int
-do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
+sftp_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
SFTP_DIRENT ***dir)
{
struct sshbuf *msg;
out:
sshbuf_free(msg);
- do_close(conn, handle, handle_len);
+ sftp_close(conn, handle, handle_len);
free(handle);
if (status != 0 && dir != NULL) {
/* Don't return results on error */
- free_sftp_dirents(*dir);
+ sftp_free_dirents(*dir);
*dir = NULL;
} else if (interrupted && dir != NULL && *dir != NULL) {
/* Don't return partial matches on interrupt */
- free_sftp_dirents(*dir);
+ sftp_free_dirents(*dir);
*dir = xcalloc(1, sizeof(**dir));
**dir = NULL;
}
}
int
-do_readdir(struct sftp_conn *conn, const char *path, SFTP_DIRENT ***dir)
+sftp_readdir(struct sftp_conn *conn, const char *path, SFTP_DIRENT ***dir)
{
- return(do_lsreaddir(conn, path, 0, dir));
+ return sftp_lsreaddir(conn, path, 0, dir);
}
-void free_sftp_dirents(SFTP_DIRENT **s)
+void sftp_free_dirents(SFTP_DIRENT **s)
{
int i;
}
int
-do_rm(struct sftp_conn *conn, const char *path)
+sftp_rm(struct sftp_conn *conn, const char *path)
{
u_int status, id;
}
int
-do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int print_flag)
+sftp_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int print_flag)
{
u_int status, id;
}
int
-do_rmdir(struct sftp_conn *conn, const char *path)
+sftp_rmdir(struct sftp_conn *conn, const char *path)
{
u_int status, id;
return status == SSH2_FX_OK ? 0 : -1;
}
-Attrib *
-do_stat(struct sftp_conn *conn, const char *path, int quiet)
+int
+sftp_stat(struct sftp_conn *conn, const char *path, int quiet, Attrib *a)
{
u_int id;
conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT,
path, strlen(path));
- return(get_decode_stat(conn, id, quiet));
+ return get_decode_stat(conn, id, quiet, a);
}
-Attrib *
-do_lstat(struct sftp_conn *conn, const char *path, int quiet)
+int
+sftp_lstat(struct sftp_conn *conn, const char *path, int quiet, Attrib *a)
{
u_int id;
if (conn->version == 0) {
- if (quiet)
- debug("Server version does not support lstat operation");
- else
- logit("Server version does not support lstat operation");
- return(do_stat(conn, path, quiet));
+ do_log2(quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_INFO,
+ "Server version does not support lstat operation");
+ return sftp_stat(conn, path, quiet, a);
}
id = conn->msg_id++;
send_string_request(conn, id, SSH2_FXP_LSTAT, path,
strlen(path));
- return(get_decode_stat(conn, id, quiet));
+ return get_decode_stat(conn, id, quiet, a);
}
#ifdef notyet
-Attrib *
-do_fstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
- int quiet)
+int
+sftp_fstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
+ int quiet, Attrib *a)
{
u_int id;
send_string_request(conn, id, SSH2_FXP_FSTAT, handle,
handle_len);
- return(get_decode_stat(conn, id, quiet));
+ return get_decode_stat(conn, id, quiet, a);
}
#endif
int
-do_setstat(struct sftp_conn *conn, const char *path, Attrib *a)
+sftp_setstat(struct sftp_conn *conn, const char *path, Attrib *a)
{
u_int status, id;
}
int
-do_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
+sftp_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
Attrib *a)
{
u_int status, id;
/* Implements both the realpath and expand-path operations */
static char *
-do_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
+sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
{
struct sshbuf *msg;
u_int expected_id, count, id;
}
char *
-do_realpath(struct sftp_conn *conn, const char *path)
+sftp_realpath(struct sftp_conn *conn, const char *path)
{
- return do_realpath_expand(conn, path, 0);
+ return sftp_realpath_expand(conn, path, 0);
}
int
-can_expand_path(struct sftp_conn *conn)
+sftp_can_expand_path(struct sftp_conn *conn)
{
return (conn->exts & SFTP_EXT_PATH_EXPAND) != 0;
}
char *
-do_expand_path(struct sftp_conn *conn, const char *path)
+sftp_expand_path(struct sftp_conn *conn, const char *path)
{
- if (!can_expand_path(conn)) {
+ if (!sftp_can_expand_path(conn)) {
debug3_f("no server support, fallback to realpath");
- return do_realpath_expand(conn, path, 0);
+ return sftp_realpath_expand(conn, path, 0);
}
- return do_realpath_expand(conn, path, 1);
+ return sftp_realpath_expand(conn, path, 1);
}
int
-do_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath)
+sftp_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath)
{
- Attrib junk, *a;
+ Attrib junk, attr;
struct sshbuf *msg;
u_char *old_handle, *new_handle;
u_int mode, status, id;
}
/* Make sure the file exists, and we can copy its perms */
- if ((a = do_stat(conn, oldpath, 0)) == NULL)
+ if (sftp_stat(conn, oldpath, 0, &attr) != 0)
return -1;
/* Do not preserve set[ug]id here, as we do not preserve ownership */
- if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
- mode = a->perm & 0777;
+ if (attr.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
+ mode = attr.perm & 0777;
- if (!S_ISREG(a->perm)) {
+ if (!S_ISREG(attr.perm)) {
error("Cannot copy non-regular file: %s", oldpath);
return -1;
}
}
/* Set up the new perms for the new file */
- attrib_clear(a);
- a->perm = mode;
- a->flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
+ attrib_clear(&attr);
+ attr.perm = mode;
+ attr.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
if ((msg = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
(r = sshbuf_put_cstring(msg, newpath)) != 0 ||
(r = sshbuf_put_u32(msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|
SSH2_FXF_TRUNC)) != 0 ||
- (r = encode_attrib(msg, a)) != 0)
+ (r = encode_attrib(msg, &attr)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
send_msg(conn, msg);
debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, newpath);
/* Clean up everything */
sshbuf_free(msg);
- do_close(conn, old_handle, old_handle_len);
- do_close(conn, new_handle, new_handle_len);
+ sftp_close(conn, old_handle, old_handle_len);
+ sftp_close(conn, new_handle, new_handle_len);
free(old_handle);
free(new_handle);
}
int
-do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath,
+sftp_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath,
int force_legacy)
{
struct sshbuf *msg;
}
int
-do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
+sftp_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
{
struct sshbuf *msg;
u_int status, id;
}
int
-do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
+sftp_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
{
struct sshbuf *msg;
u_int status, id;
}
int
-do_fsync(struct sftp_conn *conn, u_char *handle, u_int handle_len)
+sftp_fsync(struct sftp_conn *conn, u_char *handle, u_int handle_len)
{
struct sshbuf *msg;
u_int status, id;
#ifdef notyet
char *
-do_readlink(struct sftp_conn *conn, const char *path)
+sftp_readlink(struct sftp_conn *conn, const char *path)
{
struct sshbuf *msg;
u_int expected_id, count, id;
#endif
int
-do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st,
+sftp_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st,
int quiet)
{
struct sshbuf *msg;
#ifdef notyet
int
-do_fstatvfs(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
+sftp_fstatvfs(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
struct sftp_statvfs *st, int quiet)
{
struct sshbuf *msg;
#endif
int
-do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a)
+sftp_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a)
{
struct sshbuf *msg;
u_int status, id;
}
int
-do_download(struct sftp_conn *conn, const char *remote_path,
+sftp_download(struct sftp_conn *conn, const char *remote_path,
const char *local_path, Attrib *a, int preserve_flag, int resume_flag,
int fsync_flag, int inplace_flag)
{
struct requests requests;
struct request *req;
u_char type;
+ Attrib attr;
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)
- return -1;
+ if (a == NULL) {
+ if (sftp_stat(conn, remote_path, 0, &attr) != 0)
+ return -1;
+ a = &attr;
+ }
/* Do not preserve set[ug]id here, as we do not preserve ownership */
if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
error("Unable to resume download of \"%s\": "
"local file is larger than remote", local_path);
fail:
- do_close(conn, handle, handle_len);
+ sftp_close(conn, handle, handle_len);
free(handle);
if (local_fd != -1)
close(local_fd);
if (read_error) {
error("read remote \"%s\" : %s", remote_path, fx2txt(status));
status = -1;
- do_close(conn, handle, handle_len);
+ sftp_close(conn, handle, handle_len);
} else if (write_error) {
error("write local \"%s\": %s", local_path,
strerror(write_errno));
status = SSH2_FX_FAILURE;
- do_close(conn, handle, handle_len);
+ sftp_close(conn, handle, handle_len);
} else {
- if (do_close(conn, handle, handle_len) != 0 || interrupted)
+ if (sftp_close(conn, handle, handle_len) != 0 || interrupted)
status = SSH2_FX_FAILURE;
else
status = SSH2_FX_OK;
debug2_f("download dir remote \"%s\" to local \"%s\"", src, dst);
if (dirattrib == NULL) {
- if ((a = do_stat(conn, src, 1)) == NULL) {
+ if (sftp_stat(conn, src, 1, &ldirattrib) != 0) {
error("stat remote \"%s\" directory failed", src);
return -1;
}
- /* Don't let this be clobbered by later do_stat calls */
- ldirattrib = *a;
dirattrib = &ldirattrib;
}
if (!S_ISDIR(dirattrib->perm)) {
return -1;
}
- if (do_readdir(conn, src, &dir_entries) == -1) {
+ if (sftp_readdir(conn, src, &dir_entries) == -1) {
error("remote readdir \"%s\" failed", src);
return -1;
}
free(new_src);
filename = dir_entries[i]->filename;
- new_dst = path_append(dst, filename);
- new_src = path_append(src, filename);
+ new_dst = sftp_path_append(dst, filename);
+ new_src = sftp_path_append(src, filename);
a = &dir_entries[i]->a;
if (S_ISLNK(a->perm)) {
continue;
}
/* Replace the stat contents with the symlink target */
- if ((a = do_stat(conn, new_src, 1)) == NULL) {
+ if (sftp_stat(conn, new_src, 1, &lsym) != 0) {
logit("remote stat \"%s\" failed", new_src);
ret = -1;
continue;
}
- /* Don't let this be clobbered by later do_stat calls */
- lsym = *a;
a = &lsym;
}
fsync_flag, follow_link_flag, inplace_flag) == -1)
ret = -1;
} else if (S_ISREG(a->perm)) {
- if (do_download(conn, new_src, new_dst, a,
+ if (sftp_download(conn, new_src, new_dst, a,
preserve_flag, resume_flag, fsync_flag,
inplace_flag) == -1) {
error("Download of file %s to %s failed",
error("local chmod directory \"%s\": %s", dst,
strerror(errno));
- free_sftp_dirents(dir_entries);
+ sftp_free_dirents(dir_entries);
return ret;
}
int
-download_dir(struct sftp_conn *conn, const char *src, const char *dst,
+sftp_download_dir(struct sftp_conn *conn, const char *src, const char *dst,
Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag,
int fsync_flag, int follow_link_flag, int inplace_flag)
{
char *src_canon;
int ret;
- if ((src_canon = do_realpath(conn, src)) == NULL) {
+ if ((src_canon = sftp_realpath(conn, src)) == NULL) {
error("download \"%s\": path canonicalization failed", src);
return -1;
}
}
int
-do_upload(struct sftp_conn *conn, const char *local_path,
+sftp_upload(struct sftp_conn *conn, const char *local_path,
const char *remote_path, int preserve_flag, int resume,
int fsync_flag, int inplace_flag)
{
u_char type, *handle, *data;
struct sshbuf *msg;
struct stat sb;
- Attrib a, t, *c = NULL;
+ Attrib a, t, c;
u_int32_t startid, ackid;
u_int64_t highwater = 0, maxack = 0;
struct request *ack = NULL;
if (resume) {
/* Get remote file size if it exists */
- if ((c = do_stat(conn, remote_path, 0)) == NULL) {
+ if (sftp_stat(conn, remote_path, 0, &c) != 0) {
close(local_fd);
return -1;
}
- if ((off_t)c->size >= sb.st_size) {
+ if ((off_t)c.size >= sb.st_size) {
error("resume \"%s\": destination file "
"same size or larger", local_path);
close(local_fd);
return -1;
}
- if (lseek(local_fd, (off_t)c->size, SEEK_SET) == -1) {
+ if (lseek(local_fd, (off_t)c.size, SEEK_SET) == -1) {
close(local_fd);
return -1;
}
data = xmalloc(conn->upload_buflen);
/* Read from local and write to remote */
- offset = progress_counter = (resume ? c->size : 0);
+ offset = progress_counter = (resume ? c.size : 0);
if (showprogress) {
start_progress_meter(progress_meter_path(local_path),
sb.st_size, &progress_counter);
attrib_clear(&t);
t.flags = SSH2_FILEXFER_ATTR_SIZE;
t.size = highwater;
- do_fsetstat(conn, handle, handle_len, &t);
+ sftp_fsetstat(conn, handle, handle_len, &t);
}
if (close(local_fd) == -1) {
/* Override umask and utimes if asked */
if (preserve_flag)
- do_fsetstat(conn, handle, handle_len, &a);
+ sftp_fsetstat(conn, handle, handle_len, &a);
if (fsync_flag)
- (void)do_fsync(conn, handle, handle_len);
+ (void)sftp_fsync(conn, handle, handle_len);
- if (do_close(conn, handle, handle_len) != 0)
+ if (sftp_close(conn, handle, handle_len) != 0)
status = SSH2_FX_FAILURE;
free(handle);
struct dirent *dp;
char *filename, *new_src = NULL, *new_dst = NULL;
struct stat sb;
- Attrib a, *dirattrib;
+ Attrib a, dirattrib;
u_int32_t saved_perm;
debug2_f("upload local dir \"%s\" to remote \"%s\"", src, dst);
*/
saved_perm = a.perm;
a.perm |= (S_IWUSR|S_IXUSR);
- if (do_mkdir(conn, dst, &a, 0) != 0) {
- if ((dirattrib = do_stat(conn, dst, 0)) == NULL)
+ if (sftp_mkdir(conn, dst, &a, 0) != 0) {
+ if (sftp_stat(conn, dst, 0, &dirattrib) != 0)
return -1;
- if (!S_ISDIR(dirattrib->perm)) {
+ if (!S_ISDIR(dirattrib.perm)) {
error("\"%s\" exists but is not a directory", dst);
return -1;
}
free(new_dst);
free(new_src);
filename = dp->d_name;
- new_dst = path_append(dst, filename);
- new_src = path_append(src, filename);
+ new_dst = sftp_path_append(dst, filename);
+ new_src = sftp_path_append(src, filename);
if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0)
continue;
fsync_flag, follow_link_flag, inplace_flag) == -1)
ret = -1;
} else if (S_ISREG(sb.st_mode)) {
- if (do_upload(conn, new_src, new_dst,
+ if (sftp_upload(conn, new_src, new_dst,
preserve_flag, resume, fsync_flag,
inplace_flag) == -1) {
error("upload \"%s\" to \"%s\" failed",
free(new_dst);
free(new_src);
- do_setstat(conn, dst, &a);
+ sftp_setstat(conn, dst, &a);
(void) closedir(dirp);
return ret;
}
int
-upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
+sftp_upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
int preserve_flag, int print_flag, int resume, int fsync_flag,
int follow_link_flag, int inplace_flag)
{
char *dst_canon;
int ret;
- if ((dst_canon = do_realpath(conn, dst)) == NULL) {
+ if ((dst_canon = sftp_realpath(conn, dst)) == NULL) {
error("upload \"%s\": path canonicalization failed", dst);
return -1;
}
*write_errorp = status;
}
/*
- * XXX this doesn't do full reply matching like do_upload and
+ * XXX this doesn't do full reply matching like sftp_upload and
* so cannot gracefully truncate terminated uploads at a
* high-water mark. ATM the only caller of this function (scp)
* doesn't support transfer resumption, so this doesn't matter
* a whole lot.
*
- * To be safe, do_crossload truncates the destination file to
+ * To be safe, sftp_crossload truncates the destination file to
* zero length on upload failure, since we can't trust the
* server not to have reordered replies that could have
* inserted holes where none existed in the source file.
}
int
-do_crossload(struct sftp_conn *from, struct sftp_conn *to,
+sftp_crossload(struct sftp_conn *from, struct sftp_conn *to,
const char *from_path, const char *to_path,
Attrib *a, int preserve_flag)
{
struct requests requests;
struct request *req;
u_char type;
+ Attrib attr;
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)
- return -1;
+ if (a == NULL) {
+ if (sftp_stat(from, from_path, 0, &attr) != 0)
+ return -1;
+ a = &attr;
+ }
if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
(!S_ISREG(a->perm))) {
if (send_open(to, to_path, "dest",
SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC, a,
&to_handle, &to_handle_len) != 0) {
- do_close(from, from_handle, from_handle_len);
+ sftp_close(from, from_handle, from_handle_len);
return -1;
}
/* Truncate at 0 length on interrupt or error to avoid holes at dest */
if (read_error || write_error || interrupted) {
debug("truncating \"%s\" at 0", to_path);
- do_close(to, to_handle, to_handle_len);
+ sftp_close(to, to_handle, to_handle_len);
free(to_handle);
if (send_open(to, to_path, "dest",
SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC, a,
if (read_error) {
error("read origin \"%s\": %s", from_path, fx2txt(status));
status = -1;
- do_close(from, from_handle, from_handle_len);
+ sftp_close(from, from_handle, from_handle_len);
if (to_handle != NULL)
- do_close(to, to_handle, to_handle_len);
+ sftp_close(to, to_handle, to_handle_len);
} else if (write_error) {
error("write dest \"%s\": %s", to_path, fx2txt(write_error));
status = SSH2_FX_FAILURE;
- do_close(from, from_handle, from_handle_len);
+ sftp_close(from, from_handle, from_handle_len);
if (to_handle != NULL)
- do_close(to, to_handle, to_handle_len);
+ sftp_close(to, to_handle, to_handle_len);
} else {
- if (do_close(from, from_handle, from_handle_len) != 0 ||
+ if (sftp_close(from, from_handle, from_handle_len) != 0 ||
interrupted)
status = -1;
else
if (to_handle != NULL) {
/* Need to resend utimes after write */
if (preserve_flag)
- do_fsetstat(to, to_handle, to_handle_len, a);
- do_close(to, to_handle, to_handle_len);
+ sftp_fsetstat(to, to_handle, to_handle_len, a);
+ sftp_close(to, to_handle, to_handle_len);
}
}
sshbuf_free(msg);
SFTP_DIRENT **dir_entries;
char *filename, *new_from_path = NULL, *new_to_path = NULL;
mode_t mode = 0777;
- Attrib curdir;
+ Attrib curdir, ldirattrib, newdir;
debug2_f("crossload dir src \"%s\" to dst \"%s\"", from_path, to_path);
return -1;
}
- if (dirattrib == NULL &&
- (dirattrib = do_stat(from, from_path, 1)) == NULL) {
- error("stat remote \"%s\" failed", from_path);
- return -1;
+ if (dirattrib == NULL) {
+ if (sftp_stat(from, from_path, 1, &ldirattrib) != 0) {
+ error("stat remote \"%s\" failed", from_path);
+ return -1;
+ }
+ dirattrib = &ldirattrib;
}
if (!S_ISDIR(dirattrib->perm)) {
error("\"%s\" is not a directory", from_path);
* the path already existed and is a directory. Ensure we can
* write to the directory we create for the duration of the transfer.
*/
- if (do_mkdir(to, to_path, &curdir, 0) != 0) {
- if ((dirattrib = do_stat(to, to_path, 0)) == NULL)
+ if (sftp_mkdir(to, to_path, &curdir, 0) != 0) {
+ if (sftp_stat(to, to_path, 0, &newdir) != 0)
return -1;
- if (!S_ISDIR(dirattrib->perm)) {
+ if (!S_ISDIR(newdir.perm)) {
error("\"%s\" exists but is not a directory", to_path);
return -1;
}
}
curdir.perm = mode;
- if (do_readdir(from, from_path, &dir_entries) == -1) {
+ if (sftp_readdir(from, from_path, &dir_entries) == -1) {
error("origin readdir \"%s\" failed", from_path);
return -1;
}
free(new_to_path);
filename = dir_entries[i]->filename;
- new_from_path = path_append(from_path, filename);
- new_to_path = path_append(to_path, filename);
+ new_from_path = sftp_path_append(from_path, filename);
+ new_to_path = sftp_path_append(to_path, filename);
if (S_ISDIR(dir_entries[i]->a.perm)) {
if (strcmp(filename, ".") == 0 ||
(follow_link_flag && S_ISLNK(dir_entries[i]->a.perm))) {
/*
* If this is a symlink then don't send the link's
- * Attrib. do_download() will do a FXP_STAT operation
+ * Attrib. sftp_download() will do a FXP_STAT operation
* and get the link target's attributes.
*/
- if (do_crossload(from, to, new_from_path, new_to_path,
+ if (sftp_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("crossload \"%s\" to \"%s\" failed",
free(new_to_path);
free(new_from_path);
- do_setstat(to, to_path, &curdir);
+ sftp_setstat(to, to_path, &curdir);
- free_sftp_dirents(dir_entries);
+ sftp_free_dirents(dir_entries);
return ret;
}
int
-crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
+sftp_crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
const char *from_path, const char *to_path,
Attrib *dirattrib, int preserve_flag, int print_flag, int follow_link_flag)
{
char *from_path_canon;
int ret;
- if ((from_path_canon = do_realpath(from, from_path)) == NULL) {
+ if ((from_path_canon = sftp_realpath(from, from_path)) == NULL) {
error("crossload \"%s\": path canonicalization failed",
from_path);
return -1;
}
int
-can_get_users_groups_by_id(struct sftp_conn *conn)
+sftp_can_get_users_groups_by_id(struct sftp_conn *conn)
{
return (conn->exts & SFTP_EXT_GETUSERSGROUPS_BY_ID) != 0;
}
int
-do_get_users_groups_by_id(struct sftp_conn *conn,
+sftp_get_users_groups_by_id(struct sftp_conn *conn,
const u_int *uids, u_int nuids,
const u_int *gids, u_int ngids,
char ***usernamesp, char ***groupnamesp)
int r;
*usernamesp = *groupnamesp = NULL;
- if (!can_get_users_groups_by_id(conn))
+ if (!sftp_can_get_users_groups_by_id(conn))
return SSH_ERR_FEATURE_UNSUPPORTED;
if ((msg = sshbuf_new()) == NULL ||
}
char *
-path_append(const char *p1, const char *p2)
+sftp_path_append(const char *p1, const char *p2)
{
char *ret;
size_t len = strlen(p1) + strlen(p2) + 2;
* freed and a replacement allocated. Caller must free returned string.
*/
char *
-make_absolute(char *p, const char *pwd)
+sftp_make_absolute(char *p, const char *pwd)
{
char *abs_str;
/* Derelativise */
if (p && !path_absolute(p)) {
- abs_str = path_append(pwd, p);
+ abs_str = sftp_path_append(pwd, p);
free(p);
return(abs_str);
} else
}
int
-remote_is_dir(struct sftp_conn *conn, const char *path)
+sftp_remote_is_dir(struct sftp_conn *conn, const char *path)
{
- Attrib *a;
+ Attrib a;
/* XXX: report errors? */
- if ((a = do_stat(conn, path, 1)) == NULL)
+ if (sftp_stat(conn, path, 1, &a) != 0)
return(0);
- if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS))
+ if (!(a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS))
return(0);
- return(S_ISDIR(a->perm));
+ return S_ISDIR(a.perm);
}
-int
-local_is_dir(const char *path)
-{
- struct stat sb;
-
- /* XXX: report errors? */
- if (stat(path, &sb) == -1)
- return(0);
-
- return(S_ISDIR(sb.st_mode));
-}
-
/* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */
int
-globpath_is_dir(const char *pathname)
+sftp_globpath_is_dir(const char *pathname)
{
size_t l = strlen(pathname);
-/* $OpenBSD: sftp-client.h,v 1.38 2022/09/19 10:43:12 djm Exp $ */
+/* $OpenBSD: sftp-client.h,v 1.39 2023/09/08 05:56:13 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
* Initialise a SSH filexfer connection. Returns NULL on error or
* a pointer to a initialized sftp_conn struct on success.
*/
-struct sftp_conn *do_init(int, int, u_int, u_int, u_int64_t);
+struct sftp_conn *sftp_init(int, int, u_int, u_int, u_int64_t);
u_int sftp_proto_version(struct sftp_conn *);
/* Query server limits */
-int do_limits(struct sftp_conn *, struct sftp_limits *);
+int sftp_get_limits(struct sftp_conn *, struct sftp_limits *);
/* Close file referred to by 'handle' */
-int do_close(struct sftp_conn *, const u_char *, u_int);
+int sftp_close(struct sftp_conn *, const u_char *, u_int);
/* Read contents of 'path' to NULL-terminated array 'dir' */
-int do_readdir(struct sftp_conn *, const char *, SFTP_DIRENT ***);
+int sftp_readdir(struct sftp_conn *, const char *, SFTP_DIRENT ***);
-/* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from do_readdir) */
-void free_sftp_dirents(SFTP_DIRENT **);
+/* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from sftp_readdir) */
+void sftp_free_dirents(SFTP_DIRENT **);
/* Delete file 'path' */
-int do_rm(struct sftp_conn *, const char *);
+int sftp_rm(struct sftp_conn *, const char *);
/* Create directory 'path' */
-int do_mkdir(struct sftp_conn *, const char *, Attrib *, int);
+int sftp_mkdir(struct sftp_conn *, const char *, Attrib *, int);
/* Remove directory 'path' */
-int do_rmdir(struct sftp_conn *, const char *);
+int sftp_rmdir(struct sftp_conn *, const char *);
/* Get file attributes of 'path' (follows symlinks) */
-Attrib *do_stat(struct sftp_conn *, const char *, int);
+int sftp_stat(struct sftp_conn *, const char *, int, Attrib *);
/* Get file attributes of 'path' (does not follow symlinks) */
-Attrib *do_lstat(struct sftp_conn *, const char *, int);
+int sftp_lstat(struct sftp_conn *, const char *, int, Attrib *);
/* Set file attributes of 'path' */
-int do_setstat(struct sftp_conn *, const char *, Attrib *);
+int sftp_setstat(struct sftp_conn *, const char *, Attrib *);
/* Set file attributes of open file 'handle' */
-int do_fsetstat(struct sftp_conn *, const u_char *, u_int, Attrib *);
+int sftp_fsetstat(struct sftp_conn *, const u_char *, u_int, Attrib *);
/* Set file attributes of 'path', not following symlinks */
-int do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a);
+int sftp_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a);
/* Canonicalise 'path' - caller must free result */
-char *do_realpath(struct sftp_conn *, const char *);
+char *sftp_realpath(struct sftp_conn *, const char *);
/* Canonicalisation with tilde expansion (requires server extension) */
-char *do_expand_path(struct sftp_conn *, const char *);
+char *sftp_expand_path(struct sftp_conn *, const char *);
/* Returns non-zero if server can tilde-expand paths */
-int can_expand_path(struct sftp_conn *);
+int sftp_can_expand_path(struct sftp_conn *);
/* Get statistics for filesystem hosting file at "path" */
-int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int);
+int sftp_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int);
/* Rename 'oldpath' to 'newpath' */
-int do_rename(struct sftp_conn *, const char *, const char *, int);
+int sftp_rename(struct sftp_conn *, const char *, const char *, int);
/* Copy 'oldpath' to 'newpath' */
-int do_copy(struct sftp_conn *, const char *, const char *);
+int sftp_copy(struct sftp_conn *, const char *, const char *);
/* Link 'oldpath' to 'newpath' */
-int do_hardlink(struct sftp_conn *, const char *, const char *);
+int sftp_hardlink(struct sftp_conn *, const char *, const char *);
/* Rename 'oldpath' to 'newpath' */
-int do_symlink(struct sftp_conn *, const char *, const char *);
+int sftp_symlink(struct sftp_conn *, const char *, const char *);
/* Call fsync() on open file 'handle' */
-int do_fsync(struct sftp_conn *conn, u_char *, u_int);
+int sftp_fsync(struct sftp_conn *conn, u_char *, u_int);
/*
* Download 'remote_path' to 'local_path'. Preserve permissions and times
* if 'pflag' is set
*/
-int do_download(struct sftp_conn *, const char *, const char *, Attrib *,
+int sftp_download(struct sftp_conn *, const char *, const char *, Attrib *,
int, int, int, int);
/*
* Recursively download 'remote_directory' to 'local_directory'. Preserve
* times if 'pflag' is set
*/
-int download_dir(struct sftp_conn *, const char *, const char *, Attrib *,
+int sftp_download_dir(struct sftp_conn *, const char *, const char *, Attrib *,
int, int, int, int, int, int);
/*
* Upload 'local_path' to 'remote_path'. Preserve permissions and times
* if 'pflag' is set
*/
-int do_upload(struct sftp_conn *, const char *, const char *,
+int sftp_upload(struct sftp_conn *, const char *, const char *,
int, int, int, int);
/*
* Recursively upload 'local_directory' to 'remote_directory'. Preserve
* times if 'pflag' is set
*/
-int upload_dir(struct sftp_conn *, const char *, const char *,
+int sftp_upload_dir(struct sftp_conn *, const char *, const char *,
int, int, int, int, int, int);
/*
* Download a 'from_path' from the 'from' connection and upload it to
* to 'to' connection at 'to_path'.
*/
-int
-do_crossload(struct sftp_conn *from, struct sftp_conn *to,
+int sftp_crossload(struct sftp_conn *from, struct sftp_conn *to,
const char *from_path, const char *to_path,
Attrib *a, int preserve_flag);
* Recursively download a directory from 'from_path' from the 'from'
* connection and upload it to 'to' connection at 'to_path'.
*/
-int crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
+int sftp_crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
const char *from_path, const char *to_path,
Attrib *dirattrib, int preserve_flag, int print_flag,
int follow_link_flag);
/*
* User/group ID to name translation.
*/
-int can_get_users_groups_by_id(struct sftp_conn *conn);
-int do_get_users_groups_by_id(struct sftp_conn *conn,
+int sftp_can_get_users_groups_by_id(struct sftp_conn *conn);
+int sftp_get_users_groups_by_id(struct sftp_conn *conn,
const u_int *uids, u_int nuids,
const u_int *gids, u_int ngids,
char ***usernamesp, char ***groupnamesp);
/* Concatenate paths, taking care of slashes. Caller must free result. */
-char *path_append(const char *, const char *);
+char *sftp_path_append(const char *, const char *);
/* Make absolute path if relative path and CWD is given. Does not modify
* original if the path is already absolute. */
-char *make_absolute(char *, const char *);
+char *sftp_make_absolute(char *, const char *);
/* Check if remote path is directory */
-int remote_is_dir(struct sftp_conn *conn, const char *path);
-
-/* Check if local path is directory */
-int local_is_dir(const char *path);
+int sftp_remote_is_dir(struct sftp_conn *conn, const char *path);
/* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */
-int globpath_is_dir(const char *pathname);
+int sftp_globpath_is_dir(const char *pathname);
#endif
-/* $OpenBSD: sftp.c,v 1.234 2023/04/12 08:53:54 jsg Exp $ */
+/* $OpenBSD: sftp.c,v 1.235 2023/09/08 05:56:13 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
escpwd = escape_glob(pwd);
if (p == NULL)
return escpwd;
- ret = make_absolute(p, escpwd);
+ ret = sftp_make_absolute(p, escpwd);
free(escpwd);
return ret;
}
+static int
+local_is_dir(const char *path)
+{
+ struct stat sb;
+
+ if (stat(path, &sb) == -1)
+ return 0;
+ return S_ISDIR(sb.st_mode);
+}
+
static int
process_get(struct sftp_conn *conn, const char *src, const char *dst,
const char *pwd, int pflag, int rflag, int resume, int fflag)
if (g.gl_matchc == 1 && dst) {
if (local_is_dir(dst)) {
- abs_dst = path_append(dst, filename);
+ abs_dst = sftp_path_append(dst, filename);
} else {
abs_dst = xstrdup(dst);
}
} else if (dst) {
- abs_dst = path_append(dst, filename);
+ abs_dst = sftp_path_append(dst, filename);
} else {
abs_dst = xstrdup(filename);
}
mprintf("Fetching %s to %s\n",
g.gl_pathv[i], abs_dst);
/* XXX follow link flag */
- if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
- if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
- pflag || global_pflag, 1, resume,
+ if (sftp_globpath_is_dir(g.gl_pathv[i]) &&
+ (rflag || global_rflag)) {
+ if (sftp_download_dir(conn, g.gl_pathv[i], abs_dst,
+ NULL, pflag || global_pflag, 1, resume,
fflag || global_fflag, 0, 0) == -1)
err = -1;
} else {
- if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
+ if (sftp_download(conn, g.gl_pathv[i], abs_dst, NULL,
pflag || global_pflag, resume,
fflag || global_fflag, 0) == -1)
err = -1;
if (dst) {
tmp_dst = xstrdup(dst);
- tmp_dst = make_absolute(tmp_dst, pwd);
+ tmp_dst = sftp_make_absolute(tmp_dst, pwd);
}
memset(&g, 0, sizeof(g));
/* If we aren't fetching to pwd then stash this status for later */
if (tmp_dst != NULL)
- dst_is_dir = remote_is_dir(conn, tmp_dst);
+ dst_is_dir = sftp_remote_is_dir(conn, tmp_dst);
/* If multiple matches, dst may be directory or unspecified */
if (g.gl_matchc > 1 && tmp_dst && !dst_is_dir) {
if (g.gl_matchc == 1 && tmp_dst) {
/* If directory specified, append filename */
if (dst_is_dir)
- abs_dst = path_append(tmp_dst, filename);
+ abs_dst = sftp_path_append(tmp_dst, filename);
else
abs_dst = xstrdup(tmp_dst);
} else if (tmp_dst) {
- abs_dst = path_append(tmp_dst, filename);
+ abs_dst = sftp_path_append(tmp_dst, filename);
} else {
- abs_dst = make_absolute(xstrdup(filename), pwd);
+ abs_dst = sftp_make_absolute(xstrdup(filename), pwd);
}
free(tmp);
mprintf("Uploading %s to %s\n",
g.gl_pathv[i], abs_dst);
/* XXX follow_link_flag */
- if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
- if (upload_dir(conn, g.gl_pathv[i], abs_dst,
+ if (sftp_globpath_is_dir(g.gl_pathv[i]) &&
+ (rflag || global_rflag)) {
+ if (sftp_upload_dir(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, 1, resume,
fflag || global_fflag, 0, 0) == -1)
err = -1;
} else {
- if (do_upload(conn, g.gl_pathv[i], abs_dst,
+ if (sftp_upload(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, resume,
fflag || global_fflag, 0) == -1)
err = -1;
u_int c = 1, colspace = 0, columns = 1;
SFTP_DIRENT **d;
- if ((n = do_readdir(conn, path, &d)) != 0)
+ if ((n = sftp_readdir(conn, path, &d)) != 0)
return (n);
if (!(lflag & LS_SHORT_VIEW)) {
if (d[n]->filename[0] == '.' && !(lflag & LS_SHOW_ALL))
continue;
- tmp = path_append(path, d[n]->filename);
+ tmp = sftp_path_append(path, d[n]->filename);
fname = path_strip(tmp, strip_path);
free(tmp);
if (lflag & LS_LONG_VIEW) {
if ((lflag & (LS_NUMERIC_VIEW|LS_SI_UNITS)) != 0 ||
- can_get_users_groups_by_id(conn)) {
+ sftp_can_get_users_groups_by_id(conn)) {
char *lname;
struct stat sb;
if (!(lflag & LS_LONG_VIEW) && (c != 1))
printf("\n");
- free_sftp_dirents(d);
+ sftp_free_dirents(d);
return (0);
}
char s_root[FMT_SCALED_STRSIZE], s_total[FMT_SCALED_STRSIZE];
char s_icapacity[16], s_dcapacity[16];
- if (do_statvfs(conn, path, &st, 1) == -1)
+ if (sftp_statvfs(conn, path, &st, 1) == -1)
return -1;
if (st.f_files == 0)
strlcpy(s_icapacity, "ERR", sizeof(s_icapacity));
int lflag = 0, pflag = 0, rflag = 0, sflag = 0;
int cmdnum, i;
unsigned long n_arg = 0;
- Attrib a, *aa;
+ Attrib a, aa;
char path_buf[PATH_MAX];
int err = 0;
glob_t g;
rflag, aflag, fflag);
break;
case I_COPY:
- path1 = make_absolute(path1, *pwd);
- path2 = make_absolute(path2, *pwd);
- err = do_copy(conn, path1, path2);
+ path1 = sftp_make_absolute(path1, *pwd);
+ path2 = sftp_make_absolute(path2, *pwd);
+ err = sftp_copy(conn, path1, path2);
break;
case I_RENAME:
- path1 = make_absolute(path1, *pwd);
- path2 = make_absolute(path2, *pwd);
- err = do_rename(conn, path1, path2, lflag);
+ path1 = sftp_make_absolute(path1, *pwd);
+ path2 = sftp_make_absolute(path2, *pwd);
+ err = sftp_rename(conn, path1, path2, lflag);
break;
case I_SYMLINK:
sflag = 1;
/* FALLTHROUGH */
case I_LINK:
if (!sflag)
- path1 = make_absolute(path1, *pwd);
- path2 = make_absolute(path2, *pwd);
- err = (sflag ? do_symlink : do_hardlink)(conn, path1, path2);
+ path1 = sftp_make_absolute(path1, *pwd);
+ path2 = sftp_make_absolute(path2, *pwd);
+ err = (sflag ? sftp_symlink : sftp_hardlink)(conn,
+ path1, path2);
break;
case I_RM:
path1 = make_absolute_pwd_glob(path1, *pwd);
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
if (!quiet)
mprintf("Removing %s\n", g.gl_pathv[i]);
- err = do_rm(conn, g.gl_pathv[i]);
+ err = sftp_rm(conn, g.gl_pathv[i]);
if (err != 0 && err_abort)
break;
}
break;
case I_MKDIR:
- path1 = make_absolute(path1, *pwd);
+ path1 = sftp_make_absolute(path1, *pwd);
attrib_clear(&a);
a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
a.perm = 0777;
- err = do_mkdir(conn, path1, &a, 1);
+ err = sftp_mkdir(conn, path1, &a, 1);
break;
case I_RMDIR:
- path1 = make_absolute(path1, *pwd);
- err = do_rmdir(conn, path1);
+ path1 = sftp_make_absolute(path1, *pwd);
+ err = sftp_rmdir(conn, path1);
break;
case I_CHDIR:
if (path1 == NULL || *path1 == '\0')
path1 = xstrdup(startdir);
- path1 = make_absolute(path1, *pwd);
- if ((tmp = do_realpath(conn, path1)) == NULL) {
+ path1 = sftp_make_absolute(path1, *pwd);
+ if ((tmp = sftp_realpath(conn, path1)) == NULL) {
err = 1;
break;
}
- if ((aa = do_stat(conn, tmp, 0)) == NULL) {
+ if (sftp_stat(conn, tmp, 0, &aa) != 0) {
free(tmp);
err = 1;
break;
}
- if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
+ if (!(aa.flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
error("Can't change directory: Can't check target");
free(tmp);
err = 1;
break;
}
- if (!S_ISDIR(aa->perm)) {
+ if (!S_ISDIR(aa.perm)) {
error("Can't change directory: \"%s\" is not "
"a directory", tmp);
free(tmp);
/* Default to current directory if no path specified */
if (path1 == NULL)
path1 = xstrdup(*pwd);
- path1 = make_absolute(path1, *pwd);
+ path1 = sftp_make_absolute(path1, *pwd);
err = do_df(conn, path1, hflag, iflag);
break;
case I_LCHDIR:
if (!quiet)
mprintf("Changing mode on %s\n",
g.gl_pathv[i]);
- err = (hflag ? do_lsetstat : do_setstat)(conn,
+ err = (hflag ? sftp_lsetstat : sftp_setstat)(conn,
g.gl_pathv[i], &a);
if (err != 0 && err_abort)
break;
path1 = make_absolute_pwd_glob(path1, *pwd);
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
- if (!(aa = (hflag ? do_lstat : do_stat)(conn,
- g.gl_pathv[i], 0))) {
+ if ((hflag ? sftp_lstat : sftp_stat)(conn,
+ g.gl_pathv[i], 0, &aa) != 0) {
if (err_abort) {
err = -1;
break;
} else
continue;
}
- if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
+ if (!(aa.flags & SSH2_FILEXFER_ATTR_UIDGID)) {
error("Can't get current ownership of "
"remote file \"%s\"", g.gl_pathv[i]);
if (err_abort) {
} else
continue;
}
- aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
+ aa.flags &= SSH2_FILEXFER_ATTR_UIDGID;
if (cmdnum == I_CHOWN) {
if (!quiet)
mprintf("Changing owner on %s\n",
g.gl_pathv[i]);
- aa->uid = n_arg;
+ aa.uid = n_arg;
} else {
if (!quiet)
mprintf("Changing group on %s\n",
g.gl_pathv[i]);
- aa->gid = n_arg;
+ aa.gid = n_arg;
}
- err = (hflag ? do_lsetstat : do_setstat)(conn,
- g.gl_pathv[i], aa);
+ err = (hflag ? sftp_lsetstat : sftp_setstat)(conn,
+ g.gl_pathv[i], &aa);
if (err != 0 && err_abort)
break;
}
el_set(el, EL_BIND, "^w", "ed-delete-prev-word", NULL);
}
- remote_path = do_realpath(conn, ".");
- if (remote_path == NULL)
+ if ((remote_path = sftp_realpath(conn, ".")) == NULL)
fatal("Need cwd");
startdir = xstrdup(remote_path);
if (file1 != NULL) {
dir = xstrdup(file1);
- dir = make_absolute(dir, remote_path);
+ dir = sftp_make_absolute(dir, remote_path);
- if (remote_is_dir(conn, dir) && file2 == NULL) {
+ if (sftp_remote_is_dir(conn, dir) && file2 == NULL) {
if (!quiet)
mprintf("Changing to: %s\n", dir);
snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
}
freeargs(&args);
- conn = do_init(in, out, copy_buffer_len, num_requests, limit_kbps);
+ conn = sftp_init(in, out, copy_buffer_len, num_requests, limit_kbps);
if (conn == NULL)
fatal("Couldn't initialise connection to server");