version 1.38.2.1, 2003/04/01 00:12:14 |
version 1.38.2.2, 2003/04/03 23:27:12 |
|
|
u_int32_t id; |
u_int32_t id; |
char *oldpath, *newpath; |
char *oldpath, *newpath; |
int status; |
int status; |
|
struct stat sb; |
|
|
id = get_int(); |
id = get_int(); |
oldpath = get_string(NULL); |
oldpath = get_string(NULL); |
newpath = get_string(NULL); |
newpath = get_string(NULL); |
TRACE("rename id %u old %s new %s", id, oldpath, newpath); |
TRACE("rename id %u old %s new %s", id, oldpath, newpath); |
/* fail if 'newpath' exists */ |
status = SSH2_FX_FAILURE; |
if (link(oldpath, newpath) == -1) |
if (lstat(oldpath, &sb) == -1) |
status = errno_to_portable(errno); |
status = errno_to_portable(errno); |
else if (unlink(oldpath) == -1) { |
else if (S_ISREG(sb.st_mode)) { |
status = errno_to_portable(errno); |
/* Race-free rename of regular files */ |
/* clean spare link */ |
if (link(oldpath, newpath) == -1) |
unlink(newpath); |
status = errno_to_portable(errno); |
} else |
else if (unlink(oldpath) == -1) { |
status = SSH2_FX_OK; |
status = errno_to_portable(errno); |
|
/* clean spare link */ |
|
unlink(newpath); |
|
} else |
|
status = SSH2_FX_OK; |
|
} else if (stat(newpath, &sb) == -1) { |
|
if (rename(oldpath, newpath) == -1) |
|
status = errno_to_portable(errno); |
|
else |
|
status = SSH2_FX_OK; |
|
} |
send_status(id, status); |
send_status(id, status); |
xfree(oldpath); |
xfree(oldpath); |
xfree(newpath); |
xfree(newpath); |