diff options
author | Darren Tucker <dtucker@cvs.openbsd.org> | 2004-06-25 05:38:49 +0000 |
---|---|---|
committer | Darren Tucker <dtucker@cvs.openbsd.org> | 2004-06-25 05:38:49 +0000 |
commit | cb6140012fe1ca285c4675a0a1f982665adbdb78 (patch) | |
tree | cc6393f1b53a97fc2e4d5a198f8358f10bd383fb /usr.bin | |
parent | 744669176f44b052fa178d68620d3a70d2fb2a44 (diff) |
Fall back to stat+rename if filesystem doesn't doesn't support hard
links. bz#823, ok djm@
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/ssh/sftp-server.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/usr.bin/ssh/sftp-server.c b/usr.bin/ssh/sftp-server.c index 23f1ed6df4f..a660bef98cb 100644 --- a/usr.bin/ssh/sftp-server.c +++ b/usr.bin/ssh/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" @@ -819,9 +819,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); |