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;
openSUSE Build Service is sponsored by