From 1dcc71b6ee8c3f8b9d3ba5ec5af48243c4f3c168 Mon Sep 17 00:00:00 2001
From: Jose Baars <peut@peut.org>
Date: Sun, 25 Apr 2010 05:02:51 -0400
Subject: [PATCH] VMS port of libssh2; changes in the libssh2 common code

---
 src/libssh2_priv.h |    2 +-
 src/misc.c         |   10 ++++++++++
 src/session.c      |   25 +++++++++++++++++++++++--
 src/userauth.c     |   10 +++++-----
 4 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h
index 3d7ba6d..cade70d 100644
--- a/src/libssh2_priv.h
+++ b/src/libssh2_priv.h
@@ -1109,7 +1109,7 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
 
 void _libssh2_session_shutdown(LIBSSH2_SESSION * session);
 
-#ifdef WIN32
+#if defined( WIN32 ) || defined( __VMS )
 ssize_t _libssh2_recv(libssh2_socket_t socket, void *buffer, size_t length, int flags);
 ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer, size_t length, int flags);
 #else
diff --git a/src/misc.c b/src/misc.c
index 5a4ec9b..139abd7 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -97,6 +97,11 @@ _libssh2_recv(libssh2_socket_t socket, void *buffer, size_t length, int flags)
     if (rc < 0 )
         errno = wsa2errno();
 #endif
+#ifdef __VMS
+    if (rc < 0 ){
+       if ( errno == EWOULDBLOCK ) errno = EAGAIN;
+    }
+#endif
     return rc;
 }
 #endif /* _libssh2_recv */
@@ -116,6 +121,11 @@ _libssh2_send(libssh2_socket_t socket, const void *buffer, size_t length, int fl
     if (rc < 0 )
         errno = wsa2errno();
 #endif
+#ifdef VMS
+    if (rc < 0 ){
+       if ( errno == EWOULDBLOCK ) errno = EAGAIN;
+    }
+#endif
     return rc;
 }
 #endif /* _libssh2_recv */
diff --git a/src/session.c b/src/session.c
index 10565c7..91d3c54 100644
--- a/src/session.c
+++ b/src/session.c
@@ -278,7 +278,7 @@ session_nonblock(libssh2_socket_t sockfd,   /* operate on this */
 #endif
 
 #if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
-    /* older unix versions */
+    /* older unix versions and VMS*/
     int flags;
 
     flags = nonblock;
@@ -312,6 +312,7 @@ session_nonblock(libssh2_socket_t sockfd,   /* operate on this */
 #define SETBLOCK 5
 #endif
 
+
 #ifdef HAVE_DISABLED_NONBLOCKING
     return 0;                   /* returns success */
 #undef SETBLOCK
@@ -373,10 +374,30 @@ get_socket_nonblocking(int sockfd)
 #define GETBLOCK 5
 #endif
 
+#if defined(SO_STATE) && defined( __VMS ) && (GETBLOCK == 0)
+
+    /* VMS TCP/IP Services */
+
+    size_t sockstat = 0;
+    int    callstat = 0;
+    size_t size = sizeof( int );
+
+    callstat = getsockopt(sockfd, SOL_SOCKET, SO_STATE, 
+                                  (char *)&sockstat, &size);
+    if ( callstat == -1 ) return(0);
+    if ( (sockstat&SS_NBIO) )return(1);
+    return(0);
+
+
+#undef GETBLOCK
+#define GETBLOCK 6
+#endif
+
+
 #ifdef HAVE_DISABLED_NONBLOCKING
     return 1;                   /* returns blocking */
 #undef GETBLOCK
-#define GETBLOCK 6
+#define GETBLOCK 7
 #endif
 
 #if (GETBLOCK == 0)
diff --git a/src/userauth.c b/src/userauth.c
index 5527ff5..1685a12 100644
--- a/src/userauth.c
+++ b/src/userauth.c
@@ -599,8 +599,8 @@ sign_fromfile(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
     if(rc)
         return rc;
 
-    datavec.iov_base = (unsigned char *)data;
-    datavec.iov_len = data_len;
+    datavec.iov_base = (void *)data;
+    datavec.iov_len  = data_len;
 
     if (privkeyobj->signv(session, sig, sig_len, 1, &datavec,
                           &hostkey_abstract)) {
@@ -709,11 +709,11 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
         }
 
         _libssh2_htonu32(buf, session->session_id_len);
-        datavec[0].iov_base = buf;
+        datavec[0].iov_base = (void *)buf;
         datavec[0].iov_len = 4;
-        datavec[1].iov_base = session->session_id;
+        datavec[1].iov_base = (void *)session->session_id;
         datavec[1].iov_len = session->session_id_len;
-        datavec[2].iov_base = session->userauth_host_packet;
+        datavec[2].iov_base = (void *)session->userauth_host_packet;
         datavec[2].iov_len = session->userauth_host_packet_len;
 
         if (privkeyobj->signv(session, &sig, &sig_len, 3, datavec, &abstract)) {
-- 
1.6.6.1

