version 1.89, 2010/01/04 02:25:15 |
version 1.90, 2010/01/09 00:20:26 |
|
|
/* Version of client */ |
/* Version of client */ |
int version; |
int version; |
|
|
|
/* Disable writes */ |
|
int readonly; |
|
|
/* portable attributes, etc. */ |
/* portable attributes, etc. */ |
|
|
typedef struct Stat Stat; |
typedef struct Stat Stat; |
|
|
mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666; |
mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666; |
logit("open \"%s\" flags %s mode 0%o", |
logit("open \"%s\" flags %s mode 0%o", |
name, string_from_portable(pflags), mode); |
name, string_from_portable(pflags), mode); |
fd = open(name, flags, mode); |
if (readonly && |
if (fd < 0) { |
((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR)) |
status = errno_to_portable(errno); |
status = SSH2_FX_PERMISSION_DENIED; |
} else { |
else { |
handle = handle_new(HANDLE_FILE, name, fd, NULL); |
fd = open(name, flags, mode); |
if (handle < 0) { |
if (fd < 0) { |
close(fd); |
status = errno_to_portable(errno); |
} else { |
} else { |
send_handle(id, handle); |
handle = handle_new(HANDLE_FILE, name, fd, NULL); |
status = SSH2_FX_OK; |
if (handle < 0) { |
|
close(fd); |
|
} else { |
|
send_handle(id, handle); |
|
status = SSH2_FX_OK; |
|
} |
} |
} |
} |
} |
if (status != SSH2_FX_OK) |
if (status != SSH2_FX_OK) |
|
|
u_int32_t id; |
u_int32_t id; |
u_int64_t off; |
u_int64_t off; |
u_int len; |
u_int len; |
int handle, fd, ret, status = SSH2_FX_FAILURE; |
int handle, fd, ret, status; |
char *data; |
char *data; |
|
|
id = get_int(); |
id = get_int(); |
|
|
debug("request %u: write \"%s\" (handle %d) off %llu len %d", |
debug("request %u: write \"%s\" (handle %d) off %llu len %d", |
id, handle_to_name(handle), handle, (unsigned long long)off, len); |
id, handle_to_name(handle), handle, (unsigned long long)off, len); |
fd = handle_to_fd(handle); |
fd = handle_to_fd(handle); |
if (fd >= 0) { |
|
|
if (fd < 0) |
|
status = SSH2_FX_FAILURE; |
|
else if (readonly) |
|
status = SSH2_FX_PERMISSION_DENIED; |
|
else { |
if (lseek(fd, off, SEEK_SET) < 0) { |
if (lseek(fd, off, SEEK_SET) < 0) { |
status = errno_to_portable(errno); |
status = errno_to_portable(errno); |
error("process_write: seek failed"); |
error("process_write: seek failed"); |
|
|
handle_update_write(handle, ret); |
handle_update_write(handle, ret); |
} else { |
} else { |
debug2("nothing at all written"); |
debug2("nothing at all written"); |
|
status = SSH2_FX_FAILURE; |
} |
} |
} |
} |
} |
} |
|
|
name = get_string(NULL); |
name = get_string(NULL); |
a = get_attrib(); |
a = get_attrib(); |
debug("request %u: setstat name \"%s\"", id, name); |
debug("request %u: setstat name \"%s\"", id, name); |
|
if (readonly) { |
|
status = SSH2_FX_PERMISSION_DENIED; |
|
a->flags = 0; |
|
} |
if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { |
if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { |
logit("set \"%s\" size %llu", |
logit("set \"%s\" size %llu", |
name, (unsigned long long)a->size); |
name, (unsigned long long)a->size); |
|
|
a = get_attrib(); |
a = get_attrib(); |
debug("request %u: fsetstat handle %d", id, handle); |
debug("request %u: fsetstat handle %d", id, handle); |
fd = handle_to_fd(handle); |
fd = handle_to_fd(handle); |
if (fd < 0) { |
if (fd < 0) |
status = SSH2_FX_FAILURE; |
status = SSH2_FX_FAILURE; |
} else { |
else if (readonly) |
|
status = SSH2_FX_PERMISSION_DENIED; |
|
else { |
char *name = handle_to_name(handle); |
char *name = handle_to_name(handle); |
|
|
if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { |
if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { |
|
|
name = get_string(NULL); |
name = get_string(NULL); |
debug3("request %u: remove", id); |
debug3("request %u: remove", id); |
logit("remove name \"%s\"", name); |
logit("remove name \"%s\"", name); |
ret = unlink(name); |
if (readonly) |
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
status = SSH2_FX_PERMISSION_DENIED; |
|
else { |
|
ret = unlink(name); |
|
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
|
} |
send_status(id, status); |
send_status(id, status); |
xfree(name); |
xfree(name); |
} |
} |
|
|
a->perm & 07777 : 0777; |
a->perm & 07777 : 0777; |
debug3("request %u: mkdir", id); |
debug3("request %u: mkdir", id); |
logit("mkdir name \"%s\" mode 0%o", name, mode); |
logit("mkdir name \"%s\" mode 0%o", name, mode); |
ret = mkdir(name, mode); |
if (readonly) |
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
status = SSH2_FX_PERMISSION_DENIED; |
|
else { |
|
ret = mkdir(name, mode); |
|
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
|
} |
send_status(id, status); |
send_status(id, status); |
xfree(name); |
xfree(name); |
} |
} |
|
|
name = get_string(NULL); |
name = get_string(NULL); |
debug3("request %u: rmdir", id); |
debug3("request %u: rmdir", id); |
logit("rmdir name \"%s\"", name); |
logit("rmdir name \"%s\"", name); |
ret = rmdir(name); |
if (readonly) |
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
status = SSH2_FX_PERMISSION_DENIED; |
|
else { |
|
ret = rmdir(name); |
|
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
|
} |
send_status(id, status); |
send_status(id, status); |
xfree(name); |
xfree(name); |
} |
} |
|
|
debug3("request %u: rename", id); |
debug3("request %u: rename", id); |
logit("rename old \"%s\" new \"%s\"", oldpath, newpath); |
logit("rename old \"%s\" new \"%s\"", oldpath, newpath); |
status = SSH2_FX_FAILURE; |
status = SSH2_FX_FAILURE; |
if (lstat(oldpath, &sb) == -1) |
if (readonly) |
|
status = SSH2_FX_PERMISSION_DENIED; |
|
else if (lstat(oldpath, &sb) == -1) |
status = errno_to_portable(errno); |
status = errno_to_portable(errno); |
else if (S_ISREG(sb.st_mode)) { |
else if (S_ISREG(sb.st_mode)) { |
/* Race-free rename of regular files */ |
/* Race-free rename of regular files */ |
|
|
debug3("request %u: symlink", id); |
debug3("request %u: symlink", id); |
logit("symlink old \"%s\" new \"%s\"", oldpath, newpath); |
logit("symlink old \"%s\" new \"%s\"", oldpath, newpath); |
/* this will fail if 'newpath' exists */ |
/* this will fail if 'newpath' exists */ |
ret = symlink(oldpath, newpath); |
if (readonly) |
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
status = SSH2_FX_PERMISSION_DENIED; |
|
else { |
|
ret = symlink(oldpath, newpath); |
|
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); |
|
|
process_extended_posix_rename(u_int32_t id) |
process_extended_posix_rename(u_int32_t id) |
{ |
{ |
char *oldpath, *newpath; |
char *oldpath, *newpath; |
|
int ret, status; |
|
|
oldpath = get_string(NULL); |
oldpath = get_string(NULL); |
newpath = get_string(NULL); |
newpath = get_string(NULL); |
debug3("request %u: posix-rename", id); |
debug3("request %u: posix-rename", id); |
logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath); |
logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath); |
if (rename(oldpath, newpath) == -1) |
if (readonly) |
send_status(id, errno_to_portable(errno)); |
status = SSH2_FX_PERMISSION_DENIED; |
else |
else { |
send_status(id, SSH2_FX_OK); |
ret = rename(oldpath, newpath); |
|
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
|
} |
|
send_status(id, status); |
xfree(oldpath); |
xfree(oldpath); |
xfree(newpath); |
xfree(newpath); |
} |
} |
|
|
extern char *__progname; |
extern char *__progname; |
|
|
fprintf(stderr, |
fprintf(stderr, |
"usage: %s [-eh] [-f log_facility] [-l log_level] [-u umask]\n", |
"usage: %s [-ehR] [-f log_facility] [-l log_level] [-u umask]\n", |
__progname); |
__progname); |
exit(1); |
exit(1); |
} |
} |
|
|
|
|
log_init(__progname, log_level, log_facility, log_stderr); |
log_init(__progname, log_level, log_facility, log_stderr); |
|
|
while (!skipargs && (ch = getopt(argc, argv, "f:l:u:che")) != -1) { |
while (!skipargs && (ch = getopt(argc, argv, "f:l:u:cehR")) != -1) { |
switch (ch) { |
switch (ch) { |
|
case 'R': |
|
readonly = 1; |
|
break; |
case 'c': |
case 'c': |
/* |
/* |
* Ignore all arguments if we are invoked as a |
* Ignore all arguments if we are invoked as a |