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?
> 
> -d

Improved the diff slightly by removing temp arglist, and
converting while loops to for loops. This makes the diff
less hackish.

Index: src/usr.bin/ssh/sftp.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/sftp.c,v
retrieving revision 1.133
diff -u -p -r1.133 sftp.c
--- src/usr.bin/ssh/sftp.c      22 Sep 2011 06:29:03 -0000      1.133
+++ src/usr.bin/ssh/sftp.c      10 Oct 2011 19:36:13 -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
@@ -1835,7 +1835,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;
@@ -1874,7 +1874,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);
 
@@ -1904,6 +1904,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);
@@ -2035,8 +2047,8 @@ usage(void)
 int
 main(int argc, char **argv)
 {
-       int in, out, ch, err;
-       char *host = NULL, *userhost, *cp, *file2 = NULL;
+       int in, out, ch, tflag = 0, err, ind;
+       char *host = NULL, *userhost, *cp;
        int debug_level = 0, sshver = 2;
        char *file1 = NULL, *sftp_server = NULL;
        char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL;
@@ -2160,68 +2172,158 @@ main(int argc, char **argv)
 
        log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
 
+       char *file2[argc - (optind + 1)];
+       int stat = args.num;
+
        if (sftp_direct == NULL) {
-               if (optind == argc || argc > (optind + 2))
+               if (optind == argc)
                        usage();
-
-               userhost = xstrdup(argv[optind]);
-               file2 = argv[optind+1];
-
-               if ((host = strrchr(userhost, '@')) == NULL)
-                       host = userhost;
-               else {
-                       *host++ = '\0';
-                       if (!userhost[0]) {
-                               fprintf(stderr, "Missing username\n");
+               ind = optind;
+               if (colon(argv[argc - 1]) == NULL ||
+                   argc == (optind + 1)) {
+                       if (argc != (optind + 1))
+                               file1 = argv[argc - 1];
+                       int d;
+                       for (d = 0; (d <= (argc - (ind + 2))) ||
+                            (argc == optind + 1); d++) {
+                               userhost = xstrdup(argv[ind + d]);
+                               if ((host = strrchr(userhost, '@')) == NULL)
+                                       host = userhost;
+                               else {
+                                       *host++ = '\0';
+                               if (!userhost[0]) {
+                                       fprintf(stderr, "Missing username\n");
+                                       usage();
+                               }
+                               addargs(&args, "-l");
+                               addargs(&args, "%s", userhost);
+                       }
+                       if ((cp = colon(host)) != NULL) {
+                               *cp++ = '\0';
+                               file2[d] = cp;
+                       }
+                       host = cleanhostname(host);
+                       if (!*host) {
+                               fprintf(stderr, "Missing hostname\n");
                                usage();
                        }
-                       addargs(&args, "-l");
-                       addargs(&args, "%s", userhost);
-               }
 
-               if ((cp = colon(host)) != NULL) {
-                       *cp++ = '\0';
-                       file1 = cp;
-               }
+                       addargs(&args, "-oProtocol %d", sshver);
+                       /* no subsystem if the server-spec contains a '/' */
+                       if (sftp_server == NULL || strchr(sftp_server, '/') ==
+                           NULL)
+                               addargs(&args, "-s");
+                       addargs(&args, "--");
+                       addargs(&args, "%s", host);
+                       addargs(&args, "%s", (sftp_server != NULL ?
+                       sftp_server : "sftp"));
+
+                       connect_to_server(ssh_program, args.list, &in, &out);
+                       int k;
+                       for (k = (stat + 1); k < args.num; k++)
+                               xfree(args.list[k]);
+
+                       args.num = stat;
+                       conn = do_init(in, out, copy_buffer_len, num_requests,
+                                      limit_kbps);
+                       if (conn == NULL)
+                               fatal("Couldn't initialise connection to 
server");
+                       if (!batchmode) {
+                               if (sftp_direct == NULL)
+                                       fprintf(stderr, "Connected to %s.\n", 
+                                               host);
+                       else
+                               fprintf(stderr, "Attached to %s.\n", 
+                                       sftp_direct);
+                       }
 
-               host = cleanhostname(host);
-               if (!*host) {
-                       fprintf(stderr, "Missing hostname\n");
-                       usage();
+                       err = interactive_loop(conn, file2[d], file1, 0);
+                       if (argc == (optind + 1))
+                               break;
+                       }
+                       freeargs(&args);
                }
+               else {
+                       tflag = 1;
+                       userhost = xstrdup(argv[argc - 1]);
+                       int c;
+                       for (c = 0; c <= (argc - (ind + 2)); c++)
+                               file2[c] = argv[optind + c];
+                       if ((host = strrchr(userhost, '@')) == NULL)
+                               host = userhost;
+                       else {
+                               *host++ = '\0';
+                               if (!userhost[0]) {
+                                       fprintf(stderr, "Missing username\n");
+                                       usage();                                
+                               }
+                               addargs(&args, "-l");
+                               addargs(&args, "%s", userhost);
+                       }
 
-               addargs(&args, "-oProtocol %d", sshver);
+                        if ((cp = colon(host)) != NULL) {
+                                *cp++ = '\0';
+                                file1 = cp;
+                        }
+
+                       host = cleanhostname(host);
+                       if (!*host) {
+                               fprintf(stderr, "Missing hostname\n");
+                               usage();
+                       }
 
-               /* no subsystem if the server-spec contains a '/' */
-               if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
-                       addargs(&args, "-s");
-
-               addargs(&args, "--");
-               addargs(&args, "%s", host);
-               addargs(&args, "%s", (sftp_server != NULL ?
-                   sftp_server : "sftp"));
+                       addargs(&args, "-oProtocol %d", sshver);
 
-               connect_to_server(ssh_program, args.list, &in, &out);
+                       /* no subsystem if the server-spec contains a '/' */
+                       if (sftp_server == NULL || strchr(sftp_server, '/') ==
+                           NULL)
+                               addargs(&args, "-s");
+
+                       addargs(&args, "--");
+                       addargs(&args, "%s", host);
+                       addargs(&args, "%s", (sftp_server != NULL ?
+                       sftp_server : "sftp"));
+
+                       connect_to_server(ssh_program, args.list, &in, &out);
+                       freeargs(&args);
+                       int d;
+                       for (d = 0; d <= (argc - (ind + 2)); d++) {
+                               conn = do_init(in, out, copy_buffer_len, 
+                                              num_requests, limit_kbps);
+                               if (conn == NULL)
+                                       fatal("Couldn't initialise connection 
server");
+                               if (!batchmode) {
+                                       if (sftp_direct == NULL)
+                                               fprintf(stderr, "Connected to 
%s.\n", host);
+                                       else
+                                               fprintf(stderr, "Attached to 
%s.\n", sftp_direct);
+                               }
+                               err = interactive_loop(conn, file2[d], file1,
+                                                      1);
+                       } 
+               }
        } else {
                args.list = NULL;
                addargs(&args, "sftp-server");
 
                connect_to_server(sftp_direct, args.list, &in, &out);
-       }
-       freeargs(&args);
+               freeargs(&args);
 
-       conn = do_init(in, out, copy_buffer_len, num_requests, limit_kbps);
-       if (conn == NULL)
-               fatal("Couldn't initialise connection to server");
-
-       if (!batchmode) {
-               if (sftp_direct == NULL)
-                       fprintf(stderr, "Connected to %s.\n", host);
+               conn = do_init(in, out, copy_buffer_len, num_requests,
+                              limit_kbps);
+               if (conn == NULL)
+                       fatal("Couldn't initialise connection to server");
+
+               if (!batchmode) {
+                       if (sftp_direct == NULL)
+                               fprintf(stderr, "Connected to %s.\n", host);
                else
                        fprintf(stderr, "Attached to %s.\n", sftp_direct);
-       }
+               }
+
+               err = interactive_loop(conn, NULL, NULL, 0);
 
-       err = interactive_loop(conn, file1, file2);
+       }
 
        close(in);
        close(out);

Reply via email to