]> andersk Git - openssh.git/blobdiff - sftp-server.c
- OpenBSD CVS Sync
[openssh.git] / sftp-server.c
index 6575eb941d41b719992ec9d10d860f601317dd16..178084577e129d3ff7e1a8dc1adbf9ae9a1cbd1e 100644 (file)
@@ -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"
@@ -49,6 +49,9 @@ char *__progname;
 Buffer iqueue;
 Buffer oqueue;
 
+/* Version of client */
+int version;
+
 /* portable attibutes, etc. */
 
 typedef struct Stat Stat;
@@ -266,12 +269,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);
 }
@@ -347,8 +367,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);
@@ -859,6 +879,51 @@ process_rename(void)
        xfree(newpath);
 }
 
+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)
 {
@@ -944,6 +1009,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;
This page took 0.102941 seconds and 4 git commands to generate.