summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--sftp-int.c46
-rw-r--r--sftp.114
-rw-r--r--sftp.c18
4 files changed, 65 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index 9d580f786..34a17e98b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,9 @@
3 - deraadt@cvs.openbsd.org 2001/03/06 06:11:18 3 - deraadt@cvs.openbsd.org 2001/03/06 06:11:18
4 [ssh-keyscan.c] 4 [ssh-keyscan.c]
5 appease gcc 5 appease gcc
6 - deraadt@cvs.openbsd.org 2001/03/06 06:11:44
7 [sftp-int.c sftp.1 sftp.c]
8 sftp -b batchfile; mouring@etoh.eviladmin.org
6 9
720010306 1020010306
8 - (bal) OpenBSD CVS Sync 11 - (bal) OpenBSD CVS Sync
@@ -4417,4 +4420,4 @@
4417 - Wrote replacements for strlcpy and mkdtemp 4420 - Wrote replacements for strlcpy and mkdtemp
4418 - Released 1.0pre1 4421 - Released 1.0pre1
4419 4422
4420$Id: ChangeLog,v 1.919 2001/03/07 01:23:30 mouring Exp $ 4423$Id: ChangeLog,v 1.920 2001/03/07 01:26:48 mouring Exp $
diff --git a/sftp-int.c b/sftp-int.c
index 53136be07..7aa7abdb9 100644
--- a/sftp-int.c
+++ b/sftp-int.c
@@ -28,7 +28,7 @@
28/* XXX: recursive operations */ 28/* XXX: recursive operations */
29 29
30#include "includes.h" 30#include "includes.h"
31RCSID("$OpenBSD: sftp-int.c,v 1.24 2001/03/04 17:42:28 millert Exp $"); 31RCSID("$OpenBSD: sftp-int.c,v 1.25 2001/03/06 06:11:44 deraadt Exp $");
32 32
33#include "buffer.h" 33#include "buffer.h"
34#include "xmalloc.h" 34#include "xmalloc.h"
@@ -40,6 +40,8 @@ RCSID("$OpenBSD: sftp-int.c,v 1.24 2001/03/04 17:42:28 millert Exp $");
40#include "sftp-client.h" 40#include "sftp-client.h"
41#include "sftp-int.h" 41#include "sftp-int.h"
42 42
43extern FILE* infile;
44
43/* Seperators for interactive commands */ 45/* Seperators for interactive commands */
44#define WHITESPACE " \t\r\n" 46#define WHITESPACE " \t\r\n"
45 47
@@ -444,6 +446,7 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
444 unsigned long n_arg; 446 unsigned long n_arg;
445 Attrib a, *aa; 447 Attrib a, *aa;
446 char path_buf[MAXPATHLEN]; 448 char path_buf[MAXPATHLEN];
449 int err = 0;
447 450
448 path1 = path2 = NULL; 451 path1 = path2 = NULL;
449 cmdnum = parse_args(&cmd, &pflag, &n_arg, &path1, &path2); 452 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)
454 break; 457 break;
455 case I_GET: 458 case I_GET:
456 path1 = make_absolute(path1, *pwd); 459 path1 = make_absolute(path1, *pwd);
457 do_download(in, out, path1, path2, pflag); 460 err = do_download(in, out, path1, path2, pflag);
458 break; 461 break;
459 case I_PUT: 462 case I_PUT:
460 path2 = make_absolute(path2, *pwd); 463 path2 = make_absolute(path2, *pwd);
461 do_upload(in, out, path1, path2, pflag); 464 err = do_upload(in, out, path1, path2, pflag);
462 break; 465 break;
463 case I_RENAME: 466 case I_RENAME:
464 path1 = make_absolute(path1, *pwd); 467 path1 = make_absolute(path1, *pwd);
465 path2 = make_absolute(path2, *pwd); 468 path2 = make_absolute(path2, *pwd);
466 do_rename(in, out, path1, path2); 469 err = do_rename(in, out, path1, path2);
467 break; 470 break;
468 case I_RM: 471 case I_RM:
469 path1 = make_absolute(path1, *pwd); 472 path1 = make_absolute(path1, *pwd);
470 do_rm(in, out, path1); 473 err = do_rm(in, out, path1);
471 break; 474 break;
472 case I_MKDIR: 475 case I_MKDIR:
473 path1 = make_absolute(path1, *pwd); 476 path1 = make_absolute(path1, *pwd);
474 attrib_clear(&a); 477 attrib_clear(&a);
475 a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; 478 a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
476 a.perm = 0777; 479 a.perm = 0777;
477 do_mkdir(in, out, path1, &a); 480 err = do_mkdir(in, out, path1, &a);
478 break; 481 break;
479 case I_RMDIR: 482 case I_RMDIR:
480 path1 = make_absolute(path1, *pwd); 483 path1 = make_absolute(path1, *pwd);
481 do_rmdir(in, out, path1); 484 err = do_rmdir(in, out, path1);
482 break; 485 break;
483 case I_CHDIR: 486 case I_CHDIR:
484 path1 = make_absolute(path1, *pwd); 487 path1 = make_absolute(path1, *pwd);
485 if ((tmp = do_realpath(in, out, path1)) == NULL) 488 if ((tmp = do_realpath(in, out, path1)) == NULL) {
489 err = 1;
486 break; 490 break;
491 }
487 if ((aa = do_stat(in, out, tmp)) == NULL) { 492 if ((aa = do_stat(in, out, tmp)) == NULL) {
488 xfree(tmp); 493 xfree(tmp);
494 err = 1;
489 break; 495 break;
490 } 496 }
491 if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) { 497 if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
492 error("Can't change directory: Can't check target"); 498 error("Can't change directory: Can't check target");
493 xfree(tmp); 499 xfree(tmp);
500 err = 1;
494 break; 501 break;
495 } 502 }
496 if (!S_ISDIR(aa->perm)) { 503 if (!S_ISDIR(aa->perm)) {
497 error("Can't change directory: \"%s\" is not " 504 error("Can't change directory: \"%s\" is not "
498 "a directory", tmp); 505 "a directory", tmp);
499 xfree(tmp); 506 xfree(tmp);
507 err = 1;
500 break; 508 break;
501 } 509 }
502 xfree(*pwd); 510 xfree(*pwd);
@@ -522,14 +530,18 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
522 do_ls(in, out, path1); 530 do_ls(in, out, path1);
523 break; 531 break;
524 case I_LCHDIR: 532 case I_LCHDIR:
525 if (chdir(path1) == -1) 533 if (chdir(path1) == -1) {
526 error("Couldn't change local directory to " 534 error("Couldn't change local directory to "
527 "\"%s\": %s", path1, strerror(errno)); 535 "\"%s\": %s", path1, strerror(errno));
536 err = 1;
537 }
528 break; 538 break;
529 case I_LMKDIR: 539 case I_LMKDIR:
530 if (mkdir(path1, 0777) == -1) 540 if (mkdir(path1, 0777) == -1) {
531 error("Couldn't create local directory " 541 error("Couldn't create local directory "
532 "\"%s\": %s", path1, strerror(errno)); 542 "\"%s\": %s", path1, strerror(errno));
543 err = 1;
544 }
533 break; 545 break;
534 case I_LLS: 546 case I_LLS:
535 local_do_ls(cmd); 547 local_do_ls(cmd);
@@ -598,6 +610,11 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
598 xfree(path1); 610 xfree(path1);
599 if (path2) 611 if (path2)
600 xfree(path2); 612 xfree(path2);
613
614 /* If an error occurs in batch mode we should abort. */
615 if (infile != stdin && err > 0)
616 return -1;
617
601 return(0); 618 return(0);
602} 619}
603 620
@@ -612,7 +629,7 @@ interactive_loop(int fd_in, int fd_out)
612 fatal("Need cwd"); 629 fatal("Need cwd");
613 630
614 setvbuf(stdout, NULL, _IOLBF, 0); 631 setvbuf(stdout, NULL, _IOLBF, 0);
615 setvbuf(stdin, NULL, _IOLBF, 0); 632 setvbuf(infile, NULL, _IOLBF, 0);
616 633
617 for(;;) { 634 for(;;) {
618 char *cp; 635 char *cp;
@@ -620,13 +637,16 @@ interactive_loop(int fd_in, int fd_out)
620 printf("sftp> "); 637 printf("sftp> ");
621 638
622 /* XXX: use libedit */ 639 /* XXX: use libedit */
623 if (fgets(cmd, sizeof(cmd), stdin) == NULL) { 640 if (fgets(cmd, sizeof(cmd), infile) == NULL) {
624 printf("\n"); 641 printf("\n");
625 break; 642 break;
626 } 643 } else if (infile != stdin) /* Bluff typing */
644 printf("%s", cmd);
645
627 cp = strrchr(cmd, '\n'); 646 cp = strrchr(cmd, '\n');
628 if (cp) 647 if (cp)
629 *cp = '\0'; 648 *cp = '\0';
649
630 if (parse_dispatch_command(fd_in, fd_out, cmd, &pwd)) 650 if (parse_dispatch_command(fd_in, fd_out, cmd, &pwd))
631 break; 651 break;
632 } 652 }
diff --git a/sftp.1 b/sftp.1
index 22915133b..e1c6960f8 100644
--- a/sftp.1
+++ b/sftp.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: sftp.1,v 1.9 2001/03/02 18:54:31 deraadt Exp $ 1.\" $OpenBSD: sftp.1,v 1.10 2001/03/06 06:11:44 deraadt Exp $
2.\" 2.\"
3.\" Copyright (c) 2001 Damien Miller. All rights reserved. 3.\" Copyright (c) 2001 Damien Miller. All rights reserved.
4.\" 4.\"
@@ -31,6 +31,7 @@
31.Sh SYNOPSIS 31.Sh SYNOPSIS
32.Nm sftp 32.Nm sftp
33.Op Fl vC 33.Op Fl vC
34.Op Fl b Ar batchfile
34.Op Fl o Ar ssh_option 35.Op Fl o Ar ssh_option
35.Op Ar hostname | user@hostname 36.Op Ar hostname | user@hostname
36.Sh DESCRIPTION 37.Sh DESCRIPTION
@@ -55,6 +56,17 @@ Raise logging level. This option is also passed to ssh.
55Enables compression (via ssh's 56Enables compression (via ssh's
56.Fl C 57.Fl C
57flag) 58flag)
59.It Fl b Ar batchfile
60Batch mode reads a series of commands from an input
61.Fn batchfile
62instead of
63.Fn stdin .
64Since it lacks user interaction it should be used in conjuction with a
65non-interactive authentication. Sftp will abort if any of the following
66commands fail:
67.Pa get, put, rename, rm, mkdir, chdir, lchdir
68and
69.Pa lmkdir.
58.It Fl o Ar ssh_option 70.It Fl o Ar ssh_option
59Specify an option to be directly passed to 71Specify an option to be directly passed to
60.Xr ssh 1 . 72.Xr ssh 1 .
diff --git a/sftp.c b/sftp.c
index f24f75071..c22825093 100644
--- a/sftp.c
+++ b/sftp.c
@@ -24,7 +24,7 @@
24 24
25#include "includes.h" 25#include "includes.h"
26 26
27RCSID("$OpenBSD: sftp.c,v 1.9 2001/03/03 23:52:22 markus Exp $"); 27RCSID("$OpenBSD: sftp.c,v 1.10 2001/03/06 06:11:44 deraadt Exp $");
28 28
29/* XXX: commandline mode */ 29/* XXX: commandline mode */
30/* XXX: copy between two remote hosts (commandline) */ 30/* XXX: copy between two remote hosts (commandline) */
@@ -49,6 +49,7 @@ char *__progname;
49int use_ssh1 = 0; 49int use_ssh1 = 0;
50char *ssh_program = _PATH_SSH_PROGRAM; 50char *ssh_program = _PATH_SSH_PROGRAM;
51char *sftp_server = NULL; 51char *sftp_server = NULL;
52FILE* infile;
52 53
53void 54void
54connect_to_server(char **args, int *in, int *out, pid_t *sshpid) 55connect_to_server(char **args, int *in, int *out, pid_t *sshpid)
@@ -146,7 +147,7 @@ make_ssh_args(char *add_arg)
146void 147void
147usage(void) 148usage(void)
148{ 149{
149 fprintf(stderr, "usage: sftp [-1vC] [-osshopt=value] [user@]host\n"); 150 fprintf(stderr, "usage: sftp [-1vC] [-b batchfile] [-osshopt=value] [user@]host\n");
150 exit(1); 151 exit(1);
151} 152}
152 153
@@ -161,9 +162,10 @@ main(int argc, char **argv)
161 extern char *optarg; 162 extern char *optarg;
162 163
163 __progname = get_progname(argv[0]); 164 __progname = get_progname(argv[0]);
165 infile = stdin; /* Read from STDIN unless changed by -b */
164 debug_level = compress_flag = 0; 166 debug_level = compress_flag = 0;
165 167
166 while ((ch = getopt(argc, argv, "1hvCo:s:S:")) != -1) { 168 while ((ch = getopt(argc, argv, "1hvCo:s:S:b:")) != -1) {
167 switch (ch) { 169 switch (ch) {
168 case 'C': 170 case 'C':
169 compress_flag = 1; 171 compress_flag = 1;
@@ -186,6 +188,14 @@ main(int argc, char **argv)
186 case 'S': 188 case 'S':
187 ssh_program = optarg; 189 ssh_program = optarg;
188 break; 190 break;
191 case 'b':
192 if (infile == stdin) {
193 infile = fopen(optarg, "r");
194 if (infile == NULL)
195 fatal("%s (%s).", strerror(errno), optarg);
196 } else
197 fatal("Filename already specified.");
198 break;
189 case 'h': 199 case 'h':
190 default: 200 default:
191 usage(); 201 usage();
@@ -257,6 +267,8 @@ main(int argc, char **argv)
257 267
258 close(in); 268 close(in);
259 close(out); 269 close(out);
270 if (infile != stdin)
271 fclose(infile);
260 272
261 if (waitpid(sshpid, NULL, 0) == -1) 273 if (waitpid(sshpid, NULL, 0) == -1)
262 fatal("Couldn't wait for ssh process: %s", strerror(errno)); 274 fatal("Couldn't wait for ssh process: %s", strerror(errno));