- djm@cvs.openbsd.org 2013/08/08 05:04:03
     [sftp-client.c sftp-client.h sftp.c]
     add a "-l" flag for the rename command to force it to use the silly
     standard SSH_FXP_RENAME command instead of the POSIX-rename- like
     posix-rename@openssh.com extension.

     intended for use in regress tests, so no documentation.
diff --git a/ChangeLog b/ChangeLog
index 16bb10b..cd46b83 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -19,7 +19,13 @@
      [sftp.c]
      fix two year old regression: symlinking a file would incorrectly
      canonicalise the target path. bz#2129 report from delphij AT freebsd.org
+   - djm@cvs.openbsd.org 2013/08/08 05:04:03
+     [sftp-client.c sftp-client.h sftp.c]
+     add a "-l" flag for the rename command to force it to use the silly
+     standard SSH_FXP_RENAME command instead of the POSIX-rename- like
+     posix-rename@openssh.com extension.
 
+     intended for use in regress tests, so no documentation.
 20130808
  - (dtucker) [regress/Makefile regress/test-exec.sh] Don't try to use test -nt
    since some platforms (eg really old FreeBSD) don't have it.  Instead,
diff --git a/sftp-client.c b/sftp-client.c
index f4f1970..0eeb73c 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-client.c,v 1.101 2013/07/25 00:56:51 djm Exp $ */
+/* $OpenBSD: sftp-client.c,v 1.102 2013/08/08 05:04:03 djm Exp $ */
 /*
  * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
  *
@@ -768,16 +768,18 @@
 }
 
 int
-do_rename(struct sftp_conn *conn, char *oldpath, char *newpath)
+do_rename(struct sftp_conn *conn, char *oldpath, char *newpath,
+    int force_legacy)
 {
 	Buffer msg;
 	u_int status, id;
+	int use_ext = (conn->exts & SFTP_EXT_POSIX_RENAME) && !force_legacy;
 
 	buffer_init(&msg);
 
 	/* Send rename request */
 	id = conn->msg_id++;
-	if ((conn->exts & SFTP_EXT_POSIX_RENAME)) {
+	if (use_ext) {
 		buffer_put_char(&msg, SSH2_FXP_EXTENDED);
 		buffer_put_int(&msg, id);
 		buffer_put_cstring(&msg, "posix-rename@openssh.com");
@@ -789,8 +791,8 @@
 	buffer_put_cstring(&msg, newpath);
 	send_msg(conn, &msg);
 	debug3("Sent message %s \"%s\" -> \"%s\"",
-	    (conn->exts & SFTP_EXT_POSIX_RENAME) ? "posix-rename@openssh.com" :
-	    "SSH2_FXP_RENAME", oldpath, newpath);
+	    use_ext ? "posix-rename@openssh.com" : "SSH2_FXP_RENAME",
+	    oldpath, newpath);
 	buffer_free(&msg);
 
 	status = get_status(conn, id);
diff --git a/sftp-client.h b/sftp-client.h
index 111a998..dc54cfe 100644
--- a/sftp-client.h
+++ b/sftp-client.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-client.h,v 1.21 2013/07/25 00:56:51 djm Exp $ */
+/* $OpenBSD: sftp-client.h,v 1.22 2013/08/08 05:04:03 djm Exp $ */
 
 /*
  * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
@@ -92,7 +92,7 @@
 int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int);
 
 /* Rename 'oldpath' to 'newpath' */
-int do_rename(struct sftp_conn *, char *, char *);
+int do_rename(struct sftp_conn *, char *, char *m, int force_legacy);
 
 /* Link 'oldpath' to 'newpath' */
 int do_hardlink(struct sftp_conn *, char *, char *);
diff --git a/sftp.c b/sftp.c
index 6f16f7c..66ab2b0 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp.c,v 1.151 2013/08/08 04:52:04 djm Exp $ */
+/* $OpenBSD: sftp.c,v 1.152 2013/08/08 05:04:03 djm Exp $ */
 /*
  * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
  *
@@ -415,6 +415,30 @@
 }
 
 static int
+parse_rename_flags(const char *cmd, char **argv, int argc, int *lflag)
+{
+	extern int opterr, optind, optopt, optreset;
+	int ch;
+
+	optind = optreset = 1;
+	opterr = 0;
+
+	*lflag = 0;
+	while ((ch = getopt(argc, argv, "l")) != -1) {
+		switch (ch) {
+		case 'l':
+			*lflag = 1;
+			break;
+		default:
+			error("%s: Invalid flag -%c", cmd, optopt);
+			return -1;
+		}
+	}
+
+	return optind;
+}
+
+static int
 parse_ls_flags(char **argv, int argc, int *lflag)
 {
 	extern int opterr, optind, optopt, optreset;
@@ -1210,8 +1234,13 @@
 	case I_LINK:
 		if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1)
 			return -1;
-	case I_SYMLINK:
+		goto parse_two_paths;
 	case I_RENAME:
+		if ((optidx = parse_rename_flags(cmd, argv, argc, lflag)) == -1)
+			return -1;
+		goto parse_two_paths;
+	case I_SYMLINK:
+ parse_two_paths:
 		if (argc - optidx < 2) {
 			error("You must specify two paths after a %s "
 			    "command.", cmd);
@@ -1353,7 +1382,7 @@
 	case I_RENAME:
 		path1 = make_absolute(path1, *pwd);
 		path2 = make_absolute(path2, *pwd);
-		err = do_rename(conn, path1, path2);
+		err = do_rename(conn, path1, path2, lflag);
 		break;
 	case I_SYMLINK:
 		sflag = 1;