On Sat, Sep 24, 2011 at 12:57:17PM +1000, Damien Miller wrote:
> On Wed, 21 Sep 2011, Loganaden Velvindron wrote:
>
> > s/similar/A little bit like
> >
> > The diff has issues with stuff like sftp 127.0.0.1. I've
> > fixed it.
>
> I think this might get confused by something like:
>
> sftp blah user@host: foo user2@host:
>
> IMO it would be better to walk all the arguments and then either
> error (if multiple remote entries were specified) or continue. What
> do you think?
>
If I understand correctly, blah, user@host: and foo are the local
src files that need to be uploaded to host with user user2 ?
In process_put(), stat() is used for local src files before sending
to remote destinations.
I was looking at scp, and it seems that the last argument is
used to decide whether dest is remote or local. I used the same
function colon().
In interactive_loop, my previous diff had issues since the cli
function was designed for sending from remote host to local file.
I added another condition using tflag as a flag to indicate whether
the transfer was PUT(1) or GET(0), based on the return parameters
on the colon() function, and act accordingly.
Definitely, we need to walk over each argument, and decide how
to proceed. What i had in mind was using an array and then
sending each element to interactive_loop(), and using the err
ret value as an indication of failure/success ?
Something like this:
Index: sftp.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/sftp.c,v
retrieving revision 1.132
diff -u -p -r1.132 sftp.c
--- sftp.c 4 Dec 2010 00:18:01 -0000 1.132
+++ sftp.c 24 Sep 2011 06:23:00 -0000
@@ -175,7 +175,7 @@ static const struct CMD cmds[] = {
{ NULL, -1, -1 }
};
-int interactive_loop(struct sftp_conn *, char *file1, char *file2);
+int interactive_loop(struct sftp_conn *, char *file1, char *file2, int tflag);
/* ARGSUSED */
static void
@@ -1834,7 +1834,7 @@ complete(EditLine *el, int ch)
}
int
-interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
+interactive_loop(struct sftp_conn *conn, char *file1, char *file2, int tflag)
{
char *remote_path;
char *dir = NULL;
@@ -1873,7 +1873,7 @@ interactive_loop(struct sftp_conn *conn,
if (remote_path == NULL)
fatal("Need cwd");
- if (file1 != NULL) {
+ if (file1 != NULL && tflag == 0) {
dir = xstrdup(file1);
dir = make_absolute(dir, remote_path);
@@ -1903,6 +1903,18 @@ interactive_loop(struct sftp_conn *conn,
}
xfree(dir);
}
+ if (file1 != NULL && tflag == 1) {
+ dir = xstrdup(file1);
+ if (file2 == NULL)
+ snprintf(cmd, sizeof cmd, "put %s", dir);
+ else
+ snprintf(cmd, sizeof cmd, "put %s %s", dir, file2);
+ err = parse_dispatch_command(conn, cmd, &remote_path, 1);
+ xfree(dir);
+ xfree(remote_path);
+ xfree(conn);
+ return (err);
+ }
setvbuf(stdout, NULL, _IOLBF, 0);
setvbuf(infile, NULL, _IOLBF, 0);
@@ -2034,7 +2046,7 @@ usage(void)
int
main(int argc, char **argv)
{
- int in, out, ch, err;
+ int in, out, ch, tflag = 0, err;
char *host = NULL, *userhost, *cp, *file2 = NULL;
int debug_level = 0, sshver = 2;
char *file1 = NULL, *sftp_server = NULL;
@@ -2163,8 +2175,18 @@ main(int argc, char **argv)
if (optind == argc || argc > (optind + 2))
usage();
- userhost = xstrdup(argv[optind]);
- file2 = argv[optind+1];
+ if (colon(argv[argc - 1]) == NULL ||
+ argc == (optind + 1)) {
+ userhost = xstrdup(argv[optind]);
+ if (argc != (optind + 1))
+ file2 = argv[argc - 1];
+
+ }
+ else {
+ tflag = 1;
+ userhost = xstrdup(argv[argc - 1]);
+ file2 = argv[optind];
+ }
if ((host = strrchr(userhost, '@')) == NULL)
host = userhost;
@@ -2220,7 +2242,10 @@ main(int argc, char **argv)
fprintf(stderr, "Attached to %s.\n", sftp_direct);
}
- err = interactive_loop(conn, file1, file2);
+ if (tflag == 0)
+ err = interactive_loop(conn, file1, file2, 0);
+ else
+ err = interactive_loop(conn, file2, file1, 1);
close(in);
close(out);
> -d