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);