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