diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2001-03-07 10:11:24 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2001-03-07 10:11:24 +0000 |
commit | d3a6611d24ba76cf0d9a61c20b0b441946faf24a (patch) | |
tree | b6738e88f9e37ec29aee73922fbac8666f69b3be /usr.bin/ssh/sftp-server.c | |
parent | eb4a749e1d1cec4f3abb59abbe1905c6cab0fc3f (diff) |
Support for new draft (draft-ietf-secsh-filexfer-01). New symlink handling
functions and small protocol change.
Diffstat (limited to 'usr.bin/ssh/sftp-server.c')
-rw-r--r-- | usr.bin/ssh/sftp-server.c | 75 |
1 files changed, 73 insertions, 2 deletions
diff --git a/usr.bin/ssh/sftp-server.c b/usr.bin/ssh/sftp-server.c index 0715659069a..b4384ee05b2 100644 --- a/usr.bin/ssh/sftp-server.c +++ b/usr.bin/ssh/sftp-server.c @@ -22,7 +22,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: sftp-server.c,v 1.22 2001/03/03 22:07:50 deraadt Exp $"); +RCSID("$OpenBSD: sftp-server.c,v 1.23 2001/03/07 10:11:23 djm Exp $"); #include "buffer.h" #include "bufaux.h" @@ -43,6 +43,9 @@ RCSID("$OpenBSD: sftp-server.c,v 1.22 2001/03/03 22:07:50 deraadt Exp $"); Buffer iqueue; Buffer oqueue; +/* Version of client */ +int version; + /* portable attibutes, etc. */ typedef struct Stat Stat; @@ -260,12 +263,29 @@ void send_status(u_int32_t id, u_int32_t error) { Buffer msg; + const char *status_messages[] = { + "Success", /* SSH_FX_OK */ + "End of file", /* SSH_FX_EOF */ + "No such file", /* SSH_FX_NO_SUCH_FILE */ + "Permission denied", /* SSH_FX_PERMISSION_DENIED */ + "Failure", /* SSH_FX_FAILURE */ + "Bad message", /* SSH_FX_BAD_MESSAGE */ + "No connection", /* SSH_FX_NO_CONNECTION */ + "Connection lost", /* SSH_FX_CONNECTION_LOST */ + "Operation unsupported", /* SSH_FX_OP_UNSUPPORTED */ + "Unknown error" /* Others */ + }; TRACE("sent status id %d error %d", id, error); buffer_init(&msg); buffer_put_char(&msg, SSH2_FXP_STATUS); buffer_put_int(&msg, id); buffer_put_int(&msg, error); + if (version >= 3) { + buffer_put_cstring(&msg, + status_messages[MIN(error,SSH2_FX_MAX)]); + buffer_put_cstring(&msg, ""); + } send_msg(&msg); buffer_free(&msg); } @@ -341,8 +361,8 @@ void process_init(void) { Buffer msg; - int version = buffer_get_int(&iqueue); + version = buffer_get_int(&iqueue); TRACE("client version %d", version); buffer_init(&msg); buffer_put_char(&msg, SSH2_FXP_VERSION); @@ -840,6 +860,51 @@ process_rename(void) } void +process_readlink(void) +{ + u_int32_t id; + char link[MAXPATHLEN]; + char *path; + + id = get_int(); + path = get_string(NULL); + TRACE("readlink id %d path %s", id, path); + if (readlink(path, link, sizeof(link) - 1) == -1) + send_status(id, errno_to_portable(errno)); + else { + Stat s; + + link[sizeof(link) - 1] = '\0'; + attrib_clear(&s.attrib); + s.name = s.long_name = link; + send_names(id, 1, &s); + } + xfree(path); +} + +void +process_symlink(void) +{ + u_int32_t id; + struct stat st; + char *oldpath, *newpath; + int ret, status = SSH2_FX_FAILURE; + + id = get_int(); + oldpath = get_string(NULL); + newpath = get_string(NULL); + TRACE("symlink id %d old %s new %s", id, oldpath, newpath); + /* fail if 'newpath' exists */ + if (stat(newpath, &st) == -1) { + ret = symlink(oldpath, newpath); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + } + send_status(id, status); + xfree(oldpath); + xfree(newpath); +} + +void process_extended(void) { u_int32_t id; @@ -924,6 +989,12 @@ process(void) case SSH2_FXP_RENAME: process_rename(); break; + case SSH2_FXP_READLINK: + process_readlink(); + break; + case SSH2_FXP_SYMLINK: + process_symlink(); + break; case SSH2_FXP_EXTENDED: process_extended(); break; |