diff options
author | Damien Miller <djm@mindrot.org> | 2010-10-07 21:39:17 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2010-10-07 21:39:17 +1100 |
commit | a6e121aaa0ab61965db2dcfe8e2ba5d719fbe1e6 (patch) | |
tree | 4583d2a94482493f21537611187bd119f496807c /sftp.c | |
parent | aa18063baf35e303832d9ec58204ffaab221de85 (diff) |
- djm@cvs.openbsd.org 2010/09/25 09:30:16
[sftp.c configure.ac openbsd-compat/glob.c openbsd-compat/glob.h]
make use of new glob(3) GLOB_KEEPSTAT extension to save extra server
rountrips to fetch per-file stat(2) information.
NB. update openbsd-compat/ glob(3) implementation from OpenBSD libc to
match.
Diffstat (limited to 'sftp.c')
-rw-r--r-- | sftp.c | 56 |
1 files changed, 19 insertions, 37 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sftp.c,v 1.127 2010/09/23 13:34:43 jmc Exp $ */ | 1 | /* $OpenBSD: sftp.c,v 1.128 2010/09/25 09:30:16 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> | 3 | * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> |
4 | * | 4 | * |
@@ -761,15 +761,18 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, | |||
761 | glob_t g; | 761 | glob_t g; |
762 | u_int i, c = 1, colspace = 0, columns = 1; | 762 | u_int i, c = 1, colspace = 0, columns = 1; |
763 | Attrib *a = NULL; | 763 | Attrib *a = NULL; |
764 | int err; | ||
765 | char *fname, *lname; | ||
764 | 766 | ||
765 | memset(&g, 0, sizeof(g)); | 767 | memset(&g, 0, sizeof(g)); |
766 | 768 | ||
767 | if (remote_glob(conn, path, GLOB_MARK|GLOB_NOCHECK|GLOB_BRACE, | 769 | if (remote_glob(conn, path, |
768 | NULL, &g) || (g.gl_pathc && !g.gl_matchc)) { | 770 | GLOB_MARK|GLOB_NOCHECK|GLOB_BRACE|GLOB_KEEPSTAT, NULL, &g) || |
771 | (g.gl_pathc && !g.gl_matchc)) { | ||
769 | if (g.gl_pathc) | 772 | if (g.gl_pathc) |
770 | globfree(&g); | 773 | globfree(&g); |
771 | error("Can't ls: \"%s\" not found", path); | 774 | error("Can't ls: \"%s\" not found", path); |
772 | return (-1); | 775 | return -1; |
773 | } | 776 | } |
774 | 777 | ||
775 | if (interrupted) | 778 | if (interrupted) |
@@ -779,19 +782,11 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, | |||
779 | * If the glob returns a single match and it is a directory, | 782 | * If the glob returns a single match and it is a directory, |
780 | * then just list its contents. | 783 | * then just list its contents. |
781 | */ | 784 | */ |
782 | if (g.gl_matchc == 1) { | 785 | if (g.gl_matchc == 1 && g.gl_statv[0] != NULL && |
783 | if ((a = do_lstat(conn, g.gl_pathv[0], 1)) == NULL) { | 786 | S_ISDIR(g.gl_statv[0]->st_mode)) { |
784 | globfree(&g); | 787 | err = do_ls_dir(conn, g.gl_pathv[0], strip_path, lflag); |
785 | return (-1); | 788 | globfree(&g); |
786 | } | 789 | return err; |
787 | if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) && | ||
788 | S_ISDIR(a->perm)) { | ||
789 | int err; | ||
790 | |||
791 | err = do_ls_dir(conn, g.gl_pathv[0], strip_path, lflag); | ||
792 | globfree(&g); | ||
793 | return (err); | ||
794 | } | ||
795 | } | 790 | } |
796 | 791 | ||
797 | if (!(lflag & LS_SHORT_VIEW)) { | 792 | if (!(lflag & LS_SHORT_VIEW)) { |
@@ -811,27 +806,14 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, | |||
811 | } | 806 | } |
812 | 807 | ||
813 | for (i = 0; g.gl_pathv[i] && !interrupted; i++, a = NULL) { | 808 | for (i = 0; g.gl_pathv[i] && !interrupted; i++, a = NULL) { |
814 | char *fname; | ||
815 | |||
816 | fname = path_strip(g.gl_pathv[i], strip_path); | 809 | fname = path_strip(g.gl_pathv[i], strip_path); |
817 | |||
818 | if (lflag & LS_LONG_VIEW) { | 810 | if (lflag & LS_LONG_VIEW) { |
819 | char *lname; | 811 | if (g.gl_statv[i] == NULL) { |
820 | struct stat sb; | 812 | error("no stat information for %s", fname); |
821 | 813 | continue; | |
822 | /* | 814 | } |
823 | * XXX: this is slow - 1 roundtrip per path | 815 | lname = ls_file(fname, g.gl_statv[i], 1, |
824 | * A solution to this is to fork glob() and | 816 | (lflag & LS_SI_UNITS)); |
825 | * build a sftp specific version which keeps the | ||
826 | * attribs (which currently get thrown away) | ||
827 | * that the server returns as well as the filenames. | ||
828 | */ | ||
829 | memset(&sb, 0, sizeof(sb)); | ||
830 | if (a == NULL) | ||
831 | a = do_lstat(conn, g.gl_pathv[i], 1); | ||
832 | if (a != NULL) | ||
833 | attrib_to_stat(a, &sb); | ||
834 | lname = ls_file(fname, &sb, 1, (lflag & LS_SI_UNITS)); | ||
835 | printf("%s\n", lname); | 817 | printf("%s\n", lname); |
836 | xfree(lname); | 818 | xfree(lname); |
837 | } else { | 819 | } else { |
@@ -852,7 +834,7 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, | |||
852 | if (g.gl_pathc) | 834 | if (g.gl_pathc) |
853 | globfree(&g); | 835 | globfree(&g); |
854 | 836 | ||
855 | return (0); | 837 | return 0; |
856 | } | 838 | } |
857 | 839 | ||
858 | static int | 840 | static int |