Patch: sftp client support of "ls [flags] [path [localfile]]" feature

Calvin Cheng calcheng at cisco.com
Sat Oct 19 06:44:00 EST 2002


Hello,

I just downloaded OpenSSH 3.5p1. This version has some great improvement in
sftp client.
But I still miss the FTP's "ls [flags] remote-path [localpath]" feature to
redirect the output of ls/dir
to a local file.

The following are the diff outputs against 3.5p1 to enable this feature.

*** sftp-int.c.orig Wed Sep 11 20:34:15 2002
--- sftp-int.c Fri Oct 18 13:39:46 2002
***************
*** 555,567 ****

  /* sftp ls.1 replacement for directories */
  static int
! do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag)
  {
   int n;
   SFTP_DIRENT **d;

   if ((n = do_readdir(conn, path, &d)) != 0)
    return (n);

   /* Count entries for sort */
   for (n = 0; d[n] != NULL; n++)
--- 555,587 ----

  /* sftp ls.1 replacement for directories */
  static int
! do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag,
!     char *localpath)
  {
   int n;
   SFTP_DIRENT **d;
+  FILE *fp = NULL;
+  FILE *fp1 = NULL;
+
+  if (localpath) {
+   fp = fopen(localpath, "w");
+   if (!fp)
+   {
+    error("Can't write to file %s", localpath);
+    return -1;
+   }
+  }
+
+  if (fp)
+   fp1 = fp;
+  else
+   fp1 = stdout;

   if ((n = do_readdir(conn, path, &d)) != 0)
+  {
+   if (fp) fclose(fp);
    return (n);
+  }

   /* Count entries for sort */
   for (n = 0; d[n] != NULL; n++)
***************
*** 583,598 ****
     memset(&sb, 0, sizeof(sb));
     attrib_to_stat(&d[n]->a, &sb);
     lname = ls_file(fname, &sb, 1);
!    printf("%s\n", lname);
     xfree(lname);
    } else {
     /* XXX - multicolumn display would be nice here */
!    printf("%s\n", fname);
    }

    xfree(fname);
   }

   free_sftp_dirents(d);
   return (0);
  }
--- 603,619 ----
     memset(&sb, 0, sizeof(sb));
     attrib_to_stat(&d[n]->a, &sb);
     lname = ls_file(fname, &sb, 1);
!    fprintf(fp1, "%s\n", lname);
     xfree(lname);
    } else {
     /* XXX - multicolumn display would be nice here */
!    fprintf(fp1, "%s\n", fname);
    }

    xfree(fname);
   }

+  if (fp) fclose(fp);
   free_sftp_dirents(d);
   return (0);
  }
***************
*** 600,611 ****
  /* sftp ls.1 replacement which handles path globs */
  static int
  do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
!     int lflag)
  {
   glob_t g;
   int i;
   Attrib *a;
   struct stat sb;

   memset(&g, 0, sizeof(g));

--- 621,634 ----
  /* sftp ls.1 replacement which handles path globs */
  static int
  do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
!     int lflag, char* localpath)
  {
   glob_t g;
   int i;
   Attrib *a;
   struct stat sb;
+  FILE *fp = NULL;
+  FILE *fp1 = NULL;

   memset(&g, 0, sizeof(g));

***************
*** 628,637 ****
    if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
        S_ISDIR(a->perm)) {
     globfree(&g);
!    return (do_ls_dir(conn, path, strip_path, lflag));
    }
   }

   for (i = 0; g.gl_pathv[i]; i++) {
    char *fname, *lname;

--- 651,675 ----
    if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
        S_ISDIR(a->perm)) {
     globfree(&g);
!    return (do_ls_dir(conn, path, strip_path, lflag, localpath));
    }
   }

+  if (localpath)
+  {
+   fp = fopen(localpath, "w");
+   if (!fp)
+   {
+    error("Can't write to file %s", localpath);
+    return -1;
+   }
+  }
+
+  if (fp)
+   fp1 = fp;
+  else
+   fp1 = stdout;
+
   for (i = 0; g.gl_pathv[i]; i++) {
    char *fname, *lname;

***************
*** 650,666 ****
     if (a != NULL)
      attrib_to_stat(a, &sb);
     lname = ls_file(fname, &sb, 1);
!    printf("%s\n", lname);
     xfree(lname);
    } else {
     /* XXX - multicolumn display would be nice here */
!    printf("%s\n", fname);
    }
    xfree(fname);
   }

   if (g.gl_pathc)
    globfree(&g);

   return (0);
  }
--- 688,706 ----
     if (a != NULL)
      attrib_to_stat(a, &sb);
     lname = ls_file(fname, &sb, 1);
!    fprintf(fp1, "%s\n", lname);
     xfree(lname);
    } else {
     /* XXX - multicolumn display would be nice here */
!    fprintf(fp1, "%s\n", fname);
    }
    xfree(fname);
   }

   if (g.gl_pathc)
    globfree(&g);
+  if (fp)
+   fclose(fp);

   return (0);
  }
***************
*** 759,764 ****
--- 799,806 ----
    /* Path is optional */
    if (get_pathname(&cp, path1))
     return(-1);
+   if (get_pathname(&cp, path2))
+    return(-1);
    break;
   case I_LLS:
   case I_SHELL:
***************
*** 897,903 ****
    break;
   case I_LS:
    if (!path1) {
!    do_globbed_ls(conn, *pwd, *pwd, lflag);
     break;
    }

--- 939,945 ----
    break;
   case I_LS:
    if (!path1) {
!    do_globbed_ls(conn, *pwd, *pwd, lflag, NULL);
     break;
    }

***************
*** 908,914 ****

    path1 = make_absolute(path1, *pwd);

!   do_globbed_ls(conn, path1, tmp, lflag);
    break;
   case I_LCHDIR:
    if (chdir(path1) == -1) {
--- 950,956 ----

    path1 = make_absolute(path1, *pwd);

!   do_globbed_ls(conn, path1, tmp, lflag, path2);
    break;
   case I_LCHDIR:
    if (chdir(path1) == -1) {



*** sftp.1.orig Wed Sep 11 19:54:27 2002
--- sftp.1 Fri Oct 18 16:39:56 2002
***************
*** 205,211 ****
  Print local working directory.
  .It Xo Ic ls
  .Op Ar flags
! .Op Ar path
  .Xc
  Display remote directory listing of either
  .Ar path
--- 205,211 ----
  Print local working directory.
  .It Xo Ic ls
  .Op Ar flags
! .Op Ar path Op Ar local-path
  .Xc
  Display remote directory listing of either
  .Ar path
***************
*** 214,220 ****
  is not specified. If the
  .Fl l
  flag is specified, then display additional details including permissions
! and ownership information.
  .It Ic lumask Ar umask
  Set local umask to
  .Ar umask .
--- 214,225 ----
  is not specified. If the
  .Fl l
  flag is specified, then display additional details including permissions
! and ownership information. If
! .Ar local-path
! is not specified, display the output on the terminal. If
! .Ar local-path
! is specified, then redirect the output to
! .Ar local-path .
  .It Ic lumask Ar umask
  Set local umask to
  .Ar umask .





More information about the openssh-unix-dev mailing list