summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2018-11-16 02:30:20 +0000
committerDamien Miller <djm@mindrot.org>2018-11-16 13:51:58 +1100
commit5c1a63562cac0574c226224075b0829a50b48c9d (patch)
treeb6b6ad2964a1fd120f6ed06a5be2d8e3ff7df808
parent90ef45f7aac33eaf55ec344e101548a01e570f29 (diff)
upstream: support a prefix of '@' to suppress echo of sftp batch
commands; bz#2926; ok dtucker@ OpenBSD-Commit-ID: 9d635636bc84aeae796467e059f7634de990a79d
-rw-r--r--sftp.111
-rw-r--r--sftp.c57
2 files changed, 40 insertions, 28 deletions
diff --git a/sftp.1 b/sftp.1
index 50e2fef0a..7140bc19b 100644
--- a/sftp.1
+++ b/sftp.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: sftp.1,v 1.121 2018/11/13 07:22:45 schwarze Exp $ 1.\" $OpenBSD: sftp.1,v 1.122 2018/11/16 02:30:20 djm Exp $
2.\" 2.\"
3.\" Copyright (c) 2001 Damien Miller. All rights reserved. 3.\" Copyright (c) 2001 Damien Miller. All rights reserved.
4.\" 4.\"
@@ -22,7 +22,7 @@
22.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24.\" 24.\"
25.Dd $Mdocdate: November 13 2018 $ 25.Dd $Mdocdate: November 16 2018 $
26.Dt SFTP 1 26.Dt SFTP 1
27.Os 27.Os
28.Sh NAME 28.Sh NAME
@@ -127,6 +127,7 @@ at connection time (see
127and 127and
128.Xr ssh-keygen 1 128.Xr ssh-keygen 1
129for details). 129for details).
130.Pp
130A 131A
131.Ar batchfile 132.Ar batchfile
132of 133of
@@ -141,11 +142,17 @@ commands fail:
141.Ic chgrp , lpwd , df , symlink , 142.Ic chgrp , lpwd , df , symlink ,
142and 143and
143.Ic lmkdir . 144.Ic lmkdir .
145.Pp
144Termination on error can be suppressed on a command by command basis by 146Termination on error can be suppressed on a command by command basis by
145prefixing the command with a 147prefixing the command with a
146.Sq \- 148.Sq \-
147character (for example, 149character (for example,
148.Ic -rm /tmp/blah* ) . 150.Ic -rm /tmp/blah* ) .
151Echo of the command may be suppressed by prefixing the command with a
152.Sq @
153character.
154These two prefixes may be combined in any order, for example
155.Ic -@ls /bsd .
149.It Fl C 156.It Fl C
150Enables compression (via ssh's 157Enables compression (via ssh's
151.Fl C 158.Fl C
diff --git a/sftp.c b/sftp.c
index 7db86c2d3..e3091969c 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp.c,v 1.186 2018/09/07 04:26:56 dtucker Exp $ */ 1/* $OpenBSD: sftp.c,v 1.187 2018/11/16 02:30:20 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 *
@@ -1296,7 +1296,7 @@ makeargv(const char *arg, int *argcp, int sloppy, char *lastquote,
1296} 1296}
1297 1297
1298static int 1298static int
1299parse_args(const char **cpp, int *ignore_errors, int *aflag, 1299parse_args(const char **cpp, int *ignore_errors, int *disable_echo, int *aflag,
1300 int *fflag, int *hflag, int *iflag, int *lflag, int *pflag, 1300 int *fflag, int *hflag, int *iflag, int *lflag, int *pflag,
1301 int *rflag, int *sflag, 1301 int *rflag, int *sflag,
1302 unsigned long *n_arg, char **path1, char **path2) 1302 unsigned long *n_arg, char **path1, char **path2)
@@ -1310,13 +1310,23 @@ parse_args(const char **cpp, int *ignore_errors, int *aflag,
1310 /* Skip leading whitespace */ 1310 /* Skip leading whitespace */
1311 cp = cp + strspn(cp, WHITESPACE); 1311 cp = cp + strspn(cp, WHITESPACE);
1312 1312
1313 /* Check for leading '-' (disable error processing) */ 1313 /*
1314 * Check for leading '-' (disable error processing) and '@' (suppress
1315 * command echo)
1316 */
1314 *ignore_errors = 0; 1317 *ignore_errors = 0;
1315 if (*cp == '-') { 1318 *disable_echo = 0;
1316 *ignore_errors = 1; 1319 for (;*cp != '\0'; cp++) {
1317 cp++; 1320 if (*cp == '-') {
1318 cp = cp + strspn(cp, WHITESPACE); 1321 *ignore_errors = 1;
1322 } else if (*cp == '@') {
1323 *disable_echo = 1;
1324 } else {
1325 /* all other characters terminate prefix processing */
1326 break;
1327 }
1319 } 1328 }
1329 cp = cp + strspn(cp, WHITESPACE);
1320 1330
1321 /* Ignore blank lines and lines which begin with comment '#' char */ 1331 /* Ignore blank lines and lines which begin with comment '#' char */
1322 if (*cp == '\0' || *cp == '#') 1332 if (*cp == '\0' || *cp == '#')
@@ -1491,11 +1501,12 @@ parse_args(const char **cpp, int *ignore_errors, int *aflag,
1491 1501
1492static int 1502static int
1493parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, 1503parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1494 const char *startdir, int err_abort) 1504 const char *startdir, int err_abort, int echo_command)
1495{ 1505{
1506 const char *ocmd = cmd;
1496 char *path1, *path2, *tmp; 1507 char *path1, *path2, *tmp;
1497 int ignore_errors = 0, aflag = 0, fflag = 0, hflag = 0, 1508 int ignore_errors = 0, disable_echo = 1;
1498 iflag = 0; 1509 int aflag = 0, fflag = 0, hflag = 0, iflag = 0;
1499 int lflag = 0, pflag = 0, rflag = 0, sflag = 0; 1510 int lflag = 0, pflag = 0, rflag = 0, sflag = 0;
1500 int cmdnum, i; 1511 int cmdnum, i;
1501 unsigned long n_arg = 0; 1512 unsigned long n_arg = 0;
@@ -1505,11 +1516,15 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1505 glob_t g; 1516 glob_t g;
1506 1517
1507 path1 = path2 = NULL; 1518 path1 = path2 = NULL;
1508 cmdnum = parse_args(&cmd, &ignore_errors, &aflag, &fflag, &hflag, 1519 cmdnum = parse_args(&cmd, &ignore_errors, &disable_echo, &aflag, &fflag,
1509 &iflag, &lflag, &pflag, &rflag, &sflag, &n_arg, &path1, &path2); 1520 &hflag, &iflag, &lflag, &pflag, &rflag, &sflag, &n_arg,
1521 &path1, &path2);
1510 if (ignore_errors != 0) 1522 if (ignore_errors != 0)
1511 err_abort = 0; 1523 err_abort = 0;
1512 1524
1525 if (echo_command && !disable_echo)
1526 mprintf("sftp> %s\n", ocmd);
1527
1513 memset(&g, 0, sizeof(g)); 1528 memset(&g, 0, sizeof(g));
1514 1529
1515 /* Perform command */ 1530 /* Perform command */
@@ -2169,7 +2184,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
2169 mprintf("Changing to: %s\n", dir); 2184 mprintf("Changing to: %s\n", dir);
2170 snprintf(cmd, sizeof cmd, "cd \"%s\"", dir); 2185 snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
2171 if (parse_dispatch_command(conn, cmd, 2186 if (parse_dispatch_command(conn, cmd,
2172 &remote_path, startdir, 1) != 0) { 2187 &remote_path, startdir, 1, 0) != 0) {
2173 free(dir); 2188 free(dir);
2174 free(startdir); 2189 free(startdir);
2175 free(remote_path); 2190 free(remote_path);
@@ -2183,7 +2198,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
2183 file2 == NULL ? "" : " ", 2198 file2 == NULL ? "" : " ",
2184 file2 == NULL ? "" : file2); 2199 file2 == NULL ? "" : file2);
2185 err = parse_dispatch_command(conn, cmd, 2200 err = parse_dispatch_command(conn, cmd,
2186 &remote_path, startdir, 1); 2201 &remote_path, startdir, 1, 0);
2187 free(dir); 2202 free(dir);
2188 free(startdir); 2203 free(startdir);
2189 free(remote_path); 2204 free(remote_path);
@@ -2199,8 +2214,6 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
2199 interactive = !batchmode && isatty(STDIN_FILENO); 2214 interactive = !batchmode && isatty(STDIN_FILENO);
2200 err = 0; 2215 err = 0;
2201 for (;;) { 2216 for (;;) {
2202 char *cp;
2203
2204 signal(SIGINT, SIG_IGN); 2217 signal(SIGINT, SIG_IGN);
2205 2218
2206 if (el == NULL) { 2219 if (el == NULL) {
@@ -2211,12 +2224,6 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
2211 printf("\n"); 2224 printf("\n");
2212 break; 2225 break;
2213 } 2226 }
2214 if (!interactive) { /* Echo command */
2215 mprintf("sftp> %s", cmd);
2216 if (strlen(cmd) > 0 &&
2217 cmd[strlen(cmd) - 1] != '\n')
2218 printf("\n");
2219 }
2220 } else { 2227 } else {
2221#ifdef USE_LIBEDIT 2228#ifdef USE_LIBEDIT
2222 const char *line; 2229 const char *line;
@@ -2235,16 +2242,14 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
2235#endif /* USE_LIBEDIT */ 2242#endif /* USE_LIBEDIT */
2236 } 2243 }
2237 2244
2238 cp = strrchr(cmd, '\n'); 2245 cmd[strcspn(cmd, "\n")] = '\0';
2239 if (cp)
2240 *cp = '\0';
2241 2246
2242 /* Handle user interrupts gracefully during commands */ 2247 /* Handle user interrupts gracefully during commands */
2243 interrupted = 0; 2248 interrupted = 0;
2244 signal(SIGINT, cmd_interrupt); 2249 signal(SIGINT, cmd_interrupt);
2245 2250
2246 err = parse_dispatch_command(conn, cmd, &remote_path, 2251 err = parse_dispatch_command(conn, cmd, &remote_path,
2247 startdir, batchmode); 2252 startdir, batchmode, !interactive && el == NULL);
2248 if (err != 0) 2253 if (err != 0)
2249 break; 2254 break;
2250 } 2255 }