summaryrefslogtreecommitdiff
path: root/sftp-server.c
diff options
context:
space:
mode:
Diffstat (limited to 'sftp-server.c')
-rw-r--r--sftp-server.c75
1 files changed, 73 insertions, 2 deletions
diff --git a/sftp-server.c b/sftp-server.c
index 6575eb941..178084577 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -22,7 +22,7 @@
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */ 23 */
24#include "includes.h" 24#include "includes.h"
25RCSID("$OpenBSD: sftp-server.c,v 1.22 2001/03/03 22:07:50 deraadt Exp $"); 25RCSID("$OpenBSD: sftp-server.c,v 1.23 2001/03/07 10:11:23 djm Exp $");
26 26
27#include "buffer.h" 27#include "buffer.h"
28#include "bufaux.h" 28#include "bufaux.h"
@@ -49,6 +49,9 @@ char *__progname;
49Buffer iqueue; 49Buffer iqueue;
50Buffer oqueue; 50Buffer oqueue;
51 51
52/* Version of client */
53int version;
54
52/* portable attibutes, etc. */ 55/* portable attibutes, etc. */
53 56
54typedef struct Stat Stat; 57typedef struct Stat Stat;
@@ -266,12 +269,29 @@ void
266send_status(u_int32_t id, u_int32_t error) 269send_status(u_int32_t id, u_int32_t error)
267{ 270{
268 Buffer msg; 271 Buffer msg;
272 const char *status_messages[] = {
273 "Success", /* SSH_FX_OK */
274 "End of file", /* SSH_FX_EOF */
275 "No such file", /* SSH_FX_NO_SUCH_FILE */
276 "Permission denied", /* SSH_FX_PERMISSION_DENIED */
277 "Failure", /* SSH_FX_FAILURE */
278 "Bad message", /* SSH_FX_BAD_MESSAGE */
279 "No connection", /* SSH_FX_NO_CONNECTION */
280 "Connection lost", /* SSH_FX_CONNECTION_LOST */
281 "Operation unsupported", /* SSH_FX_OP_UNSUPPORTED */
282 "Unknown error" /* Others */
283 };
269 284
270 TRACE("sent status id %d error %d", id, error); 285 TRACE("sent status id %d error %d", id, error);
271 buffer_init(&msg); 286 buffer_init(&msg);
272 buffer_put_char(&msg, SSH2_FXP_STATUS); 287 buffer_put_char(&msg, SSH2_FXP_STATUS);
273 buffer_put_int(&msg, id); 288 buffer_put_int(&msg, id);
274 buffer_put_int(&msg, error); 289 buffer_put_int(&msg, error);
290 if (version >= 3) {
291 buffer_put_cstring(&msg,
292 status_messages[MIN(error,SSH2_FX_MAX)]);
293 buffer_put_cstring(&msg, "");
294 }
275 send_msg(&msg); 295 send_msg(&msg);
276 buffer_free(&msg); 296 buffer_free(&msg);
277} 297}
@@ -347,8 +367,8 @@ void
347process_init(void) 367process_init(void)
348{ 368{
349 Buffer msg; 369 Buffer msg;
350 int version = buffer_get_int(&iqueue);
351 370
371 version = buffer_get_int(&iqueue);
352 TRACE("client version %d", version); 372 TRACE("client version %d", version);
353 buffer_init(&msg); 373 buffer_init(&msg);
354 buffer_put_char(&msg, SSH2_FXP_VERSION); 374 buffer_put_char(&msg, SSH2_FXP_VERSION);
@@ -860,6 +880,51 @@ process_rename(void)
860} 880}
861 881
862void 882void
883process_readlink(void)
884{
885 u_int32_t id;
886 char link[MAXPATHLEN];
887 char *path;
888
889 id = get_int();
890 path = get_string(NULL);
891 TRACE("readlink id %d path %s", id, path);
892 if (readlink(path, link, sizeof(link) - 1) == -1)
893 send_status(id, errno_to_portable(errno));
894 else {
895 Stat s;
896
897 link[sizeof(link) - 1] = '\0';
898 attrib_clear(&s.attrib);
899 s.name = s.long_name = link;
900 send_names(id, 1, &s);
901 }
902 xfree(path);
903}
904
905void
906process_symlink(void)
907{
908 u_int32_t id;
909 struct stat st;
910 char *oldpath, *newpath;
911 int ret, status = SSH2_FX_FAILURE;
912
913 id = get_int();
914 oldpath = get_string(NULL);
915 newpath = get_string(NULL);
916 TRACE("symlink id %d old %s new %s", id, oldpath, newpath);
917 /* fail if 'newpath' exists */
918 if (stat(newpath, &st) == -1) {
919 ret = symlink(oldpath, newpath);
920 status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
921 }
922 send_status(id, status);
923 xfree(oldpath);
924 xfree(newpath);
925}
926
927void
863process_extended(void) 928process_extended(void)
864{ 929{
865 u_int32_t id; 930 u_int32_t id;
@@ -944,6 +1009,12 @@ process(void)
944 case SSH2_FXP_RENAME: 1009 case SSH2_FXP_RENAME:
945 process_rename(); 1010 process_rename();
946 break; 1011 break;
1012 case SSH2_FXP_READLINK:
1013 process_readlink();
1014 break;
1015 case SSH2_FXP_SYMLINK:
1016 process_symlink();
1017 break;
947 case SSH2_FXP_EXTENDED: 1018 case SSH2_FXP_EXTENDED:
948 process_extended(); 1019 process_extended();
949 break; 1020 break;