summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2001-03-06 06:11:45 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2001-03-06 06:11:45 +0000
commitb99a05c240d58e4923ce45db6fa8cb82833ba3c9 (patch)
treefd7850e493d48a443a7cf4e65b322e6fe42bccf0
parent4a0545f26c0e8f60eabdab8a5dfd6f2e005a3033 (diff)
sftp -b batchfile; mouring@etoh.eviladmin.org
-rw-r--r--usr.bin/ssh/sftp-int.c46
-rw-r--r--usr.bin/ssh/sftp.114
-rw-r--r--usr.bin/ssh/sftp.c18
3 files changed, 61 insertions, 17 deletions
diff --git a/usr.bin/ssh/sftp-int.c b/usr.bin/ssh/sftp-int.c
index 53136be0754..7aa7abdb942 100644
--- a/usr.bin/ssh/sftp-int.c
+++ b/usr.bin/ssh/sftp-int.c
@@ -28,7 +28,7 @@
/* XXX: recursive operations */
#include "includes.h"
-RCSID("$OpenBSD: sftp-int.c,v 1.24 2001/03/04 17:42:28 millert Exp $");
+RCSID("$OpenBSD: sftp-int.c,v 1.25 2001/03/06 06:11:44 deraadt Exp $");
#include "buffer.h"
#include "xmalloc.h"
@@ -40,6 +40,8 @@ RCSID("$OpenBSD: sftp-int.c,v 1.24 2001/03/04 17:42:28 millert Exp $");
#include "sftp-client.h"
#include "sftp-int.h"
+extern FILE* infile;
+
/* Seperators for interactive commands */
#define WHITESPACE " \t\r\n"
@@ -444,6 +446,7 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
unsigned long n_arg;
Attrib a, *aa;
char path_buf[MAXPATHLEN];
+ int err = 0;
path1 = path2 = NULL;
cmdnum = parse_args(&cmd, &pflag, &n_arg, &path1, &path2);
@@ -454,49 +457,54 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
break;
case I_GET:
path1 = make_absolute(path1, *pwd);
- do_download(in, out, path1, path2, pflag);
+ err = do_download(in, out, path1, path2, pflag);
break;
case I_PUT:
path2 = make_absolute(path2, *pwd);
- do_upload(in, out, path1, path2, pflag);
+ err = do_upload(in, out, path1, path2, pflag);
break;
case I_RENAME:
path1 = make_absolute(path1, *pwd);
path2 = make_absolute(path2, *pwd);
- do_rename(in, out, path1, path2);
+ err = do_rename(in, out, path1, path2);
break;
case I_RM:
path1 = make_absolute(path1, *pwd);
- do_rm(in, out, path1);
+ err = do_rm(in, out, path1);
break;
case I_MKDIR:
path1 = make_absolute(path1, *pwd);
attrib_clear(&a);
a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
a.perm = 0777;
- do_mkdir(in, out, path1, &a);
+ err = do_mkdir(in, out, path1, &a);
break;
case I_RMDIR:
path1 = make_absolute(path1, *pwd);
- do_rmdir(in, out, path1);
+ err = do_rmdir(in, out, path1);
break;
case I_CHDIR:
path1 = make_absolute(path1, *pwd);
- if ((tmp = do_realpath(in, out, path1)) == NULL)
+ if ((tmp = do_realpath(in, out, path1)) == NULL) {
+ err = 1;
break;
+ }
if ((aa = do_stat(in, out, tmp)) == NULL) {
xfree(tmp);
+ err = 1;
break;
}
if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
error("Can't change directory: Can't check target");
xfree(tmp);
+ err = 1;
break;
}
if (!S_ISDIR(aa->perm)) {
error("Can't change directory: \"%s\" is not "
"a directory", tmp);
xfree(tmp);
+ err = 1;
break;
}
xfree(*pwd);
@@ -522,14 +530,18 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
do_ls(in, out, path1);
break;
case I_LCHDIR:
- if (chdir(path1) == -1)
+ if (chdir(path1) == -1) {
error("Couldn't change local directory to "
"\"%s\": %s", path1, strerror(errno));
+ err = 1;
+ }
break;
case I_LMKDIR:
- if (mkdir(path1, 0777) == -1)
+ if (mkdir(path1, 0777) == -1) {
error("Couldn't create local directory "
"\"%s\": %s", path1, strerror(errno));
+ err = 1;
+ }
break;
case I_LLS:
local_do_ls(cmd);
@@ -598,6 +610,11 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
xfree(path1);
if (path2)
xfree(path2);
+
+ /* If an error occurs in batch mode we should abort. */
+ if (infile != stdin && err > 0)
+ return -1;
+
return(0);
}
@@ -612,7 +629,7 @@ interactive_loop(int fd_in, int fd_out)
fatal("Need cwd");
setvbuf(stdout, NULL, _IOLBF, 0);
- setvbuf(stdin, NULL, _IOLBF, 0);
+ setvbuf(infile, NULL, _IOLBF, 0);
for(;;) {
char *cp;
@@ -620,13 +637,16 @@ interactive_loop(int fd_in, int fd_out)
printf("sftp> ");
/* XXX: use libedit */
- if (fgets(cmd, sizeof(cmd), stdin) == NULL) {
+ if (fgets(cmd, sizeof(cmd), infile) == NULL) {
printf("\n");
break;
- }
+ } else if (infile != stdin) /* Bluff typing */
+ printf("%s", cmd);
+
cp = strrchr(cmd, '\n');
if (cp)
*cp = '\0';
+
if (parse_dispatch_command(fd_in, fd_out, cmd, &pwd))
break;
}
diff --git a/usr.bin/ssh/sftp.1 b/usr.bin/ssh/sftp.1
index 22915133b16..e1c6960f898 100644
--- a/usr.bin/ssh/sftp.1
+++ b/usr.bin/ssh/sftp.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sftp.1,v 1.9 2001/03/02 18:54:31 deraadt Exp $
+.\" $OpenBSD: sftp.1,v 1.10 2001/03/06 06:11:44 deraadt Exp $
.\"
.\" Copyright (c) 2001 Damien Miller. All rights reserved.
.\"
@@ -31,6 +31,7 @@
.Sh SYNOPSIS
.Nm sftp
.Op Fl vC
+.Op Fl b Ar batchfile
.Op Fl o Ar ssh_option
.Op Ar hostname | user@hostname
.Sh DESCRIPTION
@@ -55,6 +56,17 @@ Raise logging level. This option is also passed to ssh.
Enables compression (via ssh's
.Fl C
flag)
+.It Fl b Ar batchfile
+Batch mode reads a series of commands from an input
+.Fn batchfile
+instead of
+.Fn stdin .
+Since it lacks user interaction it should be used in conjuction with a
+non-interactive authentication. Sftp will abort if any of the following
+commands fail:
+.Pa get, put, rename, rm, mkdir, chdir, lchdir
+and
+.Pa lmkdir.
.It Fl o Ar ssh_option
Specify an option to be directly passed to
.Xr ssh 1 .
diff --git a/usr.bin/ssh/sftp.c b/usr.bin/ssh/sftp.c
index a997db083e0..6d1e556fbd9 100644
--- a/usr.bin/ssh/sftp.c
+++ b/usr.bin/ssh/sftp.c
@@ -24,7 +24,7 @@
#include "includes.h"
-RCSID("$OpenBSD: sftp.c,v 1.9 2001/03/03 23:52:22 markus Exp $");
+RCSID("$OpenBSD: sftp.c,v 1.10 2001/03/06 06:11:44 deraadt Exp $");
/* XXX: commandline mode */
/* XXX: copy between two remote hosts (commandline) */
@@ -43,6 +43,7 @@ RCSID("$OpenBSD: sftp.c,v 1.9 2001/03/03 23:52:22 markus Exp $");
int use_ssh1 = 0;
char *ssh_program = _PATH_SSH_PROGRAM;
char *sftp_server = NULL;
+FILE* infile;
void
connect_to_server(char **args, int *in, int *out, pid_t *sshpid)
@@ -140,7 +141,7 @@ make_ssh_args(char *add_arg)
void
usage(void)
{
- fprintf(stderr, "usage: sftp [-1vC] [-osshopt=value] [user@]host\n");
+ fprintf(stderr, "usage: sftp [-1vC] [-b batchfile] [-osshopt=value] [user@]host\n");
exit(1);
}
@@ -154,9 +155,10 @@ main(int argc, char **argv)
extern int optind;
extern char *optarg;
+ infile = stdin; /* Read from STDIN unless changed by -b */
debug_level = compress_flag = 0;
- while ((ch = getopt(argc, argv, "1hvCo:s:S:")) != -1) {
+ while ((ch = getopt(argc, argv, "1hvCo:s:S:b:")) != -1) {
switch (ch) {
case 'C':
compress_flag = 1;
@@ -179,6 +181,14 @@ main(int argc, char **argv)
case 'S':
ssh_program = optarg;
break;
+ case 'b':
+ if (infile == stdin) {
+ infile = fopen(optarg, "r");
+ if (infile == NULL)
+ fatal("%s (%s).", strerror(errno), optarg);
+ } else
+ fatal("Filename already specified.");
+ break;
case 'h':
default:
usage();
@@ -245,6 +255,8 @@ main(int argc, char **argv)
close(in);
close(out);
+ if (infile != stdin)
+ fclose(infile);
if (waitpid(sshpid, NULL, 0) == -1)
fatal("Couldn't wait for ssh process: %s", strerror(errno));