File 0002-Add-errno-mapping.patch of Package libssh
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;