summaryrefslogtreecommitdiff
path: root/sftp-int.c
diff options
context:
space:
mode:
Diffstat (limited to 'sftp-int.c')
-rw-r--r--sftp-int.c104
1 files changed, 46 insertions, 58 deletions
diff --git a/sftp-int.c b/sftp-int.c
index babc0ed60..5de93891a 100644
--- a/sftp-int.c
+++ b/sftp-int.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2001 Damien Miller. All rights reserved. 2 * Copyright (c) 2001,2002 Damien Miller. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
@@ -26,7 +26,7 @@
26/* XXX: recursive operations */ 26/* XXX: recursive operations */
27 27
28#include "includes.h" 28#include "includes.h"
29RCSID("$OpenBSD: sftp-int.c,v 1.43 2002/02/12 12:32:27 djm Exp $"); 29RCSID("$OpenBSD: sftp-int.c,v 1.44 2002/02/13 00:59:23 djm Exp $");
30 30
31#include "buffer.h" 31#include "buffer.h"
32#include "xmalloc.h" 32#include "xmalloc.h"
@@ -48,9 +48,6 @@ extern size_t copy_buffer_len;
48/* Number of concurrent outstanding requests */ 48/* Number of concurrent outstanding requests */
49extern int num_requests; 49extern int num_requests;
50 50
51/* Version of server we are speaking to */
52int version;
53
54/* Seperators for interactive commands */ 51/* Seperators for interactive commands */
55#define WHITESPACE " \t\r\n" 52#define WHITESPACE " \t\r\n"
56 53
@@ -336,12 +333,12 @@ is_dir(char *path)
336} 333}
337 334
338static int 335static int
339remote_is_dir(int in, int out, char *path) 336remote_is_dir(struct sftp_conn *conn, char *path)
340{ 337{
341 Attrib *a; 338 Attrib *a;
342 339
343 /* XXX: report errors? */ 340 /* XXX: report errors? */
344 if ((a = do_stat(in, out, path, 1)) == NULL) 341 if ((a = do_stat(conn, path, 1)) == NULL)
345 return(0); 342 return(0);
346 if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) 343 if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS))
347 return(0); 344 return(0);
@@ -349,7 +346,7 @@ remote_is_dir(int in, int out, char *path)
349} 346}
350 347
351static int 348static int
352process_get(int in, int out, char *src, char *dst, char *pwd, int pflag) 349process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
353{ 350{
354 char *abs_src = NULL; 351 char *abs_src = NULL;
355 char *abs_dst = NULL; 352 char *abs_dst = NULL;
@@ -363,7 +360,7 @@ process_get(int in, int out, char *src, char *dst, char *pwd, int pflag)
363 360
364 memset(&g, 0, sizeof(g)); 361 memset(&g, 0, sizeof(g));
365 debug3("Looking up %s", abs_src); 362 debug3("Looking up %s", abs_src);
366 if (remote_glob(in, out, abs_src, 0, NULL, &g)) { 363 if (remote_glob(conn, abs_src, 0, NULL, &g)) {
367 error("File \"%s\" not found.", abs_src); 364 error("File \"%s\" not found.", abs_src);
368 err = -1; 365 err = -1;
369 goto out; 366 goto out;
@@ -387,8 +384,7 @@ process_get(int in, int out, char *src, char *dst, char *pwd, int pflag)
387 goto out; 384 goto out;
388 } 385 }
389 printf("Fetching %s to %s\n", g.gl_pathv[0], abs_dst); 386 printf("Fetching %s to %s\n", g.gl_pathv[0], abs_dst);
390 err = do_download(in, out, g.gl_pathv[0], abs_dst, pflag, 387 err = do_download(conn, g.gl_pathv[0], abs_dst, pflag);
391 copy_buffer_len, num_requests);
392 goto out; 388 goto out;
393 } 389 }
394 390
@@ -412,8 +408,7 @@ process_get(int in, int out, char *src, char *dst, char *pwd, int pflag)
412 abs_dst = tmp; 408 abs_dst = tmp;
413 409
414 printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); 410 printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
415 if (do_download(in, out, g.gl_pathv[i], abs_dst, pflag, 411 if (do_download(conn, g.gl_pathv[i], abs_dst, pflag) == -1)
416 copy_buffer_len, num_requests) == -1)
417 err = -1; 412 err = -1;
418 xfree(abs_dst); 413 xfree(abs_dst);
419 abs_dst = NULL; 414 abs_dst = NULL;
@@ -428,7 +423,7 @@ out:
428} 423}
429 424
430static int 425static int
431process_put(int in, int out, char *src, char *dst, char *pwd, int pflag) 426process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
432{ 427{
433 char *tmp_dst = NULL; 428 char *tmp_dst = NULL;
434 char *abs_dst = NULL; 429 char *abs_dst = NULL;
@@ -454,7 +449,7 @@ process_put(int in, int out, char *src, char *dst, char *pwd, int pflag)
454 if (g.gl_pathv[0] && g.gl_matchc == 1) { 449 if (g.gl_pathv[0] && g.gl_matchc == 1) {
455 if (tmp_dst) { 450 if (tmp_dst) {
456 /* If directory specified, append filename */ 451 /* If directory specified, append filename */
457 if (remote_is_dir(in, out, tmp_dst)) { 452 if (remote_is_dir(conn, tmp_dst)) {
458 if (infer_path(g.gl_pathv[0], &tmp)) { 453 if (infer_path(g.gl_pathv[0], &tmp)) {
459 err = 1; 454 err = 1;
460 goto out; 455 goto out;
@@ -471,13 +466,12 @@ process_put(int in, int out, char *src, char *dst, char *pwd, int pflag)
471 abs_dst = make_absolute(abs_dst, pwd); 466 abs_dst = make_absolute(abs_dst, pwd);
472 } 467 }
473 printf("Uploading %s to %s\n", g.gl_pathv[0], abs_dst); 468 printf("Uploading %s to %s\n", g.gl_pathv[0], abs_dst);
474 err = do_upload(in, out, g.gl_pathv[0], abs_dst, pflag, 469 err = do_upload(conn, g.gl_pathv[0], abs_dst, pflag);
475 copy_buffer_len, num_requests);
476 goto out; 470 goto out;
477 } 471 }
478 472
479 /* Multiple matches, dst may be directory or unspecified */ 473 /* Multiple matches, dst may be directory or unspecified */
480 if (tmp_dst && !remote_is_dir(in, out, tmp_dst)) { 474 if (tmp_dst && !remote_is_dir(conn, tmp_dst)) {
481 error("Multiple files match, but \"%s\" is not a directory", 475 error("Multiple files match, but \"%s\" is not a directory",
482 tmp_dst); 476 tmp_dst);
483 err = -1; 477 err = -1;
@@ -496,8 +490,7 @@ process_put(int in, int out, char *src, char *dst, char *pwd, int pflag)
496 abs_dst = make_absolute(tmp, pwd); 490 abs_dst = make_absolute(tmp, pwd);
497 491
498 printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst); 492 printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
499 if (do_upload(in, out, g.gl_pathv[i], abs_dst, pflag, 493 if (do_upload(conn, g.gl_pathv[i], abs_dst, pflag) == -1)
500 copy_buffer_len, num_requests) == -1)
501 err = -1; 494 err = -1;
502 } 495 }
503 496
@@ -655,7 +648,7 @@ parse_args(const char **cpp, int *pflag, unsigned long *n_arg,
655} 648}
656 649
657static int 650static int
658parse_dispatch_command(int in, int out, const char *cmd, char **pwd) 651parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd)
659{ 652{
660 char *path1, *path2, *tmp; 653 char *path1, *path2, *tmp;
661 int pflag, cmdnum, i; 654 int pflag, cmdnum, i;
@@ -675,32 +668,26 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
675 case -1: 668 case -1:
676 break; 669 break;
677 case I_GET: 670 case I_GET:
678 err = process_get(in, out, path1, path2, *pwd, pflag); 671 err = process_get(conn, path1, path2, *pwd, pflag);
679 break; 672 break;
680 case I_PUT: 673 case I_PUT:
681 err = process_put(in, out, path1, path2, *pwd, pflag); 674 err = process_put(conn, path1, path2, *pwd, pflag);
682 break; 675 break;
683 case I_RENAME: 676 case I_RENAME:
684 path1 = make_absolute(path1, *pwd); 677 path1 = make_absolute(path1, *pwd);
685 path2 = make_absolute(path2, *pwd); 678 path2 = make_absolute(path2, *pwd);
686 err = do_rename(in, out, path1, path2); 679 err = do_rename(conn, path1, path2);
687 break; 680 break;
688 case I_SYMLINK: 681 case I_SYMLINK:
689 if (version < 3) { 682 path2 = make_absolute(path2, *pwd);
690 error("The server (version %d) does not support " 683 err = do_symlink(conn, path1, path2);
691 "this operation", version);
692 err = -1;
693 } else {
694 path2 = make_absolute(path2, *pwd);
695 err = do_symlink(in, out, path1, path2);
696 }
697 break; 684 break;
698 case I_RM: 685 case I_RM:
699 path1 = make_absolute(path1, *pwd); 686 path1 = make_absolute(path1, *pwd);
700 remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g); 687 remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
701 for (i = 0; g.gl_pathv[i]; i++) { 688 for (i = 0; g.gl_pathv[i]; i++) {
702 printf("Removing %s\n", g.gl_pathv[i]); 689 printf("Removing %s\n", g.gl_pathv[i]);
703 if (do_rm(in, out, g.gl_pathv[i]) == -1) 690 if (do_rm(conn, g.gl_pathv[i]) == -1)
704 err = -1; 691 err = -1;
705 } 692 }
706 break; 693 break;
@@ -709,19 +696,19 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
709 attrib_clear(&a); 696 attrib_clear(&a);
710 a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; 697 a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
711 a.perm = 0777; 698 a.perm = 0777;
712 err = do_mkdir(in, out, path1, &a); 699 err = do_mkdir(conn, path1, &a);
713 break; 700 break;
714 case I_RMDIR: 701 case I_RMDIR:
715 path1 = make_absolute(path1, *pwd); 702 path1 = make_absolute(path1, *pwd);
716 err = do_rmdir(in, out, path1); 703 err = do_rmdir(conn, path1);
717 break; 704 break;
718 case I_CHDIR: 705 case I_CHDIR:
719 path1 = make_absolute(path1, *pwd); 706 path1 = make_absolute(path1, *pwd);
720 if ((tmp = do_realpath(in, out, path1)) == NULL) { 707 if ((tmp = do_realpath(conn, path1)) == NULL) {
721 err = 1; 708 err = 1;
722 break; 709 break;
723 } 710 }
724 if ((aa = do_stat(in, out, tmp, 0)) == NULL) { 711 if ((aa = do_stat(conn, tmp, 0)) == NULL) {
725 xfree(tmp); 712 xfree(tmp);
726 err = 1; 713 err = 1;
727 break; 714 break;
@@ -744,22 +731,22 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
744 break; 731 break;
745 case I_LS: 732 case I_LS:
746 if (!path1) { 733 if (!path1) {
747 do_ls(in, out, *pwd); 734 do_ls(conn, *pwd);
748 break; 735 break;
749 } 736 }
750 path1 = make_absolute(path1, *pwd); 737 path1 = make_absolute(path1, *pwd);
751 if ((tmp = do_realpath(in, out, path1)) == NULL) 738 if ((tmp = do_realpath(conn, path1)) == NULL)
752 break; 739 break;
753 xfree(path1); 740 xfree(path1);
754 path1 = tmp; 741 path1 = tmp;
755 if ((aa = do_stat(in, out, path1, 0)) == NULL) 742 if ((aa = do_stat(conn, path1, 0)) == NULL)
756 break; 743 break;
757 if ((aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) && 744 if ((aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
758 !S_ISDIR(aa->perm)) { 745 !S_ISDIR(aa->perm)) {
759 error("Can't ls: \"%s\" is not a directory", path1); 746 error("Can't ls: \"%s\" is not a directory", path1);
760 break; 747 break;
761 } 748 }
762 do_ls(in, out, path1); 749 do_ls(conn, path1);
763 break; 750 break;
764 case I_LCHDIR: 751 case I_LCHDIR:
765 if (chdir(path1) == -1) { 752 if (chdir(path1) == -1) {
@@ -790,17 +777,17 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
790 attrib_clear(&a); 777 attrib_clear(&a);
791 a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; 778 a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
792 a.perm = n_arg; 779 a.perm = n_arg;
793 remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g); 780 remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
794 for (i = 0; g.gl_pathv[i]; i++) { 781 for (i = 0; g.gl_pathv[i]; i++) {
795 printf("Changing mode on %s\n", g.gl_pathv[i]); 782 printf("Changing mode on %s\n", g.gl_pathv[i]);
796 do_setstat(in, out, g.gl_pathv[i], &a); 783 do_setstat(conn, g.gl_pathv[i], &a);
797 } 784 }
798 break; 785 break;
799 case I_CHOWN: 786 case I_CHOWN:
800 path1 = make_absolute(path1, *pwd); 787 path1 = make_absolute(path1, *pwd);
801 remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g); 788 remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
802 for (i = 0; g.gl_pathv[i]; i++) { 789 for (i = 0; g.gl_pathv[i]; i++) {
803 if (!(aa = do_stat(in, out, g.gl_pathv[i], 0))) 790 if (!(aa = do_stat(conn, g.gl_pathv[i], 0)))
804 continue; 791 continue;
805 if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) { 792 if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
806 error("Can't get current ownership of " 793 error("Can't get current ownership of "
@@ -810,14 +797,14 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
810 printf("Changing owner on %s\n", g.gl_pathv[i]); 797 printf("Changing owner on %s\n", g.gl_pathv[i]);
811 aa->flags &= SSH2_FILEXFER_ATTR_UIDGID; 798 aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
812 aa->uid = n_arg; 799 aa->uid = n_arg;
813 do_setstat(in, out, g.gl_pathv[i], aa); 800 do_setstat(conn, g.gl_pathv[i], aa);
814 } 801 }
815 break; 802 break;
816 case I_CHGRP: 803 case I_CHGRP:
817 path1 = make_absolute(path1, *pwd); 804 path1 = make_absolute(path1, *pwd);
818 remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g); 805 remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
819 for (i = 0; g.gl_pathv[i]; i++) { 806 for (i = 0; g.gl_pathv[i]; i++) {
820 if (!(aa = do_stat(in, out, g.gl_pathv[i], 0))) 807 if (!(aa = do_stat(conn, g.gl_pathv[i], 0)))
821 continue; 808 continue;
822 if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) { 809 if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
823 error("Can't get current ownership of " 810 error("Can't get current ownership of "
@@ -827,7 +814,7 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
827 printf("Changing group on %s\n", g.gl_pathv[i]); 814 printf("Changing group on %s\n", g.gl_pathv[i]);
828 aa->flags &= SSH2_FILEXFER_ATTR_UIDGID; 815 aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
829 aa->gid = n_arg; 816 aa->gid = n_arg;
830 do_setstat(in, out, g.gl_pathv[i], aa); 817 do_setstat(conn, g.gl_pathv[i], aa);
831 } 818 }
832 break; 819 break;
833 case I_PWD: 820 case I_PWD:
@@ -847,7 +834,7 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
847 help(); 834 help();
848 break; 835 break;
849 case I_VERSION: 836 case I_VERSION:
850 printf("SFTP protocol version %d\n", version); 837 printf("SFTP protocol version %d\n", sftp_proto_version(conn));
851 break; 838 break;
852 default: 839 default:
853 fatal("%d is not implemented", cmdnum); 840 fatal("%d is not implemented", cmdnum);
@@ -873,12 +860,13 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
873 char *pwd; 860 char *pwd;
874 char *dir = NULL; 861 char *dir = NULL;
875 char cmd[2048]; 862 char cmd[2048];
863 struct sftp_conn *conn;
876 864
877 version = do_init(fd_in, fd_out); 865 conn = do_init(fd_in, fd_out, copy_buffer_len, num_requests);
878 if (version == -1) 866 if (conn == NULL)
879 fatal("Couldn't initialise connection to server"); 867 fatal("Couldn't initialise connection to server");
880 868
881 pwd = do_realpath(fd_in, fd_out, "."); 869 pwd = do_realpath(conn, ".");
882 if (pwd == NULL) 870 if (pwd == NULL)
883 fatal("Need cwd"); 871 fatal("Need cwd");
884 872
@@ -886,10 +874,10 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
886 dir = xstrdup(file1); 874 dir = xstrdup(file1);
887 dir = make_absolute(dir, pwd); 875 dir = make_absolute(dir, pwd);
888 876
889 if (remote_is_dir(fd_in, fd_out, dir) && file2 == NULL) { 877 if (remote_is_dir(conn, dir) && file2 == NULL) {
890 printf("Changing to: %s\n", dir); 878 printf("Changing to: %s\n", dir);
891 snprintf(cmd, sizeof cmd, "cd \"%s\"", dir); 879 snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
892 parse_dispatch_command(fd_in, fd_out, cmd, &pwd); 880 parse_dispatch_command(conn, cmd, &pwd);
893 } else { 881 } else {
894 if (file2 == NULL) 882 if (file2 == NULL)
895 snprintf(cmd, sizeof cmd, "get %s", dir); 883 snprintf(cmd, sizeof cmd, "get %s", dir);
@@ -897,7 +885,7 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
897 snprintf(cmd, sizeof cmd, "get %s %s", dir, 885 snprintf(cmd, sizeof cmd, "get %s %s", dir,
898 file2); 886 file2);
899 887
900 parse_dispatch_command(fd_in, fd_out, cmd, &pwd); 888 parse_dispatch_command(conn, cmd, &pwd);
901 return; 889 return;
902 } 890 }
903 } 891 }
@@ -925,7 +913,7 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
925 if (cp) 913 if (cp)
926 *cp = '\0'; 914 *cp = '\0';
927 915
928 if (parse_dispatch_command(fd_in, fd_out, cmd, &pwd)) 916 if (parse_dispatch_command(conn, cmd, &pwd))
929 break; 917 break;
930 } 918 }
931 xfree(pwd); 919 xfree(pwd);