forked from pool/libssh
367 lines
15 KiB
Diff
367 lines
15 KiB
Diff
From b0b78a34891489b26aaabf71975bed4bc533c9cc Mon Sep 17 00:00:00 2001
|
|
From: Andreas Schneider <mail@cynapses.org>
|
|
Date: Wed, 20 Aug 2008 18:38:25 +0200
|
|
Subject: [PATCH] Add errno mapping.
|
|
|
|
---
|
|
libssh/sftp.c | 252 ++++++++++++++++++++++++++++++++++++++++++++------------
|
|
1 files changed, 198 insertions(+), 54 deletions(-)
|
|
|
|
Index: libssh-0.2/libssh/sftp.c
|
|
===================================================================
|
|
--- libssh-0.2.orig/libssh/sftp.c
|
|
+++ libssh-0.2/libssh/sftp.c
|
|
@@ -22,6 +22,7 @@ the Free Software Foundation, Inc., 59 T
|
|
MA 02111-1307, USA. */
|
|
|
|
|
|
+#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
@@ -393,6 +394,17 @@ SFTP_DIR *sftp_opendir(SFTP_SESSION *sft
|
|
sftp_message_free(msg);
|
|
if(!status)
|
|
return NULL;
|
|
+ switch (status->status) {
|
|
+ case SSH_FX_NO_SUCH_FILE:
|
|
+ errno = ENOENT;
|
|
+ break;
|
|
+ case SSH_FX_PERMISSION_DENIED:
|
|
+ errno = EACCES;
|
|
+ break;
|
|
+ default:
|
|
+ ssh_say(1, "%s:%d - handle status: %d\n", __FILE__, __LINE__, status->status);
|
|
+ break;
|
|
+ }
|
|
ssh_set_error(sftp->session,SSH_REQUEST_DENIED,"sftp server : %s",status->errormsg);
|
|
status_msg_free(status);
|
|
return NULL;
|
|
@@ -709,10 +721,20 @@ SFTP_ATTRIBUTES *sftp_readdir(SFTP_SESSI
|
|
sftp_message_free(msg);
|
|
if(!status)
|
|
return NULL;
|
|
- if(status->status==SSH_FX_EOF){
|
|
- dir->eof=1;
|
|
+ switch (status->status) {
|
|
+ case SSH_FX_NO_SUCH_FILE:
|
|
+ errno = ENOENT;
|
|
+ break;
|
|
+ case SSH_FX_PERMISSION_DENIED:
|
|
+ errno = EACCES;
|
|
+ break;
|
|
+ case SSH_FX_EOF:
|
|
+ dir->eof = 1;
|
|
status_msg_free(status);
|
|
return NULL;
|
|
+ default:
|
|
+ ssh_say(1, "%s:%d - handle status: %d\n", __FILE__, __LINE__, status->status);
|
|
+ break;
|
|
}
|
|
ssh_set_error(sftp->session,SSH_FATAL,"Unknown error status : %d",status->status);
|
|
status_msg_free(status);
|
|
@@ -789,12 +811,29 @@ static int sftp_handle_close(SFTP_SESSIO
|
|
sftp_message_free(msg);
|
|
if(!status)
|
|
return -1;
|
|
- if(status->status != SSH_FX_OK){
|
|
- ssh_set_error(sftp->session,SSH_REQUEST_DENIED,"sftp server : %s",status->errormsg);
|
|
- err=-1;
|
|
+ switch (status->status) {
|
|
+ case SSH_FX_INVALID_HANDLE:
|
|
+ errno = EBADF;
|
|
+ break;
|
|
+#if 0
|
|
+ case SSH_FX_NO_SPACE_ON_FILESYSTEM:
|
|
+ errno = ENOSPC;
|
|
+ break;
|
|
+ case SSH_FX_QUOTA_EXCEEDED:
|
|
+ errno = EDQUOT;
|
|
+ break:
|
|
+#endif
|
|
+ case SSH_FX_OK:
|
|
+ status_msg_free(status);
|
|
+ return err;
|
|
+ break;
|
|
+ default:
|
|
+ ssh_say(1, "%s:%d - handle status: %d\n", __FILE__, __LINE__, status->status);
|
|
+ break;
|
|
}
|
|
+ ssh_set_error(sftp->session,SSH_REQUEST_DENIED,"sftp server : %s",status->errormsg);
|
|
status_msg_free(status);
|
|
- return err;
|
|
+ return -1;
|
|
default:
|
|
ssh_set_error(sftp->session,SSH_FATAL,"Received message %d during sftp_handle_close!",msg->packet_type);
|
|
sftp_message_free(msg);
|
|
@@ -868,6 +907,23 @@ SFTP_FILE *sftp_open(SFTP_SESSION *sftp,
|
|
sftp_message_free(msg);
|
|
if(!status)
|
|
return NULL;
|
|
+ switch (status->status) {
|
|
+ case SSH_FX_FILE_ALREADY_EXISTS:
|
|
+ errno = EEXIST;
|
|
+ break;
|
|
+ case SSH_FX_NO_SUCH_FILE:
|
|
+ errno = ENOENT;
|
|
+ break;
|
|
+ case SSH_FX_PERMISSION_DENIED:
|
|
+ errno = EACCES;
|
|
+ break;
|
|
+ case SSH_FX_OP_UNSUPPORTED:
|
|
+ errno = EINVAL;
|
|
+ break;
|
|
+ default:
|
|
+ ssh_say(1, "%s:%d - handle status: %d\n", __FILE__, __LINE__, status->status);
|
|
+ break;
|
|
+ }
|
|
ssh_set_error(sftp->session,SSH_REQUEST_DENIED,"sftp server : %s",status->errormsg);
|
|
status_msg_free(status);
|
|
return NULL;
|
|
@@ -925,14 +981,21 @@ int sftp_read(SFTP_FILE *handle, void *d
|
|
sftp_message_free(msg);
|
|
if(!status)
|
|
return -1;
|
|
- if(status->status != SSH_FX_EOF){
|
|
- ssh_set_error(sftp->session,SSH_REQUEST_DENIED,"sftp server : %s",status->errormsg);
|
|
- err=-1;
|
|
- }
|
|
- else
|
|
+ switch (status->status) {
|
|
+ case SSH_FX_INVALID_HANDLE:
|
|
+ errno = EBADF;
|
|
+ break;
|
|
+ case SSH_FX_EOF:
|
|
handle->eof=1;
|
|
+ status_msg_free(status);
|
|
+ return err ? err : 0;
|
|
+ default:
|
|
+ ssh_say(1, "%s:%d - handle status: %d\n", __FILE__, __LINE__, status->status);
|
|
+ break;
|
|
+ }
|
|
+ ssh_set_error(sftp->session,SSH_REQUEST_DENIED,"sftp server : %s",status->errormsg);
|
|
status_msg_free(status);
|
|
- return err?err:0;
|
|
+ return -1;
|
|
case SSH_FXP_DATA:
|
|
datastring=buffer_get_ssh_string(msg->payload);
|
|
sftp_message_free(msg);
|
|
@@ -992,13 +1055,22 @@ int sftp_write(SFTP_FILE *file, void *da
|
|
sftp_message_free(msg);
|
|
if(!status)
|
|
return -1;
|
|
- if(status->status != SSH_FX_OK){
|
|
- ssh_set_error(sftp->session,SSH_REQUEST_DENIED,"sftp server : %s",status->errormsg);
|
|
- err=-1;
|
|
+ switch (status->status) {
|
|
+ case SSH_FX_INVALID_HANDLE:
|
|
+ errno = EBADF;
|
|
+ break;
|
|
+ case SSH_FX_OK:
|
|
+ file->offset+=len;
|
|
+ status_msg_free(status);
|
|
+ return err ? err : len;
|
|
+ default:
|
|
+ ssh_say(1, "%s:%d - handle status: %d\n", __FILE__, __LINE__, status->status);
|
|
+ break;
|
|
}
|
|
+ ssh_set_error(sftp->session,SSH_REQUEST_DENIED,"sftp server : %s",status->errormsg);
|
|
file->offset+=len;
|
|
status_msg_free(status);
|
|
- return (err?err:len);
|
|
+ return -1;
|
|
default:
|
|
ssh_set_error(sftp->session,SSH_FATAL,"Received message %d during write!",msg->packet_type);
|
|
sftp_message_free(msg);
|
|
@@ -1044,14 +1116,27 @@ int sftp_rm(SFTP_SESSION *sftp, char *fi
|
|
sftp_message_free(msg);
|
|
if (!status)
|
|
return -1;
|
|
- if (status->status != SSH_FX_OK) {
|
|
- /* status should be SSH_FX_OK if the command was successful, if it didn't, then there was an error */
|
|
- ssh_set_error(sftp->session,SSH_REQUEST_DENIED, "sftp server: %s", status->errormsg);
|
|
- status_msg_free(status);
|
|
- return -1;
|
|
+ switch (status->status) {
|
|
+ case SSH_FX_FILE_ALREADY_EXISTS:
|
|
+ errno = EEXIST;
|
|
+ break;
|
|
+ case SSH_FX_OP_UNSUPPORTED:
|
|
+ errno = EINVAL;
|
|
+ break;
|
|
+ case SSH_FX_NO_SUCH_FILE:
|
|
+ errno = ENOENT;
|
|
+ break;
|
|
+ case SSH_FX_OK:
|
|
+ status_msg_free(status);
|
|
+ return 0;
|
|
+ default:
|
|
+ ssh_say(1, "%s:%d - handle status: %d\n", __FILE__, __LINE__, status->status);
|
|
+ break;
|
|
}
|
|
+ /* status should be SSH_FX_OK if the command was successful, if it didn't, then there was an error */
|
|
+ ssh_set_error(sftp->session,SSH_REQUEST_DENIED, "sftp server: %s", status->errormsg);
|
|
status_msg_free(status);
|
|
- return 0; /* at this point, everything turned out OK */
|
|
+ return -1;
|
|
} else {
|
|
ssh_set_error(sftp->session,SSH_FATAL, "Received message %d when attempting to remove file", msg->packet_type);
|
|
sftp_message_free(msg);
|
|
@@ -1083,18 +1168,21 @@ int sftp_rmdir(SFTP_SESSION *sftp, char
|
|
{
|
|
status = parse_status_msg(msg);
|
|
sftp_message_free(msg);
|
|
- if (!status)
|
|
- {
|
|
+ if (!status) {
|
|
return -1;
|
|
}
|
|
- else if (status->status != SSH_FX_OK) /* status should be SSH_FX_OK if the command was successful, if it didn't, then there was an error */
|
|
- {
|
|
- ssh_set_error(sftp->session,SSH_REQUEST_DENIED, "sftp server: %s", status->errormsg);
|
|
+ switch (status->status) {
|
|
+ case SSH_FX_OK:
|
|
status_msg_free(status);
|
|
- return -1;
|
|
+ return 0;
|
|
+ break;
|
|
+ default:
|
|
+ ssh_say(1, "%s:%d - handle status: %d\n", __FILE__, __LINE__, status->status);
|
|
+ break;
|
|
}
|
|
+ ssh_set_error(sftp->session,SSH_REQUEST_DENIED, "sftp server: %s", status->errormsg);
|
|
status_msg_free(status);
|
|
- return 0; /* at this point, everything turned out OK */
|
|
+ return -1;
|
|
}
|
|
else
|
|
{
|
|
@@ -1111,6 +1199,7 @@ int sftp_mkdir(SFTP_SESSION *sftp, char
|
|
STRING *path = string_from_char(directory);
|
|
SFTP_MESSAGE *msg = NULL;
|
|
STATUS_MESSAGE *status = NULL;
|
|
+ SFTP_ATTRIBUTES *errno_attr = NULL;
|
|
|
|
buffer_add_u32(buffer, id);
|
|
buffer_add_ssh_string(buffer, path);
|
|
@@ -1127,17 +1216,30 @@ int sftp_mkdir(SFTP_SESSION *sftp, char
|
|
/* by specification, this command's only supposed to return SSH_FXP_STATUS */
|
|
status = parse_status_msg(msg);
|
|
sftp_message_free(msg);
|
|
- if (!status)
|
|
- return -1;
|
|
- else
|
|
- if (status->status != SSH_FX_OK) {
|
|
- /* status should be SSH_FX_OK if the command was successful, if it didn't, then there was an error */
|
|
- ssh_set_error(sftp->session,SSH_REQUEST_DENIED, "sftp server: %s", status->errormsg);
|
|
+ switch (status->status) {
|
|
+ case SSH_FX_FAILURE:
|
|
+ /*
|
|
+ * mkdir always returns a failure, even if the path already exists.
|
|
+ * To be POSIX conform and to be able to map it to EEXIST a stat
|
|
+ * call should be issued here
|
|
+ */
|
|
+ errno_attr = sftp_lstat(sftp, directory);
|
|
+ if (errno_attr != NULL) {
|
|
+ errno = EEXIST;
|
|
+ }
|
|
+ break;
|
|
+ case SSH_FX_OK:
|
|
status_msg_free(status);
|
|
- return -1;
|
|
+ return 0;
|
|
+ break;
|
|
+ default:
|
|
+ ssh_say(1, "%s:%d - handle status: %d\n", __FILE__, __LINE__, status->status);
|
|
+ break;
|
|
}
|
|
+ /* status should be SSH_FX_OK if the command was successful, if it didn't, then there was an error */
|
|
+ ssh_set_error(sftp->session,SSH_REQUEST_DENIED, "sftp server: %s", status->errormsg);
|
|
status_msg_free(status);
|
|
- return 0; /* at this point, everything turned out OK */
|
|
+ return -1;
|
|
} else {
|
|
ssh_set_error(sftp->session,SSH_FATAL, "Received message %d when attempting to make directory", msg->packet_type);
|
|
sftp_message_free(msg);
|
|
@@ -1172,14 +1274,24 @@ int sftp_rename(SFTP_SESSION *sftp, char
|
|
sftp_message_free(msg);
|
|
if (!status)
|
|
return -1;
|
|
- else if (status->status != SSH_FX_OK) {
|
|
- /* status should be SSH_FX_OK if the command was successful, if it didn't, then there was an error */
|
|
- ssh_set_error(sftp->session,SSH_REQUEST_DENIED, "sftp server: %s", status->errormsg);
|
|
+ switch (status->status) {
|
|
+ case SSH_FX_FILE_ALREADY_EXISTS:
|
|
+ errno = EEXIST;
|
|
+ break;
|
|
+ case SSH_FX_OP_UNSUPPORTED:
|
|
+ errno = EINVAL;
|
|
+ break;
|
|
+ case SSH_FX_OK:
|
|
status_msg_free(status);
|
|
- return -1;
|
|
+ return 0;
|
|
+ default:
|
|
+ ssh_say(1, "%s:%d - handle status: %d\n", __FILE__, __LINE__, status->status);
|
|
+ break;
|
|
}
|
|
+ /* status should be SSH_FX_OK if the command was successful, if it didn't, then there was an error */
|
|
+ ssh_set_error(sftp->session,SSH_REQUEST_DENIED, "sftp server: %s", status->errormsg);
|
|
status_msg_free(status);
|
|
- return 0; /* at this point, everything turned out OK */
|
|
+ return -1;
|
|
} else {
|
|
ssh_set_error(sftp->session,SSH_FATAL, "Received message %d when attempting to rename", msg->packet_type);
|
|
sftp_message_free(msg);
|
|
@@ -1212,14 +1324,27 @@ int sftp_setstat(SFTP_SESSION *sftp, cha
|
|
sftp_message_free(msg);
|
|
if (!status)
|
|
return -1;
|
|
- else if (status->status != SSH_FX_OK) {
|
|
- /* status should be SSH_FX_OK if the command was successful, if it didn't, then there was an error */
|
|
- ssh_set_error(sftp->session,SSH_REQUEST_DENIED, "sftp server: %s", status->errormsg);
|
|
+ switch (status->status) {
|
|
+ case SSH_FX_NO_SUCH_FILE:
|
|
+ errno = ENOENT;
|
|
+ break;
|
|
+ case SSH_FX_PERMISSION_DENIED:
|
|
+ errno = EACCES;
|
|
+ break;
|
|
+ case SSH_FX_INVALID_HANDLE:
|
|
+ errno = EBADF;
|
|
+ break;
|
|
+ case SSH_FX_OK:
|
|
status_msg_free(status);
|
|
- return -1;
|
|
+ return 0;
|
|
+ default:
|
|
+ ssh_say(1, "%s:%d - handle status: %d\n", __FILE__, __LINE__, status->status);
|
|
+ break;
|
|
}
|
|
+ /* status should be SSH_FX_OK if the command was successful, if it didn't, then there was an error */
|
|
+ ssh_set_error(sftp->session,SSH_REQUEST_DENIED, "sftp server: %s", status->errormsg);
|
|
status_msg_free(status);
|
|
- return 0; /* at this point, everything turned out OK */
|
|
+ return -1;
|
|
} else {
|
|
ssh_set_error(sftp->session,SSH_FATAL, "Received message %d when attempting to set stats", msg->packet_type);
|
|
sftp_message_free(msg);
|
|
@@ -1302,6 +1427,17 @@ SFTP_ATTRIBUTES *sftp_xstat(SFTP_SESSION
|
|
sftp_message_free(msg);
|
|
if(!status)
|
|
return NULL;
|
|
+ switch (status->status) {
|
|
+ case SSH_FX_NO_SUCH_FILE:
|
|
+ errno = ENOENT;
|
|
+ break;
|
|
+ case SSH_FX_PERMISSION_DENIED:
|
|
+ errno = EACCES;
|
|
+ break;
|
|
+ default:
|
|
+ ssh_say(1, "%s:%d - handle status: %d\n", __FILE__, __LINE__, status->status);
|
|
+ break;
|
|
+ }
|
|
ssh_set_error(sftp->session,SSH_REQUEST_DENIED,"sftp server: %s",status->errormsg);
|
|
status_msg_free(status);
|
|
return NULL;
|