summaryrefslogtreecommitdiff
path: root/sftp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sftp.c')
-rw-r--r--sftp.c56
1 files changed, 19 insertions, 37 deletions
diff --git a/sftp.c b/sftp.c
index f6cadd113..46bee1982 100644
--- a/sftp.c
+++ b/sftp.c
@@ -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
858static int 840static int