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? > I think it's better to continue. If a remote file was wrongly specified, but the remaining entries are correct, it should continue. I've been running this diff for 2 days now:
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 8 Oct 2011 10:23:14 -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,14 +2047,14 @@ 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; const char *errstr; LogLevel ll = SYSLOG_LEVEL_INFO; - arglist args; + arglist args, temp; extern int optind; extern char *optarg; struct sftp_conn *conn; @@ -2160,68 +2172,169 @@ 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"); + memcpy(&temp, &args, sizeof(args)); + ind = optind; + if (colon(argv[argc - 1]) == NULL || + argc == (optind + 1)) { + if (argc != (optind + 1)) + file1 = argv[argc - 1]; + int d = 0; + while (d <= (argc - (ind + 2)) || + argc == (optind + 1)) { + userhost = xstrdup(argv[ind + d]); + 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--; + } + 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); + memset(&args, '\0', sizeof(args)); + args.list = NULL; + memcpy(&args, &temp, sizeof(temp)); + fprintf(stderr, "\n\narg.num %d", args.num); + if (argc == (optind + 1)) + break; + } + freeargs(&args); } + else { + tflag = 1; + userhost = xstrdup(argv[argc - 1]); + int c = 0; + while (c <= (argc - (ind + 2))) { + file2[c] = argv[optind + c]; + 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 = 0; + while (d <= (argc - (ind + 2))) { + 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); + d++; + } + } } 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, file1, file2); + err = interactive_loop(conn, NULL, NULL, 0); + + } close(in); close(out); > -d