summaryrefslogtreecommitdiffstats
path: root/sftp.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2019-01-17 00:23:45 +0100
committerDamien Miller <djm@mindrot.org>2019-01-17 01:08:13 +0100
commit60d8c84e0887514c99c9ce071965fafaa1c3d34a (patch)
tree771daf5a0f48b41115daf2b9b552e4e6d10dba7d /sftp.c
parentupstream: add support for a "lsetstat@openssh.com" extension. This (diff)
downloadopenssh-60d8c84e0887514c99c9ce071965fafaa1c3d34a.tar.xz
openssh-60d8c84e0887514c99c9ce071965fafaa1c3d34a.zip
upstream: Add "-h" flag to sftp chown/chgrp/chmod commands to
request they do not follow symlinks. Requires recently-committed lsetstat@openssh.com extension on the server side. ok markus@ dtucker@ OpenBSD-Commit-ID: f93bb3f6f7eb2fb7ef1e59126e72714f1626d604
Diffstat (limited to 'sftp.c')
-rw-r--r--sftp.c43
1 files changed, 35 insertions, 8 deletions
diff --git a/sftp.c b/sftp.c
index f886b330b..0f3f89d33 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp.c,v 1.188 2018/11/16 03:26:01 djm Exp $ */
+/* $OpenBSD: sftp.c,v 1.189 2019/01/16 23:23:45 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@@ -278,9 +278,9 @@ help(void)
printf("Available commands:\n"
"bye Quit sftp\n"
"cd path Change remote directory to 'path'\n"
- "chgrp grp path Change group of file 'path' to 'grp'\n"
- "chmod mode path Change permissions of file 'path' to 'mode'\n"
- "chown own path Change owner of file 'path' to 'own'\n"
+ "chgrp [-h] grp path Change group of file 'path' to 'grp'\n"
+ "chmod [-h] mode path Change permissions of file 'path' to 'mode'\n"
+ "chown [-h] own path Change owner of file 'path' to 'own'\n"
"df [-hi] [path] Display statistics for current directory or\n"
" filesystem containing 'path'\n"
"exit Quit sftp\n"
@@ -562,6 +562,30 @@ parse_df_flags(const char *cmd, char **argv, int argc, int *hflag, int *iflag)
}
static int
+parse_ch_flags(const char *cmd, char **argv, int argc, int *hflag)
+{
+ extern int opterr, optind, optopt, optreset;
+ int ch;
+
+ optind = optreset = 1;
+ opterr = 0;
+
+ *hflag = 0;
+ while ((ch = getopt(argc, argv, "h")) != -1) {
+ switch (ch) {
+ case 'h':
+ *hflag = 1;
+ break;
+ default:
+ error("%s: Invalid flag -%c", cmd, optopt);
+ return -1;
+ }
+ }
+
+ return optind;
+}
+
+static int
parse_no_flags(const char *cmd, char **argv, int argc)
{
extern int opterr, optind, optopt, optreset;
@@ -1456,7 +1480,7 @@ parse_args(const char **cpp, int *ignore_errors, int *disable_echo, int *aflag,
/* FALLTHROUGH */
case I_CHOWN:
case I_CHGRP:
- if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
+ if ((optidx = parse_ch_flags(cmd, argv, argc, hflag)) == -1)
return -1;
/* Get numeric arg (mandatory) */
if (argc - optidx < 1)
@@ -1675,7 +1699,8 @@ 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 = do_setstat(conn, g.gl_pathv[i], &a);
+ err = (hflag ? do_lsetstat : do_setstat)(conn,
+ g.gl_pathv[i], &a);
if (err != 0 && err_abort)
break;
}
@@ -1685,7 +1710,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
path1 = make_absolute(path1, *pwd);
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
- if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) {
+ if (!(aa = (hflag ? do_lstat : do_stat)(conn,
+ g.gl_pathv[i], 0))) {
if (err_abort) {
err = -1;
break;
@@ -1713,7 +1739,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
g.gl_pathv[i]);
aa->gid = n_arg;
}
- err = do_setstat(conn, g.gl_pathv[i], aa);
+ err = (hflag ? do_lsetstat : do_setstat)(conn,
+ g.gl_pathv[i], aa);
if (err != 0 && err_abort)
break;
}