version 1.38, 2002/09/11 22:41:50 |
version 1.38.2.3, 2003/09/16 21:20:27 |
|
|
/* Version of client */ |
/* Version of client */ |
int version; |
int version; |
|
|
/* portable attibutes, etc. */ |
/* portable attributes, etc. */ |
|
|
typedef struct Stat Stat; |
typedef struct Stat Stat; |
|
|
|
|
handles[i].use = use; |
handles[i].use = use; |
handles[i].dirp = dirp; |
handles[i].dirp = dirp; |
handles[i].fd = fd; |
handles[i].fd = fd; |
handles[i].name = name; |
handles[i].name = xstrdup(name); |
return i; |
return i; |
} |
} |
} |
} |
|
|
if (handle_is_ok(handle, HANDLE_FILE)) { |
if (handle_is_ok(handle, HANDLE_FILE)) { |
ret = close(handles[handle].fd); |
ret = close(handles[handle].fd); |
handles[handle].use = HANDLE_UNUSED; |
handles[handle].use = HANDLE_UNUSED; |
|
xfree(handles[handle].name); |
} else if (handle_is_ok(handle, HANDLE_DIR)) { |
} else if (handle_is_ok(handle, HANDLE_DIR)) { |
ret = closedir(handles[handle].dirp); |
ret = closedir(handles[handle].dirp); |
handles[handle].use = HANDLE_UNUSED; |
handles[handle].use = HANDLE_UNUSED; |
|
xfree(handles[handle].name); |
} else { |
} else { |
errno = ENOENT; |
errno = ENOENT; |
} |
} |
|
|
if (fd < 0) { |
if (fd < 0) { |
status = errno_to_portable(errno); |
status = errno_to_portable(errno); |
} else { |
} else { |
handle = handle_new(HANDLE_FILE, xstrdup(name), fd, NULL); |
handle = handle_new(HANDLE_FILE, name, fd, NULL); |
if (handle < 0) { |
if (handle < 0) { |
close(fd); |
close(fd); |
} else { |
} else { |
|
|
(unsigned long long)off, len); |
(unsigned long long)off, len); |
if (len > sizeof buf) { |
if (len > sizeof buf) { |
len = sizeof buf; |
len = sizeof buf; |
log("read change len %d", len); |
logit("read change len %d", len); |
} |
} |
fd = handle_to_fd(handle); |
fd = handle_to_fd(handle); |
if (fd >= 0) { |
if (fd >= 0) { |
|
|
} else if (ret == len) { |
} else if (ret == len) { |
status = SSH2_FX_OK; |
status = SSH2_FX_OK; |
} else { |
} else { |
log("nothing at all written"); |
logit("nothing at all written"); |
} |
} |
} |
} |
} |
} |
|
|
if (dirp == NULL) { |
if (dirp == NULL) { |
status = errno_to_portable(errno); |
status = errno_to_portable(errno); |
} else { |
} else { |
handle = handle_new(HANDLE_DIR, xstrdup(path), 0, dirp); |
handle = handle_new(HANDLE_DIR, path, 0, dirp); |
if (handle < 0) { |
if (handle < 0) { |
closedir(dirp); |
closedir(dirp); |
} else { |
} else { |
|
|
process_rename(void) |
process_rename(void) |
{ |
{ |
u_int32_t id; |
u_int32_t id; |
struct stat st; |
|
char *oldpath, *newpath; |
char *oldpath, *newpath; |
int ret, status = SSH2_FX_FAILURE; |
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 (stat(newpath, &st) == -1) { |
if (lstat(oldpath, &sb) == -1) |
ret = rename(oldpath, newpath); |
status = errno_to_portable(errno); |
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
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) { |
|
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); |
|
|
process_symlink(void) |
process_symlink(void) |
{ |
{ |
u_int32_t id; |
u_int32_t id; |
struct stat st; |
|
char *oldpath, *newpath; |
char *oldpath, *newpath; |
int ret, status = SSH2_FX_FAILURE; |
int ret, status; |
|
|
id = get_int(); |
id = get_int(); |
oldpath = get_string(NULL); |
oldpath = get_string(NULL); |
newpath = get_string(NULL); |
newpath = get_string(NULL); |
TRACE("symlink id %u old %s new %s", id, oldpath, newpath); |
TRACE("symlink id %u old %s new %s", id, oldpath, newpath); |
/* fail if 'newpath' exists */ |
/* this will fail if 'newpath' exists */ |
if (stat(newpath, &st) == -1) { |
ret = symlink(oldpath, newpath); |
ret = symlink(oldpath, newpath); |
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
|
} |
|
send_status(id, status); |
send_status(id, status); |
xfree(oldpath); |
xfree(oldpath); |
xfree(newpath); |
xfree(newpath); |