diff --git a/ChangeLog b/ChangeLog index 94172428a..1252df061 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,10 @@ - djm@cvs.openbsd.org 2004/06/25 01:25:12 [regress/test-exec.sh] clean reexec-specific junk out of text-exec.sh and simplify; idea markus@ + - dtucker@cvs.openbsd.org 2004/06/25 05:38:48 + [sftp-server.c] + Fall back to stat+rename if filesystem doesn't doesn't support hard + links. bz#823, ok djm@ - (dtucker) [configure.ac openbsd-compat/misc.c [openbsd-compat/misc.h] Add closefrom() for platforms that don't have it. - (dtucker) [sshd.c] add line missing from reexec sync. @@ -1419,4 +1423,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3449 2004/06/25 04:22:23 dtucker Exp $ +$Id: ChangeLog,v 1.3450 2004/06/25 07:06:02 dtucker Exp $ diff --git a/sftp-server.c b/sftp-server.c index 8349c1763..39a6bdab4 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" -RCSID("$OpenBSD: sftp-server.c,v 1.46 2004/06/21 17:36:31 avsm Exp $"); +RCSID("$OpenBSD: sftp-server.c,v 1.47 2004/06/25 05:38:48 dtucker Exp $"); #include "buffer.h" #include "bufaux.h" @@ -839,9 +839,25 @@ process_rename(void) status = errno_to_portable(errno); else if (S_ISREG(sb.st_mode)) { /* Race-free rename of regular files */ - if (link(oldpath, newpath) == -1) - status = errno_to_portable(errno); - else if (unlink(oldpath) == -1) { + if (link(oldpath, newpath) == -1) { + if (errno == EOPNOTSUPP) { + struct stat st; + + /* + * fs doesn't support links, so fall back to + * stat+rename. This is racy. + */ + if (stat(newpath, &st) == -1) { + if (rename(oldpath, newpath) == -1) + status = + errno_to_portable(errno); + else + status = SSH2_FX_OK; + } + } else { + status = errno_to_portable(errno); + } + } else if (unlink(oldpath) == -1) { status = errno_to_portable(errno); /* clean spare link */ unlink(newpath);