diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | sftp-int.c | 46 | ||||
-rw-r--r-- | sftp.1 | 14 | ||||
-rw-r--r-- | sftp.c | 18 |
4 files changed, 65 insertions, 18 deletions
@@ -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 | ||
7 | 20010306 | 10 | 20010306 |
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" |
31 | RCSID("$OpenBSD: sftp-int.c,v 1.24 2001/03/04 17:42:28 millert Exp $"); | 31 | RCSID("$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 | ||
43 | extern 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 | } |
@@ -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. | |||
55 | Enables compression (via ssh's | 56 | Enables compression (via ssh's |
56 | .Fl C | 57 | .Fl C |
57 | flag) | 58 | flag) |
59 | .It Fl b Ar batchfile | ||
60 | Batch mode reads a series of commands from an input | ||
61 | .Fn batchfile | ||
62 | instead of | ||
63 | .Fn stdin . | ||
64 | Since it lacks user interaction it should be used in conjuction with a | ||
65 | non-interactive authentication. Sftp will abort if any of the following | ||
66 | commands fail: | ||
67 | .Pa get, put, rename, rm, mkdir, chdir, lchdir | ||
68 | and | ||
69 | .Pa lmkdir. | ||
58 | .It Fl o Ar ssh_option | 70 | .It Fl o Ar ssh_option |
59 | Specify an option to be directly passed to | 71 | Specify an option to be directly passed to |
60 | .Xr ssh 1 . | 72 | .Xr ssh 1 . |
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | 26 | ||
27 | RCSID("$OpenBSD: sftp.c,v 1.9 2001/03/03 23:52:22 markus Exp $"); | 27 | RCSID("$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; | |||
49 | int use_ssh1 = 0; | 49 | int use_ssh1 = 0; |
50 | char *ssh_program = _PATH_SSH_PROGRAM; | 50 | char *ssh_program = _PATH_SSH_PROGRAM; |
51 | char *sftp_server = NULL; | 51 | char *sftp_server = NULL; |
52 | FILE* infile; | ||
52 | 53 | ||
53 | void | 54 | void |
54 | connect_to_server(char **args, int *in, int *out, pid_t *sshpid) | 55 | connect_to_server(char **args, int *in, int *out, pid_t *sshpid) |
@@ -146,7 +147,7 @@ make_ssh_args(char *add_arg) | |||
146 | void | 147 | void |
147 | usage(void) | 148 | usage(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)); |