summaryrefslogtreecommitdiff
path: root/sftp.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2019-01-16 23:23:45 +0000
committerDamien Miller <djm@mindrot.org>2019-01-17 11:08:13 +1100
commit60d8c84e0887514c99c9ce071965fafaa1c3d34a (patch)
tree771daf5a0f48b41115daf2b9b552e4e6d10dba7d /sftp.c
parentdbbc7e0eab7262f34b8e0cd6efecd1c77b905ed0 (diff)
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 @@
1/* $OpenBSD: sftp.c,v 1.188 2018/11/16 03:26:01 djm Exp $ */ 1/* $OpenBSD: sftp.c,v 1.189 2019/01/16 23:23:45 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -278,9 +278,9 @@ help(void)
278 printf("Available commands:\n" 278 printf("Available commands:\n"
279 "bye Quit sftp\n" 279 "bye Quit sftp\n"
280 "cd path Change remote directory to 'path'\n" 280 "cd path Change remote directory to 'path'\n"
281 "chgrp grp path Change group of file 'path' to 'grp'\n" 281 "chgrp [-h] grp path Change group of file 'path' to 'grp'\n"
282 "chmod mode path Change permissions of file 'path' to 'mode'\n" 282 "chmod [-h] mode path Change permissions of file 'path' to 'mode'\n"
283 "chown own path Change owner of file 'path' to 'own'\n" 283 "chown [-h] own path Change owner of file 'path' to 'own'\n"
284 "df [-hi] [path] Display statistics for current directory or\n" 284 "df [-hi] [path] Display statistics for current directory or\n"
285 " filesystem containing 'path'\n" 285 " filesystem containing 'path'\n"
286 "exit Quit sftp\n" 286 "exit Quit sftp\n"
@@ -562,6 +562,30 @@ parse_df_flags(const char *cmd, char **argv, int argc, int *hflag, int *iflag)
562} 562}
563 563
564static int 564static int
565parse_ch_flags(const char *cmd, char **argv, int argc, int *hflag)
566{
567 extern int opterr, optind, optopt, optreset;
568 int ch;
569
570 optind = optreset = 1;
571 opterr = 0;
572
573 *hflag = 0;
574 while ((ch = getopt(argc, argv, "h")) != -1) {
575 switch (ch) {
576 case 'h':
577 *hflag = 1;
578 break;
579 default:
580 error("%s: Invalid flag -%c", cmd, optopt);
581 return -1;
582 }
583 }
584
585 return optind;
586}
587
588static int
565parse_no_flags(const char *cmd, char **argv, int argc) 589parse_no_flags(const char *cmd, char **argv, int argc)
566{ 590{
567 extern int opterr, optind, optopt, optreset; 591 extern int opterr, optind, optopt, optreset;
@@ -1456,7 +1480,7 @@ parse_args(const char **cpp, int *ignore_errors, int *disable_echo, int *aflag,
1456 /* FALLTHROUGH */ 1480 /* FALLTHROUGH */
1457 case I_CHOWN: 1481 case I_CHOWN:
1458 case I_CHGRP: 1482 case I_CHGRP:
1459 if ((optidx = parse_no_flags(cmd, argv, argc)) == -1) 1483 if ((optidx = parse_ch_flags(cmd, argv, argc, hflag)) == -1)
1460 return -1; 1484 return -1;
1461 /* Get numeric arg (mandatory) */ 1485 /* Get numeric arg (mandatory) */
1462 if (argc - optidx < 1) 1486 if (argc - optidx < 1)
@@ -1675,7 +1699,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1675 if (!quiet) 1699 if (!quiet)
1676 mprintf("Changing mode on %s\n", 1700 mprintf("Changing mode on %s\n",
1677 g.gl_pathv[i]); 1701 g.gl_pathv[i]);
1678 err = do_setstat(conn, g.gl_pathv[i], &a); 1702 err = (hflag ? do_lsetstat : do_setstat)(conn,
1703 g.gl_pathv[i], &a);
1679 if (err != 0 && err_abort) 1704 if (err != 0 && err_abort)
1680 break; 1705 break;
1681 } 1706 }
@@ -1685,7 +1710,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1685 path1 = make_absolute(path1, *pwd); 1710 path1 = make_absolute(path1, *pwd);
1686 remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); 1711 remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
1687 for (i = 0; g.gl_pathv[i] && !interrupted; i++) { 1712 for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
1688 if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) { 1713 if (!(aa = (hflag ? do_lstat : do_stat)(conn,
1714 g.gl_pathv[i], 0))) {
1689 if (err_abort) { 1715 if (err_abort) {
1690 err = -1; 1716 err = -1;
1691 break; 1717 break;
@@ -1713,7 +1739,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1713 g.gl_pathv[i]); 1739 g.gl_pathv[i]);
1714 aa->gid = n_arg; 1740 aa->gid = n_arg;
1715 } 1741 }
1716 err = do_setstat(conn, g.gl_pathv[i], aa); 1742 err = (hflag ? do_lsetstat : do_setstat)(conn,
1743 g.gl_pathv[i], aa);
1717 if (err != 0 && err_abort) 1744 if (err != 0 && err_abort)
1718 break; 1745 break;
1719 } 1746 }