upstream: support a prefix of '@' to suppress echo of sftp batch

commands; bz#2926; ok dtucker@

OpenBSD-Commit-ID: 9d635636bc84aeae796467e059f7634de990a79d
This commit is contained in:
djm@openbsd.org 2018-11-16 02:30:20 +00:00 committed by Damien Miller
parent 90ef45f7aa
commit 5c1a63562c
2 changed files with 40 additions and 28 deletions

11
sftp.1
View File

@ -1,4 +1,4 @@
.\" $OpenBSD: sftp.1,v 1.121 2018/11/13 07:22:45 schwarze Exp $
.\" $OpenBSD: sftp.1,v 1.122 2018/11/16 02:30:20 djm Exp $
.\"
.\" Copyright (c) 2001 Damien Miller. All rights reserved.
.\"
@ -22,7 +22,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd $Mdocdate: November 13 2018 $
.Dd $Mdocdate: November 16 2018 $
.Dt SFTP 1
.Os
.Sh NAME
@ -127,6 +127,7 @@ at connection time (see
and
.Xr ssh-keygen 1
for details).
.Pp
A
.Ar batchfile
of
@ -141,11 +142,17 @@ commands fail:
.Ic chgrp , lpwd , df , symlink ,
and
.Ic lmkdir .
.Pp
Termination on error can be suppressed on a command by command basis by
prefixing the command with a
.Sq \-
character (for example,
.Ic -rm /tmp/blah* ) .
Echo of the command may be suppressed by prefixing the command with a
.Sq @
character.
These two prefixes may be combined in any order, for example
.Ic -@ls /bsd .
.It Fl C
Enables compression (via ssh's
.Fl C

57
sftp.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: sftp.c,v 1.186 2018/09/07 04:26:56 dtucker Exp $ */
/* $OpenBSD: sftp.c,v 1.187 2018/11/16 02:30:20 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@ -1296,7 +1296,7 @@ makeargv(const char *arg, int *argcp, int sloppy, char *lastquote,
}
static int
parse_args(const char **cpp, int *ignore_errors, int *aflag,
parse_args(const char **cpp, int *ignore_errors, int *disable_echo, int *aflag,
int *fflag, int *hflag, int *iflag, int *lflag, int *pflag,
int *rflag, int *sflag,
unsigned long *n_arg, char **path1, char **path2)
@ -1310,13 +1310,23 @@ parse_args(const char **cpp, int *ignore_errors, int *aflag,
/* Skip leading whitespace */
cp = cp + strspn(cp, WHITESPACE);
/* Check for leading '-' (disable error processing) */
/*
* Check for leading '-' (disable error processing) and '@' (suppress
* command echo)
*/
*ignore_errors = 0;
if (*cp == '-') {
*ignore_errors = 1;
cp++;
cp = cp + strspn(cp, WHITESPACE);
*disable_echo = 0;
for (;*cp != '\0'; cp++) {
if (*cp == '-') {
*ignore_errors = 1;
} else if (*cp == '@') {
*disable_echo = 1;
} else {
/* all other characters terminate prefix processing */
break;
}
}
cp = cp + strspn(cp, WHITESPACE);
/* Ignore blank lines and lines which begin with comment '#' char */
if (*cp == '\0' || *cp == '#')
@ -1491,11 +1501,12 @@ parse_args(const char **cpp, int *ignore_errors, int *aflag,
static int
parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
const char *startdir, int err_abort)
const char *startdir, int err_abort, int echo_command)
{
const char *ocmd = cmd;
char *path1, *path2, *tmp;
int ignore_errors = 0, aflag = 0, fflag = 0, hflag = 0,
iflag = 0;
int ignore_errors = 0, disable_echo = 1;
int aflag = 0, fflag = 0, hflag = 0, iflag = 0;
int lflag = 0, pflag = 0, rflag = 0, sflag = 0;
int cmdnum, i;
unsigned long n_arg = 0;
@ -1505,11 +1516,15 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
glob_t g;
path1 = path2 = NULL;
cmdnum = parse_args(&cmd, &ignore_errors, &aflag, &fflag, &hflag,
&iflag, &lflag, &pflag, &rflag, &sflag, &n_arg, &path1, &path2);
cmdnum = parse_args(&cmd, &ignore_errors, &disable_echo, &aflag, &fflag,
&hflag, &iflag, &lflag, &pflag, &rflag, &sflag, &n_arg,
&path1, &path2);
if (ignore_errors != 0)
err_abort = 0;
if (echo_command && !disable_echo)
mprintf("sftp> %s\n", ocmd);
memset(&g, 0, sizeof(g));
/* Perform command */
@ -2169,7 +2184,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
mprintf("Changing to: %s\n", dir);
snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
if (parse_dispatch_command(conn, cmd,
&remote_path, startdir, 1) != 0) {
&remote_path, startdir, 1, 0) != 0) {
free(dir);
free(startdir);
free(remote_path);
@ -2183,7 +2198,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
file2 == NULL ? "" : " ",
file2 == NULL ? "" : file2);
err = parse_dispatch_command(conn, cmd,
&remote_path, startdir, 1);
&remote_path, startdir, 1, 0);
free(dir);
free(startdir);
free(remote_path);
@ -2199,8 +2214,6 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
interactive = !batchmode && isatty(STDIN_FILENO);
err = 0;
for (;;) {
char *cp;
signal(SIGINT, SIG_IGN);
if (el == NULL) {
@ -2211,12 +2224,6 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
printf("\n");
break;
}
if (!interactive) { /* Echo command */
mprintf("sftp> %s", cmd);
if (strlen(cmd) > 0 &&
cmd[strlen(cmd) - 1] != '\n')
printf("\n");
}
} else {
#ifdef USE_LIBEDIT
const char *line;
@ -2235,16 +2242,14 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
#endif /* USE_LIBEDIT */
}
cp = strrchr(cmd, '\n');
if (cp)
*cp = '\0';
cmd[strcspn(cmd, "\n")] = '\0';
/* Handle user interrupts gracefully during commands */
interrupted = 0;
signal(SIGINT, cmd_interrupt);
err = parse_dispatch_command(conn, cmd, &remote_path,
startdir, batchmode);
startdir, batchmode, !interactive && el == NULL);
if (err != 0)
break;
}