cURL / Mailing Lists / curl-library / Single Mail


Re: sftp postquote command rename fix/diff question

From: Kristian Gunstone <>
Date: Thu, 10 May 2007 11:59:23 +0200

* Dan Fandrich <> [2007-05-10 11:29:32]:
> On Thu, May 10, 2007 at 12:24:22AM +0200, Kristian Gunstone wrote:
> > This patch has modifications to the rename and rm handlers in lib/ssh.c.
> > As tipped, I'm now just returning an error if rename fails due to
> > destination already existing.
> >
> > In order to test this, I also had to make modifications to the file
> > delete handler at the same time, since it also returns an unknown error
> > to the user application if the file does _not_ exist, and thus I added
> > support for this return code at the same time.
> >
> > Seems to work properly now, but it sure makes renaming slow for user
> > applications since the entire connection has to be reestablished between
> > rename, delete, and reattempt to rename (that's how it is right now for
> > sftp it seems)
> That does seem like an annoying limitation. Can't you simply look at the
> error code returned by sftp_libssh2_strerror after a failed
> libssh2_sftp_rename? Doesn't that provide a sane error status of some sort?
> Failing that, how about just doing the stat call after the rename fails
> instead of before?
> In any case, calling libssh2_sftp_stat in this way opens up a race condition;
> even if stat shows no file exists, a process on the server might create
> the file before the rename can be executed and it will *still* return an
> error.
> > Well, hope you prefer this method.
> Not quite sure I do...

Ok, I've just spent this morning looking through code in both libcurl
and openssh2.

I was wondering why libssh2_sftp_last_error after a rename still
returned LIBSSH2_FX_FAILURE and not a proper error code.

As you probably know, libssh2_sftp_rename is just a macro to

If you have a look at the spec,

you can clearly see that libssh2_sftp_rename actually has
LIBSSH2_SFTP_RENAME_OVERWRITE set, so by all means the rename issued
from libssh2 _should_ overwrite the file.

I then had a look why it wasn't - and why we were getting that ambiguous

in libssh2's src/sftp.c, line 1664, we can clearly see that libssh2
won't send the flags to the server unless the sshd version is >= 5.

In my testing environment I'm running sshd v4.2p1!

If we then look further down in that code, we can see where
sftp->last_errno is set.

the return is received from libssh2_ntohu32(data + 5).

And surely enough, it checks for LIBSSH2_FX_FILE_ALREADY_EXISTS and
should set the appropriate error, but according to the error string,
       "File already exists and SSH_FXP_RENAME_OVERWRITE not specified",
it only does this is SSH_FXP_RENAME_OVERWRITE is not set.

I'm still a but confused about the code in libssh2, but it seems to me
that we should either get an LIBSSH2_FX_OP_UNSUPPORTED or
LIBSSH2_FX_FILE_ALREADY_EXISTS regardless of sshd versions.

What do you think of this information?

Kristian Gunstone
Received on 2007-05-10