sync code with last improvements from OpenBSD

This commit is contained in:
purplerain 2023-09-08 20:30:31 +00:00
parent 0e5a54c21a
commit 9bb7c570b7
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
33 changed files with 1190 additions and 596 deletions

View file

@ -1,4 +1,4 @@
/* $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>
*
@ -607,11 +607,21 @@ make_absolute_pwd_glob(char *p, const char *pwd)
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)
@ -656,12 +666,12 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
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);
}
@ -675,13 +685,14 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
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;
@ -710,7 +721,7 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
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));
@ -723,7 +734,7 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
/* 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) {
@ -753,13 +764,13 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
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);
@ -771,13 +782,14 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
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;
@ -818,7 +830,7 @@ do_ls_dir(struct sftp_conn *conn, const char *path,
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)) {
@ -860,13 +872,13 @@ do_ls_dir(struct sftp_conn *conn, const char *path,
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;
@ -895,7 +907,7 @@ do_ls_dir(struct sftp_conn *conn, const char *path,
if (!(lflag & LS_LONG_VIEW) && (c != 1))
printf("\n");
free_sftp_dirents(d);
sftp_free_dirents(d);
return (0);
}
@ -1043,7 +1055,7 @@ do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag)
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));
@ -1517,7 +1529,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
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;
@ -1558,23 +1570,24 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
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);
@ -1582,42 +1595,42 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **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);
@ -1645,7 +1658,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
/* 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:
@ -1687,7 +1700,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
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;
@ -1698,15 +1711,15 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
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) {
@ -1715,20 +1728,20 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
} 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;
}
@ -2203,16 +2216,15 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
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);
@ -2603,7 +2615,7 @@ main(int argc, char **argv)
}
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");