]> git.pld-linux.org Git - packages/php-pecl-ssh2.git/commitdiff
up to 0.13 (2016-06-12); cleanup branch.diff
authorElan Ruusamäe <glen@delfi.ee>
Thu, 4 May 2017 11:58:37 +0000 (14:58 +0300)
committerElan Ruusamäe <glen@delfi.ee>
Thu, 4 May 2017 11:59:09 +0000 (14:59 +0300)
branch.diff [deleted file]
php-pecl-ssh2.spec

diff --git a/branch.diff b/branch.diff
deleted file mode 100644 (file)
index 6375c0c..0000000
+++ /dev/null
@@ -1,19467 +0,0 @@
-Index: config.w32
-===================================================================
---- config.w32 (.../tags/RELEASE_0_11_0)
-+++ config.w32 (.../trunk)
-@@ -0,0 +1,37 @@
-+// $Id$
-+// vim:ft=javascript
-+
-+ARG_WITH("ssh2", "SSH2 support", "no");
-+
-+if (PHP_SSH2 != "no") {
-+      if ((((PHP_ZLIB=="no") && (CHECK_LIB("zlib_a.lib", "ssh2", PHP_SSH2) ||  CHECK_LIB("zlib.lib", "ssh2", PHP_SSH2))) || 
-+              (PHP_ZLIB_SHARED && CHECK_LIB("zlib.lib", "ssh2", PHP_SSH2)) || (PHP_ZLIB == "yes" && (!PHP_ZLIB_SHARED))) &&
-+              CHECK_LIB("libeay32.lib", "ssh2", PHP_SSH2) &&
-+              CHECK_LIB("ssleay32.lib", "ssh2", PHP_SSH2) &&
-+              CHECK_LIB("ws2_32.lib", "ssh2", PHP_SSH2)) {
-+
-+              // Use bundled lib if none installed, even if it is outdated.
-+              if (!(CHECK_LIB("libssh2_a.lib;libssh2.lib", "ssh2", PHP_SSH2) &&
-+                              CHECK_HEADER_ADD_INCLUDE("libssh2.h", "CFLAGS_SSH2", PHP_PHP_BUILD + "\\include\\libssh2"))) {
-+                      FSO.CopyFile(configure_module_dirname + "\\libssh2\\src\\libssh2_config.h.in.w32",
-+                                      configure_module_dirname + "\\libssh2\\src\\libssh2_config.h");
-+
-+                      ADD_FLAG('CFLAGS_SSH2', '/DLIBSSH2_WIN32=1 /DLIBSSH2_API= /I ' + 
-+                                      configure_module_dirname + '/libssh2/include');
-+              }
-+
-+              AC_DEFINE('HAVE_SSH2LIB', 1);
-+              AC_DEFINE('PHP_SSH2_REMOTE_FORWARDING', 1);
-+              AC_DEFINE('PHP_SSH2_HOSTBASED_AUTH', 1);
-+              AC_DEFINE('PHP_SSH2_POLL', 1);
-+              AC_DEFINE('PHP_SSH2_PUBLICKEY_SUBSYSTEM', 1);
-+
-+              EXTENSION("ssh2", "ssh2.c ssh2_fopen_wrappers.c ssh2_sftp.c");
-+
-+              ADD_SOURCES(configure_module_dirname + "/libssh2/src", "channel.c comp.c crypt.c \
-+                              hostkey.c kex.c mac.c misc.c openssl.c packet.c pem.c publickey.c scp.c \
-+                              session.c sftp.c transport.c userauth.c", "ssh2");
-+      } else {
-+              WARNING("ssh2 not enabled: libraries or headers not found");
-+      }
-+}
-
-Property changes on: config.w32
-___________________________________________________________________
-Added: svn:eol-style
-   + native
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.11
-
-Index: ssh2.c
-===================================================================
---- ssh2.c     (.../tags/RELEASE_0_11_0)
-+++ ssh2.c     (.../trunk)
-@@ -47,14 +47,9 @@
- int le_ssh2_pkey_subsys;
- #endif
--#ifdef ZEND_ENGINE_2
--static
--    ZEND_BEGIN_ARG_INFO(php_ssh2_first_arg_force_ref, 0)
--        ZEND_ARG_PASS_INFO(1)
--    ZEND_END_ARG_INFO()
--#else
--static unsigned char php_ssh2_first_arg_force_ref[] = { 1, BYREF_FORCE };
--#endif
-+ZEND_BEGIN_ARG_INFO(php_ssh2_first_arg_force_ref, 0)
-+    ZEND_ARG_PASS_INFO(1)
-+ZEND_END_ARG_INFO()
- /* *************
-    * Callbacks *
-@@ -248,7 +243,7 @@
- /* {{{ php_ssh2_set_callback
-  * Try to set a method if it's passed in with the hash table
-  */
--static int php_ssh2_set_callback(LIBSSH2_SESSION *session, HashTable *ht, char *callback, int callback_len, int callback_type, php_ssh2_session_data *data)
-+static int php_ssh2_set_callback(LIBSSH2_SESSION *session, HashTable *ht, char *callback, int callback_len, int callback_type, php_ssh2_session_data *data TSRMLS_DC)
- {
-       zval **handler, *copyval;
-       void *internal_handler;
-@@ -257,7 +252,7 @@
-               return 0;
-       }
--      if (!handler || !*handler || !zend_is_callable(*handler, 0, NULL)) {
-+      if (!handler || !*handler || !zend_is_callable(*handler, 0, NULL ZEND_IS_CALLABLE_TSRMLS_CC)) {
-               return -1;
-       }
-@@ -358,7 +353,7 @@
-       if (!session) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to initialize SSH2 session");
-               efree(data);
--              close(socket);
-+              closesocket(socket);
-               return NULL;
-       }
-       libssh2_banner_set(session, LIBSSH2_SSH_DEFAULT_BANNER " PHP");
-@@ -411,19 +406,19 @@
-       if (callbacks) {
-               /* ignore debug disconnect macerror */
--              if (php_ssh2_set_callback(session, HASH_OF(callbacks), "ignore", sizeof("ignore") - 1, LIBSSH2_CALLBACK_IGNORE, data)) {
-+              if (php_ssh2_set_callback(session, HASH_OF(callbacks), "ignore", sizeof("ignore") - 1, LIBSSH2_CALLBACK_IGNORE, data TSRMLS_CC)) {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed setting IGNORE callback");
-               }
--              if (php_ssh2_set_callback(session, HASH_OF(callbacks), "debug", sizeof("debug") - 1, LIBSSH2_CALLBACK_DEBUG, data)) {
-+              if (php_ssh2_set_callback(session, HASH_OF(callbacks), "debug", sizeof("debug") - 1, LIBSSH2_CALLBACK_DEBUG, data TSRMLS_CC)) {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed setting DEBUG callback");
-               }
--              if (php_ssh2_set_callback(session, HASH_OF(callbacks), "macerror", sizeof("macerror") - 1, LIBSSH2_CALLBACK_MACERROR, data)) {
-+              if (php_ssh2_set_callback(session, HASH_OF(callbacks), "macerror", sizeof("macerror") - 1, LIBSSH2_CALLBACK_MACERROR, data TSRMLS_CC)) {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed setting MACERROR callback");
-               }
--              if (php_ssh2_set_callback(session, HASH_OF(callbacks), "disconnect", sizeof("disconnect") - 1, LIBSSH2_CALLBACK_DISCONNECT, data)) {
-+              if (php_ssh2_set_callback(session, HASH_OF(callbacks), "disconnect", sizeof("disconnect") - 1, LIBSSH2_CALLBACK_DISCONNECT, data TSRMLS_CC)) {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed setting DISCONNECT callback");
-               }
-       }
-@@ -434,7 +429,7 @@
-               last_error = libssh2_session_last_error(session, &error_msg, NULL, 0);
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error starting up SSH connection(%d): %s", last_error, error_msg);
--              close(socket);
-+              closesocket(socket);
-               libssh2_session_free(session);
-               efree(data);
-               return NULL;
-@@ -1148,7 +1143,7 @@
-                       zval_ptr_dtor(&(*data)->disconnect_cb);
-               }
--              close((*data)->socket);
-+              closesocket((*data)->socket);
-               efree(*data);
-               *data = NULL;
-@@ -1274,7 +1269,7 @@
- /* {{{ ssh2_functions[]
-  */
--function_entry ssh2_functions[] = {
-+zend_function_entry ssh2_functions[] = {
-       PHP_FE(ssh2_connect,                                            NULL)
-       PHP_FE(ssh2_methods_negotiated,                         NULL)
-       PHP_FE(ssh2_fingerprint,                                        NULL)
-
-Property changes on: ssh2.c
-___________________________________________________________________
-Modified: cvs2svn:cvs-rev
-   - 1.22
-   + 1.25
-
-Index: libssh2/include/libssh2_publickey.h
-===================================================================
---- libssh2/include/libssh2_publickey.h        (.../tags/RELEASE_0_11_0)
-+++ libssh2/include/libssh2_publickey.h        (.../trunk)
-@@ -0,0 +1,101 @@
-+/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+/* Note: This include file is only needed for using the
-+ * publickey SUBSYSTEM which is not the same as publickey
-+ * authentication.  For authentication you only need libssh2.h
-+ *
-+ * For more information on the publickey subsystem,
-+ * refer to IETF draft: secsh-publickey
-+ */
-+
-+#ifndef LIBSSH2_PUBLICKEY_H
-+#define LIBSSH2_PUBLICKEY_H 1
-+
-+typedef struct _LIBSSH2_PUBLICKEY               LIBSSH2_PUBLICKEY;
-+
-+typedef struct _libssh2_publickey_attribute {
-+    const char *name;
-+    unsigned long name_len;
-+    const char *value;
-+    unsigned long value_len;
-+    char mandatory;
-+} libssh2_publickey_attribute;
-+
-+typedef struct _libssh2_publickey_list {
-+    unsigned char *packet; /* For freeing */
-+
-+    const unsigned char *name;
-+    unsigned long name_len;
-+    const unsigned char *blob;
-+    unsigned long blob_len;
-+    unsigned long num_attrs;
-+    libssh2_publickey_attribute *attrs; /* free me */
-+} libssh2_publickey_list;
-+
-+/* Generally use the first macro here, but if both name and value are string literals, you can use _fast() to take advantage of preprocessing */
-+#define libssh2_publickey_attribute(name, value, mandatory)         { (name), strlen(name), (value), strlen(value), (mandatory) },
-+#define libssh2_publickey_attribute_fast(name, value, mandatory)    { (name), sizeof(name) - 1, (value), sizeof(value) - 1, (mandatory) },
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/* Publickey Subsystem */
-+LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session);
-+
-+LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len,
-+                                                            const unsigned char *blob, unsigned long blob_len, char overwrite,
-+                                                            unsigned long num_attrs, const libssh2_publickey_attribute attrs[]);
-+#define libssh2_publickey_add(pkey, name, blob, blob_len, overwrite, num_attrs, attrs) \
-+        libssh2_publickey_add_ex((pkey), (name), strlen(name), (blob), (blob_len), (overwrite), (num_attrs), (attrs))
-+
-+LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len,
-+                                                            const unsigned char *blob, unsigned long blob_len);
-+#define libssh2_publickey_remove(pkey, name, blob, blob_len) \
-+        libssh2_publickey_remove_ex((pkey), (name), strlen(name), (blob), (blob_len))
-+
-+LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, libssh2_publickey_list **pkey_list);
-+LIBSSH2_API void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey, libssh2_publickey_list *pkey_list);
-+
-+LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey);
-+
-+#ifdef __cplusplus
-+} /* extern "C" */
-+#endif
-+
-+#endif /* ndef: LIBSSH2_PUBLICKEY_H */
-
-Property changes on: libssh2/include/libssh2_publickey.h
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.2
-Added: svn:eol-style
-   + native
-
-Index: libssh2/include/libssh2_sftp.h
-===================================================================
---- libssh2/include/libssh2_sftp.h     (.../tags/RELEASE_0_11_0)
-+++ libssh2/include/libssh2_sftp.h     (.../trunk)
-@@ -0,0 +1,251 @@
-+/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#ifndef LIBSSH2_SFTP_H
-+#define LIBSSH2_SFTP_H 1
-+
-+#ifndef WIN32
-+#include <unistd.h>
-+#endif
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/* Note: Version 6 was documented at the time of writing
-+ * However it was marked as "DO NOT IMPLEMENT" due to pending changes
-+ *
-+ * Let's start with Version 3 (The version found in OpenSSH) and go from there
-+ */
-+#define LIBSSH2_SFTP_VERSION        3
-+#define LIBSSH2_SFTP_PACKET_MAXLEN  40000
-+
-+typedef struct _LIBSSH2_SFTP                LIBSSH2_SFTP;
-+typedef struct _LIBSSH2_SFTP_HANDLE         LIBSSH2_SFTP_HANDLE;
-+typedef struct _LIBSSH2_SFTP_ATTRIBUTES     LIBSSH2_SFTP_ATTRIBUTES;
-+
-+/* Flags for open_ex() */
-+#define LIBSSH2_SFTP_OPENFILE           0
-+#define LIBSSH2_SFTP_OPENDIR            1
-+
-+/* Flags for rename_ex() */
-+#define LIBSSH2_SFTP_RENAME_OVERWRITE   0x00000001
-+#define LIBSSH2_SFTP_RENAME_ATOMIC      0x00000002
-+#define LIBSSH2_SFTP_RENAME_NATIVE      0x00000004
-+
-+/* Flags for stat_ex() */
-+#define LIBSSH2_SFTP_STAT               0
-+#define LIBSSH2_SFTP_LSTAT              1
-+#define LIBSSH2_SFTP_SETSTAT            2
-+
-+/* Flags for symlink_ex() */
-+#define LIBSSH2_SFTP_SYMLINK            0
-+#define LIBSSH2_SFTP_READLINK           1
-+#define LIBSSH2_SFTP_REALPATH           2
-+
-+/* SFTP attribute flag bits */
-+#define LIBSSH2_SFTP_ATTR_SIZE              0x00000001
-+#define LIBSSH2_SFTP_ATTR_UIDGID            0x00000002
-+#define LIBSSH2_SFTP_ATTR_PERMISSIONS       0x00000004
-+#define LIBSSH2_SFTP_ATTR_ACMODTIME         0x00000008
-+#define LIBSSH2_SFTP_ATTR_EXTENDED          0x80000000
-+
-+struct _LIBSSH2_SFTP_ATTRIBUTES {
-+    /* If flags & ATTR_* bit is set, then the value in this struct will be meaningful
-+     * Otherwise it should be ignored
-+     */
-+    unsigned long flags;
-+
-+    libssh2_uint64_t filesize;
-+    unsigned long uid, gid;
-+    unsigned long permissions;
-+    unsigned long atime, mtime;
-+};
-+
-+/* SFTP filetypes */
-+#define LIBSSH2_SFTP_TYPE_REGULAR           1
-+#define LIBSSH2_SFTP_TYPE_DIRECTORY         2
-+#define LIBSSH2_SFTP_TYPE_SYMLINK           3
-+#define LIBSSH2_SFTP_TYPE_SPECIAL           4
-+#define LIBSSH2_SFTP_TYPE_UNKNOWN           5
-+#define LIBSSH2_SFTP_TYPE_SOCKET            6
-+#define LIBSSH2_SFTP_TYPE_CHAR_DEVICE       7
-+#define LIBSSH2_SFTP_TYPE_BLOCK_DEVICE      8
-+#define LIBSSH2_SFTP_TYPE_FIFO              9
-+
-+/*
-+ * Reproduce the POSIX file modes here for systems that are not
-+ * POSIX compliant.  
-+ *
-+ * These is used in "permissions" of "struct _LIBSSH2_SFTP_ATTRIBUTES"
-+ */
-+/* File type */
-+#define LIBSSH2_SFTP_S_IFMT         0170000     /* type of file mask */
-+#define LIBSSH2_SFTP_S_IFIFO        0010000     /* named pipe (fifo) */
-+#define LIBSSH2_SFTP_S_IFCHR        0020000     /* character special */
-+#define LIBSSH2_SFTP_S_IFDIR        0040000     /* directory */
-+#define LIBSSH2_SFTP_S_IFBLK        0060000     /* block special */
-+#define LIBSSH2_SFTP_S_IFREG        0100000     /* regular */
-+#define LIBSSH2_SFTP_S_IFLNK        0120000     /* symbolic link */
-+#define LIBSSH2_SFTP_S_IFSOCK       0140000     /* socket */
-+
-+/* File mode */
-+/* Read, write, execute/search by owner */
-+#define LIBSSH2_SFTP_S_IRWXU        0000700     /* RWX mask for owner */
-+#define LIBSSH2_SFTP_S_IRUSR        0000400     /* R for owner */
-+#define LIBSSH2_SFTP_S_IWUSR        0000200     /* W for owner */
-+#define LIBSSH2_SFTP_S_IXUSR        0000100     /* X for owner */
-+/* Read, write, execute/search by group */
-+#define LIBSSH2_SFTP_S_IRWXG        0000070     /* RWX mask for group */
-+#define LIBSSH2_SFTP_S_IRGRP        0000040     /* R for group */
-+#define LIBSSH2_SFTP_S_IWGRP        0000020     /* W for group */
-+#define LIBSSH2_SFTP_S_IXGRP        0000010     /* X for group */
-+/* Read, write, execute/search by others */
-+#define LIBSSH2_SFTP_S_IRWXO        0000007     /* RWX mask for other */
-+#define LIBSSH2_SFTP_S_IROTH        0000004     /* R for other */
-+#define LIBSSH2_SFTP_S_IWOTH        0000002     /* W for other */
-+#define LIBSSH2_SFTP_S_IXOTH        0000001     /* X for other */
-+
-+/* SFTP File Transfer Flags -- (e.g. flags parameter to sftp_open())
-+ * Danger will robinson... APPEND doesn't have any effect on OpenSSH servers */
-+#define LIBSSH2_FXF_READ                        0x00000001
-+#define LIBSSH2_FXF_WRITE                       0x00000002
-+#define LIBSSH2_FXF_APPEND                      0x00000004
-+#define LIBSSH2_FXF_CREAT                       0x00000008
-+#define LIBSSH2_FXF_TRUNC                       0x00000010
-+#define LIBSSH2_FXF_EXCL                        0x00000020
-+
-+/* SFTP Status Codes (returned by libssh2_sftp_last_error() ) */
-+#define LIBSSH2_FX_OK                       0
-+#define LIBSSH2_FX_EOF                      1
-+#define LIBSSH2_FX_NO_SUCH_FILE             2
-+#define LIBSSH2_FX_PERMISSION_DENIED        3
-+#define LIBSSH2_FX_FAILURE                  4
-+#define LIBSSH2_FX_BAD_MESSAGE              5
-+#define LIBSSH2_FX_NO_CONNECTION            6
-+#define LIBSSH2_FX_CONNECTION_LOST          7
-+#define LIBSSH2_FX_OP_UNSUPPORTED           8
-+#define LIBSSH2_FX_INVALID_HANDLE           9
-+#define LIBSSH2_FX_NO_SUCH_PATH             10
-+#define LIBSSH2_FX_FILE_ALREADY_EXISTS      11
-+#define LIBSSH2_FX_WRITE_PROTECT            12
-+#define LIBSSH2_FX_NO_MEDIA                 13
-+#define LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM   14
-+#define LIBSSH2_FX_QUOTA_EXCEEDED           15
-+#define LIBSSH2_FX_UNKNOWN_PRINCIPLE        16 /* Initial mis-spelling */
-+#define LIBSSH2_FX_UNKNOWN_PRINCIPAL        16
-+#define LIBSSH2_FX_LOCK_CONFlICT            17 /* Initial mis-spelling */
-+#define LIBSSH2_FX_LOCK_CONFLICT            17
-+#define LIBSSH2_FX_DIR_NOT_EMPTY            18
-+#define LIBSSH2_FX_NOT_A_DIRECTORY          19
-+#define LIBSSH2_FX_INVALID_FILENAME         20
-+#define LIBSSH2_FX_LINK_LOOP                21
-+
-+/* Returned by any function that would block during a read/write opperation */
-+#define LIBSSH2SFTP_EAGAIN LIBSSH2_ERROR_EAGAIN
-+
-+/* SFTP API */
-+LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session);
-+LIBSSH2_API int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp);
-+LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp);
-+
-+/* File / Directory Ops */
-+LIBSSH2_API LIBSSH2_SFTP_HANDLE *libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len,
-+                                                      unsigned long flags, long mode, int open_type);
-+#define libssh2_sftp_open(sftp, filename, flags, mode) \
-+                    libssh2_sftp_open_ex((sftp), (filename), strlen(filename), (flags), (mode), LIBSSH2_SFTP_OPENFILE)
-+#define libssh2_sftp_opendir(sftp, path) \
-+                    libssh2_sftp_open_ex((sftp), (path), strlen(path), 0, 0, LIBSSH2_SFTP_OPENDIR)
-+
-+LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen);
-+
-+LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen, 
-+                                        char *longentry, size_t longentry_maxlen, 
-+                                        LIBSSH2_SFTP_ATTRIBUTES *attrs);
-+#define libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs) \
-+                    libssh2_sftp_readdir_ex((handle), (buffer), (buffer_maxlen), NULL, 0, (attrs))
-+
-+LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer, size_t count);
-+
-+LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle);
-+#define libssh2_sftp_close(handle)                  libssh2_sftp_close_handle(handle)
-+#define libssh2_sftp_closedir(handle)               libssh2_sftp_close_handle(handle)
-+
-+LIBSSH2_API void libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset);
-+LIBSSH2_API void libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, libssh2_uint64_t offset);
-+#define libssh2_sftp_rewind(handle)         libssh2_sftp_seek64((handle), 0)
-+
-+LIBSSH2_API size_t libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle);
-+LIBSSH2_API libssh2_uint64_t libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle);
-+
-+LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat);
-+#define libssh2_sftp_fstat(handle, attrs)               libssh2_sftp_fstat_ex((handle), (attrs), 0)
-+#define libssh2_sftp_fsetstat(handle, attrs)            libssh2_sftp_fstat_ex((handle), (attrs), 1)
-+
-+
-+
-+/* Miscellaneous Ops */
-+LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp,  const char *source_filename,    unsigned int srouce_filename_len,
-+                                                            const char *dest_filename,      unsigned int dest_filename_len,
-+                                                            long flags);
-+#define libssh2_sftp_rename(sftp, sourcefile, destfile)     libssh2_sftp_rename_ex((sftp), (sourcefile), strlen(sourcefile), (destfile), strlen(destfile), \
-+                                                            LIBSSH2_SFTP_RENAME_OVERWRITE | LIBSSH2_SFTP_RENAME_ATOMIC | LIBSSH2_SFTP_RENAME_NATIVE)
-+
-+LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len);
-+#define libssh2_sftp_unlink(sftp, filename)                 libssh2_sftp_unlink_ex((sftp), (filename), strlen(filename))
-+
-+LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, long mode);
-+#define libssh2_sftp_mkdir(sftp, path, mode)                libssh2_sftp_mkdir_ex((sftp), (path), strlen(path), (mode))
-+
-+LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len);
-+#define libssh2_sftp_rmdir(sftp, path)                      libssh2_sftp_rmdir_ex((sftp), (path), strlen(path))
-+
-+LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, int stat_type, LIBSSH2_SFTP_ATTRIBUTES *attrs);
-+#define libssh2_sftp_stat(sftp, path, attrs)                libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_STAT, (attrs))
-+#define libssh2_sftp_lstat(sftp, path, attrs)               libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_LSTAT, (attrs))
-+#define libssh2_sftp_setstat(sftp, path, attrs)             libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_SETSTAT, (attrs))
-+
-+LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, char *target, unsigned int target_len, int link_type);
-+#define libssh2_sftp_symlink(sftp, orig, linkpath)          libssh2_sftp_symlink_ex((sftp), (orig), strlen(orig), (linkpath), strlen(linkpath), LIBSSH2_SFTP_SYMLINK)
-+#define libssh2_sftp_readlink(sftp, path, target, maxlen)   libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), LIBSSH2_SFTP_READLINK)
-+#define libssh2_sftp_realpath(sftp, path, target, maxlen)   libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), LIBSSH2_SFTP_REALPATH)
-+
-+#ifdef __cplusplus
-+} /* extern "C" */
-+#endif
-+
-+#endif /* LIBSSH2_SFTP_H */
-
-Property changes on: libssh2/include/libssh2_sftp.h
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.2
-Added: svn:eol-style
-   + native
-
-Index: libssh2/include/libssh2.h
-===================================================================
---- libssh2/include/libssh2.h  (.../tags/RELEASE_0_11_0)
-+++ libssh2/include/libssh2.h  (.../trunk)
-@@ -0,0 +1,489 @@
-+/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#ifndef LIBSSH2_H
-+#define LIBSSH2_H 1
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#include <stddef.h>
-+#include <string.h>
-+#include <sys/stat.h>
-+#include <sys/types.h>
-+
-+/* Allow alternate API prefix from CFLAGS or calling app */
-+#ifndef LIBSSH2_API
-+# ifdef LIBSSH2_WIN32
-+#  ifdef LIBSSH2_LIBRARY
-+#   define LIBSSH2_API __declspec(dllexport)
-+#  else
-+#   define LIBSSH2_API __declspec(dllimport)
-+#  endif /* LIBSSH2_LIBRARY */
-+# else /* !LIBSSH2_WIN32 */
-+#  define LIBSSH2_API
-+# endif /* LIBSSH2_WIN32 */
-+#endif /* LIBSSH2_API */
-+
-+#if defined(LIBSSH2_DARWIN) || (defined(LIBSSH2_WIN32) && !defined(_MSC_VER) && !defined(__MINGW32__))
-+# include <sys/uio.h>
-+#endif
-+
-+#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
-+# include <sys/bsdskt.h>
-+typedef unsigned int uint32_t;
-+#endif
-+
-+#if defined(LIBSSH2_WIN32) && defined(_MSC_VER) && (_MSC_VER <= 1400)
-+typedef unsigned __int64 libssh2_uint64_t;
-+typedef __int64 libssh2_int64_t;
-+typedef unsigned int uint32_t;
-+#ifndef _SSIZE_T_DEFINED
-+typedef int ssize_t;
-+#define _SSIZE_T_DEFINED
-+#endif
-+#else
-+typedef unsigned long long libssh2_uint64_t;
-+typedef long long libssh2_int64_t;
-+#endif
-+
-+/* We use underscore instead of dash when appending CVS in dev versions just
-+   to make the BANNER define (used by src/session.c) be a valid SSH
-+   banner. Release versions have no appended strings and may of coruse not
-+   have dashes either. */
-+#define LIBSSH2_VERSION "1.0"
-+
-+/* The numeric version number is also available "in parts" by using these
-+   defines: */
-+#define LIBSSH2_VERSION_MAJOR 1
-+#define LIBSSH2_VERSION_MINOR 0
-+#define LIBSSH2_VERSION_PATCH 
-+
-+/* This is the numeric version of the libssh2 version number, meant for easier
-+   parsing and comparions by programs. The LIBSSH2_VERSION_NUM define will
-+   always follow this syntax:
-+
-+         0xXXYYZZ
-+
-+   Where XX, YY and ZZ are the main version, release and patch numbers in
-+   hexadecimal (using 8 bits each). All three numbers are always represented
-+   using two digits.  1.2 would appear as "0x010200" while version 9.11.7
-+   appears as "0x090b07".
-+
-+   This 6-digit (24 bits) hexadecimal number does not show pre-release number,
-+   and it is always a greater number in a more recent release. It makes
-+   comparisons with greater than and less than work.
-+*/
-+#define LIBSSH2_VERSION_NUM 0x010000
-+
-+/*
-+ * This is the date and time when the full source package was created. The
-+ * timestamp is not stored in CVS, as the timestamp is properly set in the
-+ * tarballs by the maketgz script.
-+ *
-+ * The format of the date should follow this template:
-+ *
-+ * "Mon Feb 12 11:35:33 UTC 2007"
-+ */
-+#define LIBSSH2_TIMESTAMP "Fri Dec 26 21:35:07 UTC 2008"
-+
-+/* Part of every banner, user specified or not */
-+#define LIBSSH2_SSH_BANNER                  "SSH-2.0-libssh2_" LIBSSH2_VERSION
-+
-+/* We *could* add a comment here if we so chose */
-+#define LIBSSH2_SSH_DEFAULT_BANNER                  LIBSSH2_SSH_BANNER
-+#define LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF        LIBSSH2_SSH_DEFAULT_BANNER "\r\n"
-+
-+/* Default generate and safe prime sizes for diffie-hellman-group-exchange-sha1 */
-+#define LIBSSH2_DH_GEX_MINGROUP     1024
-+#define LIBSSH2_DH_GEX_OPTGROUP     1536
-+#define LIBSSH2_DH_GEX_MAXGROUP     2048
-+
-+/* Defaults for pty requests */
-+#define LIBSSH2_TERM_WIDTH      80
-+#define LIBSSH2_TERM_HEIGHT     24
-+#define LIBSSH2_TERM_WIDTH_PX   0
-+#define LIBSSH2_TERM_HEIGHT_PX  0
-+
-+/* 1/4 second */
-+#define LIBSSH2_SOCKET_POLL_UDELAY      250000
-+/* 0.25 * 120 == 30 seconds */
-+#define LIBSSH2_SOCKET_POLL_MAXLOOPS    120
-+
-+/* Maximum size to allow a payload to compress to, plays it safe by falling short of spec limits */
-+#define LIBSSH2_PACKET_MAXCOMP      32000
-+
-+/* Maximum size to allow a payload to deccompress to, plays it safe by allowing more than spec requires */
-+#define LIBSSH2_PACKET_MAXDECOMP    40000
-+
-+/* Maximum size for an inbound compressed payload, plays it safe by overshooting spec limits */
-+#define LIBSSH2_PACKET_MAXPAYLOAD   40000
-+
-+/* Malloc callbacks */
-+#define LIBSSH2_ALLOC_FUNC(name)                    void *name(size_t count, void **abstract)
-+#define LIBSSH2_REALLOC_FUNC(name)                  void *name(void *ptr, size_t count, void **abstract)
-+#define LIBSSH2_FREE_FUNC(name)                     void name(void *ptr, void **abstract)
-+
-+typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT
-+{
-+    char* text;
-+    unsigned int length;
-+    unsigned char echo;
-+} LIBSSH2_USERAUTH_KBDINT_PROMPT;
-+
-+typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE
-+{
-+    char* text;
-+    unsigned int length;
-+} LIBSSH2_USERAUTH_KBDINT_RESPONSE;
-+
-+/* 'keyboard-interactive' authentication callback */
-+#define LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC(name_) void name_(const char* name, int name_len, const char* instruction, int instruction_len, int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses, void **abstract)
-+
-+/* Callbacks for special SSH packets */
-+#define LIBSSH2_IGNORE_FUNC(name)                   void name(LIBSSH2_SESSION *session, const char *message, int message_len, void **abstract)
-+#define LIBSSH2_DEBUG_FUNC(name)                    void name(LIBSSH2_SESSION *session, int always_display, const char *message, int message_len, const char *language, int language_len,void **abstract)
-+#define LIBSSH2_DISCONNECT_FUNC(name)               void name(LIBSSH2_SESSION *session, int reason, const char *message, int message_len, const char *language, int language_len, void **abstract)
-+#define LIBSSH2_PASSWD_CHANGEREQ_FUNC(name)         void name(LIBSSH2_SESSION *session, char **newpw, int *newpw_len, void **abstract)
-+#define LIBSSH2_MACERROR_FUNC(name)                 int  name(LIBSSH2_SESSION *session, const char *packet, int packet_len, void **abstract)
-+#define LIBSSH2_X11_OPEN_FUNC(name)                 void name(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, const char *shost, int sport, void **abstract)
-+
-+#define LIBSSH2_CHANNEL_CLOSE_FUNC(name)            void name(LIBSSH2_SESSION *session, void **session_abstract, LIBSSH2_CHANNEL *channel, void **channel_abstract)
-+
-+/* libssh2_session_callback_set() constants */
-+#define LIBSSH2_CALLBACK_IGNORE             0
-+#define LIBSSH2_CALLBACK_DEBUG              1
-+#define LIBSSH2_CALLBACK_DISCONNECT         2
-+#define LIBSSH2_CALLBACK_MACERROR           3
-+#define LIBSSH2_CALLBACK_X11                4
-+
-+/* libssh2_session_method_pref() constants */
-+#define LIBSSH2_METHOD_KEX          0
-+#define LIBSSH2_METHOD_HOSTKEY      1
-+#define LIBSSH2_METHOD_CRYPT_CS     2
-+#define LIBSSH2_METHOD_CRYPT_SC     3
-+#define LIBSSH2_METHOD_MAC_CS       4
-+#define LIBSSH2_METHOD_MAC_SC       5
-+#define LIBSSH2_METHOD_COMP_CS      6
-+#define LIBSSH2_METHOD_COMP_SC      7
-+#define LIBSSH2_METHOD_LANG_CS      8
-+#define LIBSSH2_METHOD_LANG_SC      9
-+
-+/* session.flags bits */
-+#define LIBSSH2_FLAG_SIGPIPE        0x00000001
-+
-+typedef struct _LIBSSH2_SESSION                     LIBSSH2_SESSION;
-+typedef struct _LIBSSH2_CHANNEL                     LIBSSH2_CHANNEL;
-+typedef struct _LIBSSH2_LISTENER                    LIBSSH2_LISTENER;
-+
-+typedef struct _LIBSSH2_POLLFD {
-+    unsigned char type; /* LIBSSH2_POLLFD_* below */
-+
-+    union {
-+        int socket; /* File descriptors -- examined with system select() call */
-+        LIBSSH2_CHANNEL *channel; /* Examined by checking internal state */
-+        LIBSSH2_LISTENER *listener; /* Read polls only -- are inbound connections waiting to be accepted? */
-+    } fd;
-+
-+    unsigned long events; /* Requested Events */
-+    unsigned long revents; /* Returned Events */
-+} LIBSSH2_POLLFD;
-+
-+/* Poll FD Descriptor Types */
-+#define LIBSSH2_POLLFD_SOCKET       1
-+#define LIBSSH2_POLLFD_CHANNEL      2
-+#define LIBSSH2_POLLFD_LISTENER     3
-+
-+/* Note: Win32 Doesn't actually have a poll() implementation, so some of these values are faked with select() data */
-+/* Poll FD events/revents -- Match sys/poll.h where possible */
-+#define LIBSSH2_POLLFD_POLLIN           0x0001      /* Data available to be read or connection available -- All */
-+#define LIBSSH2_POLLFD_POLLPRI          0x0002      /* Priority data available to be read -- Socket only */
-+#define LIBSSH2_POLLFD_POLLEXT          0x0002      /* Extended data available to be read -- Channel only */
-+#define LIBSSH2_POLLFD_POLLOUT          0x0004      /* Can may be written -- Socket/Channel */
-+/* revents only */
-+#define LIBSSH2_POLLFD_POLLERR          0x0008      /* Error Condition -- Socket */
-+#define LIBSSH2_POLLFD_POLLHUP          0x0010      /* HangUp/EOF -- Socket */
-+#define LIBSSH2_POLLFD_SESSION_CLOSED   0x0010      /* Session Disconnect */
-+#define LIBSSH2_POLLFD_POLLNVAL         0x0020      /* Invalid request -- Socket Only */
-+#define LIBSSH2_POLLFD_POLLEX           0x0040      /* Exception Condition -- Socket/Win32 */
-+#define LIBSSH2_POLLFD_CHANNEL_CLOSED   0x0080      /* Channel Disconnect */
-+#define LIBSSH2_POLLFD_LISTENER_CLOSED  0x0080      /* Listener Disconnect */
-+
-+#define HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
-+/* Block Direction Types */
-+#define LIBSSH2_SESSION_BLOCK_INBOUND                  0x0001
-+#define LIBSSH2_SESSION_BLOCK_OUTBOUND                 0x0002
-+
-+/* Hash Types */
-+#define LIBSSH2_HOSTKEY_HASH_MD5                            1
-+#define LIBSSH2_HOSTKEY_HASH_SHA1                           2
-+
-+/* Disconnect Codes (defined by SSH protocol) */
-+#define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT          1
-+#define SSH_DISCONNECT_PROTOCOL_ERROR                       2
-+#define SSH_DISCONNECT_KEY_EXCHANGE_FAILED                  3
-+#define SSH_DISCONNECT_RESERVED                             4
-+#define SSH_DISCONNECT_MAC_ERROR                            5
-+#define SSH_DISCONNECT_COMPRESSION_ERROR                    6
-+#define SSH_DISCONNECT_SERVICE_NOT_AVAILABLE                7
-+#define SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED       8
-+#define SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE              9
-+#define SSH_DISCONNECT_CONNECTION_LOST                      10
-+#define SSH_DISCONNECT_BY_APPLICATION                       11
-+#define SSH_DISCONNECT_TOO_MANY_CONNECTIONS                 12
-+#define SSH_DISCONNECT_AUTH_CANCELLED_BY_USER               13
-+#define SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE       14
-+#define SSH_DISCONNECT_ILLEGAL_USER_NAME                    15
-+
-+/* Error Codes (defined by libssh2) */
-+#define LIBSSH2_ERROR_NONE                      0
-+#define LIBSSH2_ERROR_SOCKET_NONE               -1
-+#define LIBSSH2_ERROR_BANNER_NONE               -2
-+#define LIBSSH2_ERROR_BANNER_SEND               -3
-+#define LIBSSH2_ERROR_INVALID_MAC               -4
-+#define LIBSSH2_ERROR_KEX_FAILURE               -5
-+#define LIBSSH2_ERROR_ALLOC                     -6
-+#define LIBSSH2_ERROR_SOCKET_SEND               -7
-+#define LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE      -8
-+#define LIBSSH2_ERROR_TIMEOUT                   -9
-+#define LIBSSH2_ERROR_HOSTKEY_INIT              -10
-+#define LIBSSH2_ERROR_HOSTKEY_SIGN              -11
-+#define LIBSSH2_ERROR_DECRYPT                   -12
-+#define LIBSSH2_ERROR_SOCKET_DISCONNECT         -13
-+#define LIBSSH2_ERROR_PROTO                     -14
-+#define LIBSSH2_ERROR_PASSWORD_EXPIRED          -15
-+#define LIBSSH2_ERROR_FILE                      -16
-+#define LIBSSH2_ERROR_METHOD_NONE               -17
-+#define LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED    -18
-+#define LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED      -19
-+#define LIBSSH2_ERROR_CHANNEL_OUTOFORDER        -20
-+#define LIBSSH2_ERROR_CHANNEL_FAILURE           -21
-+#define LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED    -22
-+#define LIBSSH2_ERROR_CHANNEL_UNKNOWN           -23
-+#define LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED   -24
-+#define LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED   -25
-+#define LIBSSH2_ERROR_CHANNEL_CLOSED            -26
-+#define LIBSSH2_ERROR_CHANNEL_EOF_SENT          -27
-+#define LIBSSH2_ERROR_SCP_PROTOCOL              -28
-+#define LIBSSH2_ERROR_ZLIB                      -29
-+#define LIBSSH2_ERROR_SOCKET_TIMEOUT            -30
-+#define LIBSSH2_ERROR_SFTP_PROTOCOL             -31
-+#define LIBSSH2_ERROR_REQUEST_DENIED            -32
-+#define LIBSSH2_ERROR_METHOD_NOT_SUPPORTED      -33
-+#define LIBSSH2_ERROR_INVAL                     -34
-+#define LIBSSH2_ERROR_INVALID_POLL_TYPE         -35
-+#define LIBSSH2_ERROR_PUBLICKEY_PROTOCOL        -36
-+#define LIBSSH2_ERROR_EAGAIN                    -37
-+
-+/* Session API */
-+LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)), LIBSSH2_FREE_FUNC((*my_free)), LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract);
-+#define libssh2_session_init()                      libssh2_session_init_ex(NULL, NULL, NULL, NULL)
-+LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session);
-+
-+LIBSSH2_API void *libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbtype, void *callback);
-+LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner);
-+
-+LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int sock);
-+LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, const char *description, const char *lang);
-+#define libssh2_session_disconnect(session, description)    libssh2_session_disconnect_ex((session), SSH_DISCONNECT_BY_APPLICATION, (description), "")
-+LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session);
-+
-+LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session, int hash_type);
-+
-+LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session, int method_type, const char *prefs);
-+LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, int method_type);
-+LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf);
-+LIBSSH2_API int libssh2_session_last_errno(LIBSSH2_SESSION *session);
-+LIBSSH2_API int libssh2_session_block_directions(LIBSSH2_SESSION *session);
-+
-+LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int value);
-+
-+/* Userauth API */
-+LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, const char *username, unsigned int username_len);
-+LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session);
-+LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, const char *password, unsigned int password_len, LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb)));
-+#define libssh2_userauth_password(session, username, password)  libssh2_userauth_password_ex((session), (username), strlen(username), (password), strlen(password), NULL)
-+
-+LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len,
-+                                                                                 const char *publickey, const char *privatekey,
-+                                                                                 const char *passphrase);
-+#define libssh2_userauth_publickey_fromfile(session, username, publickey, privatekey, passphrase)   \
-+        libssh2_userauth_publickey_fromfile_ex((session), (username), strlen(username), (publickey), (privatekey), (passphrase))
-+LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len,
-+                                                                                 const char *publickey, const char *privatekey,
-+                                                                                 const char *passphrase,
-+                                                                                 const char *hostname, unsigned int hostname_len,
-+                                                                                 const char *local_username, unsigned int local_username_len);
-+#define libssh2_userauth_hostbased_fromfile(session, username, publickey, privatekey, passphrase, hostname) \
-+        libssh2_userauth_hostbased_fromfile_ex((session), (username), strlen(username), (publickey), (privatekey), (passphrase), (hostname), strlen(hostname), (username), strlen(username))
-+
-+/*
-+ * response_callback is provided with filled by library prompts array,
-+ * but client must allocate and fill individual responses. Responses
-+ * array is already allocated. Responses data will be freed by libssh2
-+ * after callback return, but before subsequent callback invokation.
-+ */
-+LIBSSH2_API int libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION* session, const char *username, unsigned int username_len,
-+                                                         LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback)));
-+#define libssh2_userauth_keyboard_interactive(session, username, response_callback) \
-+        libssh2_userauth_keyboard_interactive_ex((session), (username), strlen(username), (response_callback))
-+
-+LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout);
-+
-+/* Channel API */
-+#define LIBSSH2_CHANNEL_WINDOW_DEFAULT  65536
-+#define LIBSSH2_CHANNEL_PACKET_DEFAULT  16384
-+#define LIBSSH2_CHANNEL_MINADJUST       1024
-+
-+/* Extended Data Handling */
-+#define LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL        0
-+#define LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE        1
-+#define LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE         2
-+
-+#define SSH_EXTENDED_DATA_STDERR 1
-+
-+/* Returned by any function that would block during a read/write opperation */
-+#define LIBSSH2CHANNEL_EAGAIN LIBSSH2_ERROR_EAGAIN
-+
-+LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, unsigned int channel_type_len, unsigned int window_size, unsigned int packet_size, const char *message, unsigned int message_len);
-+#define libssh2_channel_open_session(session)   libssh2_channel_open_ex((session), "session", sizeof("session") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0)
-+
-+LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, int port, const char *shost, int sport);
-+#define libssh2_channel_direct_tcpip(session, host, port)   libssh2_channel_direct_tcpip_ex((session), (host), (port), "127.0.0.1", 22)
-+
-+LIBSSH2_API LIBSSH2_LISTENER *libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, int port, int *bound_port, int queue_maxsize);
-+#define libssh2_channel_forward_listen(session, port)           libssh2_channel_forward_listen_ex((session), NULL, (port), NULL, 16)
-+
-+LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener);
-+
-+LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener);
-+
-+LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, const char *varname, unsigned int varname_len, const char *value, unsigned int value_len);
-+#define libssh2_channel_setenv(channel, varname, value) libssh2_channel_setenv_ex((channel), (varname), strlen(varname), (value), strlen(value))
-+
-+LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, unsigned int term_len, const char *modes, unsigned int modes_len, int width, int height, int width_px, int height_px);
-+#define libssh2_channel_request_pty(channel, term)  libssh2_channel_request_pty_ex((channel), (term), strlen(term), NULL, 0, LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX)
-+
-+LIBSSH2_API int libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL * channel, int width, int height, int width_px, int height_px);
-+#define libssh2_channel_request_pty_size(channel, width, height) libssh2_channel_request_pty_size_ex( (channel), (width), (height), 0, 0)
-+
-+LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, const char *auth_proto, const char *auth_cookie, int screen_number);
-+#define libssh2_channel_x11_req(channel, screen_number) libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number))
-+
-+LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const char *request, unsigned int request_len, const char *message, unsigned int message_len);
-+#define libssh2_channel_shell(channel)                  libssh2_channel_process_startup((channel), "shell", sizeof("shell") - 1, NULL, 0)
-+#define libssh2_channel_exec(channel, command)          libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, (command), strlen(command))
-+#define libssh2_channel_subsystem(channel, subsystem)   libssh2_channel_process_startup((channel), "subsystem", sizeof("subsystem") - 1, (subsystem), strlen(subsystem))
-+
-+LIBSSH2_API ssize_t libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen);
-+#define libssh2_channel_read(channel, buf, buflen) \
-+                                libssh2_channel_read_ex((channel), 0, (buf), (buflen))
-+#define libssh2_channel_read_stderr(channel, buf, buflen) \
-+                                libssh2_channel_read_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
-+
-+LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended);
-+
-+LIBSSH2_API unsigned long libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel, unsigned long *read_avail, unsigned long *window_size_initial);
-+#define libssh2_channel_window_read(channel) \
-+            libssh2_channel_window_read_ex((channel), NULL, NULL)
-+
-+LIBSSH2_API unsigned long libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, unsigned long adjustment, unsigned char force);
-+
-+LIBSSH2_API ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id, const char *buf, size_t buflen);
-+
-+#define libssh2_channel_write(channel, buf, buflen) \
-+                                libssh2_channel_write_ex((channel), 0, (buf), (buflen))
-+#define libssh2_channel_write_stderr(channel, buf, buflen)  \
-+                                libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
-+
-+LIBSSH2_API unsigned long libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, unsigned long *window_size_initial);
-+#define libssh2_channel_window_write(channel)           libssh2_channel_window_write_ex((channel), NULL)
-+
-+LIBSSH2_API void libssh2_session_set_blocking(LIBSSH2_SESSION* session, int blocking);
-+LIBSSH2_API int libssh2_session_get_blocking(LIBSSH2_SESSION* session);
-+
-+LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking);
-+
-+LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode);
-+LIBSSH2_API int libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel, int ignore_mode);
-+/* libssh2_channel_ignore_extended_data() is defined below for BC with version 0.1
-+ * Future uses should use libssh2_channel_handle_extended_data() directly
-+ * if LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE is passed, extended data will be read (FIFO) from the standard data channel
-+ */
-+/* DEPRECATED */
-+#define libssh2_channel_ignore_extended_data(channel, ignore)       libssh2_channel_handle_extended_data((channel), (ignore) ? LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE : LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL )
-+
-+#define LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA     -1
-+#define LIBSSH2_CHANNEL_FLUSH_ALL               -2
-+LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int streamid);
-+#define libssh2_channel_flush(channel)          libssh2_channel_flush_ex((channel), 0)
-+#define libssh2_channel_flush_stderr(channel)   libssh2_channel_flush_ex((channel), SSH_EXTENDED_DATA_STDERR)
-+LIBSSH2_API int libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel);
-+
-+LIBSSH2_API int libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel);
-+LIBSSH2_API int libssh2_channel_eof(LIBSSH2_CHANNEL *channel);
-+LIBSSH2_API int libssh2_channel_wait_eof(LIBSSH2_CHANNEL *channel);
-+LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel);
-+LIBSSH2_API int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel);
-+LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel);
-+
-+LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat *sb);
-+LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t size, long mtime, long atime);
-+#define libssh2_scp_send(session, path, mode, size)                 libssh2_scp_send_ex((session), (path), (mode), (size), 0, 0)
-+
-+LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **dest, unsigned int *dest_len, const char *src, unsigned int src_len);
-+
-+/* NOTE NOTE NOTE
-+   libssh2_trace() has no function in builds that aren't built with debug
-+   enabled
-+ */
-+LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask);
-+#define LIBSSH2_TRACE_TRANS (1<<1)
-+#define LIBSSH2_TRACE_KEX   (1<<2)
-+#define LIBSSH2_TRACE_AUTH  (1<<3)
-+#define LIBSSH2_TRACE_CONN  (1<<4)
-+#define LIBSSH2_TRACE_SCP   (1<<5)
-+#define LIBSSH2_TRACE_SFTP  (1<<6)
-+#define LIBSSH2_TRACE_ERROR (1<<7)
-+#define LIBSSH2_TRACE_PUBLICKEY (1<<8)
-+
-+#ifdef __cplusplus
-+} /* extern "C" */
-+#endif
-+
-+#endif /* LIBSSH2_H */
-
-Property changes on: libssh2/include/libssh2.h
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.3
-Added: svn:eol-style
-   + native
-
-Index: libssh2/src/comp.c
-===================================================================
---- libssh2/src/comp.c (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/comp.c (.../trunk)
-@@ -0,0 +1,340 @@
-+/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#include "libssh2_priv.h"
-+#ifdef LIBSSH2_HAVE_ZLIB
-+# include <zlib.h>
-+#endif
-+
-+/* ********
-+   * none *
-+   ******** */
-+
-+/* {{{ libssh2_comp_method_none_comp
-+ * Minimalist compression: Absolutely none
-+ */
-+static int
-+libssh2_comp_method_none_comp(LIBSSH2_SESSION * session,
-+                              int compress,
-+                              unsigned char **dest,
-+                              unsigned long *dest_len,
-+                              unsigned long payload_limit,
-+                              int *free_dest,
-+                              const unsigned char *src,
-+                              unsigned long src_len, void **abstract)
-+{
-+    (void) session;
-+    (void) compress;
-+    (void) payload_limit;
-+    (void) abstract;
-+    *dest = (unsigned char *) src;
-+    *dest_len = src_len;
-+
-+    *free_dest = 0;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = {
-+    "none",
-+    NULL,
-+    libssh2_comp_method_none_comp,
-+    NULL
-+};
-+
-+#ifdef LIBSSH2_HAVE_ZLIB
-+/* ********
-+   * zlib *
-+   ******** */
-+
-+/* {{{ Memory management wrappers
-+ * Yes, I realize we're doing a callback to a callback,
-+ * Deal...
-+ */
-+
-+static voidpf
-+libssh2_comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size)
-+{
-+    LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
-+
-+    return (voidpf) LIBSSH2_ALLOC(session, items * size);
-+}
-+
-+static void
-+libssh2_comp_method_zlib_free(voidpf opaque, voidpf address)
-+{
-+    LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
-+
-+    LIBSSH2_FREE(session, address);
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_comp_method_zlib_init
-+ * All your bandwidth are belong to us (so save some)
-+ */
-+static int
-+libssh2_comp_method_zlib_init(LIBSSH2_SESSION * session, int compress,
-+                              void **abstract)
-+{
-+    z_stream *strm;
-+    int status;
-+
-+    strm = LIBSSH2_ALLOC(session, sizeof(z_stream));
-+    if (!strm) {
-+        libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                      "Unable to allocate memory for zlib compression/decompression",
-+                      0);
-+        return -1;
-+    }
-+    memset(strm, 0, sizeof(z_stream));
-+
-+    strm->opaque = (voidpf) session;
-+    strm->zalloc = (alloc_func) libssh2_comp_method_zlib_alloc;
-+    strm->zfree = (free_func) libssh2_comp_method_zlib_free;
-+    if (compress) {
-+        /* deflate */
-+        status = deflateInit(strm, Z_DEFAULT_COMPRESSION);
-+    } else {
-+        /* inflate */
-+        status = inflateInit(strm);
-+    }
-+
-+    if (status != Z_OK) {
-+        LIBSSH2_FREE(session, strm);
-+        return -1;
-+    }
-+    *abstract = strm;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_comp_method_zlib_comp
-+ * zlib, a compression standard for all occasions
-+ */
-+static int
-+libssh2_comp_method_zlib_comp(LIBSSH2_SESSION * session,
-+                              int compress,
-+                              unsigned char **dest,
-+                              unsigned long *dest_len,
-+                              unsigned long payload_limit,
-+                              int *free_dest,
-+                              const unsigned char *src,
-+                              unsigned long src_len, void **abstract)
-+{
-+    z_stream *strm = *abstract;
-+    /* A short-term alloc of a full data chunk is better than a series of
-+       reallocs */
-+    char *out;
-+    int out_maxlen = compress ? (src_len + 4) : (2 * src_len);
-+    int limiter = 0;
-+
-+    /* In practice they never come smaller than this */
-+    if (out_maxlen < 25) {
-+        out_maxlen = 25;
-+    }
-+
-+    if (out_maxlen > (int) payload_limit) {
-+        out_maxlen = payload_limit;
-+    }
-+
-+    strm->next_in = (unsigned char *) src;
-+    strm->avail_in = src_len;
-+    strm->next_out = (unsigned char *) LIBSSH2_ALLOC(session, out_maxlen);
-+    out = (char *) strm->next_out;
-+    strm->avail_out = out_maxlen;
-+    if (!strm->next_out) {
-+        libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                      "Unable to allocate compression/decompression buffer",
-+                      0);
-+        return -1;
-+    }
-+    while (strm->avail_in) {
-+        int status;
-+
-+        if (compress) {
-+            status = deflate(strm, Z_PARTIAL_FLUSH);
-+        } else {
-+            status = inflate(strm, Z_PARTIAL_FLUSH);
-+        }
-+        if (status != Z_OK) {
-+            libssh2_error(session, LIBSSH2_ERROR_ZLIB,
-+                          "compress/decompression failure", 0);
-+            LIBSSH2_FREE(session, out);
-+            return -1;
-+        }
-+        if (strm->avail_in) {
-+            unsigned long out_ofs = out_maxlen - strm->avail_out;
-+            char *newout;
-+
-+            out_maxlen +=
-+                compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
-+
-+            if ((out_maxlen > (int) payload_limit) && !compress && limiter++) {
-+                libssh2_error(session, LIBSSH2_ERROR_ZLIB,
-+                              "Excessive growth in decompression phase", 0);
-+                LIBSSH2_FREE(session, out);
-+                return -1;
-+            }
-+
-+            newout = LIBSSH2_REALLOC(session, out, out_maxlen);
-+            if (!newout) {
-+                libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                              "Unable to expand compress/decompression buffer",
-+                              0);
-+                LIBSSH2_FREE(session, out);
-+                return -1;
-+            }
-+            out = newout;
-+            strm->next_out = (unsigned char *) out + out_ofs;
-+            strm->avail_out +=
-+                compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
-+        } else
-+            while (!strm->avail_out) {
-+                /* Done with input, might be a byte or two in internal buffer during compress
-+                 * Or potentially many bytes if it's a decompress
-+                 */
-+                int grow_size = compress ? 8 : 1024;
-+                char *newout;
-+
-+                if (out_maxlen >= (int) payload_limit) {
-+                    libssh2_error(session, LIBSSH2_ERROR_ZLIB,
-+                                  "Excessive growth in decompression phase",
-+                                  0);
-+                    LIBSSH2_FREE(session, out);
-+                    return -1;
-+                }
-+
-+                if (grow_size > (int) (payload_limit - out_maxlen)) {
-+                    grow_size = payload_limit - out_maxlen;
-+                }
-+
-+                out_maxlen += grow_size;
-+                strm->avail_out = grow_size;
-+
-+                newout = LIBSSH2_REALLOC(session, out, out_maxlen);
-+                if (!newout) {
-+                    libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                                  "Unable to expand final compress/decompress buffer",
-+                                  0);
-+                    LIBSSH2_FREE(session, out);
-+                    return -1;
-+                }
-+                out = newout;
-+                strm->next_out = (unsigned char *) out + out_maxlen -
-+                    grow_size;
-+
-+                if (compress) {
-+                    status = deflate(strm, Z_PARTIAL_FLUSH);
-+                } else {
-+                    status = inflate(strm, Z_PARTIAL_FLUSH);
-+                }
-+                if (status != Z_OK) {
-+                    libssh2_error(session, LIBSSH2_ERROR_ZLIB,
-+                                  "compress/decompression failure", 0);
-+                    LIBSSH2_FREE(session, out);
-+                    return -1;
-+                }
-+            }
-+    }
-+
-+    *dest = (unsigned char *) out;
-+    *dest_len = out_maxlen - strm->avail_out;
-+    *free_dest = 1;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_comp_method_zlib_dtor
-+ * All done, no more compression for you
-+ */
-+static int
-+libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION * session, int compress,
-+                              void **abstract)
-+{
-+    z_stream *strm = *abstract;
-+
-+    if (strm) {
-+        if (compress) {
-+            /* deflate */
-+            deflateEnd(strm);
-+        } else {
-+            /* inflate */
-+            inflateEnd(strm);
-+        }
-+
-+        LIBSSH2_FREE(session, strm);
-+    }
-+
-+    *abstract = NULL;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+static const LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = {
-+    "zlib",
-+    libssh2_comp_method_zlib_init,
-+    libssh2_comp_method_zlib_comp,
-+    libssh2_comp_method_zlib_dtor,
-+};
-+#endif /* LIBSSH2_HAVE_ZLIB */
-+
-+/* ***********************
-+   * Compression Methods *
-+   *********************** */
-+
-+static const LIBSSH2_COMP_METHOD *_libssh2_comp_methods[] = {
-+    &libssh2_comp_method_none,
-+#ifdef LIBSSH2_HAVE_ZLIB
-+    &libssh2_comp_method_zlib,
-+#endif /* LIBSSH2_HAVE_ZLIB */
-+    NULL
-+};
-+
-+const LIBSSH2_COMP_METHOD **
-+libssh2_comp_methods(void)
-+{
-+    return _libssh2_comp_methods;
-+}
-
-Property changes on: libssh2/src/comp.c
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.2
-Added: svn:eol-style
-   + native
-
-Index: libssh2/src/libgcrypt.c
-===================================================================
---- libssh2/src/libgcrypt.c    (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/libgcrypt.c    (.../trunk)
-@@ -0,0 +1,560 @@
-+/* Copyright (C) 2006, 2007, The Written Word, Inc.
-+ * Copyright (C) 2008, Simon Josefsson
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#include "libssh2_priv.h"
-+#include <string.h>
-+
-+int
-+_libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
-+                 const unsigned char *edata,
-+                 unsigned long elen,
-+                 const unsigned char *ndata,
-+                 unsigned long nlen,
-+                 const unsigned char *ddata,
-+                 unsigned long dlen,
-+                 const unsigned char *pdata,
-+                 unsigned long plen,
-+                 const unsigned char *qdata,
-+                 unsigned long qlen,
-+                 const unsigned char *e1data,
-+                 unsigned long e1len,
-+                 const unsigned char *e2data,
-+                 unsigned long e2len,
-+                 const unsigned char *coeffdata, unsigned long coefflen)
-+{
-+    int rc;
-+    (void) e1data;
-+    (void) e1len;
-+    (void) e2data;
-+    (void) e2len;
-+
-+    if (ddata) {
-+        rc = gcry_sexp_build
-+            (rsa, NULL,
-+             "(private-key(rsa(n%b)(e%b)(d%b)(q%b)(p%b)(u%b)))",
-+             nlen, ndata, elen, edata, dlen, ddata, plen, pdata,
-+             qlen, qdata, coefflen, coeffdata);
-+    } else {
-+        rc = gcry_sexp_build(rsa, NULL, "(public-key(rsa(n%b)(e%b)))",
-+                             nlen, ndata, elen, edata);
-+    }
-+    if (rc) {
-+        *rsa = NULL;
-+        return -1;
-+    }
-+
-+    return 0;
-+}
-+
-+int
-+_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
-+                         const unsigned char *sig,
-+                         unsigned long sig_len,
-+                         const unsigned char *m, unsigned long m_len)
-+{
-+    unsigned char hash[SHA_DIGEST_LENGTH];
-+    gcry_sexp_t s_sig, s_hash;
-+    int rc = -1;
-+
-+    libssh2_sha1(m, m_len, hash);
-+
-+    rc = gcry_sexp_build(&s_hash, NULL,
-+                         "(data (flags pkcs1) (hash sha1 %b))",
-+                         SHA_DIGEST_LENGTH, hash);
-+    if (rc != 0) {
-+        return -1;
-+    }
-+
-+    rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s %b)))", sig_len, sig);
-+    if (rc != 0) {
-+        gcry_sexp_release(s_hash);
-+        return -1;
-+    }
-+
-+    rc = gcry_pk_verify(s_sig, s_hash, rsa);
-+    gcry_sexp_release(s_sig);
-+    gcry_sexp_release(s_hash);
-+
-+    return (rc == 0) ? 0 : -1;
-+}
-+
-+int
-+_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
-+                 const unsigned char *p,
-+                 unsigned long p_len,
-+                 const unsigned char *q,
-+                 unsigned long q_len,
-+                 const unsigned char *g,
-+                 unsigned long g_len,
-+                 const unsigned char *y,
-+                 unsigned long y_len,
-+                 const unsigned char *x, unsigned long x_len)
-+{
-+    int rc;
-+
-+    if (x_len) {
-+        rc = gcry_sexp_build
-+            (dsactx, NULL,
-+             "(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))",
-+             p_len, p, q_len, q, g_len, g, y_len, y, x_len, x);
-+    } else {
-+        rc = gcry_sexp_build(dsactx, NULL,
-+                             "(public-key(dsa(p%b)(q%b)(g%b)(y%b)))",
-+                             p_len, p, q_len, q, g_len, g, y_len, y);
-+    }
-+
-+    if (rc) {
-+        *dsactx = NULL;
-+        return -1;
-+    }
-+
-+    return 0;
-+}
-+
-+int
-+_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
-+                         LIBSSH2_SESSION * session,
-+                         FILE * fp, unsigned const char *passphrase)
-+{
-+    unsigned char *data, *save_data;
-+    unsigned int datalen;
-+    int ret;
-+    unsigned char *n, *e, *d, *p, *q, *e1, *e2, *coeff;
-+    unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen;
-+
-+    (void) passphrase;
-+
-+    ret = _libssh2_pem_parse(session,
-+                             "-----BEGIN RSA PRIVATE KEY-----",
-+                             "-----END RSA PRIVATE KEY-----",
-+                             fp, &data, &datalen);
-+    if (ret) {
-+        return -1;
-+    }
-+
-+    save_data = data;
-+
-+    if (_libssh2_pem_decode_sequence(&data, &datalen)) {
-+        ret = -1;
-+        goto fail;
-+    }
-+/* First read Version field (should be 0). */
-+    ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen);
-+    if (ret != 0 || (nlen != 1 && *n != '\0')) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+    ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen);
-+    if (ret != 0) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+    ret = _libssh2_pem_decode_integer(&data, &datalen, &e, &elen);
-+    if (ret != 0) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+    ret = _libssh2_pem_decode_integer(&data, &datalen, &d, &dlen);
-+    if (ret != 0) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+    ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
-+    if (ret != 0) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+    ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen);
-+    if (ret != 0) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+    ret = _libssh2_pem_decode_integer(&data, &datalen, &e1, &e1len);
-+    if (ret != 0) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+    ret = _libssh2_pem_decode_integer(&data, &datalen, &e2, &e2len);
-+    if (ret != 0) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+    ret = _libssh2_pem_decode_integer(&data, &datalen, &coeff, &coefflen);
-+    if (ret != 0) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+    if (_libssh2_rsa_new(rsa, e, elen, n, nlen, d, dlen, p, plen,
-+                         q, qlen, e1, e1len, e2, e2len, coeff, coefflen)) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+    ret = 0;
-+
-+  fail:
-+    LIBSSH2_FREE(session, save_data);
-+    return ret;
-+}
-+
-+int
-+_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
-+                         LIBSSH2_SESSION * session,
-+                         FILE * fp, unsigned const char *passphrase)
-+{
-+    unsigned char *data, *save_data;
-+    unsigned int datalen;
-+    int ret;
-+    unsigned char *p, *q, *g, *y, *x;
-+    unsigned int plen, qlen, glen, ylen, xlen;
-+
-+    (void) passphrase;
-+
-+    ret = _libssh2_pem_parse(session,
-+                             "-----BEGIN DSA PRIVATE KEY-----",
-+                             "-----END DSA PRIVATE KEY-----",
-+                             fp, &data, &datalen);
-+    if (ret) {
-+        return -1;
-+    }
-+
-+    save_data = data;
-+
-+    if (_libssh2_pem_decode_sequence(&data, &datalen)) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+/* First read Version field (should be 0). */
-+    ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
-+    if (ret != 0 || (plen != 1 && *p != '\0')) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+    ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
-+    if (ret != 0) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+    ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen);
-+    if (ret != 0) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+    ret = _libssh2_pem_decode_integer(&data, &datalen, &g, &glen);
-+    if (ret != 0) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+    ret = _libssh2_pem_decode_integer(&data, &datalen, &y, &ylen);
-+    if (ret != 0) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+    ret = _libssh2_pem_decode_integer(&data, &datalen, &x, &xlen);
-+    if (ret != 0) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+    if (datalen != 0) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+    if (_libssh2_dsa_new(dsa, p, plen, q, qlen, g, glen, y, ylen, x, xlen)) {
-+        ret = -1;
-+        goto fail;
-+    }
-+
-+    ret = 0;
-+
-+  fail:
-+    LIBSSH2_FREE(session, save_data);
-+    return ret;
-+}
-+
-+int
-+_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
-+                       libssh2_dsa_ctx * rsactx,
-+                       const unsigned char *hash,
-+                       unsigned long hash_len,
-+                       unsigned char **signature, unsigned long *signature_len)
-+{
-+    gcry_sexp_t sig_sexp;
-+    gcry_sexp_t data;
-+    int rc;
-+    const char *tmp;
-+    size_t size;
-+
-+    if (hash_len != SHA_DIGEST_LENGTH) {
-+        return -1;
-+    }
-+
-+    if (gcry_sexp_build(&data, NULL,
-+                        "(data (flags pkcs1) (hash sha1 %b))",
-+                        hash_len, hash)) {
-+        return -1;
-+    }
-+
-+    rc = gcry_pk_sign(&sig_sexp, data, rsactx);
-+
-+    gcry_sexp_release(data);
-+
-+    if (rc != 0) {
-+        return -1;
-+    }
-+
-+    data = gcry_sexp_find_token(sig_sexp, "s", 0);
-+    if (!data) {
-+        return -1;
-+    }
-+
-+    tmp = gcry_sexp_nth_data(data, 1, &size);
-+    if (!tmp) {
-+        return -1;
-+    }
-+
-+    if (tmp[0] == '\0') {
-+        tmp++;
-+        size--;
-+    }
-+
-+    *signature = LIBSSH2_ALLOC(session, size);
-+    memcpy(*signature, tmp, size);
-+    *signature_len = size;
-+
-+    return rc;
-+}
-+
-+int
-+_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
-+                       const unsigned char *hash,
-+                       unsigned long hash_len, unsigned char *sig)
-+{
-+    unsigned char zhash[SHA_DIGEST_LENGTH + 1];
-+    gcry_sexp_t sig_sexp;
-+    gcry_sexp_t data;
-+    int ret;
-+    const char *tmp;
-+    size_t size;
-+
-+    if (hash_len != SHA_DIGEST_LENGTH) {
-+        return -1;
-+    }
-+
-+    memcpy(zhash + 1, hash, hash_len);
-+    zhash[0] = 0;
-+
-+    if (gcry_sexp_build(&data, NULL, "(data (value %b))", hash_len + 1, zhash)) {
-+        return -1;
-+    }
-+
-+    ret = gcry_pk_sign(&sig_sexp, data, dsactx);
-+
-+    gcry_sexp_release(data);
-+
-+    if (ret != 0) {
-+        return -1;
-+    }
-+
-+/* Extract R. */
-+
-+    data = gcry_sexp_find_token(sig_sexp, "r", 0);
-+    if (!data) {
-+        ret = -1;
-+        goto out;
-+    }
-+
-+    tmp = gcry_sexp_nth_data(data, 1, &size);
-+    if (!tmp) {
-+        ret = -1;
-+        goto out;
-+    }
-+
-+    if (tmp[0] == '\0') {
-+        tmp++;
-+        size--;
-+    }
-+
-+    if (size != 20) {
-+        ret = -1;
-+        goto out;
-+    }
-+
-+    memcpy(sig, tmp, 20);
-+
-+    gcry_sexp_release(data);
-+
-+/* Extract S. */
-+
-+    data = gcry_sexp_find_token(sig_sexp, "s", 0);
-+    if (!data) {
-+        ret = -1;
-+        goto out;
-+    }
-+
-+    tmp = gcry_sexp_nth_data(data, 1, &size);
-+    if (!tmp) {
-+        ret = -1;
-+        goto out;
-+    }
-+
-+    if (tmp[0] == '\0') {
-+        tmp++;
-+        size--;
-+    }
-+
-+    if (size != 20) {
-+        ret = -1;
-+        goto out;
-+    }
-+
-+    memcpy(sig + 20, tmp, 20);
-+
-+    ret = 0;
-+  out:
-+    if (sig_sexp) {
-+        gcry_sexp_release(sig_sexp);
-+    }
-+    if (data) {
-+        gcry_sexp_release(data);
-+    }
-+    return ret;
-+}
-+
-+int
-+_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
-+                         const unsigned char *sig,
-+                         const unsigned char *m, unsigned long m_len)
-+{
-+    unsigned char hash[SHA_DIGEST_LENGTH + 1];
-+    gcry_sexp_t s_sig, s_hash;
-+    int rc = -1;
-+
-+    libssh2_sha1(m, m_len, hash + 1);
-+    hash[0] = 0;
-+
-+    if (gcry_sexp_build(&s_hash, NULL, "(data(flags raw)(value %b))",
-+                        SHA_DIGEST_LENGTH + 1, hash)) {
-+        return -1;
-+    }
-+
-+    if (gcry_sexp_build(&s_sig, NULL, "(sig-val(dsa(r %b)(s %b)))",
-+                        20, sig, 20, sig + 20)) {
-+        gcry_sexp_release(s_hash);
-+        return -1;
-+    }
-+
-+    rc = gcry_pk_verify(s_sig, s_hash, dsactx);
-+    gcry_sexp_release(s_sig);
-+    gcry_sexp_release(s_hash);
-+
-+    return (rc == 0) ? 0 : -1;
-+}
-+
-+int
-+_libssh2_cipher_init(_libssh2_cipher_ctx * h,
-+                     _libssh2_cipher_type(algo),
-+                     unsigned char *iv, unsigned char *secret, int encrypt)
-+{
-+    int mode = 0, ret;
-+    int keylen = gcry_cipher_get_algo_keylen(algo);
-+
-+    (void) encrypt;
-+
-+    if (algo != GCRY_CIPHER_ARCFOUR) {
-+        mode = GCRY_CIPHER_MODE_CBC;
-+    }
-+
-+    ret = gcry_cipher_open(h, algo, mode, 0);
-+    if (ret) {
-+        return -1;
-+    }
-+
-+    ret = gcry_cipher_setkey(*h, secret, keylen);
-+    if (ret) {
-+        gcry_cipher_close(*h);
-+        return -1;
-+    }
-+
-+    if (algo != GCRY_CIPHER_ARCFOUR) {
-+        int blklen = gcry_cipher_get_algo_blklen(algo);
-+        ret = gcry_cipher_setiv(*h, iv, blklen);
-+        if (ret) {
-+            gcry_cipher_close(*h);
-+            return -1;
-+        }
-+    }
-+
-+    return 0;
-+}
-+
-+int
-+_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
-+                      _libssh2_cipher_type(algo),
-+                      int encrypt, unsigned char *block)
-+{
-+    size_t blklen = gcry_cipher_get_algo_blklen(algo);
-+    int ret;
-+    if (blklen == 1) {
-+/* Hack for arcfour. */
-+        blklen = 8;
-+    }
-+
-+    if (encrypt) {
-+        ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen);
-+    } else {
-+        ret = gcry_cipher_decrypt(*ctx, block, blklen, block, blklen);
-+    }
-+    return ret;
-+}
-
-Property changes on: libssh2/src/libgcrypt.c
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.1
-Added: svn:eol-style
-   + native
-Added: svn:executable
-   + *
-
-Index: libssh2/src/userauth.c
-===================================================================
---- libssh2/src/userauth.c     (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/userauth.c     (.../trunk)
-@@ -0,0 +1,1473 @@
-+/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#include "libssh2_priv.h"
-+
-+#include <ctype.h>
-+#include <stdio.h>
-+
-+/* Needed for struct iovec on some platforms */
-+#ifdef HAVE_SYS_UIO_H
-+#include <sys/uio.h>
-+#endif
-+
-+
-+/* {{{ proto libssh2_userauth_list
-+ * List authentication methods
-+ * Will yield successful login if "none" happens to be allowable for this user
-+ * Not a common configuration for any SSH server though
-+ * username should be NULL, or a null terminated string
-+ */
-+LIBSSH2_API char *
-+libssh2_userauth_list(LIBSSH2_SESSION * session, const char *username,
-+                      unsigned int username_len)
-+{
-+    static const unsigned char reply_codes[3] =
-+        { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 };
-+    /* packet_type(1) + username_len(4) + service_len(4) +
-+       service(14)"ssh-connection" + method_len(4) + method(4)"none" */
-+    unsigned long methods_len;
-+    unsigned char *s;
-+    int rc;
-+
-+    if (session->userauth_list_state == libssh2_NB_state_idle) {
-+        /* Zero the whole thing out */
-+        memset(&session->userauth_list_packet_requirev_state, 0,
-+               sizeof(session->userauth_list_packet_requirev_state));
-+
-+        session->userauth_list_data_len = username_len + 31;
-+
-+        s = session->userauth_list_data =
-+            LIBSSH2_ALLOC(session, session->userauth_list_data_len);
-+        if (!session->userauth_list_data) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for userauth_list", 0);
-+            return NULL;
-+        }
-+
-+        *(s++) = SSH_MSG_USERAUTH_REQUEST;
-+        libssh2_htonu32(s, username_len);
-+        s += 4;
-+        if (username) {
-+            memcpy(s, username, username_len);
-+            s += username_len;
-+        }
-+
-+        libssh2_htonu32(s, 14);
-+        s += 4;
-+        memcpy(s, "ssh-connection", 14);
-+        s += 14;
-+
-+        libssh2_htonu32(s, 4);
-+        s += 4;
-+        memcpy(s, "none", 4);
-+        s += 4;
-+
-+        session->userauth_list_state = libssh2_NB_state_created;
-+    }
-+
-+    if (session->userauth_list_state == libssh2_NB_state_created) {
-+        rc = libssh2_packet_write(session, session->userauth_list_data,
-+                                  session->userauth_list_data_len);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block requesting userauth list", 0);
-+            return NULL;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send userauth-none request", 0);
-+            LIBSSH2_FREE(session, session->userauth_list_data);
-+            session->userauth_list_data = NULL;
-+            session->userauth_list_state = libssh2_NB_state_idle;
-+            return NULL;
-+        }
-+        LIBSSH2_FREE(session, session->userauth_list_data);
-+        session->userauth_list_data = NULL;
-+
-+        session->userauth_list_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (session->userauth_list_state == libssh2_NB_state_sent) {
-+        rc = libssh2_packet_requirev_ex(session, reply_codes,
-+                                        &session->userauth_list_data,
-+                                        &session->userauth_list_data_len, 0,
-+                                        NULL, 0,
-+                                        &session->
-+                                        userauth_list_packet_requirev_state);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block requesting userauth list", 0);
-+            return NULL;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_NONE, "No error", 0);
-+            session->userauth_list_state = libssh2_NB_state_idle;
-+            return NULL;
-+        }
-+
-+        if (session->userauth_list_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
-+            /* Wow, who'dve thought... */
-+            libssh2_error(session, LIBSSH2_ERROR_NONE, "No error", 0);
-+            LIBSSH2_FREE(session, session->userauth_list_data);
-+            session->userauth_list_data = NULL;
-+            session->state |= LIBSSH2_STATE_AUTHENTICATED;
-+            session->userauth_list_state = libssh2_NB_state_idle;
-+            return NULL;
-+        }
-+
-+        methods_len = libssh2_ntohu32(session->userauth_list_data + 1);
-+
-+        /* Do note that the memory areas overlap! */
-+        memmove(session->userauth_list_data, session->userauth_list_data + 5,
-+               methods_len);
-+        session->userauth_list_data[methods_len] = '\0';
-+        _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Permitted auth methods: %s",
-+                       session->userauth_list_data);
-+    }
-+
-+    session->userauth_list_state = libssh2_NB_state_idle;
-+    return (char *) session->userauth_list_data;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_userauth_authenticated
-+ * 0 if not yet authenticated
-+ * non-zero is already authenticated
-+ */
-+LIBSSH2_API int
-+libssh2_userauth_authenticated(LIBSSH2_SESSION * session)
-+{
-+    return session->state & LIBSSH2_STATE_AUTHENTICATED;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_userauth_password
-+ * Plain ol' login
-+ */
-+LIBSSH2_API int
-+libssh2_userauth_password_ex(LIBSSH2_SESSION * session, const char *username,
-+                             unsigned int username_len, const char *password,
-+                             unsigned int password_len,
-+                             LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb)))
-+{
-+    unsigned char *s;
-+    static const unsigned char reply_codes[4] =
-+        { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE,
-+        SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, 0
-+    };
-+    int rc;
-+
-+    if (session->userauth_pswd_state == libssh2_NB_state_idle) {
-+        /* Zero the whole thing out */
-+        memset(&session->userauth_pswd_packet_requirev_state, 0,
-+               sizeof(session->userauth_pswd_packet_requirev_state));
-+
-+        /*
-+         * 40 = acket_type(1) + username_len(4) + service_len(4) + 
-+         * service(14)"ssh-connection" + method_len(4) + method(8)"password" +
-+         * chgpwdbool(1) + password_len(4) */
-+        session->userauth_pswd_data_len = username_len + password_len + 40;
-+
-+        session->userauth_pswd_data0 = ~SSH_MSG_USERAUTH_PASSWD_CHANGEREQ;
-+
-+        s = session->userauth_pswd_data =
-+            LIBSSH2_ALLOC(session, session->userauth_pswd_data_len);
-+        if (!session->userauth_pswd_data) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for userauth-password request",
-+                          0);
-+            return -1;
-+        }
-+
-+        *(s++) = SSH_MSG_USERAUTH_REQUEST;
-+        libssh2_htonu32(s, username_len);
-+        s += 4;
-+        memcpy(s, username, username_len);
-+        s += username_len;
-+
-+        libssh2_htonu32(s, sizeof("ssh-connection") - 1);
-+        s += 4;
-+        memcpy(s, "ssh-connection", sizeof("ssh-connection") - 1);
-+        s += sizeof("ssh-connection") - 1;
-+
-+        libssh2_htonu32(s, sizeof("password") - 1);
-+        s += 4;
-+        memcpy(s, "password", sizeof("password") - 1);
-+        s += sizeof("password") - 1;
-+
-+        *s = '\0';
-+        s++;
-+
-+        libssh2_htonu32(s, password_len);
-+        s += 4;
-+        memcpy(s, password, password_len);
-+        s += password_len;
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_AUTH,
-+                       "Attempting to login using password authentication");
-+
-+        session->userauth_pswd_state = libssh2_NB_state_created;
-+    }
-+
-+    if (session->userauth_pswd_state == libssh2_NB_state_created) {
-+        rc = libssh2_packet_write(session, session->userauth_pswd_data,
-+                                  session->userauth_pswd_data_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send userauth-password request", 0);
-+            LIBSSH2_FREE(session, session->userauth_pswd_data);
-+            session->userauth_pswd_data = NULL;
-+            session->userauth_pswd_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, session->userauth_pswd_data);
-+        session->userauth_pswd_data = NULL;
-+
-+        session->userauth_pswd_state = libssh2_NB_state_sent;
-+    }
-+
-+  password_response:
-+
-+    if ((session->userauth_pswd_state == libssh2_NB_state_sent)
-+        || (session->userauth_pswd_state == libssh2_NB_state_sent1)
-+        || (session->userauth_pswd_state == libssh2_NB_state_sent2)) {
-+        if (session->userauth_pswd_state == libssh2_NB_state_sent) {
-+            rc = libssh2_packet_requirev_ex(session, reply_codes,
-+                                            &session->userauth_pswd_data,
-+                                            &session->userauth_pswd_data_len,
-+                                            0, NULL, 0,
-+                                            &session->
-+                                            userauth_pswd_packet_requirev_state);
-+            if (rc == PACKET_EAGAIN) {
-+                return PACKET_EAGAIN;
-+            } else if (rc) {
-+                session->userauth_pswd_state = libssh2_NB_state_idle;
-+                return -1;
-+            }
-+
-+            if (session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
-+                _libssh2_debug(session, LIBSSH2_DBG_AUTH,
-+                               "Password authentication successful");
-+                LIBSSH2_FREE(session, session->userauth_pswd_data);
-+                session->userauth_pswd_data = NULL;
-+                session->state |= LIBSSH2_STATE_AUTHENTICATED;
-+                session->userauth_pswd_state = libssh2_NB_state_idle;
-+                return 0;
-+            }
-+
-+            session->userauth_pswd_newpw = NULL;
-+            session->userauth_pswd_newpw_len = 0;
-+
-+            session->userauth_pswd_state = libssh2_NB_state_sent1;
-+        }
-+
-+        if ((session->userauth_pswd_data[0] ==
-+             SSH_MSG_USERAUTH_PASSWD_CHANGEREQ)
-+            || (session->userauth_pswd_data0 ==
-+                SSH_MSG_USERAUTH_PASSWD_CHANGEREQ)) {
-+            session->userauth_pswd_data0 = SSH_MSG_USERAUTH_PASSWD_CHANGEREQ;
-+
-+            if ((session->userauth_pswd_state == libssh2_NB_state_sent1) ||
-+                (session->userauth_pswd_state == libssh2_NB_state_sent2)) {
-+                if (session->userauth_pswd_state == libssh2_NB_state_sent1) {
-+                    _libssh2_debug(session, LIBSSH2_DBG_AUTH,
-+                                   "Password change required");
-+                    LIBSSH2_FREE(session, session->userauth_pswd_data);
-+                    session->userauth_pswd_data = NULL;
-+                }
-+                if (passwd_change_cb) {
-+                    if (session->userauth_pswd_state == libssh2_NB_state_sent1) {
-+                        passwd_change_cb(session,
-+                                         &session->userauth_pswd_newpw,
-+                                         &session->userauth_pswd_newpw_len,
-+                                         &session->abstract);
-+                        if (!session->userauth_pswd_newpw) {
-+                            libssh2_error(session,
-+                                          LIBSSH2_ERROR_PASSWORD_EXPIRED,
-+                                          "Password expired, and callback failed",
-+                                          0);
-+                            return -1;
-+                        }
-+
-+                        /* basic data_len + newpw_len(4) */
-+                        session->userauth_pswd_data_len =
-+                            username_len + password_len + 44 +
-+                            session->userauth_pswd_newpw_len;
-+
-+                        s = session->userauth_pswd_data =
-+                            LIBSSH2_ALLOC(session,
-+                                          session->userauth_pswd_data_len);
-+                        if (!session->userauth_pswd_data) {
-+                            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                                          "Unable to allocate memory for userauth-password-change request",
-+                                          0);
-+                            LIBSSH2_FREE(session,
-+                                         session->userauth_pswd_newpw);
-+                            session->userauth_pswd_newpw = NULL;
-+                            return -1;
-+                        }
-+
-+                        *(s++) = SSH_MSG_USERAUTH_REQUEST;
-+                        libssh2_htonu32(s, username_len);
-+                        s += 4;
-+                        memcpy(s, username, username_len);
-+                        s += username_len;
-+
-+                        libssh2_htonu32(s, sizeof("ssh-connection") - 1);
-+                        s += 4;
-+                        memcpy(s, "ssh-connection",
-+                               sizeof("ssh-connection") - 1);
-+                        s += sizeof("ssh-connection") - 1;
-+
-+                        libssh2_htonu32(s, sizeof("password") - 1);
-+                        s += 4;
-+                        memcpy(s, "password", sizeof("password") - 1);
-+                        s += sizeof("password") - 1;
-+
-+                        *s = 0x01;
-+                        s++;
-+
-+                        libssh2_htonu32(s, password_len);
-+                        s += 4;
-+                        memcpy(s, password, password_len);
-+                        s += password_len;
-+
-+                        libssh2_htonu32(s, session->userauth_pswd_newpw_len);
-+                        s += 4;
-+                        memcpy(s, session->userauth_pswd_newpw,
-+                               session->userauth_pswd_newpw_len);
-+                        s += session->userauth_pswd_newpw_len;
-+
-+                        session->userauth_pswd_state = libssh2_NB_state_sent2;
-+                    }
-+
-+                    if (session->userauth_pswd_state == libssh2_NB_state_sent2) {
-+                        rc = libssh2_packet_write(session,
-+                                                  session->userauth_pswd_data,
-+                                                  session->
-+                                                  userauth_pswd_data_len);
-+                        if (rc == PACKET_EAGAIN) {
-+                            return PACKET_EAGAIN;
-+                        } else if (rc) {
-+                            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                                          "Unable to send userauth-password-change request",
-+                                          0);
-+                            LIBSSH2_FREE(session, session->userauth_pswd_data);
-+                            session->userauth_pswd_data = NULL;
-+                            LIBSSH2_FREE(session,
-+                                         session->userauth_pswd_newpw);
-+                            session->userauth_pswd_newpw = NULL;
-+                            return -1;
-+                        }
-+                        LIBSSH2_FREE(session, session->userauth_pswd_data);
-+                        session->userauth_pswd_data = NULL;
-+                        LIBSSH2_FREE(session, session->userauth_pswd_newpw);
-+                        session->userauth_pswd_newpw = NULL;
-+
-+                        /*
-+                         * Ugliest use of goto ever.  Blame it on the
-+                         * askN => requirev migration.
-+                         */
-+                        session->userauth_pswd_state = libssh2_NB_state_sent;
-+                        goto password_response;
-+                    }
-+                }
-+            } else {
-+                libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED,
-+                              "Password Expired, and no callback specified",
-+                              0);
-+                session->userauth_pswd_state = libssh2_NB_state_idle;
-+                return -1;
-+            }
-+        }
-+    }
-+
-+    /* FAILURE */
-+    LIBSSH2_FREE(session, session->userauth_pswd_data);
-+    session->userauth_pswd_data = NULL;
-+    session->userauth_pswd_state = libssh2_NB_state_idle;
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_file_read_publickey
-+ * Read a public key from an id_???.pub style file
-+ */
-+static int
-+libssh2_file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
-+                            unsigned long *method_len,
-+                            unsigned char **pubkeydata,
-+                            unsigned long *pubkeydata_len,
-+                            const char *pubkeyfile)
-+{
-+    FILE *fd;
-+    char c;
-+    unsigned char *pubkey = NULL, *sp1, *sp2, *tmp;
-+    size_t pubkey_len = 0;
-+    unsigned int tmp_len;
-+
-+    _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Loading public key file: %s",
-+                   pubkeyfile);
-+    /* Read Public Key */
-+    fd = fopen(pubkeyfile, "r");
-+    if (!fd) {
-+        libssh2_error(session, LIBSSH2_ERROR_FILE,
-+                      "Unable to open public key file", 0);
-+        return -1;
-+    }
-+    while (!feof(fd) && (c = fgetc(fd)) != '\r' && c != '\n')
-+        pubkey_len++;
-+    if (feof(fd)) {
-+        /* the last character was EOF */
-+        pubkey_len--;
-+    }
-+    rewind(fd);
-+
-+    if (pubkey_len <= 1) {
-+        libssh2_error(session, LIBSSH2_ERROR_FILE,
-+                      "Invalid data in public key file", 0);
-+        fclose(fd);
-+        return -1;
-+    }
-+
-+    pubkey = LIBSSH2_ALLOC(session, pubkey_len);
-+    if (!pubkey) {
-+        libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                      "Unable to allocate memory for public key data", 0);
-+        fclose(fd);
-+        return -1;
-+    }
-+    if (fread(pubkey, 1, pubkey_len, fd) != pubkey_len) {
-+        libssh2_error(session, LIBSSH2_ERROR_FILE,
-+                      "Unable to read public key from file", 0);
-+        LIBSSH2_FREE(session, pubkey);
-+        fclose(fd);
-+        return -1;
-+    }
-+    fclose(fd);
-+    /*
-+     * Remove trailing whitespace
-+     */
-+    while (pubkey_len && isspace(pubkey[pubkey_len - 1]))
-+        pubkey_len--;
-+
-+    if (!pubkey_len) {
-+        libssh2_error(session, LIBSSH2_ERROR_FILE, "Missing public key data",
-+                      0);
-+        LIBSSH2_FREE(session, pubkey);
-+        return -1;
-+    }
-+
-+    if ((sp1 = memchr(pubkey, ' ', pubkey_len)) == NULL) {
-+        libssh2_error(session, LIBSSH2_ERROR_FILE, "Invalid public key data",
-+                      0);
-+        LIBSSH2_FREE(session, pubkey);
-+        return -1;
-+    }
-+    /* Wasting some bytes here (okay, more than some),
-+     * but since it's likely to be freed soon anyway, 
-+     * we'll just avoid the extra free/alloc and call it a wash */
-+    *method = pubkey;
-+    *method_len = sp1 - pubkey;
-+
-+    sp1++;
-+
-+    if ((sp2 = memchr(sp1, ' ', pubkey_len - *method_len)) == NULL) {
-+        /* Assume that the id string is missing, but that it's okay */
-+        sp2 = pubkey + pubkey_len;
-+    }
-+
-+    if (libssh2_base64_decode
-+        (session, (char **) &tmp, &tmp_len, (char *) sp1, sp2 - sp1)) {
-+        libssh2_error(session, LIBSSH2_ERROR_FILE,
-+                      "Invalid key data, not base64 encoded", 0);
-+        LIBSSH2_FREE(session, pubkey);
-+        return -1;
-+    }
-+    *pubkeydata = tmp;
-+    *pubkeydata_len = tmp_len;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_file_read_privatekey
-+ * Read a PEM encoded private key from an id_??? style file
-+ */
-+static int
-+libssh2_file_read_privatekey(LIBSSH2_SESSION * session,
-+                             const LIBSSH2_HOSTKEY_METHOD ** hostkey_method,
-+                             void **hostkey_abstract,
-+                             const unsigned char *method, int method_len,
-+                             const char *privkeyfile, const char *passphrase)
-+{
-+    const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail =
-+        libssh2_hostkey_methods();
-+
-+    _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Loading private key file: %s",
-+                   privkeyfile);
-+    *hostkey_method = NULL;
-+    *hostkey_abstract = NULL;
-+    while (*hostkey_methods_avail && (*hostkey_methods_avail)->name) {
-+        if ((*hostkey_methods_avail)->initPEM
-+            && strncmp((*hostkey_methods_avail)->name, (const char *) method,
-+                       method_len) == 0) {
-+            *hostkey_method = *hostkey_methods_avail;
-+            break;
-+        }
-+        hostkey_methods_avail++;
-+    }
-+    if (!*hostkey_method) {
-+        libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE,
-+                      "No handler for specified private key", 0);
-+        return -1;
-+    }
-+
-+    if ((*hostkey_method)->
-+        initPEM(session, privkeyfile, (unsigned char *) passphrase,
-+                hostkey_abstract)) {
-+        libssh2_error(session, LIBSSH2_ERROR_FILE,
-+                      "Unable to initialize private key from file", 0);
-+        return -1;
-+    }
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_userauth_hostbased_fromfile_ex
-+ * Authenticate using a keypair found in the named files
-+ */
-+LIBSSH2_API int
-+libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION * session,
-+                                       const char *username,
-+                                       unsigned int username_len,
-+                                       const char *publickey,
-+                                       const char *privatekey,
-+                                       const char *passphrase,
-+                                       const char *hostname,
-+                                       unsigned int hostname_len,
-+                                       const char *local_username,
-+                                       unsigned int local_username_len)
-+{
-+    static const unsigned char reply_codes[3] =
-+        { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 };
-+    int rc;
-+
-+    if (session->userauth_host_state == libssh2_NB_state_idle) {
-+        const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
-+        unsigned char *pubkeydata, *sig;
-+        unsigned long pubkeydata_len;
-+        unsigned long sig_len;
-+        void *abstract;
-+        unsigned char buf[5];
-+        struct iovec datavec[4];
-+
-+        /* Zero the whole thing out */
-+        memset(&session->userauth_host_packet_requirev_state, 0,
-+               sizeof(session->userauth_host_packet_requirev_state));
-+
-+        if (libssh2_file_read_publickey
-+            (session, &session->userauth_host_method,
-+             &session->userauth_host_method_len, &pubkeydata, &pubkeydata_len,
-+             publickey)) {
-+            return -1;
-+        }
-+
-+        /*
-+         * 48 = packet_type(1) + username_len(4) + servicename_len(4) + 
-+         * service_name(14)"ssh-connection" + authmethod_len(4) +
-+         * authmethod(9)"hostbased" + method_len(4) + pubkeydata_len(4) + 
-+         * local_username_len(4)
-+         */
-+        session->userauth_host_packet_len =
-+            username_len + session->userauth_host_method_len + hostname_len +
-+            local_username_len + pubkeydata_len + 48;
-+
-+        /*
-+         * Preallocate space for an overall length,  method name again,
-+         * and the signature, which won't be any larger than the size of 
-+         * the publickeydata itself
-+         */
-+        session->userauth_host_s = session->userauth_host_packet =
-+            LIBSSH2_ALLOC(session,
-+                          session->userauth_host_packet_len + 4 + (4 +
-+                                                                   session->
-+                                                                   userauth_host_method_len)
-+                          + (4 + pubkeydata_len));
-+        if (!session->userauth_host_packet) {
-+            LIBSSH2_FREE(session, session->userauth_host_method);
-+            session->userauth_host_method = NULL;
-+            return -1;
-+        }
-+
-+        *(session->userauth_host_s++) = SSH_MSG_USERAUTH_REQUEST;
-+        libssh2_htonu32(session->userauth_host_s, username_len);
-+        session->userauth_host_s += 4;
-+        memcpy(session->userauth_host_s, username, username_len);
-+        session->userauth_host_s += username_len;
-+
-+        libssh2_htonu32(session->userauth_host_s, 14);
-+        session->userauth_host_s += 4;
-+        memcpy(session->userauth_host_s, "ssh-connection", 14);
-+        session->userauth_host_s += 14;
-+
-+        libssh2_htonu32(session->userauth_host_s, 9);
-+        session->userauth_host_s += 4;
-+        memcpy(session->userauth_host_s, "hostbased", 9);
-+        session->userauth_host_s += 9;
-+
-+        libssh2_htonu32(session->userauth_host_s,
-+                        session->userauth_host_method_len);
-+        session->userauth_host_s += 4;
-+        memcpy(session->userauth_host_s, session->userauth_host_method,
-+               session->userauth_host_method_len);
-+        session->userauth_host_s += session->userauth_host_method_len;
-+
-+        libssh2_htonu32(session->userauth_host_s, pubkeydata_len);
-+        session->userauth_host_s += 4;
-+        memcpy(session->userauth_host_s, pubkeydata, pubkeydata_len);
-+        session->userauth_host_s += pubkeydata_len;
-+
-+        libssh2_htonu32(session->userauth_host_s, hostname_len);
-+        session->userauth_host_s += 4;
-+        memcpy(session->userauth_host_s, hostname, hostname_len);
-+        session->userauth_host_s += hostname_len;
-+
-+        libssh2_htonu32(session->userauth_host_s, local_username_len);
-+        session->userauth_host_s += 4;
-+        memcpy(session->userauth_host_s, local_username, local_username_len);
-+        session->userauth_host_s += local_username_len;
-+
-+        if (libssh2_file_read_privatekey
-+            (session, &privkeyobj, &abstract, session->userauth_host_method,
-+             session->userauth_host_method_len, privatekey, passphrase)) {
-+            LIBSSH2_FREE(session, session->userauth_host_method);
-+            session->userauth_host_method = NULL;
-+            LIBSSH2_FREE(session, session->userauth_host_packet);
-+            session->userauth_host_packet = NULL;
-+            return -1;
-+        }
-+
-+        libssh2_htonu32(buf, session->session_id_len);
-+        datavec[0].iov_base = buf;
-+        datavec[0].iov_len = 4;
-+        datavec[1].iov_base = session->session_id;
-+        datavec[1].iov_len = session->session_id_len;
-+        datavec[2].iov_base = session->userauth_host_packet;
-+        datavec[2].iov_len = session->userauth_host_packet_len;
-+
-+        if (privkeyobj->signv(session, &sig, &sig_len, 3, datavec, &abstract)) {
-+            LIBSSH2_FREE(session, session->userauth_host_method);
-+            session->userauth_host_method = NULL;
-+            LIBSSH2_FREE(session, session->userauth_host_packet);
-+            session->userauth_host_packet = NULL;
-+            if (privkeyobj->dtor) {
-+                privkeyobj->dtor(session, &abstract);
-+            }
-+            return -1;
-+        }
-+
-+        if (privkeyobj->dtor) {
-+            privkeyobj->dtor(session, &abstract);
-+        }
-+
-+        if (sig_len > pubkeydata_len) {
-+            unsigned char *newpacket;
-+            /* Should *NEVER* happen, but...well.. better safe than sorry */
-+            newpacket = LIBSSH2_REALLOC(session, session->userauth_host_packet, session->userauth_host_packet_len + 4 + (4 + session->userauth_host_method_len) + (4 + sig_len));       /* PK sigblob */
-+            if (!newpacket) {
-+                libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                              "Failed allocating additional space for userauth-hostbased packet",
-+                              0);
-+                LIBSSH2_FREE(session, sig);
-+                LIBSSH2_FREE(session, session->userauth_host_packet);
-+                session->userauth_host_packet = NULL;
-+                LIBSSH2_FREE(session, session->userauth_host_method);
-+                session->userauth_host_method = NULL;
-+                return -1;
-+            }
-+            session->userauth_host_packet = newpacket;
-+        }
-+
-+        session->userauth_host_s =
-+            session->userauth_host_packet + session->userauth_host_packet_len;
-+
-+        libssh2_htonu32(session->userauth_host_s,
-+                        4 + session->userauth_host_method_len + 4 + sig_len);
-+        session->userauth_host_s += 4;
-+
-+        libssh2_htonu32(session->userauth_host_s,
-+                        session->userauth_host_method_len);
-+        session->userauth_host_s += 4;
-+        memcpy(session->userauth_host_s, session->userauth_host_method,
-+               session->userauth_host_method_len);
-+        session->userauth_host_s += session->userauth_host_method_len;
-+        LIBSSH2_FREE(session, session->userauth_host_method);
-+        session->userauth_host_method = NULL;
-+
-+        libssh2_htonu32(session->userauth_host_s, sig_len);
-+        session->userauth_host_s += 4;
-+        memcpy(session->userauth_host_s, sig, sig_len);
-+        session->userauth_host_s += sig_len;
-+        LIBSSH2_FREE(session, sig);
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_AUTH,
-+                       "Attempting hostbased authentication");
-+
-+        session->userauth_host_state = libssh2_NB_state_created;
-+    }
-+
-+    if (session->userauth_host_state == libssh2_NB_state_created) {
-+        rc = libssh2_packet_write(session, session->userauth_host_packet,
-+                                  session->userauth_host_s -
-+                                  session->userauth_host_packet);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send userauth-hostbased request", 0);
-+            LIBSSH2_FREE(session, session->userauth_host_packet);
-+            session->userauth_host_packet = NULL;
-+            session->userauth_host_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, session->userauth_host_packet);
-+        session->userauth_host_packet = NULL;
-+
-+        session->userauth_host_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (session->userauth_host_state == libssh2_NB_state_sent) {
-+        unsigned long data_len;
-+        rc = libssh2_packet_requirev_ex(session, reply_codes,
-+                                        &session->userauth_host_data,
-+                                        &data_len, 0, NULL, 0,
-+                                        &session->
-+                                        userauth_host_packet_requirev_state);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            session->userauth_host_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+
-+        if (session->userauth_host_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
-+            _libssh2_debug(session, LIBSSH2_DBG_AUTH,
-+                           "Hostbased authentication successful");
-+            /* We are us and we've proved it. */
-+            LIBSSH2_FREE(session, session->userauth_host_data);
-+            session->userauth_host_data = NULL;
-+            session->state |= LIBSSH2_STATE_AUTHENTICATED;
-+            session->userauth_host_state = libssh2_NB_state_idle;
-+            return 0;
-+        }
-+    }
-+
-+    /* This public key is not allowed for this user on this server */
-+    LIBSSH2_FREE(session, session->userauth_host_data);
-+    session->userauth_host_data = NULL;
-+    libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED,
-+                  "Invalid signature for supplied public key, or bad username/public key combination",
-+                  0);
-+    session->userauth_host_state = libssh2_NB_state_idle;
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_userauth_publickey_fromfile_ex
-+ * Authenticate using a keypair found in the named files
-+ */
-+LIBSSH2_API int
-+libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION * session,
-+                                       const char *username,
-+                                       unsigned int username_len,
-+                                       const char *publickey,
-+                                       const char *privatekey,
-+                                       const char *passphrase)
-+{
-+    unsigned long pubkeydata_len = 0;
-+    unsigned char reply_codes[4] =
-+        { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE,
-+        SSH_MSG_USERAUTH_PK_OK, 0
-+    };
-+    int rc;
-+
-+    if (session->userauth_pblc_state == libssh2_NB_state_idle) {
-+        unsigned char *pubkeydata;
-+
-+        /* Zero the whole thing out */
-+        memset(&session->userauth_pblc_packet_requirev_state, 0,
-+               sizeof(session->userauth_pblc_packet_requirev_state));
-+
-+        if (libssh2_file_read_publickey
-+            (session, &session->userauth_pblc_method,
-+             &session->userauth_pblc_method_len, &pubkeydata, &pubkeydata_len,
-+             publickey)) {
-+            return -1;
-+        }
-+
-+        /*
-+         * 45 = packet_type(1) + username_len(4) + servicename_len(4) + 
-+         * service_name(14)"ssh-connection" + authmethod_len(4) + 
-+         * authmethod(9)"publickey" + sig_included(1)'\0' + algmethod_len(4) +
-+         * publickey_len(4)
-+         */
-+        session->userauth_pblc_packet_len =
-+            username_len + session->userauth_pblc_method_len + pubkeydata_len +
-+            45;
-+
-+        /*
-+         * Preallocate space for an overall length,  method name again, and
-+         * the signature, which won't be any larger than the size of the 
-+         * publickeydata itself
-+         */
-+        session->userauth_pblc_s = session->userauth_pblc_packet =
-+            LIBSSH2_ALLOC(session,
-+                          session->userauth_pblc_packet_len + 4 + (4 +
-+                                                                   session->
-+                                                                   userauth_pblc_method_len)
-+                          + (4 + pubkeydata_len));
-+        if (!session->userauth_pblc_packet) {
-+            LIBSSH2_FREE(session, session->userauth_pblc_method);
-+            session->userauth_pblc_method = NULL;
-+            LIBSSH2_FREE(session, pubkeydata);
-+            return -1;
-+        }
-+
-+        *(session->userauth_pblc_s++) = SSH_MSG_USERAUTH_REQUEST;
-+        libssh2_htonu32(session->userauth_pblc_s, username_len);
-+        session->userauth_pblc_s += 4;
-+        memcpy(session->userauth_pblc_s, username, username_len);
-+        session->userauth_pblc_s += username_len;
-+
-+        libssh2_htonu32(session->userauth_pblc_s, 14);
-+        session->userauth_pblc_s += 4;
-+        memcpy(session->userauth_pblc_s, "ssh-connection", 14);
-+        session->userauth_pblc_s += 14;
-+
-+        libssh2_htonu32(session->userauth_pblc_s, 9);
-+        session->userauth_pblc_s += 4;
-+        memcpy(session->userauth_pblc_s, "publickey", 9);
-+        session->userauth_pblc_s += 9;
-+
-+        session->userauth_pblc_b = session->userauth_pblc_s;
-+        /* Not sending signature with *this* packet */
-+        *(session->userauth_pblc_s++) = 0;
-+
-+        libssh2_htonu32(session->userauth_pblc_s,
-+                        session->userauth_pblc_method_len);
-+        session->userauth_pblc_s += 4;
-+        memcpy(session->userauth_pblc_s, session->userauth_pblc_method,
-+               session->userauth_pblc_method_len);
-+        session->userauth_pblc_s += session->userauth_pblc_method_len;
-+
-+        libssh2_htonu32(session->userauth_pblc_s, pubkeydata_len);
-+        session->userauth_pblc_s += 4;
-+        memcpy(session->userauth_pblc_s, pubkeydata, pubkeydata_len);
-+        session->userauth_pblc_s += pubkeydata_len;
-+        LIBSSH2_FREE(session, pubkeydata);
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_AUTH,
-+                       "Attempting publickey authentication");
-+
-+        session->userauth_pblc_state = libssh2_NB_state_created;
-+    }
-+
-+    if (session->userauth_pblc_state == libssh2_NB_state_created) {
-+        rc = libssh2_packet_write(session, session->userauth_pblc_packet,
-+                                  session->userauth_pblc_packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send userauth-publickey request", 0);
-+            LIBSSH2_FREE(session, session->userauth_pblc_packet);
-+            session->userauth_pblc_packet = NULL;
-+            LIBSSH2_FREE(session, session->userauth_pblc_method);
-+            session->userauth_pblc_method = NULL;
-+            session->userauth_pblc_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+
-+        session->userauth_pblc_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (session->userauth_pblc_state == libssh2_NB_state_sent) {
-+        const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
-+        void *abstract;
-+        unsigned char buf[5];
-+        struct iovec datavec[4];
-+        unsigned char *sig;
-+        unsigned long sig_len;
-+
-+        rc = libssh2_packet_requirev_ex(session, reply_codes,
-+                                        &session->userauth_pblc_data,
-+                                        &session->userauth_pblc_data_len, 0,
-+                                        NULL, 0,
-+                                        &session->
-+                                        userauth_pblc_packet_requirev_state);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            LIBSSH2_FREE(session, session->userauth_pblc_packet);
-+            session->userauth_pblc_packet = NULL;
-+            LIBSSH2_FREE(session, session->userauth_pblc_method);
-+            session->userauth_pblc_method = NULL;
-+            session->userauth_pblc_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+
-+        if (session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
-+            _libssh2_debug(session, LIBSSH2_DBG_AUTH,
-+                           "Pubkey authentication prematurely successful");
-+            /*
-+             * God help any SSH server that allows an UNVERIFIED
-+             * public key to validate the user
-+             */
-+            LIBSSH2_FREE(session, session->userauth_pblc_data);
-+            session->userauth_pblc_data = NULL;
-+            LIBSSH2_FREE(session, session->userauth_pblc_packet);
-+            session->userauth_pblc_packet = NULL;
-+            LIBSSH2_FREE(session, session->userauth_pblc_method);
-+            session->userauth_pblc_method = NULL;
-+            session->state |= LIBSSH2_STATE_AUTHENTICATED;
-+            session->userauth_pblc_state = libssh2_NB_state_idle;
-+            return 0;
-+        }
-+
-+        if (session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_FAILURE) {
-+            /* This public key is not allowed for this user on this server */
-+            LIBSSH2_FREE(session, session->userauth_pblc_data);
-+            session->userauth_pblc_data = NULL;
-+            LIBSSH2_FREE(session, session->userauth_pblc_packet);
-+            session->userauth_pblc_packet = NULL;
-+            LIBSSH2_FREE(session, session->userauth_pblc_method);
-+            session->userauth_pblc_method = NULL;
-+            libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED,
-+                          "Username/PublicKey combination invalid", 0);
-+            session->userauth_pblc_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+
-+        /* Semi-Success! */
-+        LIBSSH2_FREE(session, session->userauth_pblc_data);
-+        session->userauth_pblc_data = NULL;
-+
-+        if (libssh2_file_read_privatekey
-+            (session, &privkeyobj, &abstract, session->userauth_pblc_method,
-+             session->userauth_pblc_method_len, privatekey, passphrase)) {
-+            LIBSSH2_FREE(session, session->userauth_pblc_method);
-+            session->userauth_pblc_method = NULL;
-+            LIBSSH2_FREE(session, session->userauth_pblc_packet);
-+            session->userauth_pblc_packet = NULL;
-+            session->userauth_pblc_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+
-+        *session->userauth_pblc_b = 0x01;
-+
-+        libssh2_htonu32(buf, session->session_id_len);
-+        datavec[0].iov_base = buf;
-+        datavec[0].iov_len = 4;
-+        datavec[1].iov_base = session->session_id;
-+        datavec[1].iov_len = session->session_id_len;
-+        datavec[2].iov_base = session->userauth_pblc_packet;
-+        datavec[2].iov_len = session->userauth_pblc_packet_len;
-+
-+        if (privkeyobj->signv(session, &sig, &sig_len, 3, datavec, &abstract)) {
-+            LIBSSH2_FREE(session, session->userauth_pblc_method);
-+            session->userauth_pblc_method = NULL;
-+            LIBSSH2_FREE(session, session->userauth_pblc_packet);
-+            session->userauth_pblc_packet = NULL;
-+            if (privkeyobj->dtor) {
-+                privkeyobj->dtor(session, &abstract);
-+            }
-+            session->userauth_pblc_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+
-+        if (privkeyobj->dtor) {
-+            privkeyobj->dtor(session, &abstract);
-+        }
-+
-+      /* 
-+       * If this function was restarted, pubkeydata_len might still be 0
-+       * which will cause an unnecessary but harmless realloc here.
-+       */
-+        if (sig_len > pubkeydata_len) {
-+            unsigned char *newpacket;
-+            /* Should *NEVER* happen, but...well.. better safe than sorry */
-+            newpacket = LIBSSH2_REALLOC(session, session->userauth_pblc_packet, session->userauth_pblc_packet_len + 4 + (4 + session->userauth_pblc_method_len) + (4 + sig_len));       /* PK sigblob */
-+            if (!newpacket) {
-+                libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                              "Failed allocating additional space for userauth-publickey packet",
-+                              0);
-+                LIBSSH2_FREE(session, sig);
-+                LIBSSH2_FREE(session, session->userauth_pblc_packet);
-+                session->userauth_pblc_packet = NULL;
-+                LIBSSH2_FREE(session, session->userauth_pblc_method);
-+                session->userauth_pblc_method = NULL;
-+                session->userauth_pblc_state = libssh2_NB_state_idle;
-+                return -1;
-+            }
-+            session->userauth_pblc_packet = newpacket;
-+        }
-+
-+        session->userauth_pblc_s =
-+            session->userauth_pblc_packet + session->userauth_pblc_packet_len;
-+        session->userauth_pblc_b = NULL;
-+
-+        libssh2_htonu32(session->userauth_pblc_s,
-+                        4 + session->userauth_pblc_method_len + 4 + sig_len);
-+        session->userauth_pblc_s += 4;
-+
-+        libssh2_htonu32(session->userauth_pblc_s,
-+                        session->userauth_pblc_method_len);
-+        session->userauth_pblc_s += 4;
-+        memcpy(session->userauth_pblc_s, session->userauth_pblc_method,
-+               session->userauth_pblc_method_len);
-+        session->userauth_pblc_s += session->userauth_pblc_method_len;
-+        LIBSSH2_FREE(session, session->userauth_pblc_method);
-+        session->userauth_pblc_method = NULL;
-+
-+        libssh2_htonu32(session->userauth_pblc_s, sig_len);
-+        session->userauth_pblc_s += 4;
-+        memcpy(session->userauth_pblc_s, sig, sig_len);
-+        session->userauth_pblc_s += sig_len;
-+        LIBSSH2_FREE(session, sig);
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_AUTH,
-+                       "Attempting publickey authentication -- phase 2");
-+
-+        session->userauth_pblc_state = libssh2_NB_state_sent1;
-+    }
-+
-+    if (session->userauth_pblc_state == libssh2_NB_state_sent1) {
-+        rc = libssh2_packet_write(session, session->userauth_pblc_packet,
-+                                  session->userauth_pblc_s -
-+                                  session->userauth_pblc_packet);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send userauth-publickey request", 0);
-+            LIBSSH2_FREE(session, session->userauth_pblc_packet);
-+            session->userauth_pblc_packet = NULL;
-+            session->userauth_pblc_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, session->userauth_pblc_packet);
-+        session->userauth_pblc_packet = NULL;
-+
-+        session->userauth_pblc_state = libssh2_NB_state_sent2;
-+    }
-+
-+    /* PK_OK is no longer valid */
-+    reply_codes[2] = 0;
-+
-+    rc = libssh2_packet_requirev_ex(session, reply_codes,
-+                                    &session->userauth_pblc_data,
-+                                    &session->userauth_pblc_data_len, 0, NULL,
-+                                    0,
-+                                    &session->
-+                                    userauth_pblc_packet_requirev_state);
-+    if (rc == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    } else if (rc) {
-+        session->userauth_pblc_state = libssh2_NB_state_idle;
-+        return -1;
-+    }
-+
-+    if (session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
-+        _libssh2_debug(session, LIBSSH2_DBG_AUTH,
-+                       "Publickey authentication successful");
-+        /* We are us and we've proved it. */
-+        LIBSSH2_FREE(session, session->userauth_pblc_data);
-+        session->userauth_pblc_data = NULL;
-+        session->state |= LIBSSH2_STATE_AUTHENTICATED;
-+        session->userauth_pblc_state = libssh2_NB_state_idle;
-+        return 0;
-+    }
-+
-+    /* This public key is not allowed for this user on this server */
-+    LIBSSH2_FREE(session, session->userauth_pblc_data);
-+    session->userauth_pblc_data = NULL;
-+    libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED,
-+                  "Invalid signature for supplied public key, or bad username/public key combination",
-+                  0);
-+    session->userauth_pblc_state = libssh2_NB_state_idle;
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_userauth_keyboard_interactive
-+ * Authenticate using a challenge-response authentication
-+ */
-+LIBSSH2_API int
-+libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION * session,
-+                                         const char *username,
-+                                         unsigned int username_len,
-+                                         LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback)))
-+{
-+    unsigned char *s;
-+    int rc;
-+
-+    static const unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS,
-+        SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_INFO_REQUEST, 0
-+    };
-+    unsigned int language_tag_len;
-+    unsigned int i;
-+
-+    if (session->userauth_kybd_state == libssh2_NB_state_idle) {
-+        session->userauth_kybd_auth_name = NULL;
-+        session->userauth_kybd_auth_instruction = NULL;
-+        session->userauth_kybd_num_prompts = 0;
-+        session->userauth_kybd_auth_failure = 1;
-+        session->userauth_kybd_prompts = NULL;
-+        session->userauth_kybd_responses = NULL;
-+
-+        /* Zero the whole thing out */
-+        memset(&session->userauth_kybd_packet_requirev_state, 0,
-+               sizeof(session->userauth_kybd_packet_requirev_state));
-+
-+        session->userauth_kybd_packet_len = 1   /* byte      SSH_MSG_USERAUTH_REQUEST */
-+            + 4 + username_len  /* string    user name (ISO-10646 UTF-8, as defined in [RFC-3629]) */
-+            + 4 + 14            /* string    service name (US-ASCII) */
-+            + 4 + 20            /* string    "keyboard-interactive" (US-ASCII) */
-+            + 4 + 0             /* string    language tag (as defined in [RFC-3066]) */
-+            + 4 + 0             /* string    submethods (ISO-10646 UTF-8) */
-+            ;
-+
-+        session->userauth_kybd_data = s =
-+            LIBSSH2_ALLOC(session, session->userauth_kybd_packet_len);
-+        if (!s) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for keyboard-interactive authentication",
-+                          0);
-+            return -1;
-+        }
-+
-+        *s++ = SSH_MSG_USERAUTH_REQUEST;
-+
-+        /* user name */
-+        libssh2_htonu32(s, username_len);
-+        s += 4;
-+        memcpy(s, username, username_len);
-+        s += username_len;
-+
-+        /* service name */
-+        libssh2_htonu32(s, sizeof("ssh-connection") - 1);
-+        s += 4;
-+        memcpy(s, "ssh-connection", sizeof("ssh-connection") - 1);
-+        s += sizeof("ssh-connection") - 1;
-+
-+        /* "keyboard-interactive" */
-+        libssh2_htonu32(s, sizeof("keyboard-interactive") - 1);
-+        s += 4;
-+        memcpy(s, "keyboard-interactive", sizeof("keyboard-interactive") - 1);
-+        s += sizeof("keyboard-interactive") - 1;
-+
-+        /* language tag */
-+        libssh2_htonu32(s, 0);
-+        s += 4;
-+
-+        /* submethods */
-+        libssh2_htonu32(s, 0);
-+        s += 4;
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_AUTH,
-+                       "Attempting keyboard-interactive authentication");
-+
-+        session->userauth_kybd_state = libssh2_NB_state_created;
-+    }
-+
-+    if (session->userauth_kybd_state == libssh2_NB_state_created) {
-+        rc = libssh2_packet_write(session, session->userauth_kybd_data,
-+                                  session->userauth_kybd_packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send keyboard-interactive request", 0);
-+            LIBSSH2_FREE(session, session->userauth_kybd_data);
-+            session->userauth_kybd_data = NULL;
-+            session->userauth_kybd_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, session->userauth_kybd_data);
-+        session->userauth_kybd_data = NULL;
-+
-+        session->userauth_kybd_state = libssh2_NB_state_sent;
-+    }
-+
-+    for(;;) {
-+        if (session->userauth_kybd_state == libssh2_NB_state_sent) {
-+            rc = libssh2_packet_requirev_ex(session, reply_codes,
-+                                            &session->userauth_kybd_data,
-+                                            &session->userauth_kybd_data_len,
-+                                            0, NULL, 0,
-+                                            &session->
-+                                            userauth_kybd_packet_requirev_state);
-+            if (rc == PACKET_EAGAIN) {
-+                return PACKET_EAGAIN;
-+            } else if (rc) {
-+                session->userauth_kybd_state = libssh2_NB_state_idle;
-+                return -1;
-+            }
-+
-+            if (session->userauth_kybd_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
-+                _libssh2_debug(session, LIBSSH2_DBG_AUTH,
-+                               "Keyboard-interactive authentication successful");
-+                LIBSSH2_FREE(session, session->userauth_kybd_data);
-+                session->userauth_kybd_data = NULL;
-+                session->state |= LIBSSH2_STATE_AUTHENTICATED;
-+                session->userauth_kybd_state = libssh2_NB_state_idle;
-+                return 0;
-+            }
-+
-+            if (session->userauth_kybd_data[0] == SSH_MSG_USERAUTH_FAILURE) {
-+                LIBSSH2_FREE(session, session->userauth_kybd_data);
-+                session->userauth_kybd_data = NULL;
-+                session->userauth_kybd_state = libssh2_NB_state_idle;
-+                return -1;
-+            }
-+
-+            /* server requested PAM-like conversation */
-+
-+            s = session->userauth_kybd_data + 1;
-+
-+            /* string    name (ISO-10646 UTF-8) */
-+            session->userauth_kybd_auth_name_len = libssh2_ntohu32(s);
-+            s += 4;
-+            session->userauth_kybd_auth_name =
-+                LIBSSH2_ALLOC(session, session->userauth_kybd_auth_name_len);
-+            if (!session->userauth_kybd_auth_name) {
-+                libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                              "Unable to allocate memory for keyboard-interactive 'name' request field",
-+                              0);
-+                goto cleanup;
-+            }
-+            memcpy(session->userauth_kybd_auth_name, s,
-+                   session->userauth_kybd_auth_name_len);
-+            s += session->userauth_kybd_auth_name_len;
-+
-+            /* string    instruction (ISO-10646 UTF-8) */
-+            session->userauth_kybd_auth_instruction_len = libssh2_ntohu32(s);
-+            s += 4;
-+            session->userauth_kybd_auth_instruction =
-+                LIBSSH2_ALLOC(session,
-+                              session->userauth_kybd_auth_instruction_len);
-+            if (!session->userauth_kybd_auth_instruction) {
-+                libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                              "Unable to allocate memory for keyboard-interactive 'instruction' request field",
-+                              0);
-+                goto cleanup;
-+            }
-+            memcpy(session->userauth_kybd_auth_instruction, s,
-+                   session->userauth_kybd_auth_instruction_len);
-+            s += session->userauth_kybd_auth_instruction_len;
-+
-+            /* string    language tag (as defined in [RFC-3066]) */
-+            language_tag_len = libssh2_ntohu32(s);
-+            s += 4;
-+            /* ignoring this field as deprecated */
-+            s += language_tag_len;
-+
-+            /* int       num-prompts */
-+            session->userauth_kybd_num_prompts = libssh2_ntohu32(s);
-+            s += 4;
-+
-+            session->userauth_kybd_prompts =
-+                LIBSSH2_ALLOC(session,
-+                              sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) *
-+                              session->userauth_kybd_num_prompts);
-+            if (!session->userauth_kybd_prompts) {
-+                libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                              "Unable to allocate memory for keyboard-interactive prompts array",
-+                              0);
-+                goto cleanup;
-+            }
-+            memset(session->userauth_kybd_prompts, 0,
-+                   sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) *
-+                   session->userauth_kybd_num_prompts);
-+
-+            session->userauth_kybd_responses =
-+                LIBSSH2_ALLOC(session,
-+                              sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) *
-+                              session->userauth_kybd_num_prompts);
-+            if (!session->userauth_kybd_responses) {
-+                libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                              "Unable to allocate memory for keyboard-interactive responses array",
-+                              0);
-+                goto cleanup;
-+            }
-+            memset(session->userauth_kybd_responses, 0,
-+                   sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) *
-+                   session->userauth_kybd_num_prompts);
-+
-+            for(i = 0; i != session->userauth_kybd_num_prompts; ++i) {
-+                /* string    prompt[1] (ISO-10646 UTF-8) */
-+                session->userauth_kybd_prompts[i].length = libssh2_ntohu32(s);
-+                s += 4;
-+                session->userauth_kybd_prompts[i].text =
-+                    LIBSSH2_ALLOC(session,
-+                                  session->userauth_kybd_prompts[i].length);
-+                if (!session->userauth_kybd_prompts[i].text) {
-+                    libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                                  "Unable to allocate memory for keyboard-interactive prompt message",
-+                                  0);
-+                    goto cleanup;
-+                }
-+                memcpy(session->userauth_kybd_prompts[i].text, s,
-+                       session->userauth_kybd_prompts[i].length);
-+                s += session->userauth_kybd_prompts[i].length;
-+
-+                /* boolean   echo[1] */
-+                session->userauth_kybd_prompts[i].echo = *s++;
-+            }
-+
-+            response_callback(session->userauth_kybd_auth_name,
-+                              session->userauth_kybd_auth_name_len,
-+                              session->userauth_kybd_auth_instruction,
-+                              session->userauth_kybd_auth_instruction_len,
-+                              session->userauth_kybd_num_prompts,
-+                              session->userauth_kybd_prompts,
-+                              session->userauth_kybd_responses,
-+                              &session->abstract);
-+
-+            _libssh2_debug(session, LIBSSH2_DBG_AUTH,
-+                           "Keyboard-interactive response callback function invoked");
-+
-+            session->userauth_kybd_packet_len = 1       /* byte      SSH_MSG_USERAUTH_INFO_RESPONSE */
-+                + 4             /* int       num-responses */
-+                ;
-+
-+            for(i = 0; i != session->userauth_kybd_num_prompts; ++i) {
-+                /* string    response[1] (ISO-10646 UTF-8) */
-+                session->userauth_kybd_packet_len +=
-+                    4 + session->userauth_kybd_responses[i].length;
-+            }
-+
-+            session->userauth_kybd_data = s =
-+                LIBSSH2_ALLOC(session, session->userauth_kybd_packet_len);
-+            if (!s) {
-+                libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                              "Unable to allocate memory for keyboard-interactive response packet",
-+                              0);
-+                goto cleanup;
-+            }
-+
-+            *s = SSH_MSG_USERAUTH_INFO_RESPONSE;
-+            s++;
-+            libssh2_htonu32(s, session->userauth_kybd_num_prompts);
-+            s += 4;
-+
-+            for(i = 0; i != session->userauth_kybd_num_prompts; ++i) {
-+                libssh2_htonu32(s, session->userauth_kybd_responses[i].length);
-+                s += 4;
-+                memcpy(s, session->userauth_kybd_responses[i].text,
-+                       session->userauth_kybd_responses[i].length);
-+                s += session->userauth_kybd_responses[i].length;
-+            }
-+
-+            session->userauth_kybd_state = libssh2_NB_state_sent1;
-+        }
-+
-+        if (session->userauth_kybd_state == libssh2_NB_state_sent1) {
-+            rc = libssh2_packet_write(session, session->userauth_kybd_data,
-+                                      session->userauth_kybd_packet_len);
-+            if (rc == PACKET_EAGAIN) {
-+                return PACKET_EAGAIN;
-+            }
-+            if (rc) {
-+                libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                              "Unable to send userauth-keyboard-interactive request",
-+                              0);
-+                goto cleanup;
-+            }
-+
-+            session->userauth_kybd_auth_failure = 0;
-+        }
-+
-+      cleanup:
-+        /*
-+         * It's safe to clean all the data here, because unallocated pointers
-+         * are filled by zeroes
-+         */
-+
-+        LIBSSH2_FREE(session, session->userauth_kybd_data);
-+        session->userauth_kybd_data = NULL;
-+
-+        if (session->userauth_kybd_prompts) {
-+            for(i = 0; i != session->userauth_kybd_num_prompts; ++i) {
-+                LIBSSH2_FREE(session, session->userauth_kybd_prompts[i].text);
-+                session->userauth_kybd_prompts[i].text = NULL;
-+            }
-+        }
-+
-+        if (session->userauth_kybd_responses) {
-+            for(i = 0; i != session->userauth_kybd_num_prompts; ++i) {
-+                LIBSSH2_FREE(session,
-+                             session->userauth_kybd_responses[i].text);
-+                session->userauth_kybd_responses[i].text = NULL;
-+            }
-+        }
-+
-+        LIBSSH2_FREE(session, session->userauth_kybd_prompts);
-+        session->userauth_kybd_prompts = NULL;
-+        LIBSSH2_FREE(session, session->userauth_kybd_responses);
-+        session->userauth_kybd_responses = NULL;
-+
-+        if (session->userauth_kybd_auth_failure) {
-+            session->userauth_kybd_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+
-+        session->userauth_kybd_state = libssh2_NB_state_sent;
-+    }
-+}
-+
-+/* }}} */
-
-Property changes on: libssh2/src/userauth.c
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.2
-Added: svn:eol-style
-   + native
-
-Index: libssh2/src/mac.c
-===================================================================
---- libssh2/src/mac.c  (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/mac.c  (.../trunk)
-@@ -0,0 +1,311 @@
-+/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#include "libssh2_priv.h"
-+
-+#ifdef LIBSSH2_MAC_NONE
-+/* {{{ libssh2_mac_none_MAC
-+ * Minimalist MAC: No MAC
-+ */
-+static int
-+libssh2_mac_none_MAC(LIBSSH2_SESSION * session, unsigned char *buf,
-+                     unsigned long seqno, const unsigned char *packet,
-+                     unsigned long packet_len, const unsigned char *addtl,
-+                     unsigned long addtl_len, void **abstract)
-+{
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+
-+static LIBSSH2_MAC_METHOD libssh2_mac_method_none = {
-+    "none",
-+    0,
-+    0,
-+    NULL,
-+    libssh2_mac_none_MAC,
-+    NULL
-+};
-+#endif /* LIBSSH2_MAC_NONE */
-+
-+/* {{{ libssh2_mac_method_common_init
-+ * Initialize simple mac methods
-+ */
-+static int
-+libssh2_mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key,
-+                               int *free_key, void **abstract)
-+{
-+    *abstract = key;
-+    *free_key = 0;
-+    (void) session;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_mac_method_common_dtor
-+ * Cleanup simple mac methods
-+ */
-+static int
-+libssh2_mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract)
-+{
-+    if (*abstract) {
-+        LIBSSH2_FREE(session, *abstract);
-+    }
-+    *abstract = NULL;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_mac_method_hmac_sha1_hash
-+ * Calculate hash using full sha1 value
-+ */
-+static int
-+libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,
-+                                  unsigned char *buf, unsigned long seqno,
-+                                  const unsigned char *packet,
-+                                  unsigned long packet_len,
-+                                  const unsigned char *addtl,
-+                                  unsigned long addtl_len, void **abstract)
-+{
-+    libssh2_hmac_ctx ctx;
-+    unsigned char seqno_buf[4];
-+    (void) session;
-+
-+    libssh2_htonu32(seqno_buf, seqno);
-+
-+    libssh2_hmac_sha1_init(&ctx, *abstract, 20);
-+    libssh2_hmac_update(ctx, seqno_buf, 4);
-+    libssh2_hmac_update(ctx, packet, packet_len);
-+    if (addtl && addtl_len) {
-+        libssh2_hmac_update(ctx, addtl, addtl_len);
-+    }
-+    libssh2_hmac_final(ctx, buf);
-+    libssh2_hmac_cleanup(&ctx);
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1 = {
-+    "hmac-sha1",
-+    20,
-+    20,
-+    libssh2_mac_method_common_init,
-+    libssh2_mac_method_hmac_sha1_hash,
-+    libssh2_mac_method_common_dtor,
-+};
-+
-+/* {{{ libssh2_mac_method_hmac_sha1_96_hash
-+ * Calculate hash using first 96 bits of sha1 value
-+ */
-+static int
-+libssh2_mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session,
-+                                     unsigned char *buf, unsigned long seqno,
-+                                     const unsigned char *packet,
-+                                     unsigned long packet_len,
-+                                     const unsigned char *addtl,
-+                                     unsigned long addtl_len, void **abstract)
-+{
-+    unsigned char temp[SHA_DIGEST_LENGTH];
-+
-+    libssh2_mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len,
-+                                      addtl, addtl_len, abstract);
-+    memcpy(buf, (char *) temp, 96 / 8);
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = {
-+    "hmac-sha1-96",
-+    12,
-+    20,
-+    libssh2_mac_method_common_init,
-+    libssh2_mac_method_hmac_sha1_96_hash,
-+    libssh2_mac_method_common_dtor,
-+};
-+
-+/* {{{ libssh2_mac_method_hmac_md5_hash
-+ * Calculate hash using full md5 value
-+ */
-+static int
-+libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf,
-+                                 unsigned long seqno,
-+                                 const unsigned char *packet,
-+                                 unsigned long packet_len,
-+                                 const unsigned char *addtl,
-+                                 unsigned long addtl_len, void **abstract)
-+{
-+    libssh2_hmac_ctx ctx;
-+    unsigned char seqno_buf[4];
-+    (void) session;
-+
-+    libssh2_htonu32(seqno_buf, seqno);
-+
-+    libssh2_hmac_md5_init(&ctx, *abstract, 16);
-+    libssh2_hmac_update(ctx, seqno_buf, 4);
-+    libssh2_hmac_update(ctx, packet, packet_len);
-+    if (addtl && addtl_len) {
-+        libssh2_hmac_update(ctx, addtl, addtl_len);
-+    }
-+    libssh2_hmac_final(ctx, buf);
-+    libssh2_hmac_cleanup(&ctx);
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5 = {
-+    "hmac-md5",
-+    16,
-+    16,
-+    libssh2_mac_method_common_init,
-+    libssh2_mac_method_hmac_md5_hash,
-+    libssh2_mac_method_common_dtor,
-+};
-+
-+/* {{{ libssh2_mac_method_hmac_md5_96_hash
-+ * Calculate hash using first 96 bits of md5 value
-+ */
-+static int
-+libssh2_mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session,
-+                                    unsigned char *buf, unsigned long seqno,
-+                                    const unsigned char *packet,
-+                                    unsigned long packet_len,
-+                                    const unsigned char *addtl,
-+                                    unsigned long addtl_len, void **abstract)
-+{
-+    unsigned char temp[MD5_DIGEST_LENGTH];
-+
-+    libssh2_mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len,
-+                                     addtl, addtl_len, abstract);
-+    memcpy(buf, (char *) temp, 96 / 8);
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = {
-+    "hmac-md5-96",
-+    12,
-+    16,
-+    libssh2_mac_method_common_init,
-+    libssh2_mac_method_hmac_md5_96_hash,
-+    libssh2_mac_method_common_dtor,
-+};
-+
-+#if LIBSSH2_HMAC_RIPEMD
-+/* {{{ libssh2_mac_method_hmac_ripemd160_hash
-+ * Calculate hash using ripemd160 value
-+ */
-+static int
-+libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,
-+                                       unsigned char *buf, unsigned long seqno,
-+                                       const unsigned char *packet,
-+                                       unsigned long packet_len,
-+                                       const unsigned char *addtl,
-+                                       unsigned long addtl_len,
-+                                       void **abstract)
-+{
-+    libssh2_hmac_ctx ctx;
-+    unsigned char seqno_buf[4];
-+    (void) session;
-+
-+    libssh2_htonu32(seqno_buf, seqno);
-+
-+    libssh2_hmac_ripemd160_init(&ctx, *abstract, 20);
-+    libssh2_hmac_update(ctx, seqno_buf, 4);
-+    libssh2_hmac_update(ctx, packet, packet_len);
-+    if (addtl && addtl_len) {
-+        libssh2_hmac_update(ctx, addtl, addtl_len);
-+    }
-+    libssh2_hmac_final(ctx, buf);
-+    libssh2_hmac_cleanup(&ctx);
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160 = {
-+    "hmac-ripemd160",
-+    20,
-+    20,
-+    libssh2_mac_method_common_init,
-+    libssh2_mac_method_hmac_ripemd160_hash,
-+    libssh2_mac_method_common_dtor,
-+};
-+
-+static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160_openssh_com = {
-+    "hmac-ripemd160@openssh.com",
-+    20,
-+    20,
-+    libssh2_mac_method_common_init,
-+    libssh2_mac_method_hmac_ripemd160_hash,
-+    libssh2_mac_method_common_dtor,
-+};
-+#endif /* LIBSSH2_HMAC_RIPEMD */
-+
-+static const LIBSSH2_MAC_METHOD *_libssh2_mac_methods[] = {
-+    &libssh2_mac_method_hmac_sha1,
-+    &libssh2_mac_method_hmac_sha1_96,
-+    &libssh2_mac_method_hmac_md5,
-+    &libssh2_mac_method_hmac_md5_96,
-+#if LIBSSH2_HMAC_RIPEMD
-+    &libssh2_mac_method_hmac_ripemd160,
-+    &libssh2_mac_method_hmac_ripemd160_openssh_com,
-+#endif /* LIBSSH2_HMAC_RIPEMD */
-+#ifdef LIBSSH2_MAC_NONE
-+    &libssh2_mac_method_none,
-+#endif /* LIBSSH2_MAC_NONE */
-+    NULL
-+};
-+
-+const LIBSSH2_MAC_METHOD **
-+libssh2_mac_methods(void)
-+{
-+    return _libssh2_mac_methods;
-+}
-
-Property changes on: libssh2/src/mac.c
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.2
-Added: svn:eol-style
-   + native
-
-Index: libssh2/src/crypt.c
-===================================================================
---- libssh2/src/crypt.c        (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/crypt.c        (.../trunk)
-@@ -0,0 +1,256 @@
-+/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#include "libssh2_priv.h"
-+
-+#ifdef LIBSSH2_CRYPT_NONE
-+/* {{{ libssh2_crypt_none_crypt
-+ * Minimalist cipher: VERY secure *wink*
-+ */
-+static int
-+libssh2_crypt_none_crypt(LIBSSH2_SESSION * session, unsigned char *buf,
-+                         void **abstract)
-+{
-+    /* Do nothing to the data! */
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = {
-+    "none",
-+    8,                          /* blocksize (SSH2 defines minimum blocksize as 8) */
-+    0,                          /* iv_len */
-+    0,                          /* secret_len */
-+    0,                          /* flags */
-+    NULL,
-+    libssh2_crypt_none_crypt,
-+    NULL
-+};
-+#endif /* LIBSSH2_CRYPT_NONE */
-+
-+struct crypt_ctx
-+{
-+    int encrypt;
-+      _libssh2_cipher_type(algo);
-+    _libssh2_cipher_ctx h;
-+};
-+
-+static int
-+_libssh2_init(LIBSSH2_SESSION * session,
-+              const LIBSSH2_CRYPT_METHOD * method,
-+              unsigned char *iv, int *free_iv,
-+              unsigned char *secret, int *free_secret,
-+              int encrypt, void **abstract)
-+{
-+    struct crypt_ctx *ctx = LIBSSH2_ALLOC(session,
-+                                          sizeof(struct crypt_ctx));
-+    if (!ctx) {
-+        return -1;
-+    }
-+    ctx->encrypt = encrypt;
-+    ctx->algo = method->algo;
-+    if (_libssh2_cipher_init(&ctx->h, ctx->algo, iv, secret, encrypt)) {
-+        LIBSSH2_FREE(session, ctx);
-+        return -1;
-+    }
-+    *abstract = ctx;
-+    *free_iv = 1;
-+    *free_secret = 1;
-+    return 0;
-+}
-+
-+static int
-+_libssh2_encrypt(LIBSSH2_SESSION * session, unsigned char *block,
-+                 void **abstract)
-+{
-+    struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
-+    (void) session;
-+    return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block);
-+}
-+
-+static int
-+_libssh2_dtor(LIBSSH2_SESSION * session, void **abstract)
-+{
-+    struct crypt_ctx **cctx = (struct crypt_ctx **) abstract;
-+    if (cctx && *cctx) {
-+        _libssh2_cipher_dtor(&(*cctx)->h);
-+        LIBSSH2_FREE(session, *cctx);
-+        *abstract = NULL;
-+    }
-+    return 0;
-+}
-+
-+#if LIBSSH2_AES
-+static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
-+    "aes128-cbc",
-+    16,                         /* blocksize */
-+    16,                         /* initial value length */
-+    16,                         /* secret length -- 16*8 == 128bit */
-+    0,                          /* flags */
-+    &_libssh2_init,
-+    &_libssh2_encrypt,
-+    &_libssh2_dtor,
-+    _libssh2_cipher_aes128
-+};
-+
-+static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = {
-+    "aes192-cbc",
-+    16,                         /* blocksize */
-+    16,                         /* initial value length */
-+    24,                         /* secret length -- 24*8 == 192bit */
-+    0,                          /* flags */
-+    &_libssh2_init,
-+    &_libssh2_encrypt,
-+    &_libssh2_dtor,
-+    _libssh2_cipher_aes192
-+};
-+
-+static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = {
-+    "aes256-cbc",
-+    16,                         /* blocksize */
-+    16,                         /* initial value length */
-+    32,                         /* secret length -- 32*8 == 256bit */
-+    0,                          /* flags */
-+    &_libssh2_init,
-+    &_libssh2_encrypt,
-+    &_libssh2_dtor,
-+    _libssh2_cipher_aes256
-+};
-+
-+/* rijndael-cbc@lysator.liu.se == aes256-cbc */
-+static const LIBSSH2_CRYPT_METHOD
-+    libssh2_crypt_method_rijndael_cbc_lysator_liu_se = {
-+    "rijndael-cbc@lysator.liu.se",
-+    16,                         /* blocksize */
-+    16,                         /* initial value length */
-+    32,                         /* secret length -- 32*8 == 256bit */
-+    0,                          /* flags */
-+    &_libssh2_init,
-+    &_libssh2_encrypt,
-+    &_libssh2_dtor,
-+    _libssh2_cipher_aes256
-+};
-+#endif /* LIBSSH2_AES */
-+
-+#if LIBSSH2_BLOWFISH
-+static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = {
-+    "blowfish-cbc",
-+    8,                          /* blocksize */
-+    8,                          /* initial value length */
-+    16,                         /* secret length */
-+    0,                          /* flags */
-+    &_libssh2_init,
-+    &_libssh2_encrypt,
-+    &_libssh2_dtor,
-+    _libssh2_cipher_blowfish
-+};
-+#endif /* LIBSSH2_BLOWFISH */
-+
-+#if LIBSSH2_RC4
-+static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
-+    "arcfour",
-+    8,                          /* blocksize */
-+    8,                          /* initial value length */
-+    16,                         /* secret length */
-+    0,                          /* flags */
-+    &_libssh2_init,
-+    &_libssh2_encrypt,
-+    &_libssh2_dtor,
-+    _libssh2_cipher_arcfour
-+};
-+#endif /* LIBSSH2_RC4 */
-+
-+#if LIBSSH2_CAST
-+static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = {
-+    "cast128-cbc",
-+    8,                          /* blocksize */
-+    8,                          /* initial value length */
-+    16,                         /* secret length */
-+    0,                          /* flags */
-+    &_libssh2_init,
-+    &_libssh2_encrypt,
-+    &_libssh2_dtor,
-+    _libssh2_cipher_cast5
-+};
-+#endif /* LIBSSH2_CAST */
-+
-+#if LIBSSH2_3DES
-+static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
-+    "3des-cbc",
-+    8,                          /* blocksize */
-+    8,                          /* initial value length */
-+    24,                         /* secret length */
-+    0,                          /* flags */
-+    &_libssh2_init,
-+    &_libssh2_encrypt,
-+    &_libssh2_dtor,
-+    _libssh2_cipher_3des
-+};
-+#endif
-+
-+static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
-+#if LIBSSH2_AES
-+    &libssh2_crypt_method_aes256_cbc,
-+    &libssh2_crypt_method_rijndael_cbc_lysator_liu_se,  /* == aes256-cbc */
-+    &libssh2_crypt_method_aes192_cbc,
-+    &libssh2_crypt_method_aes128_cbc,
-+#endif /* LIBSSH2_AES */
-+#if LIBSSH2_BLOWFISH
-+    &libssh2_crypt_method_blowfish_cbc,
-+#endif /* LIBSSH2_BLOWFISH */
-+#if LIBSSH2_RC4
-+    &libssh2_crypt_method_arcfour,
-+#endif /* LIBSSH2_RC4 */
-+#if LIBSSH2_CAST
-+    &libssh2_crypt_method_cast128_cbc,
-+#endif /* LIBSSH2_CAST */
-+#if LIBSSH2_3DES
-+    &libssh2_crypt_method_3des_cbc,
-+#endif /*  LIBSSH2_DES */
-+#ifdef LIBSSH2_CRYPT_NONE
-+    &libssh2_crypt_method_none,
-+#endif
-+    NULL
-+};
-+
-+/* Expose to kex.c */
-+const LIBSSH2_CRYPT_METHOD **
-+libssh2_crypt_methods(void)
-+{
-+    return _libssh2_crypt_methods;
-+}
-
-Property changes on: libssh2/src/crypt.c
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.2
-Added: svn:eol-style
-   + native
-
-Index: libssh2/src/libgcrypt.h
-===================================================================
---- libssh2/src/libgcrypt.h    (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/libgcrypt.h    (.../trunk)
-@@ -0,0 +1,187 @@
-+/* Copyright (C) 2006, 2007, The Written Word, Inc.
-+ * Copyright (C) 2008, Simon Josefsson
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#include <gcrypt.h>
-+
-+#define LIBSSH2_MD5 1
-+
-+#define LIBSSH2_HMAC_RIPEMD 1
-+
-+#define LIBSSH2_AES 1
-+#define LIBSSH2_BLOWFISH 1
-+#define LIBSSH2_RC4 1
-+#define LIBSSH2_CAST 1
-+#define LIBSSH2_3DES 1
-+
-+#define LIBSSH2_RSA 1
-+#define LIBSSH2_DSA 1
-+
-+#define MD5_DIGEST_LENGTH 16
-+#define SHA_DIGEST_LENGTH 20
-+
-+#define libssh2_random(buf, len)                \
-+  (gcry_randomize ((buf), (len), GCRY_STRONG_RANDOM), 1)
-+
-+#define libssh2_sha1_ctx gcry_md_hd_t
-+#define libssh2_sha1_init(ctx) gcry_md_open (ctx,  GCRY_MD_SHA1, 0);
-+#define libssh2_sha1_update(ctx, data, len) gcry_md_write (ctx, data, len)
-+#define libssh2_sha1_final(ctx, out) \
-+  memcpy (out, gcry_md_read (ctx, 0), 20), gcry_md_close (ctx)
-+#define libssh2_sha1(message, len, out) \
-+  gcry_md_hash_buffer (GCRY_MD_SHA1, out, message, len)
-+
-+#define libssh2_md5_ctx gcry_md_hd_t
-+#define libssh2_md5_init(ctx) gcry_md_open (ctx,  GCRY_MD_MD5, 0);
-+#define libssh2_md5_update(ctx, data, len) gcry_md_write (ctx, data, len)
-+#define libssh2_md5_final(ctx, out) \
-+  memcpy (out, gcry_md_read (ctx, 0), 20), gcry_md_close (ctx)
-+#define libssh2_md5(message, len, out) \
-+  gcry_md_hash_buffer (GCRY_MD_MD5, out, message, len)
-+
-+#define libssh2_hmac_ctx gcry_md_hd_t
-+#define libssh2_hmac_sha1_init(ctx, key, keylen) \
-+  gcry_md_open (ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC), \
-+    gcry_md_setkey (*ctx, key, keylen)
-+#define libssh2_hmac_md5_init(ctx, key, keylen) \
-+  gcry_md_open (ctx, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC), \
-+    gcry_md_setkey (*ctx, key, keylen)
-+#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
-+  gcry_md_open (ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC), \
-+    gcry_md_setkey (*ctx, key, keylen)
-+#define libssh2_hmac_update(ctx, data, datalen) \
-+  gcry_md_write (ctx, data, datalen)
-+#define libssh2_hmac_final(ctx, data) \
-+  memcpy (data, gcry_md_read (ctx, 0), \
-+      gcry_md_get_algo_dlen (gcry_md_get_algo (ctx)))
-+#define libssh2_hmac_cleanup(ctx) gcry_md_close (*ctx);
-+
-+#define libssh2_crypto_init() gcry_control (GCRYCTL_DISABLE_SECMEM)
-+
-+#define libssh2_rsa_ctx struct gcry_sexp
-+
-+int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
-+                     const unsigned char *edata,
-+                     unsigned long elen,
-+                     const unsigned char *ndata,
-+                     unsigned long nlen,
-+                     const unsigned char *ddata,
-+                     unsigned long dlen,
-+                     const unsigned char *pdata,
-+                     unsigned long plen,
-+                     const unsigned char *qdata,
-+                     unsigned long qlen,
-+                     const unsigned char *e1data,
-+                     unsigned long e1len,
-+                     const unsigned char *e2data,
-+                     unsigned long e2len,
-+                     const unsigned char *coeffdata, unsigned long coefflen);
-+int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
-+                             LIBSSH2_SESSION * session,
-+                             FILE * fp, unsigned const char *passphrase);
-+int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
-+                             const unsigned char *sig,
-+                             unsigned long sig_len,
-+                             const unsigned char *m, unsigned long m_len);
-+int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
-+                           libssh2_rsa_ctx * rsactx,
-+                           const unsigned char *hash,
-+                           unsigned long hash_len,
-+                           unsigned char **signature,
-+                           unsigned long *signature_len);
-+
-+#define _libssh2_rsa_free(rsactx)  gcry_sexp_release (rsactx)
-+
-+#define libssh2_dsa_ctx struct gcry_sexp
-+
-+int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
-+                     const unsigned char *pdata,
-+                     unsigned long plen,
-+                     const unsigned char *qdata,
-+                     unsigned long qlen,
-+                     const unsigned char *gdata,
-+                     unsigned long glen,
-+                     const unsigned char *ydata,
-+                     unsigned long ylen,
-+                     const unsigned char *x, unsigned long x_len);
-+int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
-+                             LIBSSH2_SESSION * session,
-+                             FILE * fp, unsigned const char *passphrase);
-+int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsa,
-+                             const unsigned char *sig,
-+                             const unsigned char *m, unsigned long m_len);
-+int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
-+                           const unsigned char *hash,
-+                           unsigned long hash_len, unsigned char *sig);
-+
-+#define _libssh2_dsa_free(dsactx)  gcry_sexp_release (dsactx)
-+
-+#define _libssh2_cipher_type(name) int name
-+#define _libssh2_cipher_ctx gcry_cipher_hd_t
-+
-+#define _libssh2_cipher_aes256 GCRY_CIPHER_AES256
-+#define _libssh2_cipher_aes192 GCRY_CIPHER_AES192
-+#define _libssh2_cipher_aes128 GCRY_CIPHER_AES128
-+#define _libssh2_cipher_blowfish GCRY_CIPHER_BLOWFISH
-+#define _libssh2_cipher_arcfour GCRY_CIPHER_ARCFOUR
-+#define _libssh2_cipher_cast5 GCRY_CIPHER_CAST5
-+#define _libssh2_cipher_3des GCRY_CIPHER_3DES
-+
-+int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
-+                         _libssh2_cipher_type(algo),
-+                         unsigned char *iv,
-+                         unsigned char *secret, int encrypt);
-+
-+int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
-+                          _libssh2_cipher_type(algo),
-+                          int encrypt, unsigned char *block);
-+
-+#define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx))
-+
-+#define _libssh2_bn struct gcry_mpi
-+#define _libssh2_bn_ctx int
-+#define _libssh2_bn_ctx_new() 0
-+#define _libssh2_bn_ctx_free(bnctx) ((void)0)
-+#define _libssh2_bn_init() gcry_mpi_new(0)
-+#define _libssh2_bn_rand(bn, bits, top, bottom) gcry_mpi_randomize (bn, bits, GCRY_WEAK_RANDOM)
-+#define _libssh2_bn_mod_exp(r, a, p, m, ctx) gcry_mpi_powm (r, a, p, m)
-+#define _libssh2_bn_set_word(bn, val) gcry_mpi_set_ui(bn, val)
-+#define _libssh2_bn_from_bin(bn, len, val) gcry_mpi_scan(&((bn)), GCRYMPI_FMT_USG, val, len, NULL)
-+#define _libssh2_bn_to_bin(bn, val) gcry_mpi_print (GCRYMPI_FMT_USG, val, _libssh2_bn_bytes(bn), NULL, bn)
-+#define _libssh2_bn_bytes(bn) (gcry_mpi_get_nbits (bn) / 8 + ((gcry_mpi_get_nbits (bn) % 8 == 0) ? 0 : 1))
-+#define _libssh2_bn_bits(bn) gcry_mpi_get_nbits (bn)
-+#define _libssh2_bn_free(bn) gcry_mpi_release(bn)
-
-Property changes on: libssh2/src/libgcrypt.h
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.1
-Added: svn:eol-style
-   + native
-Added: svn:executable
-   + *
-
-Index: libssh2/src/packet.c
-===================================================================
---- libssh2/src/packet.c       (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/packet.c       (.../trunk)
-@@ -0,0 +1,1270 @@
-+/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#include "libssh2_priv.h"
-+#include <errno.h>
-+#include <fcntl.h>
-+
-+#ifdef HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#ifdef HAVE_SYS_TIME_H
-+#include <sys/time.h>
-+#endif
-+
-+#ifdef HAVE_INTTYPES_H
-+#include <inttypes.h>
-+#endif
-+
-+/* Needed for struct iovec on some platforms */
-+#ifdef HAVE_SYS_UIO_H
-+#include <sys/uio.h>
-+#endif
-+
-+#include <sys/types.h>
-+
-+/* {{{ libssh2_packet_queue_listener
-+ * Queue a connection request for a listener
-+ */
-+static inline int
-+libssh2_packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
-+                              unsigned long datalen,
-+                              packet_queue_listener_state_t * listen_state)
-+{
-+    /*
-+     * Look for a matching listener
-+     */
-+    unsigned char *s = data + (sizeof("forwarded-tcpip") - 1) + 5;
-+    /* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
-+    unsigned long packet_len = 17 + (sizeof(FwdNotReq) - 1);
-+    unsigned char *p;
-+    LIBSSH2_LISTENER *listen = session->listeners;
-+    char failure_code = 1;      /* SSH_OPEN_ADMINISTRATIVELY_PROHIBITED */
-+    int rc;
-+
-+    (void) datalen;
-+
-+    if (listen_state->state == libssh2_NB_state_idle) {
-+        listen_state->sender_channel = libssh2_ntohu32(s);
-+        s += 4;
-+
-+        listen_state->initial_window_size = libssh2_ntohu32(s);
-+        s += 4;
-+        listen_state->packet_size = libssh2_ntohu32(s);
-+        s += 4;
-+
-+        listen_state->host_len = libssh2_ntohu32(s);
-+        s += 4;
-+        listen_state->host = s;
-+        s += listen_state->host_len;
-+        listen_state->port = libssh2_ntohu32(s);
-+        s += 4;
-+
-+        listen_state->shost_len = libssh2_ntohu32(s);
-+        s += 4;
-+        listen_state->shost = s;
-+        s += listen_state->shost_len;
-+        listen_state->sport = libssh2_ntohu32(s);
-+        s += 4;
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                       "Remote received connection from %s:%ld to %s:%ld",
-+                       listen_state->shost, listen_state->sport,
-+                       listen_state->host, listen_state->port);
-+
-+        listen_state->state = libssh2_NB_state_allocated;
-+    }
-+
-+    if (listen_state->state != libssh2_NB_state_sent) {
-+        while (listen) {
-+            if ((listen->port == (int) listen_state->port) &&
-+                (strlen(listen->host) == listen_state->host_len) &&
-+                (memcmp
-+                 (listen->host, listen_state->host,
-+                  listen_state->host_len) == 0)) {
-+                /* This is our listener */
-+                LIBSSH2_CHANNEL *channel, *last_queued = listen->queue;
-+
-+                last_queued = listen->queue;
-+                if (listen_state->state == libssh2_NB_state_allocated) {
-+                    if (listen->queue_maxsize &&
-+                        (listen->queue_maxsize <= listen->queue_size)) {
-+                        /* Queue is full */
-+                        failure_code = 4;       /* SSH_OPEN_RESOURCE_SHORTAGE */
-+                        _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                                       "Listener queue full, ignoring");
-+                        listen_state->state = libssh2_NB_state_sent;
-+                        break;
-+                    }
-+
-+                    channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL));
-+                    if (!channel) {
-+                        libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                                      "Unable to allocate a channel for new connection",
-+                                      0);
-+                        failure_code = 4;       /* SSH_OPEN_RESOURCE_SHORTAGE */
-+                        listen_state->state = libssh2_NB_state_sent;
-+                        break;
-+                    }
-+                    memset(channel, 0, sizeof(LIBSSH2_CHANNEL));
-+
-+                    channel->session = session;
-+                    channel->channel_type_len = sizeof("forwarded-tcpip") - 1;
-+                    channel->channel_type = LIBSSH2_ALLOC(session,
-+                                                          channel->
-+                                                          channel_type_len +
-+                                                          1);
-+                    if (!channel->channel_type) {
-+                        libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                                      "Unable to allocate a channel for new connection",
-+                                      0);
-+                        LIBSSH2_FREE(session, channel);
-+                        failure_code = 4;       /* SSH_OPEN_RESOURCE_SHORTAGE */
-+                        listen_state->state = libssh2_NB_state_sent;
-+                        break;
-+                    }
-+                    memcpy(channel->channel_type, "forwarded-tcpip",
-+                           channel->channel_type_len + 1);
-+
-+                    channel->remote.id = listen_state->sender_channel;
-+                    channel->remote.window_size_initial =
-+                        LIBSSH2_CHANNEL_WINDOW_DEFAULT;
-+                    channel->remote.window_size =
-+                        LIBSSH2_CHANNEL_WINDOW_DEFAULT;
-+                    channel->remote.packet_size =
-+                        LIBSSH2_CHANNEL_PACKET_DEFAULT;
-+
-+                    channel->local.id = libssh2_channel_nextid(session);
-+                    channel->local.window_size_initial =
-+                        listen_state->initial_window_size;
-+                    channel->local.window_size =
-+                        listen_state->initial_window_size;
-+                    channel->local.packet_size = listen_state->packet_size;
-+
-+                    _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                                   "Connection queued: channel %lu/%lu win %lu/%lu packet %lu/%lu",
-+                                   channel->local.id, channel->remote.id,
-+                                   channel->local.window_size,
-+                                   channel->remote.window_size,
-+                                   channel->local.packet_size,
-+                                   channel->remote.packet_size);
-+
-+                    p = listen_state->packet;
-+                    *(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION;
-+                    libssh2_htonu32(p, channel->remote.id);
-+                    p += 4;
-+                    libssh2_htonu32(p, channel->local.id);
-+                    p += 4;
-+                    libssh2_htonu32(p, channel->remote.window_size_initial);
-+                    p += 4;
-+                    libssh2_htonu32(p, channel->remote.packet_size);
-+                    p += 4;
-+
-+                    listen_state->state = libssh2_NB_state_created;
-+                }
-+
-+                if (listen_state->state == libssh2_NB_state_created) {
-+                    rc = libssh2_packet_write(session, listen_state->packet,
-+                                              17);
-+                    if (rc == PACKET_EAGAIN) {
-+                        return PACKET_EAGAIN;
-+                    } else if (rc) {
-+                        libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                                      "Unable to send channel open confirmation",
-+                                      0);
-+                        listen_state->state = libssh2_NB_state_idle;
-+                        return -1;
-+                    }
-+
-+                    /* Link the channel into the end of the queue list */
-+
-+                    if (!last_queued) {
-+                        listen->queue = channel;
-+                        listen_state->state = libssh2_NB_state_idle;
-+                        return 0;
-+                    }
-+
-+                    while (last_queued->next) {
-+                        last_queued = last_queued->next;
-+                    }
-+
-+                    last_queued->next = channel;
-+                    channel->prev = last_queued;
-+
-+                    listen->queue_size++;
-+
-+                    listen_state->state = libssh2_NB_state_idle;
-+                    return 0;
-+                }
-+            }
-+
-+            listen = listen->next;
-+        }
-+
-+        listen_state->state = libssh2_NB_state_sent;
-+    }
-+
-+    /* We're not listening to you */
-+    {
-+        p = listen_state->packet;
-+        *(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
-+        libssh2_htonu32(p, listen_state->sender_channel);
-+        p += 4;
-+        libssh2_htonu32(p, failure_code);
-+        p += 4;
-+        libssh2_htonu32(p, sizeof(FwdNotReq) - 1);
-+        p += 4;
-+        memcpy(s, FwdNotReq, sizeof(FwdNotReq) - 1);
-+        p += sizeof(FwdNotReq) - 1;
-+        libssh2_htonu32(p, 0);
-+
-+        rc = libssh2_packet_write(session, listen_state->packet, packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send open failure", 0);
-+            listen_state->state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        listen_state->state = libssh2_NB_state_idle;
-+        return 0;
-+    }
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_packet_x11_open
-+ * Accept a forwarded X11 connection
-+ */
-+static inline int
-+libssh2_packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
-+                        unsigned long datalen,
-+                        packet_x11_open_state_t * x11open_state)
-+{
-+    int failure_code = 2;       /* SSH_OPEN_CONNECT_FAILED */
-+    unsigned char *s = data + (sizeof("x11") - 1) + 5;
-+    /* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
-+    unsigned long packet_len = 17 + (sizeof(X11FwdUnAvil) - 1);
-+    unsigned char *p;
-+    LIBSSH2_CHANNEL *channel;
-+    int rc;
-+
-+    (void) datalen;
-+
-+    if (x11open_state->state == libssh2_NB_state_idle) {
-+        x11open_state->sender_channel = libssh2_ntohu32(s);
-+        s += 4;
-+        x11open_state->initial_window_size = libssh2_ntohu32(s);
-+        s += 4;
-+        x11open_state->packet_size = libssh2_ntohu32(s);
-+        s += 4;
-+        x11open_state->shost_len = libssh2_ntohu32(s);
-+        s += 4;
-+        x11open_state->shost = s;
-+        s += x11open_state->shost_len;
-+        x11open_state->sport = libssh2_ntohu32(s);
-+        s += 4;
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                       "X11 Connection Received from %s:%ld on channel %lu",
-+                       x11open_state->shost, x11open_state->sport,
-+                       x11open_state->sender_channel);
-+
-+        x11open_state->state = libssh2_NB_state_allocated;
-+    }
-+
-+    if (session->x11) {
-+        if (x11open_state->state == libssh2_NB_state_allocated) {
-+            channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL));
-+            if (!channel) {
-+                libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                              "Unable to allocate a channel for new connection",
-+                              0);
-+                failure_code = 4;       /* SSH_OPEN_RESOURCE_SHORTAGE */
-+                goto x11_exit;
-+            }
-+            memset(channel, 0, sizeof(LIBSSH2_CHANNEL));
-+
-+            channel->session = session;
-+            channel->channel_type_len = sizeof("x11") - 1;
-+            channel->channel_type = LIBSSH2_ALLOC(session,
-+                                                  channel->channel_type_len +
-+                                                  1);
-+            if (!channel->channel_type) {
-+                libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                              "Unable to allocate a channel for new connection",
-+                              0);
-+                LIBSSH2_FREE(session, channel);
-+                failure_code = 4;       /* SSH_OPEN_RESOURCE_SHORTAGE */
-+                goto x11_exit;
-+            }
-+            memcpy(channel->channel_type, "x11",
-+                   channel->channel_type_len + 1);
-+
-+            channel->remote.id = x11open_state->sender_channel;
-+            channel->remote.window_size_initial =
-+                LIBSSH2_CHANNEL_WINDOW_DEFAULT;
-+            channel->remote.window_size = LIBSSH2_CHANNEL_WINDOW_DEFAULT;
-+            channel->remote.packet_size = LIBSSH2_CHANNEL_PACKET_DEFAULT;
-+
-+            channel->local.id = libssh2_channel_nextid(session);
-+            channel->local.window_size_initial =
-+                x11open_state->initial_window_size;
-+            channel->local.window_size = x11open_state->initial_window_size;
-+            channel->local.packet_size = x11open_state->packet_size;
-+
-+            _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                           "X11 Connection established: channel %lu/%lu win %lu/%lu packet %lu/%lu",
-+                           channel->local.id, channel->remote.id,
-+                           channel->local.window_size,
-+                           channel->remote.window_size,
-+                           channel->local.packet_size,
-+                           channel->remote.packet_size);
-+            p = x11open_state->packet;
-+            *(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION;
-+            libssh2_htonu32(p, channel->remote.id);
-+            p += 4;
-+            libssh2_htonu32(p, channel->local.id);
-+            p += 4;
-+            libssh2_htonu32(p, channel->remote.window_size_initial);
-+            p += 4;
-+            libssh2_htonu32(p, channel->remote.packet_size);
-+            p += 4;
-+
-+            x11open_state->state = libssh2_NB_state_created;
-+        }
-+
-+        if (x11open_state->state == libssh2_NB_state_created) {
-+            rc = libssh2_packet_write(session, x11open_state->packet, 17);
-+            if (rc == PACKET_EAGAIN) {
-+                return PACKET_EAGAIN;
-+            } else if (rc) {
-+                libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                              "Unable to send channel open confirmation", 0);
-+                x11open_state->state = libssh2_NB_state_idle;
-+                return -1;
-+            }
-+
-+            /* Link the channel into the session */
-+            if (session->channels.tail) {
-+                session->channels.tail->next = channel;
-+                channel->prev = session->channels.tail;
-+            } else {
-+                session->channels.head = channel;
-+                channel->prev = NULL;
-+            }
-+            channel->next = NULL;
-+            session->channels.tail = channel;
-+
-+            /*
-+             * Pass control to the callback, they may turn right around and
-+             * free the channel, or actually use it
-+             */
-+            LIBSSH2_X11_OPEN(channel, (char *) x11open_state->shost,
-+                             x11open_state->sport);
-+
-+            x11open_state->state = libssh2_NB_state_idle;
-+            return 0;
-+        }
-+    } else {
-+        failure_code = 4;       /* SSH_OPEN_RESOURCE_SHORTAGE */
-+    }
-+
-+  x11_exit:
-+    p = x11open_state->packet;
-+    *(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
-+    libssh2_htonu32(p, x11open_state->sender_channel);
-+    p += 4;
-+    libssh2_htonu32(p, failure_code);
-+    p += 4;
-+    libssh2_htonu32(p, sizeof(X11FwdUnAvil) - 1);
-+    p += 4;
-+    memcpy(s, X11FwdUnAvil, sizeof(X11FwdUnAvil) - 1);
-+    p += sizeof(X11FwdUnAvil) - 1;
-+    libssh2_htonu32(p, 0);
-+
-+    rc = libssh2_packet_write(session, x11open_state->packet, packet_len);
-+    if (rc == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    } else if (rc) {
-+        libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                      "Unable to send open failure", 0);
-+        x11open_state->state = libssh2_NB_state_idle;
-+        return -1;
-+    }
-+    x11open_state->state = libssh2_NB_state_idle;
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_packet_new
-+ * Create a new packet and attach it to the brigade
-+ */
-+int
-+libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
-+                   size_t datalen, int macstate)
-+{
-+    int rc;
-+
-+    if (session->packAdd_state == libssh2_NB_state_idle) {
-+        session->packAdd_data_head = 0;
-+
-+        /* Zero the whole thing out */
-+        memset(&session->packAdd_key_state, 0,
-+               sizeof(session->packAdd_key_state));
-+
-+        /* Zero the whole thing out */
-+        memset(&session->packAdd_Qlstn_state, 0,
-+               sizeof(session->packAdd_Qlstn_state));
-+
-+        /* Zero the whole thing out */
-+        memset(&session->packAdd_x11open_state, 0,
-+               sizeof(session->packAdd_x11open_state));
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_TRANS,
-+                       "Packet type %d received, length=%d",
-+                       (int) data[0], (int) datalen);
-+        if (macstate == LIBSSH2_MAC_INVALID) {
-+            if (session->macerror) {
-+                if (LIBSSH2_MACERROR(session, (char *) data, datalen) == 0) {
-+                    /* Calling app has given the OK, Process it anyway */
-+                    macstate = LIBSSH2_MAC_CONFIRMED;
-+                } else {
-+                    libssh2_error(session, LIBSSH2_ERROR_INVALID_MAC,
-+                                  "Invalid Message Authentication Code received",
-+                                  0);
-+                    if (session->ssh_msg_disconnect) {
-+                        LIBSSH2_DISCONNECT(session, SSH_DISCONNECT_MAC_ERROR,
-+                                           "Invalid MAC received",
-+                                           sizeof("Invalid MAC received") - 1,
-+                                           "", 0);
-+                    }
-+                    LIBSSH2_FREE(session, data);
-+                    return -1;
-+                }
-+            } else {
-+                libssh2_error(session, LIBSSH2_ERROR_INVALID_MAC,
-+                              "Invalid Message Authentication Code received",
-+                              0);
-+                if (session->ssh_msg_disconnect) {
-+                    LIBSSH2_DISCONNECT(session, SSH_DISCONNECT_MAC_ERROR,
-+                                       "Invalid MAC received",
-+                                       sizeof("Invalid MAC received") - 1,
-+                                       "", 0);
-+                }
-+                LIBSSH2_FREE(session, data);
-+                return -1;
-+            }
-+        }
-+
-+        session->packAdd_state = libssh2_NB_state_allocated;
-+    }
-+
-+    /*
-+     * =============================== NOTE ===============================
-+     * I know this is very ugly and not a really good use of "goto", but
-+     * this case statement would be even uglier to do it any other way
-+     */
-+    if (session->packAdd_state == libssh2_NB_state_jump1) {
-+        goto libssh2_packet_add_jump_point1;
-+    } else if (session->packAdd_state == libssh2_NB_state_jump2) {
-+        goto libssh2_packet_add_jump_point2;
-+    } else if (session->packAdd_state == libssh2_NB_state_jump3) {
-+        goto libssh2_packet_add_jump_point3;
-+    }
-+
-+    if (session->packAdd_state == libssh2_NB_state_allocated) {
-+        /* A couple exceptions to the packet adding rule: */
-+        switch (data[0]) {
-+        case SSH_MSG_DISCONNECT:
-+            {
-+                char *message, *language;
-+                int reason, message_len, language_len;
-+
-+                reason = libssh2_ntohu32(data + 1);
-+                message_len = libssh2_ntohu32(data + 5);
-+                /* 9 = packet_type(1) + reason(4) + message_len(4) */
-+                message = (char *) data + 9;
-+                language_len = libssh2_ntohu32(data + 9 + message_len);
-+                /*
-+                 * This is where we hack on the data a little,
-+                 * Use the MSB of language_len to to a terminating NULL
-+                 * (In all liklihood it is already)
-+                 * Shift the language tag back a byte (In all likelihood
-+                 * it's zero length anyway)
-+                 * Store a NULL in the last byte of the packet to terminate
-+                 * the language string
-+                 * With the lengths passed this isn't *REALLY* necessary,
-+                 * but it's "kind"
-+                 */
-+                message[message_len] = '\0';
-+                language = (char *) data + 9 + message_len + 3;
-+                if (language_len) {
-+                    memcpy(language, language + 1, language_len);
-+                }
-+                language[language_len] = '\0';
-+
-+                if (session->ssh_msg_disconnect) {
-+                    LIBSSH2_DISCONNECT(session, reason, message,
-+                                       message_len, language, language_len);
-+                }
-+                _libssh2_debug(session, LIBSSH2_DBG_TRANS,
-+                               "Disconnect(%d): %s(%s)", reason,
-+                               message, language);
-+                LIBSSH2_FREE(session, data);
-+                session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
-+                session->packAdd_state = libssh2_NB_state_idle;
-+                return -1;
-+            }
-+            break;
-+
-+        case SSH_MSG_IGNORE:
-+            /* As with disconnect, back it up one and add a trailing NULL */
-+            memcpy(data + 4, data + 5, datalen - 5);
-+            data[datalen] = '\0';
-+            if (session->ssh_msg_ignore) {
-+                LIBSSH2_IGNORE(session, (char *) data + 4, datalen - 5);
-+            }
-+            LIBSSH2_FREE(session, data);
-+            session->packAdd_state = libssh2_NB_state_idle;
-+            return 0;
-+            break;
-+
-+        case SSH_MSG_DEBUG:
-+            {
-+                int always_display = data[0];
-+                char *message, *language;
-+                int message_len, language_len;
-+
-+                message_len = libssh2_ntohu32(data + 2);
-+                /* 6 = packet_type(1) + display(1) + message_len(4) */
-+                message = (char *) data + 6;
-+                language_len = libssh2_ntohu32(data + 6 + message_len);
-+                /*
-+                 * This is where we hack on the data a little,
-+                 * Use the MSB of language_len to to a terminating NULL
-+                 * (In all liklihood it is already)
-+                 * Shift the language tag back a byte (In all likelihood
-+                 * it's zero length anyway)
-+                 * Store a NULL in the last byte of the packet to terminate
-+                 * the language string
-+                 * With the lengths passed this isn't *REALLY* necessary,
-+                 * but it's "kind"
-+                 */
-+                message[message_len] = '\0';
-+                language = (char *) data + 6 + message_len + 3;
-+                if (language_len) {
-+                    memcpy(language, language + 1, language_len);
-+                }
-+                language[language_len] = '\0';
-+
-+                if (session->ssh_msg_debug) {
-+                    LIBSSH2_DEBUG(session, always_display, message,
-+                                  message_len, language, language_len);
-+                }
-+                /*
-+                 * _libssh2_debug will actually truncate this for us so
-+                 * that it's not an inordinate about of data
-+                 */
-+                _libssh2_debug(session, LIBSSH2_DBG_TRANS,
-+                               "Debug Packet: %s", message);
-+                LIBSSH2_FREE(session, data);
-+                session->packAdd_state = libssh2_NB_state_idle;
-+                return 0;
-+            }
-+            break;
-+
-+        case SSH_MSG_CHANNEL_EXTENDED_DATA:
-+            /* streamid(4) */
-+            session->packAdd_data_head += 4;
-+        case SSH_MSG_CHANNEL_DATA:
-+            /* packet_type(1) + channelno(4) + datalen(4) */
-+            session->packAdd_data_head += 9;
-+            {
-+                session->packAdd_channel = libssh2_channel_locate(session,
-+                                                                  libssh2_ntohu32
-+                                                                  (data + 1));
-+
-+                if (!session->packAdd_channel) {
-+                    libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN,
-+                                  "Packet received for unknown channel, ignoring",
-+                                  0);
-+                    LIBSSH2_FREE(session, data);
-+                    session->packAdd_state = libssh2_NB_state_idle;
-+                    return 0;
-+                }
-+#ifdef LIBSSH2DEBUG
-+                {
-+                    unsigned long stream_id = 0;
-+
-+                    if (data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) {
-+                        stream_id = libssh2_ntohu32(data + 5);
-+                    }
-+
-+                    _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                                   "%d bytes received for channel %lu/%lu stream #%lu",
-+                                   (int) (datalen -
-+                                          session->packAdd_data_head),
-+                                   session->packAdd_channel->local.id,
-+                                   session->packAdd_channel->remote.id,
-+                                   stream_id);
-+                }
-+#endif
-+                if ((session->packAdd_channel->remote.
-+                     extended_data_ignore_mode ==
-+                     LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE)
-+                    && (data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) {
-+                    /* Pretend we didn't receive this */
-+                    LIBSSH2_FREE(session, data);
-+
-+                    _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                                   "Ignoring extended data and refunding %d bytes",
-+                                   (int) (datalen - 13));
-+                    /* Adjust the window based on the block we just freed */
-+                  libssh2_packet_add_jump_point1:
-+                    session->packAdd_state = libssh2_NB_state_jump1;
-+                    rc = libssh2_channel_receive_window_adjust(session->
-+                                                               packAdd_channel,
-+                                                               datalen - 13,
-+                                                               0);
-+                    if (rc == PACKET_EAGAIN) {
-+                        session->socket_block_directions =
-+                            LIBSSH2_SESSION_BLOCK_OUTBOUND;
-+                        return PACKET_EAGAIN;
-+                    }
-+                    session->packAdd_state = libssh2_NB_state_idle;
-+                    return 0;
-+                }
-+
-+                /*
-+                 * REMEMBER! remote means remote as source of data,
-+                 * NOT remote window!
-+                 */
-+                if (session->packAdd_channel->remote.packet_size <
-+                    (datalen - session->packAdd_data_head)) {
-+                    /*
-+                     * Spec says we MAY ignore bytes sent beyond 
-+                     * packet_size
-+                     */
-+                    libssh2_error(session,
-+                                  LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED,
-+                                  "Packet contains more data than we offered to receive, truncating",
-+                                  0);
-+                    datalen =
-+                        session->packAdd_channel->remote.packet_size +
-+                        session->packAdd_data_head;
-+                }
-+                if (session->packAdd_channel->remote.window_size <= 0) {
-+                    /*
-+                     * Spec says we MAY ignore bytes sent beyond
-+                     * window_size
-+                     */
-+                    libssh2_error(session,
-+                                  LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
-+                                  "The current receive window is full, data ignored",
-+                                  0);
-+                    LIBSSH2_FREE(session, data);
-+                    session->packAdd_state = libssh2_NB_state_idle;
-+                    return 0;
-+                }
-+                /* Reset EOF status */
-+                session->packAdd_channel->remote.eof = 0;
-+
-+                if ((datalen - session->packAdd_data_head) >
-+                    session->packAdd_channel->remote.window_size) {
-+                    libssh2_error(session,
-+                                  LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
-+                                  "Remote sent more data than current window allows, truncating",
-+                                  0);
-+                    datalen =
-+                        session->packAdd_channel->remote.window_size +
-+                        session->packAdd_data_head;
-+                } else {
-+                    /* Now that we've received it, shrink our window */
-+                    session->packAdd_channel->remote.window_size -=
-+                        datalen - session->packAdd_data_head;
-+                }
-+            }
-+            break;
-+
-+        case SSH_MSG_CHANNEL_EOF:
-+            {
-+                session->packAdd_channel = libssh2_channel_locate(session,
-+                                                                  libssh2_ntohu32
-+                                                                  (data + 1));
-+
-+                if (!session->packAdd_channel) {
-+                    /* We may have freed already, just quietly ignore this... */
-+                    LIBSSH2_FREE(session, data);
-+                    session->packAdd_state = libssh2_NB_state_idle;
-+                    return 0;
-+                }
-+
-+                _libssh2_debug(session,
-+                               LIBSSH2_DBG_CONN,
-+                               "EOF received for channel %lu/%lu",
-+                               session->packAdd_channel->local.id,
-+                               session->packAdd_channel->remote.id);
-+                session->packAdd_channel->remote.eof = 1;
-+
-+                LIBSSH2_FREE(session, data);
-+                session->packAdd_state = libssh2_NB_state_idle;
-+                return 0;
-+            }
-+            break;
-+
-+        case SSH_MSG_CHANNEL_REQUEST:
-+            {
-+                if (libssh2_ntohu32(data + 5) == sizeof("exit-status") - 1
-+                    && !memcmp("exit-status", data + 9,
-+                               sizeof("exit-status") - 1)) {
-+
-+                    /* we've got "exit-status" packet. Set the session value */
-+                    session->packAdd_channel =
-+                        libssh2_channel_locate(session,
-+                                               libssh2_ntohu32(data + 1));
-+
-+                    if (session->packAdd_channel) {
-+                        session->packAdd_channel->exit_status =
-+                            libssh2_ntohu32(data + 9 + sizeof("exit-status"));
-+                        _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                                       "Exit status %lu received for channel %lu/%lu",
-+                                       session->packAdd_channel->exit_status,
-+                                       session->packAdd_channel->local.id,
-+                                       session->packAdd_channel->remote.id);
-+                    }
-+
-+                    LIBSSH2_FREE(session, data);
-+                    session->packAdd_state = libssh2_NB_state_idle;
-+                    return 0;
-+                }
-+            }
-+            break;
-+
-+        case SSH_MSG_CHANNEL_CLOSE:
-+            {
-+                session->packAdd_channel = libssh2_channel_locate(session,
-+                                                                  libssh2_ntohu32
-+                                                                  (data + 1));
-+
-+                if (!session->packAdd_channel) {
-+                    /* We may have freed already, just quietly ignore this... */
-+                    LIBSSH2_FREE(session, data);
-+                    session->packAdd_state = libssh2_NB_state_idle;
-+                    return 0;
-+                }
-+                _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                               "Close received for channel %lu/%lu",
-+                               session->packAdd_channel->local.id,
-+                               session->packAdd_channel->remote.id);
-+
-+                session->packAdd_channel->remote.close = 1;
-+                session->packAdd_channel->remote.eof = 1;
-+                /* TODO: Add a callback for this */
-+
-+                LIBSSH2_FREE(session, data);
-+                session->packAdd_state = libssh2_NB_state_idle;
-+                return 0;
-+            }
-+            break;
-+
-+        case SSH_MSG_CHANNEL_OPEN:
-+            if ((datalen >= (sizeof("forwarded-tcpip") + 4)) &&
-+                ((sizeof("forwarded-tcpip") - 1) == libssh2_ntohu32(data + 1))
-+                &&
-+                (memcmp
-+                 (data + 5, "forwarded-tcpip",
-+                  sizeof("forwarded-tcpip") - 1) == 0)) {
-+
-+              libssh2_packet_add_jump_point2:
-+                session->packAdd_state = libssh2_NB_state_jump2;
-+                rc = libssh2_packet_queue_listener(session, data, datalen,
-+                                                   &session->
-+                                                   packAdd_Qlstn_state);
-+                if (rc == PACKET_EAGAIN) {
-+                    session->socket_block_directions =
-+                        LIBSSH2_SESSION_BLOCK_OUTBOUND;
-+                    return PACKET_EAGAIN;
-+                }
-+
-+                LIBSSH2_FREE(session, data);
-+                session->packAdd_state = libssh2_NB_state_idle;
-+                return rc;
-+            }
-+            if ((datalen >= (sizeof("x11") + 4)) &&
-+                ((sizeof("x11") - 1) == libssh2_ntohu32(data + 1)) &&
-+                (memcmp(data + 5, "x11", sizeof("x11") - 1) == 0)) {
-+
-+              libssh2_packet_add_jump_point3:
-+                session->packAdd_state = libssh2_NB_state_jump3;
-+                rc = libssh2_packet_x11_open(session, data, datalen,
-+                                             &session->packAdd_x11open_state);
-+                if (rc == PACKET_EAGAIN) {
-+                    session->socket_block_directions =
-+                        LIBSSH2_SESSION_BLOCK_OUTBOUND;
-+                    return PACKET_EAGAIN;
-+                }
-+
-+                LIBSSH2_FREE(session, data);
-+                session->packAdd_state = libssh2_NB_state_idle;
-+                return rc;
-+            }
-+            break;
-+
-+        case SSH_MSG_CHANNEL_WINDOW_ADJUST:
-+            {
-+                unsigned long bytestoadd = libssh2_ntohu32(data + 5);
-+                session->packAdd_channel = libssh2_channel_locate(session,
-+                                                                  libssh2_ntohu32
-+                                                                  (data + 1));
-+
-+                if (session->packAdd_channel && bytestoadd) {
-+                    session->packAdd_channel->local.window_size += bytestoadd;
-+                }
-+                _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                               "Window adjust received for channel %lu/%lu, adding %lu bytes, new window_size=%lu",
-+                               session->packAdd_channel->local.id,
-+                               session->packAdd_channel->remote.id,
-+                               bytestoadd,
-+                               session->packAdd_channel->local.window_size);
-+
-+                LIBSSH2_FREE(session, data);
-+                session->packAdd_state = libssh2_NB_state_idle;
-+                return 0;
-+            }
-+            break;
-+        }
-+
-+        session->packAdd_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (session->packAdd_state == libssh2_NB_state_sent) {
-+        session->packAdd_packet =
-+            LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
-+        if (!session->packAdd_packet) {
-+            _libssh2_debug(session, LIBSSH2_ERROR_ALLOC,
-+                           "Unable to allocate memory for LIBSSH2_PACKET");
-+            LIBSSH2_FREE(session, data);
-+            session->packAdd_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        memset(session->packAdd_packet, 0, sizeof(LIBSSH2_PACKET));
-+
-+        session->packAdd_packet->data = data;
-+        session->packAdd_packet->data_len = datalen;
-+        session->packAdd_packet->data_head = session->packAdd_data_head;
-+        session->packAdd_packet->mac = macstate;
-+        session->packAdd_packet->brigade = &session->packets;
-+        session->packAdd_packet->next = NULL;
-+
-+        if (session->packets.tail) {
-+            session->packAdd_packet->prev = session->packets.tail;
-+            session->packAdd_packet->prev->next = session->packAdd_packet;
-+            session->packets.tail = session->packAdd_packet;
-+        } else {
-+            session->packets.head = session->packAdd_packet;
-+            session->packets.tail = session->packAdd_packet;
-+            session->packAdd_packet->prev = NULL;
-+        }
-+
-+        session->packAdd_state = libssh2_NB_state_sent1;
-+    }
-+
-+    if ((data[0] == SSH_MSG_KEXINIT &&
-+         !(session->state & LIBSSH2_STATE_EXCHANGING_KEYS)) ||
-+        (session->packAdd_state == libssh2_NB_state_sent2)) {
-+        if (session->packAdd_state == libssh2_NB_state_sent1) {
-+            /*
-+             * Remote wants new keys
-+             * Well, it's already in the brigade,
-+             * let's just call back into ourselves
-+             */
-+            _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Renegotiating Keys");
-+
-+            session->packAdd_state = libssh2_NB_state_sent2;
-+        }
-+
-+        /*
-+         * The KEXINIT message has been added to the queue.
-+         * The packAdd and readPack states need to be reset
-+         * because libssh2_kex_exchange (eventually) calls upon
-+         * libssh2_packet_read to read the rest of the key exchange
-+         * conversation.
-+         */
-+        session->readPack_state = libssh2_NB_state_idle;
-+        session->packet.total_num = 0;
-+        session->packAdd_state = libssh2_NB_state_idle;
-+        session->fullpacket_state = libssh2_NB_state_idle;
-+
-+        /*
-+         * Also, don't use packAdd_key_state for key re-exchange,
-+         * as it will be wiped out in the middle of the exchange.
-+         * How about re-using the startup_key_state?
-+         */
-+        memset(&session->startup_key_state, 0, sizeof(key_exchange_state_t));
-+ 
-+        /*
-+         * If there was a key reexchange failure, let's just hope we didn't
-+         * send NEWKEYS yet, otherwise remote will drop us like a rock
-+         */
-+        rc = libssh2_kex_exchange(session, 1, &session->startup_key_state);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        }
-+    }
-+
-+    session->packAdd_state = libssh2_NB_state_idle;
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_packet_ask
-+ * Scan the brigade for a matching packet type, optionally poll the socket for
-+ * a packet first
-+ */
-+int
-+libssh2_packet_ask_ex(LIBSSH2_SESSION * session, unsigned char packet_type,
-+                      unsigned char **data, unsigned long *data_len,
-+                      unsigned long match_ofs, const unsigned char *match_buf,
-+                      unsigned long match_len, int poll_socket)
-+{
-+    LIBSSH2_PACKET *packet = session->packets.head;
-+
-+    if (poll_socket) {
-+        /*
-+         * XXX CHECK ***
-+         * When "poll_socket" is "1" libhss2_packet_read() can return
-+         * PACKET_EAGAIN.  I am not sure what should happen, but internally
-+         * there is only one location that might do so, libssh2_packet_askv_ex()
-+         */
-+        libssh2pack_t rc = libssh2_packet_read(session);
-+        if ((rc < 0) && !packet) {
-+            return rc;
-+        }
-+    }
-+    _libssh2_debug(session, LIBSSH2_DBG_TRANS,
-+                   "Looking for packet of type: %d", (int) packet_type);
-+
-+    while (packet) {
-+        if (packet->data[0] == packet_type
-+            && (packet->data_len >= (match_ofs + match_len)) && (!match_buf
-+                                                                 ||
-+                                                                 (memcmp
-+                                                                  (packet->
-+                                                                   data +
-+                                                                   match_ofs,
-+                                                                   match_buf,
-+                                                                   match_len)
-+                                                                  == 0))) {
-+            *data = packet->data;
-+            *data_len = packet->data_len;
-+
-+            if (packet->prev) {
-+                packet->prev->next = packet->next;
-+            } else {
-+                session->packets.head = packet->next;
-+            }
-+
-+            if (packet->next) {
-+                packet->next->prev = packet->prev;
-+            } else {
-+                session->packets.tail = packet->prev;
-+            }
-+
-+            LIBSSH2_FREE(session, packet);
-+
-+            return 0;
-+        }
-+        packet = packet->next;
-+    }
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_packet_askv
-+ * Scan for any of a list of packet types in the brigade, optionally poll the
-+ * socket for a packet first
-+ */
-+int
-+libssh2_packet_askv_ex(LIBSSH2_SESSION * session,
-+                       const unsigned char *packet_types,
-+                       unsigned char **data, unsigned long *data_len,
-+                       unsigned long match_ofs,
-+                       const unsigned char *match_buf,
-+                       unsigned long match_len, int poll_socket)
-+{
-+    int i, packet_types_len = strlen((char *) packet_types);
-+
-+    for(i = 0; i < packet_types_len; i++) {
-+        /*
-+         * XXX CHECK XXX
-+         * When "poll_socket" is "1" libssh2_packet_ask_ex() could
-+         * return PACKET_EAGAIN.  Not sure the correct action, I 
-+         * think it is right as is.
-+         */
-+        if (0 == libssh2_packet_ask_ex(session, packet_types[i], data,
-+                                       data_len, match_ofs, match_buf,
-+                                       match_len, i ? 0 : poll_socket)) {
-+            return 0;
-+        }
-+    }
-+
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ waitsocket
-+ * Returns
-+ * negative on error
-+ * >0 on incoming data
-+ * 0 on timeout
-+ *
-+ * FIXME: convert to use poll on systems that have it.
-+ */
-+int
-+libssh2_waitsocket(LIBSSH2_SESSION * session, long seconds)
-+{
-+    struct timeval timeout;
-+    int rc;
-+    fd_set fd;
-+
-+    timeout.tv_sec = seconds;
-+    timeout.tv_usec = 0;
-+
-+    FD_ZERO(&fd);
-+
-+    FD_SET(session->socket_fd, &fd);
-+
-+    rc = select(session->socket_fd + 1, &fd, NULL, NULL, &timeout);
-+
-+    return rc;
-+}
-+
-+/* {{{ libssh2_packet_require
-+ * Loops libssh2_packet_read() until the packet requested is available
-+ * SSH_DISCONNECT or a SOCKET_DISCONNECTED will cause a bailout
-+ *
-+ * Returns negative on error
-+ * Returns 0 when it has taken care of the requested packet.
-+ */
-+int
-+libssh2_packet_require_ex(LIBSSH2_SESSION * session, unsigned char packet_type,
-+                          unsigned char **data, unsigned long *data_len,
-+                          unsigned long match_ofs,
-+                          const unsigned char *match_buf,
-+                          unsigned long match_len,
-+                          packet_require_state_t * state)
-+{
-+    if (state->start == 0) {
-+        if (libssh2_packet_ask_ex
-+            (session, packet_type, data, data_len, match_ofs, match_buf,
-+             match_len, 0) == 0) {
-+            /* A packet was available in the packet brigade */
-+            return 0;
-+        }
-+
-+        state->start = time(NULL);
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_TRANS,
-+                       "May block until packet of type %d becomes available",
-+                       (int) packet_type);
-+    }
-+
-+    while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
-+        libssh2pack_t ret = libssh2_packet_read(session);
-+        if (ret == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if ((ret == 0) && (!session->socket_block)) {
-+            /* If we are in non-blocking and there is no data, return that */
-+            return PACKET_EAGAIN;
-+        } else if (ret < 0) {
-+            state->start = 0;
-+            /* an error which is not just because of blocking */
-+            return ret;
-+        } else if (ret == packet_type) {
-+            /* Be lazy, let packet_ask pull it out of the brigade */
-+            ret =
-+                libssh2_packet_ask_ex(session, packet_type, data, data_len,
-+                                      match_ofs, match_buf, match_len, 0);
-+            state->start = 0;
-+            return ret;
-+        } else if (ret == 0) {
-+            /* nothing available, wait until data arrives or we time out */
-+            long left = LIBSSH2_READ_TIMEOUT - (time(NULL) - state->start);
-+
-+            if ((left <= 0) || (libssh2_waitsocket(session, left) <= 0)) {
-+                state->start = 0;
-+                return PACKET_TIMEOUT;
-+            }
-+        }
-+    }
-+
-+    /* Only reached if the socket died */
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_packet_burn
-+ * Loops libssh2_packet_read() until any packet is available and promptly 
-+ * discards it
-+ * Used during KEX exchange to discard badly guessed KEX_INIT packets
-+ */
-+int
-+libssh2_packet_burn(LIBSSH2_SESSION * session,
-+                    libssh2_nonblocking_states * state)
-+{
-+    unsigned char *data;
-+    unsigned long data_len;
-+    unsigned char all_packets[255];
-+    int i;
-+    int ret;
-+
-+    if (*state == libssh2_NB_state_idle) {
-+        for(i = 1; i < 256; i++) {
-+            all_packets[i - 1] = i;
-+        }
-+
-+        if (libssh2_packet_askv_ex
-+            (session, all_packets, &data, &data_len, 0, NULL, 0, 0) == 0) {
-+            i = data[0];
-+            /* A packet was available in the packet brigade, burn it */
-+            LIBSSH2_FREE(session, data);
-+            return i;
-+        }
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_TRANS,
-+                       "Blocking until packet becomes available to burn");
-+        *state = libssh2_NB_state_created;
-+    }
-+
-+    while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
-+        if ((ret = libssh2_packet_read(session)) == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (ret < 0) {
-+            *state = libssh2_NB_state_idle;
-+            return ret;
-+        } else if (ret == 0) {
-+            /* FIXME: this might busyloop */
-+            continue;
-+        }
-+
-+        /* Be lazy, let packet_ask pull it out of the brigade */
-+        if (0 ==
-+            libssh2_packet_ask_ex(session, ret, &data, &data_len, 0, NULL, 0,
-+                                  0)) {
-+            /* Smoke 'em if you got 'em */
-+            LIBSSH2_FREE(session, data);
-+            *state = libssh2_NB_state_idle;
-+            return ret;
-+        }
-+    }
-+
-+    /* Only reached if the socket died */
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/*
-+ * {{{ libssh2_packet_requirev
-+ *
-+ * Loops libssh2_packet_read() until one of a list of packet types requested is
-+ * available
-+ * SSH_DISCONNECT or a SOCKET_DISCONNECTED will cause a bailout
-+ * packet_types is a null terminated list of packet_type numbers
-+ */
-+
-+int
-+libssh2_packet_requirev_ex(LIBSSH2_SESSION * session,
-+                           const unsigned char *packet_types,
-+                           unsigned char **data, unsigned long *data_len,
-+                           unsigned long match_ofs,
-+                           const unsigned char *match_buf,
-+                           unsigned long match_len,
-+                           packet_requirev_state_t * state)
-+{
-+    if (libssh2_packet_askv_ex
-+        (session, packet_types, data, data_len, match_ofs, match_buf,
-+         match_len, 0) == 0) {
-+        /* One of the packets listed was available in the packet
-+           brigade */
-+        state->start = 0;
-+        return 0;
-+    }
-+
-+    if (state->start == 0) {
-+        state->start = time(NULL);
-+    }
-+
-+    while (session->socket_state != LIBSSH2_SOCKET_DISCONNECTED) {
-+        int ret = libssh2_packet_read(session);
-+        if ((ret < 0) && (ret != PACKET_EAGAIN)) {
-+            state->start = 0;
-+            return ret;
-+        }
-+        if (ret <= 0) {
-+            long left = LIBSSH2_READ_TIMEOUT - (time(NULL) - state->start);
-+
-+            if ((left <= 0) || (libssh2_waitsocket(session, left) <= 0)) {
-+                state->start = 0;
-+                return PACKET_TIMEOUT;
-+            } else if (ret == PACKET_EAGAIN) {
-+                return PACKET_EAGAIN;
-+            }
-+        }
-+
-+        if (strchr((char *) packet_types, ret)) {
-+            /* Be lazy, let packet_ask pull it out of the brigade */
-+            return libssh2_packet_askv_ex(session, packet_types, data,
-+                                          data_len, match_ofs, match_buf,
-+                                          match_len, 0);
-+        }
-+    }
-+
-+    /* Only reached if the socket died */
-+    state->start = 0;
-+    return -1;
-+}
-+
-+/* }}} */
-
-Property changes on: libssh2/src/packet.c
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.2
-Added: svn:eol-style
-   + native
-
-Index: libssh2/src/channel.c
-===================================================================
---- libssh2/src/channel.c      (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/channel.c      (.../trunk)
-@@ -0,0 +1,2260 @@
-+/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
-+ * Copyright (c) 2008 by Daniel Stenberg
-+ *
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#include "libssh2_priv.h"
-+#ifdef HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#ifdef HAVE_INTTYPES_H
-+#include <inttypes.h>
-+#endif
-+
-+
-+/* {{{ libssh2_channel_nextid
-+ * Determine the next channel ID we can use at our end
-+ */
-+unsigned long
-+libssh2_channel_nextid(LIBSSH2_SESSION * session)
-+{
-+    unsigned long id = session->next_channel;
-+    LIBSSH2_CHANNEL *channel;
-+
-+    channel = session->channels.head;
-+
-+    while (channel) {
-+        if (channel->local.id > id) {
-+            id = channel->local.id;
-+        }
-+        channel = channel->next;
-+    }
-+
-+    /* This is a shortcut to avoid waiting for close packets on channels we've
-+     * forgotten about, This *could* be a problem if we request and close 4
-+     * billion or so channels in too rapid succession for the remote end to
-+     * respond, but the worst case scenario is that some data meant for
-+     * another channel Gets picked up by the new one.... Pretty unlikely all
-+     * told...
-+     */
-+    session->next_channel = id + 1;
-+    _libssh2_debug(session, LIBSSH2_DBG_CONN, "Allocated new channel ID#%lu",
-+                   id);
-+    return id;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_locate
-+ * Locate a channel pointer by number
-+ */
-+LIBSSH2_CHANNEL *
-+libssh2_channel_locate(LIBSSH2_SESSION * session, unsigned long channel_id)
-+{
-+    LIBSSH2_CHANNEL *channel = session->channels.head;
-+    while (channel) {
-+        if (channel->local.id == channel_id) {
-+            return channel;
-+        }
-+        channel = channel->next;
-+    }
-+
-+    return NULL;
-+}
-+
-+/* }}} */
-+
-+#define CHANNEL_ADD(session, channel)   \
-+{   \
-+    if ((session)->channels.tail) { \
-+        (session)->channels.tail->next = (channel); \
-+        (channel)->prev = (session)->channels.tail; \
-+    } else {    \
-+        (session)->channels.head = (channel);   \
-+        (channel)->prev = NULL; \
-+    }   \
-+    (channel)->next = NULL; \
-+    (session)->channels.tail = (channel);   \
-+    (channel)->session = (session); \
-+}
-+
-+/* {{{ libssh2_channel_open_ex
-+ * Establish a generic session channel
-+ */
-+LIBSSH2_API LIBSSH2_CHANNEL *
-+libssh2_channel_open_ex(LIBSSH2_SESSION * session, const char *channel_type,
-+                        unsigned int channel_type_len,
-+                        unsigned int window_size, unsigned int packet_size,
-+                        const char *message, unsigned int message_len)
-+{
-+    static const unsigned char reply_codes[3] = {
-+        SSH_MSG_CHANNEL_OPEN_CONFIRMATION,
-+        SSH_MSG_CHANNEL_OPEN_FAILURE,
-+        0
-+    };
-+    unsigned char *s;
-+    int rc;
-+
-+    if (session->open_state == libssh2_NB_state_idle) {
-+        session->open_channel = NULL;
-+        session->open_packet = NULL;
-+        session->open_data = NULL;
-+        /* 17 = packet_type(1) + channel_type_len(4) + sender_channel(4) +
-+         * window_size(4) + packet_size(4) */
-+        session->open_packet_len = channel_type_len + message_len + 17;
-+        session->open_local_channel = libssh2_channel_nextid(session);
-+
-+        /* Zero the whole thing out */
-+        memset(&session->open_packet_requirev_state, 0,
-+               sizeof(session->open_packet_requirev_state));
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                       "Opening Channel - win %d pack %d", window_size,
-+                       packet_size);
-+        session->open_channel =
-+            LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL));
-+        if (!session->open_channel) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate space for channel data", 0);
-+            return NULL;
-+        }
-+        memset(session->open_channel, 0, sizeof(LIBSSH2_CHANNEL));
-+
-+        session->open_channel->channel_type_len = channel_type_len;
-+        session->open_channel->channel_type =
-+            LIBSSH2_ALLOC(session, channel_type_len);
-+        if (!session->open_channel->channel_type) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Failed allocating memory for channel type name", 0);
-+            LIBSSH2_FREE(session, session->open_channel);
-+            session->open_channel = NULL;
-+            return NULL;
-+        }
-+        memcpy(session->open_channel->channel_type, channel_type,
-+               channel_type_len);
-+
-+        /* REMEMBER: local as in locally sourced */
-+        session->open_channel->local.id = session->open_local_channel;
-+        session->open_channel->remote.window_size = window_size;
-+        session->open_channel->remote.window_size_initial = window_size;
-+        session->open_channel->remote.packet_size = packet_size;
-+
-+        CHANNEL_ADD(session, session->open_channel);
-+
-+        s = session->open_packet =
-+            LIBSSH2_ALLOC(session, session->open_packet_len);
-+        if (!session->open_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate temporary space for packet", 0);
-+            goto channel_error;
-+        }
-+        *(s++) = SSH_MSG_CHANNEL_OPEN;
-+        libssh2_htonu32(s, channel_type_len);
-+        s += 4;
-+
-+        memcpy(s, channel_type, channel_type_len);
-+        s += channel_type_len;
-+
-+        libssh2_htonu32(s, session->open_local_channel);
-+        s += 4;
-+
-+        libssh2_htonu32(s, window_size);
-+        s += 4;
-+
-+        libssh2_htonu32(s, packet_size);
-+        s += 4;
-+
-+        if (message && message_len) {
-+            memcpy(s, message, message_len);
-+            s += message_len;
-+        }
-+
-+        session->open_state = libssh2_NB_state_created;
-+    }
-+
-+    if (session->open_state == libssh2_NB_state_created) {
-+        rc = libssh2_packet_write(session, session->open_packet,
-+                                  session->open_packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block sending channel-open request", 0);
-+            return NULL;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send channel-open request", 0);
-+            goto channel_error;
-+        }
-+
-+        session->open_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (session->open_state == libssh2_NB_state_sent) {
-+        rc = libssh2_packet_requirev_ex(session, reply_codes,
-+                                        &session->open_data,
-+                                        &session->open_data_len, 1,
-+                                        session->open_packet + 5 +
-+                                        channel_type_len, 4,
-+                                        &session->open_packet_requirev_state);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block", 0);
-+            return NULL;
-+        } else if (rc) {
-+            goto channel_error;
-+        }
-+
-+        if (session->open_data[0] == SSH_MSG_CHANNEL_OPEN_CONFIRMATION) {
-+            session->open_channel->remote.id =
-+                libssh2_ntohu32(session->open_data + 5);
-+            session->open_channel->local.window_size =
-+                libssh2_ntohu32(session->open_data + 9);
-+            session->open_channel->local.window_size_initial =
-+                libssh2_ntohu32(session->open_data + 9);
-+            session->open_channel->local.packet_size =
-+                libssh2_ntohu32(session->open_data + 13);
-+            _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                           "Connection Established - ID: %lu/%lu win: %lu/%lu"
-+                           " pack: %lu/%lu",
-+                           session->open_channel->local.id,
-+                           session->open_channel->remote.id,
-+                           session->open_channel->local.window_size,
-+                           session->open_channel->remote.window_size,
-+                           session->open_channel->local.packet_size,
-+                           session->open_channel->remote.packet_size);
-+            LIBSSH2_FREE(session, session->open_packet);
-+            session->open_packet = NULL;
-+            LIBSSH2_FREE(session, session->open_data);
-+            session->open_data = NULL;
-+
-+            session->open_state = libssh2_NB_state_idle;
-+            return session->open_channel;
-+        }
-+
-+        if (session->open_data[0] == SSH_MSG_CHANNEL_OPEN_FAILURE) {
-+            libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
-+                          "Channel open failure", 0);
-+        }
-+    }
-+
-+  channel_error:
-+
-+    if (session->open_data) {
-+        LIBSSH2_FREE(session, session->open_data);
-+        session->open_data = NULL;
-+    }
-+    if (session->open_packet) {
-+        LIBSSH2_FREE(session, session->open_packet);
-+        session->open_packet = NULL;
-+    }
-+    if (session->open_channel) {
-+        unsigned char channel_id[4];
-+        LIBSSH2_FREE(session, session->open_channel->channel_type);
-+
-+        if (session->open_channel->next) {
-+            session->open_channel->next->prev = session->open_channel->prev;
-+        }
-+        if (session->open_channel->prev) {
-+            session->open_channel->prev->next = session->open_channel->next;
-+        }
-+        if (session->channels.head == session->open_channel) {
-+            session->channels.head = session->open_channel->next;
-+        }
-+        if (session->channels.tail == session->open_channel) {
-+            session->channels.tail = session->open_channel->prev;
-+        }
-+
-+        /* Clear out packets meant for this channel */
-+        libssh2_htonu32(channel_id, session->open_channel->local.id);
-+        while ((libssh2_packet_ask_ex
-+                (session, SSH_MSG_CHANNEL_DATA, &session->open_data,
-+                 &session->open_data_len, 1, channel_id, 4, 0) >= 0)
-+               ||
-+               (libssh2_packet_ask_ex
-+                (session, SSH_MSG_CHANNEL_EXTENDED_DATA, &session->open_data,
-+                 &session->open_data_len, 1, channel_id, 4, 0) >= 0)) {
-+            LIBSSH2_FREE(session, session->open_data);
-+            session->open_data = NULL;
-+        }
-+
-+        /* Free any state variables still holding data */
-+        if (session->open_channel->write_packet) {
-+            LIBSSH2_FREE(session, session->open_channel->write_packet);
-+            session->open_channel->write_packet = NULL;
-+        }
-+
-+        LIBSSH2_FREE(session, session->open_channel);
-+        session->open_channel = NULL;
-+    }
-+
-+    session->open_state = libssh2_NB_state_idle;
-+    return NULL;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_direct_tcpip_ex
-+ * Tunnel TCP/IP connect through the SSH session to direct host/port
-+ */
-+LIBSSH2_API LIBSSH2_CHANNEL *
-+libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION * session, const char *host,
-+                                int port, const char *shost, int sport)
-+{
-+    LIBSSH2_CHANNEL *channel;
-+    unsigned char *s;
-+
-+    if (session->direct_state == libssh2_NB_state_idle) {
-+        session->direct_host_len = strlen(host);
-+        session->direct_shost_len = strlen(shost);
-+        /* host_len(4) + port(4) + shost_len(4) + sport(4) */
-+        session->direct_message_len =
-+            session->direct_host_len + session->direct_shost_len + 16;
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                       "Requesting direct-tcpip session to from %s:%d to %s:%d",
-+                       shost, sport, host, port);
-+
-+        s = session->direct_message =
-+            LIBSSH2_ALLOC(session, session->direct_message_len);
-+        if (!session->direct_message) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for direct-tcpip connection",
-+                          0);
-+            return NULL;
-+        }
-+        libssh2_htonu32(s, session->direct_host_len);
-+        s += 4;
-+        memcpy(s, host, session->direct_host_len);
-+        s += session->direct_host_len;
-+        libssh2_htonu32(s, port);
-+        s += 4;
-+
-+        libssh2_htonu32(s, session->direct_shost_len);
-+        s += 4;
-+        memcpy(s, shost, session->direct_shost_len);
-+        s += session->direct_shost_len;
-+        libssh2_htonu32(s, sport);
-+        s += 4;
-+
-+        session->direct_state = libssh2_NB_state_created;
-+    }
-+
-+    channel =
-+        libssh2_channel_open_ex(session, "direct-tcpip",
-+                                sizeof("direct-tcpip") - 1,
-+                                LIBSSH2_CHANNEL_WINDOW_DEFAULT,
-+                                LIBSSH2_CHANNEL_PACKET_DEFAULT,
-+                                (char *) session->direct_message,
-+                                session->direct_message_len);
-+    if (!channel) {
-+        if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
-+            /* The error code is still set to LIBSSH2_ERROR_EAGAIN */
-+            return NULL;
-+        } else {
-+            LIBSSH2_FREE(session, session->direct_message);
-+            session->direct_message = NULL;
-+            return NULL;
-+        }
-+    }
-+
-+    LIBSSH2_FREE(session, session->direct_message);
-+    session->direct_message = NULL;
-+
-+    return channel;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_forward_listen_ex
-+ * Bind a port on the remote host and listen for connections
-+ */
-+LIBSSH2_API LIBSSH2_LISTENER *
-+libssh2_channel_forward_listen_ex(LIBSSH2_SESSION * session, const char *host,
-+                                  int port, int *bound_port, int queue_maxsize)
-+{
-+    unsigned char *s, *data;
-+    static const unsigned char reply_codes[3] =
-+        { SSH_MSG_REQUEST_SUCCESS, SSH_MSG_REQUEST_FAILURE, 0 };
-+    unsigned long data_len;
-+    int rc;
-+
-+    if (session->fwdLstn_state == libssh2_NB_state_idle) {
-+        session->fwdLstn_host_len =
-+            (host ? strlen(host) : (sizeof("0.0.0.0") - 1));
-+        /* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4)
-+           + port(4) */
-+        session->fwdLstn_packet_len =
-+            session->fwdLstn_host_len + (sizeof("tcpip-forward") - 1) + 14;
-+
-+        /* Zero the whole thing out */
-+        memset(&session->fwdLstn_packet_requirev_state, 0,
-+               sizeof(session->fwdLstn_packet_requirev_state));
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                       "Requesting tcpip-forward session for %s:%d", host,
-+                       port);
-+
-+        s = session->fwdLstn_packet =
-+            LIBSSH2_ALLOC(session, session->fwdLstn_packet_len);
-+        if (!session->fwdLstn_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memeory for setenv packet", 0);
-+            return NULL;
-+        }
-+
-+        *(s++) = SSH_MSG_GLOBAL_REQUEST;
-+        libssh2_htonu32(s, sizeof("tcpip-forward") - 1);
-+        s += 4;
-+        memcpy(s, "tcpip-forward", sizeof("tcpip-forward") - 1);
-+        s += sizeof("tcpip-forward") - 1;
-+        *(s++) = 0x01;          /* want_reply */
-+
-+        libssh2_htonu32(s, session->fwdLstn_host_len);
-+        s += 4;
-+        memcpy(s, host ? host : "0.0.0.0", session->fwdLstn_host_len);
-+        s += session->fwdLstn_host_len;
-+        libssh2_htonu32(s, port);
-+        s += 4;
-+
-+        session->fwdLstn_state = libssh2_NB_state_created;
-+    }
-+
-+    if (session->fwdLstn_state == libssh2_NB_state_created) {
-+        rc = libssh2_packet_write(session, session->fwdLstn_packet,
-+                                  session->fwdLstn_packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block sending global-request packet for "
-+                          "forward listen request",
-+                          0);
-+            return NULL;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send global-request packet for forward "
-+                          "listen request",
-+                          0);
-+            LIBSSH2_FREE(session, session->fwdLstn_packet);
-+            session->fwdLstn_packet = NULL;
-+            session->fwdLstn_state = libssh2_NB_state_idle;
-+            return NULL;
-+        }
-+        LIBSSH2_FREE(session, session->fwdLstn_packet);
-+        session->fwdLstn_packet = NULL;
-+
-+        session->fwdLstn_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (session->fwdLstn_state == libssh2_NB_state_sent) {
-+        rc = libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len,
-+                                        0, NULL, 0,
-+                                        &session->
-+                                        fwdLstn_packet_requirev_state);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block", 0);
-+            return NULL;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unknown", 0);
-+            session->fwdLstn_state = libssh2_NB_state_idle;
-+            return NULL;
-+        }
-+
-+        if (data[0] == SSH_MSG_REQUEST_SUCCESS) {
-+            LIBSSH2_LISTENER *listener;
-+
-+            listener = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_LISTENER));
-+            if (!listener) {
-+                libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                              "Unable to allocate memory for listener queue",
-+                              0);
-+                LIBSSH2_FREE(session, data);
-+                session->fwdLstn_state = libssh2_NB_state_idle;
-+                return NULL;
-+            }
-+            memset(listener, 0, sizeof(LIBSSH2_LISTENER));
-+            listener->session = session;
-+            listener->host =
-+                LIBSSH2_ALLOC(session, session->fwdLstn_host_len + 1);
-+            if (!listener->host) {
-+                libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                              "Unable to allocate memory for listener queue",
-+                              0);
-+                LIBSSH2_FREE(session, listener);
-+                LIBSSH2_FREE(session, data);
-+                session->fwdLstn_state = libssh2_NB_state_idle;
-+                return NULL;
-+            }
-+            memcpy(listener->host, host ? host : "0.0.0.0",
-+                   session->fwdLstn_host_len);
-+            listener->host[session->fwdLstn_host_len] = 0;
-+            if (data_len >= 5 && !port) {
-+                listener->port = libssh2_ntohu32(data + 1);
-+                _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                               "Dynamic tcpip-forward port allocated: %d",
-+                               listener->port);
-+            } else {
-+                listener->port = port;
-+            }
-+
-+            listener->queue_size = 0;
-+            listener->queue_maxsize = queue_maxsize;
-+
-+            listener->next = session->listeners;
-+            listener->prev = NULL;
-+            if (session->listeners) {
-+                session->listeners->prev = listener;
-+            }
-+            session->listeners = listener;
-+
-+            if (bound_port) {
-+                *bound_port = listener->port;
-+            }
-+
-+            LIBSSH2_FREE(session, data);
-+            session->fwdLstn_state = libssh2_NB_state_idle;
-+            return listener;
-+        }
-+
-+        if (data[0] == SSH_MSG_REQUEST_FAILURE) {
-+            LIBSSH2_FREE(session, data);
-+            libssh2_error(session, LIBSSH2_ERROR_REQUEST_DENIED,
-+                          "Unable to complete request for forward-listen", 0);
-+            session->fwdLstn_state = libssh2_NB_state_idle;
-+            return NULL;
-+        }
-+    }
-+
-+    session->fwdLstn_state = libssh2_NB_state_idle;
-+
-+    return NULL;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_forward_cancel
-+ * Stop listening on a remote port and free the listener
-+ * Toss out any pending (un-accept()ed) connections
-+ *
-+ * Return 0 on success, PACKET_EAGAIN if would block, -1 on error
-+ */
-+LIBSSH2_API int
-+libssh2_channel_forward_cancel(LIBSSH2_LISTENER * listener)
-+{
-+    LIBSSH2_SESSION *session = listener->session;
-+    LIBSSH2_CHANNEL *queued = listener->queue;
-+    unsigned char *packet, *s;
-+    unsigned long host_len = strlen(listener->host);
-+    /* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) +
-+       port(4) */
-+    unsigned long packet_len =
-+        host_len + 14 + sizeof("cancel-tcpip-forward") - 1;
-+    int rc;
-+
-+    if (listener->chanFwdCncl_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                       "Cancelling tcpip-forward session for %s:%d",
-+                       listener->host, listener->port);
-+
-+        s = packet = LIBSSH2_ALLOC(session, packet_len);
-+        if (!packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memeory for setenv packet", 0);
-+            return -1;
-+        }
-+
-+        *(s++) = SSH_MSG_GLOBAL_REQUEST;
-+        libssh2_htonu32(s, sizeof("cancel-tcpip-forward") - 1);
-+        s += 4;
-+        memcpy(s, "cancel-tcpip-forward", sizeof("cancel-tcpip-forward") - 1);
-+        s += sizeof("cancel-tcpip-forward") - 1;
-+        *(s++) = 0x00;          /* want_reply */
-+
-+        libssh2_htonu32(s, host_len);
-+        s += 4;
-+        memcpy(s, listener->host, host_len);
-+        s += host_len;
-+        libssh2_htonu32(s, listener->port);
-+        s += 4;
-+
-+        listener->chanFwdCncl_state = libssh2_NB_state_created;
-+    } else {
-+        packet = listener->chanFwdCncl_data;
-+    }
-+
-+    if (listener->chanFwdCncl_state == libssh2_NB_state_created) {
-+        rc = libssh2_packet_write(session, packet, packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            listener->chanFwdCncl_data = packet;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send global-request packet for forward "
-+                          "listen request",
-+                          0);
-+            LIBSSH2_FREE(session, packet);
-+            listener->chanFwdCncl_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, packet);
-+
-+        listener->chanFwdCncl_state = libssh2_NB_state_sent;
-+    }
-+
-+    while (queued) {
-+        LIBSSH2_CHANNEL *next = queued->next;
-+
-+        rc = libssh2_channel_free(queued);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        }
-+        queued = next;
-+    }
-+    LIBSSH2_FREE(session, listener->host);
-+
-+    if (listener->next) {
-+        listener->next->prev = listener->prev;
-+    }
-+    if (listener->prev) {
-+        listener->prev->next = listener->next;
-+    } else {
-+        session->listeners = listener->next;
-+    }
-+
-+    LIBSSH2_FREE(session, listener);
-+
-+    listener->chanFwdCncl_state = libssh2_NB_state_idle;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_forward_accept
-+ * Accept a connection
-+ */
-+LIBSSH2_API LIBSSH2_CHANNEL *
-+libssh2_channel_forward_accept(LIBSSH2_LISTENER * listener)
-+{
-+    libssh2pack_t rc;
-+
-+    do {
-+        rc = libssh2_packet_read(listener->session);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(listener->session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block waiting for packet", 0);
-+            return NULL;
-+        }
-+    } while (rc > 0);
-+
-+    if (listener->queue) {
-+        LIBSSH2_SESSION *session = listener->session;
-+        LIBSSH2_CHANNEL *channel;
-+
-+        channel = listener->queue;
-+
-+        listener->queue = listener->queue->next;
-+        if (listener->queue) {
-+            listener->queue->prev = NULL;
-+        }
-+
-+        channel->prev = NULL;
-+        channel->next = session->channels.head;
-+        session->channels.head = channel;
-+
-+        if (channel->next) {
-+            channel->next->prev = channel;
-+        } else {
-+            session->channels.tail = channel;
-+        }
-+        listener->queue_size--;
-+
-+        return channel;
-+    }
-+
-+    return NULL;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_setenv_ex
-+ * Set an environment variable prior to requesting a shell/program/subsystem
-+ */
-+LIBSSH2_API int
-+libssh2_channel_setenv_ex(LIBSSH2_CHANNEL * channel, const char *varname,
-+                          unsigned int varname_len, const char *value,
-+                          unsigned int value_len)
-+{
-+    LIBSSH2_SESSION *session = channel->session;
-+    unsigned char *s, *data;
-+    static const unsigned char reply_codes[3] =
-+        { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
-+    unsigned long data_len;
-+    int rc;
-+
-+    if (channel->setenv_state == libssh2_NB_state_idle) {
-+        /* 21 = packet_type(1) + channel_id(4) + request_len(4) +
-+         * request(3)"env" + want_reply(1) + varname_len(4) + value_len(4) */
-+        channel->setenv_packet_len = varname_len + value_len + 21;
-+
-+        /* Zero the whole thing out */
-+        memset(&channel->setenv_packet_requirev_state, 0,
-+               sizeof(channel->setenv_packet_requirev_state));
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                       "Setting remote environment variable: %s=%s on "
-+                       "channel %lu/%lu",
-+                       varname, value, channel->local.id, channel->remote.id);
-+
-+        s = channel->setenv_packet =
-+            LIBSSH2_ALLOC(session, channel->setenv_packet_len);
-+        if (!channel->setenv_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memeory for setenv packet", 0);
-+            return -1;
-+        }
-+
-+        *(s++) = SSH_MSG_CHANNEL_REQUEST;
-+        libssh2_htonu32(s, channel->remote.id);
-+        s += 4;
-+        libssh2_htonu32(s, sizeof("env") - 1);
-+        s += 4;
-+        memcpy(s, "env", sizeof("env") - 1);
-+        s += sizeof("env") - 1;
-+
-+        *(s++) = 0x01;
-+
-+        libssh2_htonu32(s, varname_len);
-+        s += 4;
-+        memcpy(s, varname, varname_len);
-+        s += varname_len;
-+
-+        libssh2_htonu32(s, value_len);
-+        s += 4;
-+        memcpy(s, value, value_len);
-+        s += value_len;
-+
-+        channel->setenv_state = libssh2_NB_state_created;
-+    }
-+
-+    if (channel->setenv_state == libssh2_NB_state_created) {
-+        rc = libssh2_packet_write(session, channel->setenv_packet,
-+                                  channel->setenv_packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send channel-request packet for "
-+                          "setenv request",
-+                          0);
-+            LIBSSH2_FREE(session, channel->setenv_packet);
-+            channel->setenv_packet = NULL;
-+            channel->setenv_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, channel->setenv_packet);
-+        channel->setenv_packet = NULL;
-+
-+        libssh2_htonu32(channel->setenv_local_channel, channel->local.id);
-+
-+        channel->setenv_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (channel->setenv_state == libssh2_NB_state_sent) {
-+        rc = libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len,
-+                                        1, channel->setenv_local_channel, 4,
-+                                        &channel->
-+                                        setenv_packet_requirev_state);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        }
-+        if (rc) {
-+            channel->setenv_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+
-+        if (data[0] == SSH_MSG_CHANNEL_SUCCESS) {
-+            LIBSSH2_FREE(session, data);
-+            channel->setenv_state = libssh2_NB_state_idle;
-+            return 0;
-+        }
-+
-+        LIBSSH2_FREE(session, data);
-+    }
-+
-+    libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
-+                  "Unable to complete request for channel-setenv", 0);
-+    channel->setenv_state = libssh2_NB_state_idle;
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_request_pty_ex
-+ * Duh... Request a PTY
-+ */
-+LIBSSH2_API int
-+libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL * channel, const char *term,
-+                               unsigned int term_len, const char *modes,
-+                               unsigned int modes_len, int width, int height,
-+                               int width_px, int height_px)
-+{
-+    LIBSSH2_SESSION *session = channel->session;
-+    unsigned char *s, *data;
-+    static const unsigned char reply_codes[3] =
-+        { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
-+    unsigned long data_len;
-+    int rc;
-+
-+    if (channel->reqPTY_state == libssh2_NB_state_idle) {
-+        /* 41 = packet_type(1) + channel(4) + pty_req_len(4) + "pty_req"(7) +
-+         * want_reply(1) + term_len(4) + width(4) + height(4) + width_px(4) +
-+         * height_px(4) + modes_len(4) */
-+        channel->reqPTY_packet_len = term_len + modes_len + 41;
-+
-+        /* Zero the whole thing out */
-+        memset(&channel->reqPTY_packet_requirev_state, 0,
-+               sizeof(channel->reqPTY_packet_requirev_state));
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                       "Allocating tty on channel %lu/%lu", channel->local.id,
-+                       channel->remote.id);
-+
-+        s = channel->reqPTY_packet =
-+            LIBSSH2_ALLOC(session, channel->reqPTY_packet_len);
-+        if (!channel->reqPTY_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for pty-request", 0);
-+            return -1;
-+        }
-+
-+        *(s++) = SSH_MSG_CHANNEL_REQUEST;
-+        libssh2_htonu32(s, channel->remote.id);
-+        s += 4;
-+        libssh2_htonu32(s, sizeof("pty-req") - 1);
-+        s += 4;
-+        memcpy(s, "pty-req", sizeof("pty-req") - 1);
-+        s += sizeof("pty-req") - 1;
-+
-+        *(s++) = 0x01;
-+
-+        libssh2_htonu32(s, term_len);
-+        s += 4;
-+        if (term) {
-+            memcpy(s, term, term_len);
-+            s += term_len;
-+        }
-+
-+        libssh2_htonu32(s, width);
-+        s += 4;
-+        libssh2_htonu32(s, height);
-+        s += 4;
-+        libssh2_htonu32(s, width_px);
-+        s += 4;
-+        libssh2_htonu32(s, height_px);
-+        s += 4;
-+
-+        libssh2_htonu32(s, modes_len);
-+        s += 4;
-+        if (modes) {
-+            memcpy(s, modes, modes_len);
-+            s += modes_len;
-+        }
-+
-+        channel->reqPTY_state = libssh2_NB_state_created;
-+    }
-+
-+    if (channel->reqPTY_state == libssh2_NB_state_created) {
-+        rc = libssh2_packet_write(session, channel->reqPTY_packet,
-+                                  channel->reqPTY_packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send pty-request packet", 0);
-+            LIBSSH2_FREE(session, channel->reqPTY_packet);
-+            channel->reqPTY_packet = NULL;
-+            channel->reqPTY_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, channel->reqPTY_packet);
-+        channel->reqPTY_packet = NULL;
-+
-+        libssh2_htonu32(channel->reqPTY_local_channel, channel->local.id);
-+
-+        channel->reqPTY_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (channel->reqPTY_state == libssh2_NB_state_sent) {
-+        rc = libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len,
-+                                        1, channel->reqPTY_local_channel, 4,
-+                                        &channel->
-+                                        reqPTY_packet_requirev_state);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            channel->reqPTY_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+
-+        if (data[0] == SSH_MSG_CHANNEL_SUCCESS) {
-+            LIBSSH2_FREE(session, data);
-+            channel->reqPTY_state = libssh2_NB_state_idle;
-+            return 0;
-+        }
-+    }
-+
-+    LIBSSH2_FREE(session, data);
-+    libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
-+                  "Unable to complete request for channel request-pty", 0);
-+    channel->reqPTY_state = libssh2_NB_state_idle;
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+LIBSSH2_API int
-+libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL * channel, int width,
-+                                    int height, int width_px, int height_px)
-+{
-+    LIBSSH2_SESSION *session = channel->session;
-+    unsigned char *s;
-+    int rc;
-+
-+    if (channel->reqPTY_state == libssh2_NB_state_idle) {
-+        channel->reqPTY_packet_len = 39;
-+
-+        /* Zero the whole thing out */
-+        memset(&channel->reqPTY_packet_requirev_state, 0,
-+            sizeof(channel->reqPTY_packet_requirev_state));
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+            "changing tty size on channel %lu/%lu",
-+            channel->local.id,
-+            channel->remote.id);
-+
-+        s = channel->reqPTY_packet =
-+            LIBSSH2_ALLOC(session, channel->reqPTY_packet_len);
-+
-+        if (!channel->reqPTY_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+            "Unable to allocate memory for pty-request", 0);
-+            return -1;
-+        }
-+
-+        *(s++) = SSH_MSG_CHANNEL_REQUEST;
-+        libssh2_htonu32(s, channel->remote.id);
-+        s += 4;
-+        libssh2_htonu32(s, sizeof("window-change") - 1);
-+        s += 4;
-+        memcpy(s, "window-change", sizeof("window-change") - 1);
-+        s += sizeof("window-change") - 1;
-+
-+        *(s++) = 0x00; /* Don't reply */
-+        libssh2_htonu32(s, width);
-+        s += 4;
-+        libssh2_htonu32(s, height);
-+        s += 4;
-+        libssh2_htonu32(s, width_px);
-+        s += 4;
-+        libssh2_htonu32(s, height_px);
-+        s += 4;
-+
-+        channel->reqPTY_state = libssh2_NB_state_created;
-+    }
-+
-+    if (channel->reqPTY_state == libssh2_NB_state_created) {
-+        rc = libssh2_packet_write(session, channel->reqPTY_packet,
-+        channel->reqPTY_packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    } else if (rc) {
-+        libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+        "Unable to send window-change packet", 0);
-+        LIBSSH2_FREE(session, channel->reqPTY_packet);
-+        channel->reqPTY_packet = NULL;
-+        channel->reqPTY_state = libssh2_NB_state_idle;
-+        return -1;
-+    }
-+    LIBSSH2_FREE(session, channel->reqPTY_packet);
-+    channel->reqPTY_packet = NULL;
-+    libssh2_htonu32(channel->reqPTY_local_channel, channel->local.id);
-+    channel->reqPTY_state = libssh2_NB_state_sent;
-+
-+    return 0;
-+    }
-+
-+    channel->reqPTY_state = libssh2_NB_state_idle;
-+    return -1;
-+}
-+
-+/* Keep this an even number */
-+#define LIBSSH2_X11_RANDOM_COOKIE_LEN       32
-+
-+/* {{{ libssh2_channel_x11_req_ex
-+ * Request X11 forwarding
-+ */
-+LIBSSH2_API int
-+libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL * channel, int single_connection,
-+                           const char *auth_proto, const char *auth_cookie,
-+                           int screen_number)
-+{
-+    LIBSSH2_SESSION *session = channel->session;
-+    unsigned char *s, *data;
-+    static const unsigned char reply_codes[3] =
-+        { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
-+    unsigned long data_len;
-+    unsigned long proto_len =
-+        auth_proto ? strlen(auth_proto) : (sizeof("MIT-MAGIC-COOKIE-1") - 1);
-+    unsigned long cookie_len =
-+        auth_cookie ? strlen(auth_cookie) : LIBSSH2_X11_RANDOM_COOKIE_LEN;
-+    int rc;
-+
-+    if (channel->reqX11_state == libssh2_NB_state_idle) {
-+        /* 30 = packet_type(1) + channel(4) + x11_req_len(4) + "x11-req"(7) +
-+         * want_reply(1) + single_cnx(1) + proto_len(4) + cookie_len(4) +
-+         * screen_num(4) */
-+        channel->reqX11_packet_len = proto_len + cookie_len + 30;
-+
-+        /* Zero the whole thing out */
-+        memset(&channel->reqX11_packet_requirev_state, 0,
-+               sizeof(channel->reqX11_packet_requirev_state));
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                       "Requesting x11-req for channel %lu/%lu: single=%d "
-+                       "proto=%s cookie=%s screen=%d",
-+                       channel->local.id, channel->remote.id,
-+                       single_connection,
-+                       auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1",
-+                       auth_cookie ? auth_cookie : "<random>", screen_number);
-+
-+        s = channel->reqX11_packet =
-+            LIBSSH2_ALLOC(session, channel->reqX11_packet_len);
-+        if (!channel->reqX11_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for pty-request", 0);
-+            return -1;
-+        }
-+
-+        *(s++) = SSH_MSG_CHANNEL_REQUEST;
-+        libssh2_htonu32(s, channel->remote.id);
-+        s += 4;
-+        libssh2_htonu32(s, sizeof("x11-req") - 1);
-+        s += 4;
-+        memcpy(s, "x11-req", sizeof("x11-req") - 1);
-+        s += sizeof("x11-req") - 1;
-+
-+        *(s++) = 0x01;          /* want_reply */
-+        *(s++) = single_connection ? 0x01 : 0x00;
-+
-+        libssh2_htonu32(s, proto_len);
-+        s += 4;
-+        memcpy(s, auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1", proto_len);
-+        s += proto_len;
-+
-+        libssh2_htonu32(s, cookie_len);
-+        s += 4;
-+        if (auth_cookie) {
-+            memcpy(s, auth_cookie, cookie_len);
-+        } else {
-+            int i;
-+            unsigned char buffer[LIBSSH2_X11_RANDOM_COOKIE_LEN / 2];
-+
-+            libssh2_random(buffer, LIBSSH2_X11_RANDOM_COOKIE_LEN / 2);
-+            for(i = 0; i < (LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); i++) {
-+                snprintf((char *) s + (i * 2), 2, "%02X", buffer[i]);
-+            }
-+        }
-+        s += cookie_len;
-+
-+        libssh2_htonu32(s, screen_number);
-+        s += 4;
-+
-+        channel->reqX11_state = libssh2_NB_state_created;
-+    }
-+
-+    if (channel->reqX11_state == libssh2_NB_state_created) {
-+        rc = libssh2_packet_write(session, channel->reqX11_packet,
-+                                  channel->reqX11_packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        }
-+        if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send x11-req packet", 0);
-+            LIBSSH2_FREE(session, channel->reqX11_packet);
-+            channel->reqX11_packet = NULL;
-+            channel->reqX11_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, channel->reqX11_packet);
-+        channel->reqX11_packet = NULL;
-+
-+        libssh2_htonu32(channel->reqX11_local_channel, channel->local.id);
-+
-+        channel->reqX11_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (channel->reqX11_state == libssh2_NB_state_sent) {
-+        rc = libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len,
-+                                        1, channel->reqX11_local_channel, 4,
-+                                        &channel->
-+                                        reqX11_packet_requirev_state);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            channel->reqX11_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+
-+        if (data[0] == SSH_MSG_CHANNEL_SUCCESS) {
-+            LIBSSH2_FREE(session, data);
-+            channel->reqX11_state = libssh2_NB_state_idle;
-+            return 0;
-+        }
-+    }
-+
-+    LIBSSH2_FREE(session, data);
-+    libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
-+                  "Unable to complete request for channel x11-req", 0);
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_process_startup
-+ * Primitive for libssh2_channel_(shell|exec|subsystem)
-+ */
-+LIBSSH2_API int
-+libssh2_channel_process_startup(LIBSSH2_CHANNEL * channel, const char *request,
-+                                unsigned int request_len, const char *message,
-+                                unsigned int message_len)
-+{
-+    LIBSSH2_SESSION *session = channel->session;
-+    unsigned char *s, *data;
-+    static const unsigned char reply_codes[3] =
-+        { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
-+    unsigned long data_len;
-+    libssh2pack_t rc;
-+
-+    if (channel->process_state == libssh2_NB_state_idle) {
-+        /* 10 = packet_type(1) + channel(4) + request_len(4) + want_reply(1) */
-+        channel->process_packet_len = request_len + 10;
-+
-+        /* Zero the whole thing out */
-+        memset(&channel->process_packet_requirev_state, 0,
-+               sizeof(channel->process_packet_requirev_state));
-+
-+        if (message) {
-+            channel->process_packet_len += message_len + 4;
-+        }
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                       "starting request(%s) on channel %lu/%lu, message=%s",
-+                       request, channel->local.id, channel->remote.id,
-+                       message);
-+        s = channel->process_packet =
-+            LIBSSH2_ALLOC(session, channel->process_packet_len);
-+        if (!channel->process_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for channel-process request",
-+                          0);
-+            return -1;
-+        }
-+
-+        *(s++) = SSH_MSG_CHANNEL_REQUEST;
-+        libssh2_htonu32(s, channel->remote.id);
-+        s += 4;
-+        libssh2_htonu32(s, request_len);
-+        s += 4;
-+        memcpy(s, request, request_len);
-+        s += request_len;
-+
-+        *(s++) = 0x01;
-+
-+        if (message) {
-+            libssh2_htonu32(s, message_len);
-+            s += 4;
-+            memcpy(s, message, message_len);
-+            s += message_len;
-+        }
-+
-+        channel->process_state = libssh2_NB_state_created;
-+    }
-+
-+    if (channel->process_state == libssh2_NB_state_created) {
-+        rc = libssh2_packet_write(session, channel->process_packet,
-+                                  channel->process_packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send channel request", 0);
-+            LIBSSH2_FREE(session, channel->process_packet);
-+            channel->process_packet = NULL;
-+            channel->process_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, channel->process_packet);
-+        channel->process_packet = NULL;
-+
-+        libssh2_htonu32(channel->process_local_channel, channel->local.id);
-+
-+        channel->process_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (channel->process_state == libssh2_NB_state_sent) {
-+        rc = libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len,
-+                                        1, channel->process_local_channel, 4,
-+                                        &channel->
-+                                        process_packet_requirev_state);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            channel->process_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+
-+        if (data[0] == SSH_MSG_CHANNEL_SUCCESS) {
-+            LIBSSH2_FREE(session, data);
-+            channel->process_state = libssh2_NB_state_idle;
-+            return 0;
-+        }
-+    }
-+
-+    LIBSSH2_FREE(session, data);
-+    libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
-+                  "Unable to complete request for channel-process-startup", 0);
-+    channel->process_state = libssh2_NB_state_idle;
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_set_blocking
-+ * Set a channel's blocking mode on or off, similar to a socket's
-+ * fcntl(fd, F_SETFL, O_NONBLOCK); type command
-+ */
-+LIBSSH2_API void
-+libssh2_channel_set_blocking(LIBSSH2_CHANNEL * channel, int blocking)
-+{
-+    (void) _libssh2_session_set_blocking(channel->session, blocking);
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_flush_ex
-+ * Flush data from one (or all) stream
-+ * Returns number of bytes flushed, or -1 on failure
-+ */
-+LIBSSH2_API int
-+libssh2_channel_flush_ex(LIBSSH2_CHANNEL * channel, int streamid)
-+{
-+    LIBSSH2_PACKET *packet = channel->session->packets.head;
-+
-+    if (channel->flush_state == libssh2_NB_state_idle) {
-+        channel->flush_refund_bytes = 0;
-+        channel->flush_flush_bytes = 0;
-+
-+        while (packet) {
-+            LIBSSH2_PACKET *next = packet->next;
-+            unsigned char packet_type = packet->data[0];
-+
-+            if (((packet_type == SSH_MSG_CHANNEL_DATA)
-+                 || (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA))
-+                && (libssh2_ntohu32(packet->data + 1) == channel->local.id)) {
-+                /* It's our channel at least */
-+                long packet_stream_id =
-+                    (packet_type ==
-+                     SSH_MSG_CHANNEL_DATA) ? 0 : libssh2_ntohu32(packet->data +
-+                                                                 5);
-+                if ((streamid == LIBSSH2_CHANNEL_FLUSH_ALL)
-+                    || ((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)
-+                        && ((streamid == LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA)
-+                            || (streamid == packet_stream_id)))
-+                    || ((packet_type == SSH_MSG_CHANNEL_DATA)
-+                        && (streamid == 0))) {
-+                    int bytes_to_flush = packet->data_len - packet->data_head;
-+
-+                    _libssh2_debug(channel->session, LIBSSH2_DBG_CONN,
-+                                   "Flushing %d bytes of data from stream "
-+                                   "%lu on channel %lu/%lu",
-+                                   bytes_to_flush, packet_stream_id,
-+                                   channel->local.id, channel->remote.id);
-+
-+                    /* It's one of the streams we wanted to flush */
-+                    channel->flush_refund_bytes += packet->data_len - 13;
-+                    channel->flush_flush_bytes += bytes_to_flush;
-+
-+                    LIBSSH2_FREE(channel->session, packet->data);
-+                    if (packet->prev) {
-+                        packet->prev->next = packet->next;
-+                    } else {
-+                        channel->session->packets.head = packet->next;
-+                    }
-+                    if (packet->next) {
-+                        packet->next->prev = packet->prev;
-+                    } else {
-+                        channel->session->packets.tail = packet->prev;
-+                    }
-+                    LIBSSH2_FREE(channel->session, packet);
-+                }
-+            }
-+            packet = next;
-+        }
-+
-+        channel->flush_state = libssh2_NB_state_created;
-+    }
-+
-+    if (channel->flush_refund_bytes) {
-+        int rc;
-+
-+        rc = libssh2_channel_receive_window_adjust(channel,
-+                                                   channel->flush_refund_bytes,
-+                                                   0);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        }
-+    }
-+
-+    channel->flush_state = libssh2_NB_state_idle;
-+
-+    return channel->flush_flush_bytes;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_get_exit_status
-+ * Return the channel's program exit status
-+ */
-+LIBSSH2_API int
-+libssh2_channel_get_exit_status(LIBSSH2_CHANNEL * channel)
-+{
-+    return channel->exit_status;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_receive_window_adjust
-+ * Adjust the receive window for a channel by adjustment bytes
-+ * If the amount to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and
-+ * force is 0 the adjustment amount will be queued for a later packet
-+ *
-+ * Returns the new size of the receive window (as understood by remote end)
-+ */
-+LIBSSH2_API unsigned long
-+libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
-+                                      unsigned long adjustment,
-+                                      unsigned char force)
-+{
-+    int rc;
-+
-+    if (channel->adjust_state == libssh2_NB_state_idle) {
-+        if (!force
-+            && (adjustment + channel->adjust_queue <
-+                LIBSSH2_CHANNEL_MINADJUST)) {
-+            _libssh2_debug(channel->session, LIBSSH2_DBG_CONN,
-+                           "Queueing %lu bytes for receive window adjustment "
-+                           "for channel %lu/%lu",
-+                           adjustment, channel->local.id, channel->remote.id);
-+            channel->adjust_queue += adjustment;
-+            return channel->remote.window_size;
-+        }
-+
-+        if (!adjustment && !channel->adjust_queue) {
-+            return channel->remote.window_size;
-+        }
-+
-+        adjustment += channel->adjust_queue;
-+        channel->adjust_queue = 0;
-+
-+
-+        /* Adjust the window based on the block we just freed */
-+        channel->adjust_adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST;
-+        libssh2_htonu32(channel->adjust_adjust + 1, channel->remote.id);
-+        libssh2_htonu32(channel->adjust_adjust + 5, adjustment);
-+        _libssh2_debug(channel->session, LIBSSH2_DBG_CONN,
-+                       "Adjusting window %lu bytes for data flushed from "
-+                       "channel %lu/%lu",
-+                       adjustment, channel->local.id, channel->remote.id);
-+
-+        channel->adjust_state = libssh2_NB_state_created;
-+    }
-+
-+    rc = libssh2_packet_write(channel->session, channel->adjust_adjust, 9);
-+    if (rc == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    } else if (rc) {
-+        libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND,
-+                      "Unable to send transfer-window adjustment packet, "
-+                      "deferring",
-+                      0);
-+        channel->adjust_queue = adjustment;
-+        channel->adjust_state = libssh2_NB_state_idle;
-+    } else {
-+        channel->adjust_state = libssh2_NB_state_idle;
-+        channel->remote.window_size += adjustment;
-+    }
-+
-+    return channel->remote.window_size;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_handle_extended_data
-+ *
-+ * How should extended data look to the calling app?  Keep it in separate
-+ * channels[_read() _read_stdder()]? (NORMAL) Merge the extended data to the
-+ * standard data? [everything via _read()]? (MERGE) Ignore it entirely [toss
-+ * out packets as they come in]? (IGNORE)
-+ */
-+LIBSSH2_API void
-+libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL * channel,
-+                                     int ignore_mode)
-+{
-+    while (libssh2_channel_handle_extended_data2(channel, ignore_mode) ==
-+           PACKET_EAGAIN);
-+}
-+
-+LIBSSH2_API int
-+libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL * channel,
-+                                      int ignore_mode)
-+{
-+    if (channel->extData2_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(channel->session, LIBSSH2_DBG_CONN,
-+                       "Setting channel %lu/%lu handle_extended_data mode to %d",
-+                       channel->local.id, channel->remote.id, ignore_mode);
-+        channel->remote.extended_data_ignore_mode = ignore_mode;
-+
-+        channel->extData2_state = libssh2_NB_state_created;
-+    }
-+
-+    if (channel->extData2_state == libssh2_NB_state_idle) {
-+        if (ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) {
-+            if (libssh2_channel_flush_ex
-+                (channel,
-+                 LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA) == PACKET_EAGAIN) {
-+                return PACKET_EAGAIN;
-+            }
-+        }
-+    }
-+
-+    channel->extData2_state = libssh2_NB_state_idle;
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/*
-+ * {{{ libssh2_channel_read_ex
-+ * Read data from a channel blocking or non-blocking depending on set state
-+ *
-+ * When this is done non-blocking, it is important to not return 0 until the
-+ * currently read channel is complete. If we read stuff from the wire but it
-+ * was no payload data to fill in the buffer with, we MUST make sure to return
-+ * PACKET_EAGAIN.
-+ */
-+LIBSSH2_API ssize_t
-+libssh2_channel_read_ex(LIBSSH2_CHANNEL * channel, int stream_id, char *buf,
-+                        size_t buflen)
-+{
-+    LIBSSH2_SESSION *session = channel->session;
-+    libssh2pack_t rc = 0;
-+
-+    if (channel->read_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                       "Attempting to read %d bytes from channel %lu/%lu stream #%d",
-+                       (int) buflen, channel->local.id, channel->remote.id,
-+                       stream_id);
-+
-+        /* process all incoming packets */
-+        do {
-+            if (libssh2_waitsocket(session, 0) > 0) {
-+                rc = libssh2_packet_read(session);
-+            } else {
-+                /* Set for PACKET_EAGAIN so we continue */
-+                rc = PACKET_EAGAIN;
-+            }
-+        } while (rc > 0);
-+
-+        if ((rc < 0) && (rc != PACKET_EAGAIN)) {
-+            return rc;
-+        }
-+        channel->read_bytes_read = 0;
-+
-+        channel->read_packet = session->packets.head;
-+        channel->read_state = libssh2_NB_state_created;
-+    }
-+
-+    /*
-+     * =============================== NOTE ===============================
-+     * I know this is very ugly and not a really good use of "goto", but
-+     * this case statement would be even uglier to do it any other way
-+     */
-+    if (channel->read_state == libssh2_NB_state_jump1) {
-+        goto channel_read_ex_point1;
-+    }
-+
-+    rc = 0;
-+    channel->read_block = 0;
-+
-+    do {
-+        if (channel->read_block) {
-+            /* in the second lap and onwards, do this...
-+             * If we haven't yet filled our buffer, try to read more
-+             * data.  */
-+            if ( channel->read_bytes_read < (int) buflen) {
-+                rc = libssh2_packet_read(session);
-+
-+                /* If we didn't find any more data to read */
-+                if (rc < 0) {
-+                    if ( channel->read_bytes_read > 0){
-+                        break;  /* finish processing and return */
-+                    }
-+
-+                    /* no packets available, no data read. */
-+                    channel->read_state = libssh2_NB_state_idle;
-+                    return rc;
-+                }
-+                /* We read more data, restart our processing at the beginning
-+                 * of our packet list. */
-+                channel->read_packet = session->packets.head;
-+            }
-+            else { /* The read buffer is full, finish processing and return */
-+                break;
-+            }
-+        }
-+
-+        while (channel->read_packet
-+               && (channel->read_bytes_read < (int) buflen)) {
-+            /* In case packet gets destroyed during this iteration */
-+            channel->read_next = channel->read_packet->next;
-+
-+            channel->read_local_id =
-+                libssh2_ntohu32(channel->read_packet->data + 1);
-+
-+            /*
-+             * Either we asked for a specific extended data stream
-+             * (and data was available),
-+             * or the standard stream (and data was available),
-+             * or the standard stream with extended_data_merge
-+             * enabled and data was available
-+             */
-+            if ((stream_id
-+                 && (channel->read_packet->data[0] ==
-+                     SSH_MSG_CHANNEL_EXTENDED_DATA)
-+                 && (channel->local.id == channel->read_local_id)
-+                 && (stream_id ==
-+                     (int) libssh2_ntohu32(channel->read_packet->data + 5)))
-+                || (!stream_id
-+                    && (channel->read_packet->data[0] == SSH_MSG_CHANNEL_DATA)
-+                    && (channel->local.id == channel->read_local_id))
-+                || (!stream_id
-+                    && (channel->read_packet->data[0] ==
-+                        SSH_MSG_CHANNEL_EXTENDED_DATA)
-+                    && (channel->local.id == channel->read_local_id)
-+                    && (channel->remote.extended_data_ignore_mode ==
-+                        LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) {
-+
-+                channel->read_want = buflen - channel->read_bytes_read;
-+                channel->read_unlink_packet = 0;
-+
-+                if (channel->read_want >=
-+                    (int) (channel->read_packet->data_len -
-+                           channel->read_packet->data_head)) {
-+                    channel->read_want =
-+                        channel->read_packet->data_len -
-+                        channel->read_packet->data_head;
-+                    channel->read_unlink_packet = 1;
-+                }
-+
-+                _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                               "Reading %d of buffered data from %lu/%lu/%d",
-+                               channel->read_want, channel->local.id,
-+                               channel->remote.id, stream_id);
-+                memcpy(buf + channel->read_bytes_read,
-+                       channel->read_packet->data +
-+                       channel->read_packet->data_head, channel->read_want);
-+                channel->read_packet->data_head += channel->read_want;
-+                channel->read_bytes_read += channel->read_want;
-+
-+                if (channel->read_unlink_packet) {
-+                    if (channel->read_packet->prev) {
-+                        channel->read_packet->prev->next =
-+                            channel->read_packet->next;
-+                    } else {
-+                        session->packets.head = channel->read_packet->next;
-+                    }
-+                    if (channel->read_packet->next) {
-+                        channel->read_packet->next->prev =
-+                            channel->read_packet->prev;
-+                    } else {
-+                        session->packets.tail = channel->read_packet->prev;
-+                    }
-+                    LIBSSH2_FREE(session, channel->read_packet->data);
-+
-+
-+                    _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                                   "Unlinking empty packet buffer from "
-+                                   "channel %lu/%lu",
-+                                   channel->local.id, channel->remote.id);
-+                  channel_read_ex_point1:
-+                    channel->read_state = libssh2_NB_state_jump1;
-+                    rc = libssh2_channel_receive_window_adjust(channel,
-+                                                               channel->
-+                                                               read_packet->
-+                                                               data_len -
-+                                                               (stream_id ? 13
-+                                                                : 9), 0);
-+                    if (rc == PACKET_EAGAIN) {
-+                        return PACKET_EAGAIN;
-+                    }
-+                    channel->read_state = libssh2_NB_state_created;
-+                    LIBSSH2_FREE(session, channel->read_packet);
-+                    channel->read_packet = NULL;
-+                }
-+            }
-+            channel->read_packet = channel->read_next;
-+        }
-+        channel->read_block = 1;
-+    } while ((channel->read_bytes_read == 0) && !channel->remote.close);
-+
-+    channel->read_state = libssh2_NB_state_idle;
-+    if (channel->read_bytes_read == 0) {
-+        if (channel->session->socket_block) {
-+            libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED,
-+                          "Remote end has closed this channel", 0);
-+        } else {
-+            /*
-+             * when non-blocking, we must return PACKET_EAGAIN if we haven't
-+             * completed reading the channel
-+             */
-+            if (!libssh2_channel_eof(channel)) {
-+                return PACKET_EAGAIN;
-+            }
-+        }
-+    }
-+
-+    channel->read_state = libssh2_NB_state_idle;
-+    return channel->read_bytes_read;
-+}
-+
-+/* }}} */
-+
-+/*
-+ * {{{ libssh2_channel_packet_data_len
-+ * Return the size of the data block of the current packet, or 0 if there
-+ * isn't a packet.
-+ */
-+unsigned long
-+libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
-+{
-+    LIBSSH2_SESSION *session = channel->session;
-+    LIBSSH2_PACKET *read_packet;
-+    uint32_t read_local_id;
-+
-+    if ((read_packet = session->packets.head) == NULL) {
-+        return 0;
-+    }
-+
-+    while (read_packet) {
-+        read_local_id = libssh2_ntohu32(read_packet->data + 1);
-+
-+        /*
-+         * Either we asked for a specific extended data stream
-+         * (and data was available),
-+         * or the standard stream (and data was available),
-+         * or the standard stream with extended_data_merge
-+         * enabled and data was available
-+         */
-+        if ((stream_id
-+             && (read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)
-+             && (channel->local.id == read_local_id)
-+             && (stream_id == (int) libssh2_ntohu32(read_packet->data + 5)))
-+            || (!stream_id && (read_packet->data[0] == SSH_MSG_CHANNEL_DATA)
-+                && (channel->local.id == read_local_id)) ||
-+            (!stream_id
-+             && (read_packet->
-+                 data[0] ==
-+                 SSH_MSG_CHANNEL_EXTENDED_DATA)
-+             && (channel->
-+                 local.id ==
-+                 read_local_id)
-+             && (channel->
-+                 remote.
-+                 extended_data_ignore_mode
-+                 ==
-+                 LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE)))
-+        {
-+            return (read_packet->data_len - read_packet->data_head);
-+        }
-+        read_packet = read_packet->next;
-+    }
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_write_ex
-+ * Send data to a channel
-+ */
-+LIBSSH2_API ssize_t
-+libssh2_channel_write_ex(LIBSSH2_CHANNEL * channel, int stream_id,
-+                         const char *buf, size_t buflen)
-+{
-+    LIBSSH2_SESSION *session = channel->session;
-+    libssh2pack_t rc;
-+
-+    if (channel->write_state == libssh2_NB_state_idle) {
-+        channel->write_bufwrote = 0;
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                       "Writing %d bytes on channel %lu/%lu, stream #%d",
-+                       (int) buflen, channel->local.id, channel->remote.id,
-+                       stream_id);
-+
-+        if (channel->local.close) {
-+            libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED,
-+                          "We've already closed this channel", 0);
-+            return -1;
-+        }
-+
-+        if (channel->local.eof) {
-+            libssh2_error(session, LIBSSH2_ERROR_CHANNEL_EOF_SENT,
-+                          "EOF has already been sight, data might be ignored",
-+                          0);
-+        }
-+
-+        /* [13] 9 = packet_type(1) + channelno(4) [ + streamid(4) ] +
-+           buflen(4) */
-+        channel->write_packet_len = buflen + (stream_id ? 13 : 9);
-+        channel->write_packet =
-+            LIBSSH2_ALLOC(session, channel->write_packet_len);
-+        if (!channel->write_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocte space for data transmission packet",
-+                          0);
-+            return -1;
-+        }
-+
-+        channel->write_state = libssh2_NB_state_allocated;
-+    }
-+
-+    while (buflen > 0) {
-+        if (channel->write_state == libssh2_NB_state_allocated) {
-+            channel->write_bufwrite = buflen;
-+            channel->write_s = channel->write_packet;
-+
-+            *(channel->write_s++) =
-+                stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA :
-+                SSH_MSG_CHANNEL_DATA;
-+            libssh2_htonu32(channel->write_s, channel->remote.id);
-+            channel->write_s += 4;
-+            if (stream_id) {
-+                libssh2_htonu32(channel->write_s, stream_id);
-+                channel->write_s += 4;
-+            }
-+
-+            /* twiddle our thumbs until there's window space available */
-+            while (channel->local.window_size <= 0) {
-+                /* Don't worry -- This is never hit unless it's a
-+                   blocking channel anyway */
-+                rc = libssh2_packet_read(session);
-+
-+                if (rc < 0) {
-+                    /* Error or EAGAIN occurred, disconnect? */
-+                    if (rc != PACKET_EAGAIN) {
-+                        channel->write_state = libssh2_NB_state_idle;
-+                    }
-+                    return rc;
-+                }
-+
-+                if ((rc == 0) && (session->socket_block == 0)) {
-+                    /*
-+                     * if rc == 0 and in non-blocking, then fake EAGAIN
-+                     * to prevent busyloops until data arriaves on the network
-+                     * which seemed like a very bad idea
-+                     */
-+                    return PACKET_EAGAIN;
-+                }
-+            }
-+
-+            /* Don't exceed the remote end's limits */
-+            /* REMEMBER local means local as the SOURCE of the data */
-+            if (channel->write_bufwrite > channel->local.window_size) {
-+                _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                               "Splitting write block due to %lu byte "
-+                               "window_size on %lu/%lu/%d",
-+                               channel->local.window_size, channel->local.id,
-+                               channel->remote.id, stream_id);
-+                channel->write_bufwrite = channel->local.window_size;
-+            }
-+            if (channel->write_bufwrite > channel->local.packet_size) {
-+                _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                               "Splitting write block due to %lu byte "
-+                               "packet_size on %lu/%lu/%d",
-+                               channel->local.packet_size, channel->local.id,
-+                               channel->remote.id, stream_id);
-+                channel->write_bufwrite = channel->local.packet_size;
-+            }
-+            libssh2_htonu32(channel->write_s, channel->write_bufwrite);
-+            channel->write_s += 4;
-+            memcpy(channel->write_s, buf, channel->write_bufwrite);
-+            channel->write_s += channel->write_bufwrite;
-+
-+            _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                           "Sending %d bytes on channel %lu/%lu, stream_id=%d",
-+                           (int) channel->write_bufwrite, channel->local.id,
-+                           channel->remote.id, stream_id);
-+
-+            channel->write_state = libssh2_NB_state_created;
-+        }
-+
-+        if (channel->write_state == libssh2_NB_state_created) {
-+            rc = libssh2_packet_write(session, channel->write_packet,
-+                                      channel->write_s -
-+                                      channel->write_packet);
-+            if (rc == PACKET_EAGAIN) {
-+                _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                               "libssh2_packet_write returned EAGAIN");
-+                return PACKET_EAGAIN;
-+            }
-+            else if (rc) {
-+                libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                              "Unable to send channel data", 0);
-+                LIBSSH2_FREE(session, channel->write_packet);
-+                channel->write_packet = NULL;
-+                channel->write_state = libssh2_NB_state_idle;
-+                return -1;
-+            }
-+            /* Shrink local window size */
-+            channel->local.window_size -= channel->write_bufwrite;
-+
-+            /* Adjust buf for next iteration */
-+            buflen -= channel->write_bufwrite;
-+            buf += channel->write_bufwrite;
-+            channel->write_bufwrote += channel->write_bufwrite;
-+
-+            channel->write_state = libssh2_NB_state_allocated;
-+
-+            /*
-+             * Not sure this is still wanted
-+             if (!channel->session->socket_block) {
-+             break;
-+             }
-+             */
-+        }
-+    }
-+
-+    LIBSSH2_FREE(session, channel->write_packet);
-+    channel->write_packet = NULL;
-+
-+    channel->write_state = libssh2_NB_state_idle;
-+
-+    return channel->write_bufwrote;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_send_eof
-+ * Send EOF on channel
-+ */
-+LIBSSH2_API int
-+libssh2_channel_send_eof(LIBSSH2_CHANNEL * channel)
-+{
-+    LIBSSH2_SESSION *session = channel->session;
-+    unsigned char packet[5];    /* packet_type(1) + channelno(4) */
-+    int rc;
-+
-+    _libssh2_debug(session, LIBSSH2_DBG_CONN, "Sending EOF on channel %lu/%lu",
-+                   channel->local.id, channel->remote.id);
-+    packet[0] = SSH_MSG_CHANNEL_EOF;
-+    libssh2_htonu32(packet + 1, channel->remote.id);
-+    rc = libssh2_packet_write(session, packet, 5);
-+    if (rc == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    } else if (rc) {
-+        libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                      "Unable to send EOF on channel", 0);
-+        return -1;
-+    }
-+    channel->local.eof = 1;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_eof
-+ * Read channel's eof status
-+ */
-+LIBSSH2_API int
-+libssh2_channel_eof(LIBSSH2_CHANNEL * channel)
-+{
-+    LIBSSH2_SESSION *session = channel->session;
-+    LIBSSH2_PACKET *packet = session->packets.head;
-+
-+    while (packet) {
-+        if (((packet->data[0] == SSH_MSG_CHANNEL_DATA)
-+             || (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA))
-+            && (channel->local.id == libssh2_ntohu32(packet->data + 1))) {
-+            /* There's data waiting to be read yet, mask the EOF status */
-+            return 0;
-+        }
-+        packet = packet->next;
-+    }
-+
-+    return channel->remote.eof;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_wait_eof
-+* Awaiting channel EOF
-+*/
-+LIBSSH2_API int
-+libssh2_channel_wait_eof(LIBSSH2_CHANNEL * channel)
-+{
-+    LIBSSH2_SESSION *session = channel->session;
-+    int rc;
-+
-+    if (channel->wait_eof_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                       "Awaiting close of channel %lu/%lu", channel->local.id,
-+                       channel->remote.id);
-+
-+        channel->wait_eof_state = libssh2_NB_state_created;
-+    }
-+
-+    /*
-+     * While channel is not eof, read more packets from the network.
-+     * Either the EOF will be set or network timeout will occur.
-+     */
-+    do {
-+        if (channel->remote.eof) {
-+            break;
-+        }
-+        rc = libssh2_packet_read(session);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc < 0) {
-+            channel->wait_eof_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+    } while (1);
-+
-+    channel->wait_eof_state = libssh2_NB_state_idle;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+
-+/* {{{ libssh2_channel_close
-+ * Close a channel
-+ */
-+LIBSSH2_API int
-+libssh2_channel_close(LIBSSH2_CHANNEL * channel)
-+{
-+    LIBSSH2_SESSION *session = channel->session;
-+    int rc = 0;
-+    int retcode;
-+
-+    if (channel->local.close) {
-+        /* Already closed, act like we sent another close,
-+         * even though we didn't... shhhhhh */
-+        channel->close_state = libssh2_NB_state_idle;
-+        return 0;
-+    }
-+
-+    if (channel->close_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_CONN, "Closing channel %lu/%lu",
-+                       channel->local.id, channel->remote.id);
-+
-+        if (channel->close_cb) {
-+            LIBSSH2_CHANNEL_CLOSE(session, channel);
-+        }
-+        channel->local.close = 1;
-+
-+        channel->close_packet[0] = SSH_MSG_CHANNEL_CLOSE;
-+        libssh2_htonu32(channel->close_packet + 1, channel->remote.id);
-+
-+        channel->close_state = libssh2_NB_state_created;
-+    }
-+
-+    if (channel->close_state == libssh2_NB_state_created) {
-+        retcode = libssh2_packet_write(session, channel->close_packet, 5);
-+        if (retcode == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (retcode) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send close-channel request", 0);
-+            channel->close_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+
-+        channel->close_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (channel->close_state == libssh2_NB_state_sent) {
-+        /* We must wait for the remote SSH_MSG_CHANNEL_CLOSE message */
-+        if (!channel->remote.close) {
-+            libssh2pack_t ret;
-+
-+            do {
-+                ret = libssh2_packet_read(session);
-+                if (ret == PACKET_EAGAIN) {
-+                    return PACKET_EAGAIN;
-+                } else if (ret < 0) {
-+                    rc = -1;
-+                }
-+            } while ((ret != SSH_MSG_CHANNEL_CLOSE) && (rc == 0));
-+        }
-+    }
-+
-+    channel->close_state = libssh2_NB_state_idle;
-+
-+    return rc;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_wait_closed
-+ * Awaiting channel close after EOF
-+ */
-+LIBSSH2_API int
-+libssh2_channel_wait_closed(LIBSSH2_CHANNEL * channel)
-+{
-+    LIBSSH2_SESSION *session = channel->session;
-+    int rc;
-+
-+    if (!libssh2_channel_eof(channel)) {
-+        libssh2_error(session, LIBSSH2_ERROR_INVAL,
-+                      "libssh2_channel_wait_closed() invoked when channel is "
-+                      "not in EOF state",
-+                      0);
-+        return -1;
-+    }
-+
-+    if (channel->wait_closed_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                       "Awaiting close of channel %lu/%lu", channel->local.id,
-+                       channel->remote.id);
-+
-+        channel->wait_closed_state = libssh2_NB_state_created;
-+    }
-+
-+    /*
-+     * While channel is not closed, read more packets from the network.
-+     * Either the channel will be closed or network timeout will occur.
-+     */
-+    do {
-+        if (!channel->remote.close) {
-+            break;
-+        }
-+        rc = libssh2_packet_read(session);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc <= 0) {
-+            break;
-+        }
-+    } while (1);
-+
-+    channel->wait_closed_state = libssh2_NB_state_idle;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+
-+/* {{{ libssh2_channel_free
-+ * Make sure a channel is closed, then remove the channel from the session
-+ * and free its resource(s)
-+ *
-+ * Returns 0 on success, -1 on failure
-+ */
-+LIBSSH2_API int
-+libssh2_channel_free(LIBSSH2_CHANNEL * channel)
-+{
-+    LIBSSH2_SESSION *session = channel->session;
-+    unsigned char channel_id[4];
-+    unsigned char *data;
-+    unsigned long data_len;
-+    int rc;
-+
-+    if (channel->free_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                       "Freeing channel %lu/%lu resources", channel->local.id,
-+                       channel->remote.id);
-+
-+        channel->free_state = libssh2_NB_state_created;
-+    }
-+
-+    /* Allow channel freeing even when the socket has lost its connection */
-+    if (!channel->local.close
-+        && (session->socket_state == LIBSSH2_SOCKET_CONNECTED)) {
-+        while ((rc = libssh2_channel_close(channel)) == PACKET_EAGAIN);
-+        if (rc) {
-+            channel->free_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+    }
-+
-+    channel->free_state = libssh2_NB_state_idle;
-+
-+    /*
-+     * channel->remote.close *might* not be set yet, Well...
-+     * We've sent the close packet, what more do you want?
-+     * Just let packet_add ignore it when it finally arrives
-+     */
-+
-+    /* Clear out packets meant for this channel */
-+    libssh2_htonu32(channel_id, channel->local.id);
-+    while ((libssh2_packet_ask_ex
-+            (session, SSH_MSG_CHANNEL_DATA, &data, &data_len, 1, channel_id, 4,
-+             0) >= 0)
-+           ||
-+           (libssh2_packet_ask_ex
-+            (session, SSH_MSG_CHANNEL_EXTENDED_DATA, &data, &data_len, 1,
-+             channel_id, 4, 0) >= 0)) {
-+        LIBSSH2_FREE(session, data);
-+    }
-+
-+    /* free "channel_type" */
-+    if (channel->channel_type) {
-+        LIBSSH2_FREE(session, channel->channel_type);
-+    }
-+
-+    /* Unlink from channel brigade */
-+    if (channel->prev) {
-+        channel->prev->next = channel->next;
-+    } else {
-+        session->channels.head = channel->next;
-+    }
-+    if (channel->next) {
-+        channel->next->prev = channel->prev;
-+    } else {
-+        session->channels.tail = channel->prev;
-+    }
-+
-+    /*
-+     * Make sure all memory used in the state variables are free
-+     */
-+    if (channel->setenv_packet) {
-+        LIBSSH2_FREE(session, channel->setenv_packet);
-+    }
-+    if (channel->reqPTY_packet) {
-+        LIBSSH2_FREE(session, channel->reqPTY_packet);
-+    }
-+    if (channel->reqX11_packet) {
-+        LIBSSH2_FREE(session, channel->reqX11_packet);
-+    }
-+    if (channel->process_packet) {
-+        LIBSSH2_FREE(session, channel->process_packet);
-+    }
-+    if (channel->write_packet) {
-+        LIBSSH2_FREE(session, channel->write_packet);
-+    }
-+
-+    LIBSSH2_FREE(session, channel);
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_window_read_ex
-+ *
-+ * Check the status of the read window. Returns the number of bytes which the
-+ * remote end may send without overflowing the window limit read_avail (if
-+ * passed) will be populated with the number of bytes actually available to be
-+ * read window_size_initial (if passed) will be populated with the
-+ * window_size_initial as defined by the channel_open request
-+ */
-+LIBSSH2_API unsigned long
-+libssh2_channel_window_read_ex(LIBSSH2_CHANNEL * channel,
-+                               unsigned long *read_avail,
-+                               unsigned long *window_size_initial)
-+{
-+    if (window_size_initial) {
-+        *window_size_initial = channel->remote.window_size_initial;
-+    }
-+
-+    if (read_avail) {
-+        unsigned long bytes_queued = 0;
-+        LIBSSH2_PACKET *packet = channel->session->packets.head;
-+
-+        while (packet) {
-+            unsigned char packet_type = packet->data[0];
-+
-+            if (((packet_type == SSH_MSG_CHANNEL_DATA)
-+                 || (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA))
-+                && (libssh2_ntohu32(packet->data + 1) == channel->local.id)) {
-+                bytes_queued += packet->data_len - packet->data_head;
-+            }
-+
-+            packet = packet->next;
-+        }
-+
-+        *read_avail = bytes_queued;
-+    }
-+
-+    return channel->remote.window_size;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_channel_window_write_ex
-+ *
-+ * Check the status of the write window Returns the number of bytes which may
-+ * be safely writen on the channel without blocking window_size_initial (if
-+ * passed) will be populated with the size of the initial window as defined by
-+ * the channel_open request
-+ */
-+LIBSSH2_API unsigned long
-+libssh2_channel_window_write_ex(LIBSSH2_CHANNEL * channel,
-+                                unsigned long *window_size_initial)
-+{
-+    if (window_size_initial) {
-+        /* For locally initiated channels this is very often 0, so it's not
-+         * *that* useful as information goes */
-+        *window_size_initial = channel->local.window_size_initial;
-+    }
-+
-+    return channel->local.window_size;
-+}
-+
-+/* }}} */
-
-Property changes on: libssh2/src/channel.c
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.2
-Added: svn:eol-style
-   + native
-
-Index: libssh2/src/libssh2_priv.h
-===================================================================
---- libssh2/src/libssh2_priv.h (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/libssh2_priv.h (.../trunk)
-@@ -0,0 +1,1211 @@
-+/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#ifndef LIBSSH2_PRIV_H
-+#define LIBSSH2_PRIV_H 1
-+
-+#define LIBSSH2_LIBRARY
-+#include "libssh2_config.h"
-+
-+#ifdef HAVE_WINDOWS_H
-+#include <windows.h>
-+#endif
-+
-+#ifdef HAVE_WS2TCPIP_H
-+#include <ws2tcpip.h>
-+#endif
-+
-+#include <stdio.h>
-+#include <time.h>
-+
-+/* The following CPP block should really only be in session.c and
-+   packet.c.  However, AIX have #define's for 'events' and 'revents'
-+   and we are using those names in libssh2.h, so we need to include
-+   the AIX headers first, to make sure all code is compiled with
-+   consistent names of these fields.  While arguable the best would to
-+   change libssh2.h to use other names, that would break backwards
-+   compatibility.  For more information, see:
-+   http://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00003.html
-+   http://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00224.html
-+*/
-+#ifdef HAVE_POLL
-+# include <sys/poll.h>
-+#else
-+# if defined(HAVE_SELECT) && !defined(WIN32)
-+# ifdef HAVE_SYS_SELECT_H
-+# include <sys/select.h>
-+# else
-+# include <sys/time.h>
-+# include <sys/types.h>
-+# endif
-+# endif
-+#endif
-+
-+#include "libssh2.h"
-+#include "libssh2_publickey.h"
-+#include "libssh2_sftp.h"
-+
-+/* Provide iovec / writev on WIN32 platform. */
-+#ifdef WIN32
-+
-+/* same as WSABUF */
-+struct iovec {
-+      u_long iov_len;
-+      char *iov_base;
-+};
-+
-+#define inline __inline
-+
-+static inline int writev(int sock, struct iovec *iov, int nvecs)
-+{
-+      DWORD ret;
-+      if (WSASend(sock, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL) == 0) {
-+              return ret;
-+      }
-+      return -1;
-+}
-+
-+#endif /* WIN32 */
-+
-+/* Needed for struct iovec on some platforms */
-+#ifdef HAVE_SYS_UIO_H
-+#include <sys/uio.h>
-+#endif
-+
-+#ifdef HAVE_SYS_SOCKET_H
-+# include <sys/socket.h>
-+#endif
-+#ifdef HAVE_SYS_IOCTL_H
-+# include <sys/ioctl.h>
-+#endif
-+#ifdef HAVE_INTTYPES_H
-+#include <inttypes.h>
-+#endif
-+
-+#ifdef LIBSSH2_LIBGCRYPT
-+#include "libgcrypt.h"
-+#else
-+#include "openssl.h"
-+#endif
-+
-+#ifdef HAVE_WINSOCK2_H
-+
-+#include <winsock2.h>
-+#include <mswsock.h>
-+#include <ws2tcpip.h>
-+
-+#ifdef _MSC_VER
-+/* "inline" keyword is valid only with C++ engine! */
-+#define inline __inline
-+#endif
-+
-+/* not really usleep, but safe for the way we use it in this lib */
-+static inline int usleep(int udelay)
-+{
-+      Sleep(udelay / 1000);
-+      return 0;
-+}
-+
-+#endif
-+
-+/* RFC4253 section 6.1 Maximum Packet Length says:
-+ *
-+ * "All implementations MUST be able to process packets with
-+ * uncompressed payload length of 32768 bytes or less and
-+ * total packet size of 35000 bytes or less (including length,
-+ * padding length, payload, padding, and MAC.)."
-+ */
-+#define MAX_SSH_PACKET_LEN 35000
-+
-+#define LIBSSH2_ALLOC(session, count)                               session->alloc((count), &(session)->abstract)
-+#define LIBSSH2_REALLOC(session, ptr, count)                        ((ptr) ? session->realloc((ptr), (count), &(session)->abstract) : session->alloc((count), &(session)->abstract))
-+#define LIBSSH2_FREE(session, ptr)                                  session->free((ptr), &(session)->abstract)
-+
-+#define LIBSSH2_IGNORE(session, data, datalen)                      session->ssh_msg_ignore((session), (data), (datalen), &(session)->abstract)
-+#define LIBSSH2_DEBUG(session, always_display, message, message_len, language, language_len)    \
-+                session->ssh_msg_disconnect((session), (always_display), (message), (message_len), (language), (language_len), &(session)->abstract)
-+#define LIBSSH2_DISCONNECT(session, reason, message, message_len, language, language_len)   \
-+                session->ssh_msg_disconnect((session), (reason), (message), (message_len), (language), (language_len), &(session)->abstract)
-+
-+#define LIBSSH2_MACERROR(session, data, datalen)                    session->macerror((session), (data), (datalen), &(session)->abstract)
-+#define LIBSSH2_X11_OPEN(channel, shost, sport)                     channel->session->x11(((channel)->session), (channel), (shost), (sport), (&(channel)->session->abstract))
-+
-+#define LIBSSH2_CHANNEL_CLOSE(session, channel)                     channel->close_cb((session), &(session)->abstract, (channel), &(channel)->abstract)
-+
-+typedef struct _LIBSSH2_KEX_METHOD LIBSSH2_KEX_METHOD;
-+typedef struct _LIBSSH2_HOSTKEY_METHOD LIBSSH2_HOSTKEY_METHOD;
-+typedef struct _LIBSSH2_MAC_METHOD LIBSSH2_MAC_METHOD;
-+typedef struct _LIBSSH2_CRYPT_METHOD LIBSSH2_CRYPT_METHOD;
-+typedef struct _LIBSSH2_COMP_METHOD LIBSSH2_COMP_METHOD;
-+
-+typedef struct _LIBSSH2_PACKET LIBSSH2_PACKET;
-+typedef struct _LIBSSH2_PACKET_BRIGADE LIBSSH2_PACKET_BRIGADE;
-+typedef struct _LIBSSH2_CHANNEL_BRIGADE LIBSSH2_CHANNEL_BRIGADE;
-+
-+typedef int libssh2pack_t;
-+
-+typedef enum
-+{
-+    libssh2_NB_state_idle = 0,
-+    libssh2_NB_state_allocated,
-+    libssh2_NB_state_created,
-+    libssh2_NB_state_sent,
-+    libssh2_NB_state_sent1,
-+    libssh2_NB_state_sent2,
-+    libssh2_NB_state_sent3,
-+    libssh2_NB_state_sent4,
-+    libssh2_NB_state_sent5,
-+    libssh2_NB_state_sent6,
-+    libssh2_NB_state_sent7,
-+    libssh2_NB_state_jump1,
-+    libssh2_NB_state_jump2,
-+    libssh2_NB_state_jump3
-+} libssh2_nonblocking_states;
-+
-+typedef struct packet_require_state_t
-+{
-+    libssh2_nonblocking_states state;
-+    time_t start;
-+} packet_require_state_t;
-+
-+typedef struct packet_requirev_state_t
-+{
-+    time_t start;
-+} packet_requirev_state_t;
-+
-+typedef struct kmdhgGPsha1kex_state_t
-+{
-+    libssh2_nonblocking_states state;
-+    unsigned char *e_packet;
-+    unsigned char *s_packet;
-+    unsigned char *tmp;
-+    unsigned char h_sig_comp[SHA_DIGEST_LENGTH];
-+    unsigned char c;
-+    unsigned long e_packet_len;
-+    unsigned long s_packet_len;
-+    unsigned long tmp_len;
-+    _libssh2_bn_ctx *ctx;
-+    _libssh2_bn *x;
-+    _libssh2_bn *e;
-+    _libssh2_bn *f;
-+    _libssh2_bn *k;
-+    unsigned char *s;
-+    unsigned char *f_value;
-+    unsigned char *k_value;
-+    unsigned char *h_sig;
-+    unsigned long f_value_len;
-+    unsigned long k_value_len;
-+    unsigned long h_sig_len;
-+    libssh2_sha1_ctx exchange_hash;
-+    packet_require_state_t req_state;
-+    libssh2_nonblocking_states burn_state;
-+} kmdhgGPsha1kex_state_t;
-+
-+typedef struct key_exchange_state_low_t
-+{
-+    libssh2_nonblocking_states state;
-+    packet_require_state_t req_state;
-+    kmdhgGPsha1kex_state_t exchange_state;
-+    _libssh2_bn *p;             /* SSH2 defined value (p_value) */
-+    _libssh2_bn *g;             /* SSH2 defined value (2) */
-+    unsigned char request[13];
-+    unsigned char *data;
-+    unsigned long request_len;
-+    unsigned long data_len;
-+} key_exchange_state_low_t;
-+
-+typedef struct key_exchange_state_t
-+{
-+    libssh2_nonblocking_states state;
-+    packet_require_state_t req_state;
-+    key_exchange_state_low_t key_state_low;
-+    unsigned char *data;
-+    unsigned long data_len;
-+    unsigned char *oldlocal;
-+    unsigned long oldlocal_len;
-+} key_exchange_state_t;
-+
-+#define FwdNotReq "Forward not requested"
-+
-+typedef struct packet_queue_listener_state_t
-+{
-+    libssh2_nonblocking_states state;
-+    unsigned char packet[17 + (sizeof(FwdNotReq) - 1)];
-+    unsigned char *host;
-+    unsigned char *shost;
-+    uint32_t sender_channel;
-+    uint32_t initial_window_size;
-+    uint32_t packet_size;
-+    uint32_t port;
-+    uint32_t sport;
-+    uint32_t host_len;
-+    uint32_t shost_len;
-+} packet_queue_listener_state_t;
-+
-+#define X11FwdUnAvil "X11 Forward Unavailable"
-+
-+typedef struct packet_x11_open_state_t
-+{
-+    libssh2_nonblocking_states state;
-+    unsigned char packet[17 + (sizeof(X11FwdUnAvil) - 1)];
-+    unsigned char *shost;
-+    uint32_t sender_channel;
-+    uint32_t initial_window_size;
-+    uint32_t packet_size;
-+    uint32_t sport;
-+    uint32_t shost_len;
-+} packet_x11_open_state_t;
-+
-+struct _LIBSSH2_PACKET
-+{
-+    unsigned char type;
-+
-+    /* Unencrypted Payload (no type byte, no padding, just the facts ma'am) */
-+    unsigned char *data;
-+    unsigned long data_len;
-+
-+    /* Where to start reading data from,
-+     * used for channel data that's been partially consumed */
-+    unsigned long data_head;
-+
-+    /* Can the message be confirmed? */
-+    int mac;
-+
-+    LIBSSH2_PACKET_BRIGADE *brigade;
-+
-+    LIBSSH2_PACKET *next, *prev;
-+};
-+
-+struct _LIBSSH2_PACKET_BRIGADE
-+{
-+    LIBSSH2_PACKET *head, *tail;
-+};
-+
-+typedef struct _libssh2_channel_data
-+{
-+    /* Identifier */
-+    unsigned long id;
-+
-+    /* Limits and restrictions */
-+    unsigned long window_size_initial, window_size, packet_size;
-+
-+    /* Set to 1 when CHANNEL_CLOSE / CHANNEL_EOF sent/received */
-+    char close, eof, extended_data_ignore_mode;
-+} libssh2_channel_data;
-+
-+struct _LIBSSH2_CHANNEL
-+{
-+    unsigned char *channel_type;
-+    unsigned channel_type_len;
-+
-+    /* channel's program exit status */
-+    int exit_status;
-+
-+    libssh2_channel_data local, remote;
-+    /* Amount of bytes to be refunded to receive window (but not yet sent) */
-+    unsigned long adjust_queue;
-+
-+    LIBSSH2_SESSION *session;
-+
-+    LIBSSH2_CHANNEL *next, *prev;
-+
-+    void *abstract;
-+      LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb));
-+
-+    /* State variables used in libssh2_channel_setenv_ex() */
-+    libssh2_nonblocking_states setenv_state;
-+    unsigned char *setenv_packet;
-+    unsigned long setenv_packet_len;
-+    unsigned char setenv_local_channel[4];
-+    packet_requirev_state_t setenv_packet_requirev_state;
-+
-+    /* State variables used in libssh2_channel_request_pty_ex() */
-+    libssh2_nonblocking_states reqPTY_state;
-+    unsigned char *reqPTY_packet;
-+    unsigned long reqPTY_packet_len;
-+    unsigned char reqPTY_local_channel[4];
-+    packet_requirev_state_t reqPTY_packet_requirev_state;
-+
-+    /* State variables used in libssh2_channel_x11_req_ex() */
-+    libssh2_nonblocking_states reqX11_state;
-+    unsigned char *reqX11_packet;
-+    unsigned long reqX11_packet_len;
-+    unsigned char reqX11_local_channel[4];
-+    packet_requirev_state_t reqX11_packet_requirev_state;
-+
-+    /* State variables used in libssh2_channel_process_startup() */
-+    libssh2_nonblocking_states process_state;
-+    unsigned char *process_packet;
-+    unsigned long process_packet_len;
-+    unsigned char process_local_channel[4];
-+    packet_requirev_state_t process_packet_requirev_state;
-+
-+    /* State variables used in libssh2_channel_flush_ex() */
-+    libssh2_nonblocking_states flush_state;
-+    unsigned long flush_refund_bytes;
-+    unsigned long flush_flush_bytes;
-+
-+    /* State variables used in libssh2_channel_receive_window_adjust() */
-+    libssh2_nonblocking_states adjust_state;
-+    unsigned char adjust_adjust[9];     /* packet_type(1) + channel(4) + adjustment(4) */
-+
-+    /* State variables used in libssh2_channel_read_ex() */
-+    libssh2_nonblocking_states read_state;
-+    LIBSSH2_PACKET *read_packet;
-+    LIBSSH2_PACKET *read_next;
-+    int read_block;
-+    int read_bytes_read;
-+    uint32_t read_local_id;
-+    int read_want;
-+    int read_unlink_packet;
-+
-+    /* State variables used in libssh2_channel_write_ex() */
-+    libssh2_nonblocking_states write_state;
-+    unsigned char *write_packet;
-+    unsigned char *write_s;
-+    unsigned long write_packet_len;
-+    unsigned long write_bufwrote;
-+    size_t write_bufwrite;
-+
-+    /* State variables used in libssh2_channel_close() */
-+    libssh2_nonblocking_states close_state;
-+    unsigned char close_packet[5];
-+
-+    /* State variables used in libssh2_channel_wait_closedeof() */
-+    libssh2_nonblocking_states wait_eof_state;
-+
-+    /* State variables used in libssh2_channel_wait_closed() */
-+    libssh2_nonblocking_states wait_closed_state;
-+
-+    /* State variables used in libssh2_channel_free() */
-+    libssh2_nonblocking_states free_state;
-+
-+    /* State variables used in libssh2_channel_handle_extended_data2() */
-+    libssh2_nonblocking_states extData2_state;
-+};
-+
-+struct _LIBSSH2_CHANNEL_BRIGADE
-+{
-+    LIBSSH2_CHANNEL *head, *tail;
-+};
-+
-+struct _LIBSSH2_LISTENER
-+{
-+    LIBSSH2_SESSION *session;
-+
-+    char *host;
-+    int port;
-+
-+    LIBSSH2_CHANNEL *queue;
-+    int queue_size;
-+    int queue_maxsize;
-+
-+    LIBSSH2_LISTENER *prev, *next;
-+
-+    /* State variables used in libssh2_channel_forward_cancel() */
-+    libssh2_nonblocking_states chanFwdCncl_state;
-+    unsigned char *chanFwdCncl_data;
-+    size_t chanFwdCncl_data_len;
-+};
-+
-+typedef struct _libssh2_endpoint_data
-+{
-+    unsigned char *banner;
-+
-+    unsigned char *kexinit;
-+    unsigned long kexinit_len;
-+
-+    const LIBSSH2_CRYPT_METHOD *crypt;
-+    void *crypt_abstract;
-+
-+    const LIBSSH2_MAC_METHOD *mac;
-+    unsigned long seqno;
-+    void *mac_abstract;
-+
-+    const LIBSSH2_COMP_METHOD *comp;
-+    void *comp_abstract;
-+
-+    /* Method Preferences -- NULL yields "load order" */
-+    char *crypt_prefs;
-+    char *mac_prefs;
-+    char *comp_prefs;
-+    char *lang_prefs;
-+} libssh2_endpoint_data;
-+
-+#define PACKETBUFSIZE 4096
-+
-+struct transportpacket
-+{
-+    /* ------------- for incoming data --------------- */
-+    unsigned char buf[PACKETBUFSIZE];
-+    unsigned char init[5];      /* first 5 bytes of the incoming data stream,
-+                                   still encrypted */
-+    int writeidx;               /* at what array index we do the next write into
-+                                   the buffer */
-+    int readidx;                /* at what array index we do the next read from
-+                                   the buffer */
-+    int packet_length;          /* the most recent packet_length as read from the
-+                                   network data */
-+    int padding_length;         /* the most recent padding_length as read from the
-+                                   network data */
-+    int data_num;               /* How much of the total package that has been read
-+                                   so far. */
-+    int total_num;              /* How much a total package is supposed to be, in
-+                                   number of bytes. A full package is
-+                                   packet_length + padding_length + 4 +
-+                                   mac_length. */
-+    unsigned char *payload;     /* this is a pointer to a LIBSSH2_ALLOC()
-+                                   area to which we write decrypted data */
-+    unsigned char *wptr;        /* write pointer into the payload to where we
-+                                   are currently writing decrypted data */
-+
-+    /* ------------- for outgoing data --------------- */
-+    unsigned char *outbuf;      /* pointer to a LIBSSH2_ALLOC() area for the
-+                                   outgoing data */
-+    int ototal_num;             /* size of outbuf in number of bytes */
-+    unsigned char *odata;       /* original pointer to the data we stored in
-+                                   outbuf */
-+    unsigned long olen;         /* original size of the data we stored in
-+                                   outbuf */
-+    unsigned long osent;        /* number of bytes already sent */
-+};
-+
-+struct _LIBSSH2_PUBLICKEY
-+{
-+    LIBSSH2_CHANNEL *channel;
-+    unsigned long version;
-+
-+    /* State variables used in libssh2_publickey_packet_receive() */
-+    libssh2_nonblocking_states receive_state;
-+    unsigned char *receive_packet;
-+    unsigned long receive_packet_len;
-+
-+    /* State variables used in libssh2_publickey_add_ex() */
-+    libssh2_nonblocking_states add_state;
-+    unsigned char *add_packet;
-+    unsigned char *add_s;
-+
-+    /* State variables used in libssh2_publickey_remove_ex() */
-+    libssh2_nonblocking_states remove_state;
-+    unsigned char *remove_packet;
-+    unsigned char *remove_s;
-+
-+    /* State variables used in libssh2_publickey_list_fetch() */
-+    libssh2_nonblocking_states listFetch_state;
-+    unsigned char *listFetch_s;
-+    unsigned char listFetch_buffer[12];
-+    unsigned char *listFetch_data;
-+    unsigned long listFetch_data_len;
-+};
-+
-+#define SFTP_HANDLE_MAXLEN 256 /* according to spec! */
-+
-+struct _LIBSSH2_SFTP_HANDLE
-+{
-+    LIBSSH2_SFTP *sftp;
-+    LIBSSH2_SFTP_HANDLE *prev, *next;
-+
-+    /* This is a pre-allocated buffer used for sending SFTP requests as the
-+       whole thing might not get sent in one go. This buffer is used for read,
-+       write, close and MUST thus be big enough to suit all these. */
-+    unsigned char request_packet[SFTP_HANDLE_MAXLEN + 25];
-+
-+    char handle[SFTP_HANDLE_MAXLEN];
-+    int handle_len;
-+
-+    char handle_type;
-+
-+    union _libssh2_sftp_handle_data
-+    {
-+        struct _libssh2_sftp_handle_file_data
-+        {
-+            libssh2_uint64_t offset;
-+        } file;
-+        struct _libssh2_sftp_handle_dir_data
-+        {
-+            unsigned long names_left;
-+            void *names_packet;
-+            char *next_name;
-+        } dir;
-+    } u;
-+
-+    /* State variables used in libssh2_sftp_close_handle() */
-+    libssh2_nonblocking_states close_state;
-+    unsigned long close_request_id;
-+    unsigned char *close_packet;
-+};
-+
-+struct _LIBSSH2_SFTP
-+{
-+    LIBSSH2_CHANNEL *channel;
-+
-+    unsigned long request_id, version;
-+
-+    LIBSSH2_PACKET_BRIGADE packets;
-+
-+    LIBSSH2_SFTP_HANDLE *handles;
-+
-+    unsigned long last_errno;
-+
-+    /* Holder for partial packet, use in libssh2_sftp_packet_read() */
-+    unsigned char *partial_packet;      /* The data                */
-+    unsigned long partial_len;  /* Desired number of bytes */
-+    unsigned long partial_received;     /* Bytes received so far   */
-+
-+    /* Time that libssh2_sftp_packet_requirev() started reading */
-+    time_t requirev_start;
-+
-+    /* State variables used in libssh2_sftp_open_ex() */
-+    libssh2_nonblocking_states open_state;
-+    unsigned char *open_packet;
-+    ssize_t open_packet_len;
-+    unsigned long open_request_id;
-+
-+    /* State variables used in libssh2_sftp_read() */
-+    libssh2_nonblocking_states read_state;
-+    unsigned char *read_packet;
-+    unsigned long read_request_id;
-+    size_t read_total_read;
-+
-+    /* State variables used in libssh2_sftp_readdir() */
-+    libssh2_nonblocking_states readdir_state;
-+    unsigned char *readdir_packet;
-+    unsigned long readdir_request_id;
-+
-+    /* State variables used in libssh2_sftp_write() */
-+    libssh2_nonblocking_states write_state;
-+    unsigned char *write_packet;
-+    unsigned long write_request_id;
-+
-+    /* State variables used in libssh2_sftp_fstat_ex() */
-+    libssh2_nonblocking_states fstat_state;
-+    unsigned char *fstat_packet;
-+    unsigned long fstat_request_id;
-+
-+    /* State variables used in libssh2_sftp_unlink_ex() */
-+    libssh2_nonblocking_states unlink_state;
-+    unsigned char *unlink_packet;
-+    unsigned long unlink_request_id;
-+
-+    /* State variables used in libssh2_sftp_rename_ex() */
-+    libssh2_nonblocking_states rename_state;
-+    unsigned char *rename_packet;
-+    unsigned char *rename_s;
-+    unsigned long rename_request_id;
-+
-+    /* State variables used in libssh2_sftp_mkdir() */
-+    libssh2_nonblocking_states mkdir_state;
-+    unsigned char *mkdir_packet;
-+    unsigned long mkdir_request_id;
-+
-+    /* State variables used in libssh2_sftp_rmdir() */
-+    libssh2_nonblocking_states rmdir_state;
-+    unsigned char *rmdir_packet;
-+    unsigned long rmdir_request_id;
-+
-+    /* State variables used in libssh2_sftp_stat() */
-+    libssh2_nonblocking_states stat_state;
-+    unsigned char *stat_packet;
-+    unsigned long stat_request_id;
-+
-+    /* State variables used in libssh2_sftp_symlink() */
-+    libssh2_nonblocking_states symlink_state;
-+    unsigned char *symlink_packet;
-+    unsigned long symlink_request_id;
-+};
-+
-+#define LIBSSH2_SCP_RESPONSE_BUFLEN     256
-+
-+struct _LIBSSH2_SESSION
-+{
-+    /* Memory management callbacks */
-+    void *abstract;
-+      LIBSSH2_ALLOC_FUNC((*alloc));
-+      LIBSSH2_REALLOC_FUNC((*realloc));
-+      LIBSSH2_FREE_FUNC((*free));
-+
-+    /* Other callbacks */
-+      LIBSSH2_IGNORE_FUNC((*ssh_msg_ignore));
-+      LIBSSH2_DEBUG_FUNC((*ssh_msg_debug));
-+      LIBSSH2_DISCONNECT_FUNC((*ssh_msg_disconnect));
-+      LIBSSH2_MACERROR_FUNC((*macerror));
-+      LIBSSH2_X11_OPEN_FUNC((*x11));
-+
-+    /* Method preferences -- NULL yields "load order" */
-+    char *kex_prefs;
-+    char *hostkey_prefs;
-+
-+    int state;
-+    int flags;
-+
-+    /* Agreed Key Exchange Method */
-+    const LIBSSH2_KEX_METHOD *kex;
-+    int burn_optimistic_kexinit:1;
-+
-+    unsigned char *session_id;
-+    unsigned long session_id_len;
-+
-+    /* Server's public key */
-+    const LIBSSH2_HOSTKEY_METHOD *hostkey;
-+    void *server_hostkey_abstract;
-+
-+    /* Either set with libssh2_session_hostkey() (for server mode)
-+     * Or read from server in (eg) KEXDH_INIT (for client mode)
-+     */
-+    unsigned char *server_hostkey;
-+    unsigned long server_hostkey_len;
-+#if LIBSSH2_MD5
-+    unsigned char server_hostkey_md5[MD5_DIGEST_LENGTH];
-+#endif                          /* ! LIBSSH2_MD5 */
-+    unsigned char server_hostkey_sha1[SHA_DIGEST_LENGTH];
-+
-+    /* (remote as source of data -- packet_read ) */
-+    libssh2_endpoint_data remote;
-+
-+    /* (local as source of data -- packet_write ) */
-+    libssh2_endpoint_data local;
-+
-+    /* Inbound Data buffer -- Sometimes the packet that comes in isn't the packet we're ready for */
-+    LIBSSH2_PACKET_BRIGADE packets;
-+
-+    /* Active connection channels */
-+    LIBSSH2_CHANNEL_BRIGADE channels;
-+    unsigned long next_channel;
-+
-+    LIBSSH2_LISTENER *listeners;
-+
-+    /* Actual I/O socket */
-+    int socket_fd;
-+    int socket_block;
-+    int socket_state;
-+    int socket_block_directions;
-+
-+    /* Error tracking */
-+    char *err_msg;
-+    unsigned long err_msglen;
-+    int err_should_free;
-+    int err_code;
-+
-+    /* struct members for packet-level reading */
-+    struct transportpacket packet;
-+#ifdef LIBSSH2DEBUG
-+    int showmask;               /* what debug/trace messages to display */
-+#endif
-+
-+    /* State variables used in libssh2_banner_send() */
-+    libssh2_nonblocking_states banner_TxRx_state;
-+    char banner_TxRx_banner[256];
-+    ssize_t banner_TxRx_total_send;
-+
-+    /* State variables used in libssh2_kexinit() */
-+    libssh2_nonblocking_states kexinit_state;
-+    unsigned char *kexinit_data;
-+    size_t kexinit_data_len;
-+
-+    /* State variables used in libssh2_session_startup() */
-+    libssh2_nonblocking_states startup_state;
-+    unsigned char *startup_data;
-+    unsigned long startup_data_len;
-+    unsigned char startup_service[sizeof("ssh-userauth") + 5 - 1];
-+    unsigned long startup_service_length;
-+    packet_require_state_t startup_req_state;
-+    key_exchange_state_t startup_key_state;
-+
-+    /* State variables used in libssh2_session_free() */
-+    libssh2_nonblocking_states free_state;
-+
-+    /* State variables used in libssh2_session_disconnect_ex() */
-+    libssh2_nonblocking_states disconnect_state;
-+    unsigned char *disconnect_data;
-+    unsigned long disconnect_data_len;
-+
-+    /* State variables used in libssh2_packet_read() */
-+    libssh2_nonblocking_states readPack_state;
-+    int readPack_encrypted;
-+
-+    /* State variables used in libssh2_userauth_list() */
-+    libssh2_nonblocking_states userauth_list_state;
-+    unsigned char *userauth_list_data;
-+    unsigned long userauth_list_data_len;
-+    packet_requirev_state_t userauth_list_packet_requirev_state;
-+
-+    /* State variables used in libssh2_userauth_password_ex() */
-+    libssh2_nonblocking_states userauth_pswd_state;
-+    unsigned char *userauth_pswd_data;
-+    unsigned char userauth_pswd_data0;
-+    unsigned long userauth_pswd_data_len;
-+    char *userauth_pswd_newpw;
-+    int userauth_pswd_newpw_len;
-+    packet_requirev_state_t userauth_pswd_packet_requirev_state;
-+
-+    /* State variables used in libssh2_userauth_hostbased_fromfile_ex() */
-+    libssh2_nonblocking_states userauth_host_state;
-+    unsigned char *userauth_host_data;
-+    unsigned long userauth_host_data_len;
-+    unsigned char *userauth_host_packet;
-+    unsigned long userauth_host_packet_len;
-+    unsigned char *userauth_host_method;
-+    unsigned long userauth_host_method_len;
-+    unsigned char *userauth_host_s;
-+    packet_requirev_state_t userauth_host_packet_requirev_state;
-+
-+    /* State variables used in libssh2_userauth_publickey_fromfile_ex() */
-+    libssh2_nonblocking_states userauth_pblc_state;
-+    unsigned char *userauth_pblc_data;
-+    unsigned long userauth_pblc_data_len;
-+    unsigned char *userauth_pblc_packet;
-+    unsigned long userauth_pblc_packet_len;
-+    unsigned char *userauth_pblc_method;
-+    unsigned long userauth_pblc_method_len;
-+    unsigned char *userauth_pblc_s;
-+    unsigned char *userauth_pblc_b;
-+    packet_requirev_state_t userauth_pblc_packet_requirev_state;
-+
-+    /* State variables used in llibssh2_userauth_keyboard_interactive_ex() */
-+    libssh2_nonblocking_states userauth_kybd_state;
-+    unsigned char *userauth_kybd_data;
-+    unsigned long userauth_kybd_data_len;
-+    unsigned char *userauth_kybd_packet;
-+    unsigned long userauth_kybd_packet_len;
-+    unsigned int userauth_kybd_auth_name_len;
-+    char *userauth_kybd_auth_name;
-+    unsigned userauth_kybd_auth_instruction_len;
-+    char *userauth_kybd_auth_instruction;
-+    unsigned int userauth_kybd_num_prompts;
-+    int userauth_kybd_auth_failure;
-+    LIBSSH2_USERAUTH_KBDINT_PROMPT *userauth_kybd_prompts;
-+    LIBSSH2_USERAUTH_KBDINT_RESPONSE *userauth_kybd_responses;
-+    packet_requirev_state_t userauth_kybd_packet_requirev_state;
-+
-+    /* State variables used in libssh2_channel_open_ex() */
-+    libssh2_nonblocking_states open_state;
-+    packet_requirev_state_t open_packet_requirev_state;
-+    LIBSSH2_CHANNEL *open_channel;
-+    unsigned char *open_packet;
-+    unsigned long open_packet_len;
-+    unsigned char *open_data;
-+    unsigned long open_data_len;
-+    unsigned long open_local_channel;
-+
-+    /* State variables used in libssh2_channel_direct_tcpip_ex() */
-+    libssh2_nonblocking_states direct_state;
-+    unsigned char *direct_message;
-+    unsigned long direct_host_len;
-+    unsigned long direct_shost_len;
-+    unsigned long direct_message_len;
-+
-+    /* State variables used in libssh2_channel_forward_listen_ex() */
-+    libssh2_nonblocking_states fwdLstn_state;
-+    unsigned char *fwdLstn_packet;
-+    unsigned long fwdLstn_host_len;
-+    unsigned long fwdLstn_packet_len;
-+    packet_requirev_state_t fwdLstn_packet_requirev_state;
-+
-+    /* State variables used in libssh2_publickey_init() */
-+    libssh2_nonblocking_states pkeyInit_state;
-+    LIBSSH2_PUBLICKEY *pkeyInit_pkey;
-+    LIBSSH2_CHANNEL *pkeyInit_channel;
-+    unsigned char *pkeyInit_data;
-+    unsigned long pkeyInit_data_len;
-+
-+    /* State variables used in libssh2_packet_add() */
-+    libssh2_nonblocking_states packAdd_state;
-+    LIBSSH2_PACKET *packAdd_packet;
-+    LIBSSH2_CHANNEL *packAdd_channel;
-+    unsigned long packAdd_data_head;
-+    key_exchange_state_t packAdd_key_state;
-+    packet_queue_listener_state_t packAdd_Qlstn_state;
-+    packet_x11_open_state_t packAdd_x11open_state;
-+
-+    /* State variables used in fullpacket() */
-+    libssh2_nonblocking_states fullpacket_state;
-+    int fullpacket_macstate;
-+    int fullpacket_payload_len;
-+    libssh2pack_t fullpacket_packet_type;
-+
-+    /* State variables used in libssh2_sftp_init() */
-+    libssh2_nonblocking_states sftpInit_state;
-+    LIBSSH2_SFTP *sftpInit_sftp;
-+    LIBSSH2_CHANNEL *sftpInit_channel;
-+    unsigned char sftpInit_buffer[9];   /* sftp_header(5){excludes request_id} + version_id(4) */
-+
-+    /* State variables used in libssh2_scp_recv() */
-+    libssh2_nonblocking_states scpRecv_state;
-+    unsigned char *scpRecv_command;
-+    unsigned long scpRecv_command_len;
-+    unsigned char scpRecv_response[LIBSSH2_SCP_RESPONSE_BUFLEN];
-+    unsigned long scpRecv_response_len;
-+    long scpRecv_mode;
-+#if defined(HAVE_LONGLONG) && defined(strtoll)
-+    /* we have the type and we can parse such numbers */
-+    long long scpRecv_size;
-+#define scpsize_strtol strtoll
-+#else
-+    long scpRecv_size;
-+#define scpsize_strtol strtol
-+#endif
-+    long scpRecv_mtime;
-+    long scpRecv_atime;
-+    char *scpRecv_err_msg;
-+    long scpRecv_err_len;
-+    LIBSSH2_CHANNEL *scpRecv_channel;
-+
-+    /* State variables used in libssh2_scp_send_ex() */
-+    libssh2_nonblocking_states scpSend_state;
-+    unsigned char *scpSend_command;
-+    unsigned long scpSend_command_len;
-+    unsigned char scpSend_response[LIBSSH2_SCP_RESPONSE_BUFLEN];
-+    unsigned long scpSend_response_len;
-+    char *scpSend_err_msg;
-+    long scpSend_err_len;
-+    LIBSSH2_CHANNEL *scpSend_channel;
-+};
-+
-+/* session.state bits */
-+#define LIBSSH2_STATE_EXCHANGING_KEYS   0x00000001
-+#define LIBSSH2_STATE_NEWKEYS           0x00000002
-+#define LIBSSH2_STATE_AUTHENTICATED     0x00000004
-+#define LIBSSH2_STATE_KEX_ACTIVE        0x00000008
-+
-+/* session.flag helpers */
-+#ifdef MSG_NOSIGNAL
-+#define LIBSSH2_SOCKET_SEND_FLAGS(session)      (((session)->flags & LIBSSH2_FLAG_SIGPIPE) ? 0 : MSG_NOSIGNAL)
-+#define LIBSSH2_SOCKET_RECV_FLAGS(session)      (((session)->flags & LIBSSH2_FLAG_SIGPIPE) ? 0 : MSG_NOSIGNAL)
-+#else
-+/* If MSG_NOSIGNAL isn't defined we're SOL on blocking SIGPIPE */
-+#define LIBSSH2_SOCKET_SEND_FLAGS(session)      0
-+#define LIBSSH2_SOCKET_RECV_FLAGS(session)      0
-+#endif
-+
-+/* libssh2 extensible ssh api, ultimately I'd like to allow loading additional methods via .so/.dll */
-+
-+struct _LIBSSH2_KEX_METHOD
-+{
-+    const char *name;
-+
-+    /* Key exchange, populates session->* and returns 0 on success, non-0 on error */
-+    int (*exchange_keys) (LIBSSH2_SESSION * session,
-+                          key_exchange_state_low_t * key_state);
-+
-+    long flags;
-+};
-+
-+struct _LIBSSH2_HOSTKEY_METHOD
-+{
-+    const char *name;
-+    unsigned long hash_len;
-+
-+    int (*init) (LIBSSH2_SESSION * session, const unsigned char *hostkey_data,
-+                 unsigned long hostkey_data_len, void **abstract);
-+    int (*initPEM) (LIBSSH2_SESSION * session, const char *privkeyfile,
-+                    unsigned const char *passphrase, void **abstract);
-+    int (*sig_verify) (LIBSSH2_SESSION * session, const unsigned char *sig,
-+                       unsigned long sig_len, const unsigned char *m,
-+                       unsigned long m_len, void **abstract);
-+    int (*signv) (LIBSSH2_SESSION * session, unsigned char **signature,
-+                  unsigned long *signature_len, unsigned long veccount,
-+                  const struct iovec datavec[], void **abstract);
-+    int (*encrypt) (LIBSSH2_SESSION * session, unsigned char **dst,
-+                    unsigned long *dst_len, const unsigned char *src,
-+                    unsigned long src_len, void **abstract);
-+    int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
-+};
-+
-+struct _LIBSSH2_CRYPT_METHOD
-+{
-+    const char *name;
-+
-+    int blocksize;
-+
-+    /* iv and key sizes (-1 for variable length) */
-+    int iv_len;
-+    int secret_len;
-+
-+    long flags;
-+
-+    int (*init) (LIBSSH2_SESSION * session,
-+                 const LIBSSH2_CRYPT_METHOD * method, unsigned char *iv,
-+                 int *free_iv, unsigned char *secret, int *free_secret,
-+                 int encrypt, void **abstract);
-+    int (*crypt) (LIBSSH2_SESSION * session, unsigned char *block,
-+                  void **abstract);
-+    int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
-+
-+      _libssh2_cipher_type(algo);
-+};
-+
-+struct _LIBSSH2_COMP_METHOD
-+{
-+    const char *name;
-+
-+    int (*init) (LIBSSH2_SESSION * session, int compress, void **abstract);
-+    int (*comp) (LIBSSH2_SESSION * session, int compress, unsigned char **dest,
-+                 unsigned long *dest_len, unsigned long payload_limit,
-+                 int *free_dest, const unsigned char *src,
-+                 unsigned long src_len, void **abstract);
-+    int (*dtor) (LIBSSH2_SESSION * session, int compress, void **abstract);
-+};
-+
-+struct _LIBSSH2_MAC_METHOD
-+{
-+    const char *name;
-+
-+    /* The length of a given MAC packet */
-+    int mac_len;
-+
-+    /* integrity key length */
-+    int key_len;
-+
-+    /* Message Authentication Code Hashing algo */
-+    int (*init) (LIBSSH2_SESSION * session, unsigned char *key, int *free_key,
-+                 void **abstract);
-+    int (*hash) (LIBSSH2_SESSION * session, unsigned char *buf,
-+                 unsigned long seqno, const unsigned char *packet,
-+                 unsigned long packet_len, const unsigned char *addtl,
-+                 unsigned long addtl_len, void **abstract);
-+    int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
-+};
-+
-+#define LIBSSH2_DBG_TRANS   1
-+#define LIBSSH2_DBG_KEX     2
-+#define LIBSSH2_DBG_AUTH    3
-+#define LIBSSH2_DBG_CONN    4
-+#define LIBSSH2_DBG_SCP     5
-+#define LIBSSH2_DBG_SFTP    6
-+#define LIBSSH2_DBG_ERROR   7
-+#define LIBSSH2_DBG_PUBLICKEY   8
-+#ifdef LIBSSH2DEBUG
-+void _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format,
-+                    ...);
-+#else
-+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
-+/* C99 style */
-+#define _libssh2_debug(x,y,z, __VA_ARGS__) do {} while (0)
-+#elif defined(__GNUC__)
-+/* GNU style */
-+#define _libssh2_debug(x,y,z,...) do {} while (0)
-+#else
-+/* no gcc and not C99, do static and hopefully inline */
-+static inline void
-+_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
-+{
-+}
-+#endif
-+#endif
-+
-+#ifdef LIBSSH2DEBUG
-+#define libssh2_error(session, errcode, errmsg, should_free)    \
-+{ \
-+    if (session->err_msg && session->err_should_free) { \
-+        LIBSSH2_FREE(session, session->err_msg); \
-+    } \
-+    session->err_msg = (char *)errmsg; \
-+    session->err_msglen = strlen(errmsg); \
-+    session->err_should_free = should_free; \
-+    session->err_code = errcode; \
-+    _libssh2_debug(session, LIBSSH2_DBG_ERROR, "%d - %s", session->err_code, session->err_msg); \
-+}
-+
-+#else /* ! LIBSSH2DEBUG */
-+
-+#define libssh2_error(session, errcode, errmsg, should_free)    \
-+{ \
-+    if (session->err_msg && session->err_should_free) { \
-+        LIBSSH2_FREE(session, session->err_msg); \
-+    } \
-+    session->err_msg = (char *)errmsg; \
-+    session->err_msglen = strlen(errmsg); \
-+    session->err_should_free = should_free; \
-+    session->err_code = errcode; \
-+}
-+
-+#endif /* ! LIBSSH2DEBUG */
-+
-+
-+#define LIBSSH2_SOCKET_UNKNOWN                   1
-+#define LIBSSH2_SOCKET_CONNECTED                 0
-+#define LIBSSH2_SOCKET_DISCONNECTED             -1
-+
-+/* Initial packet state, prior to MAC check */
-+#define LIBSSH2_MAC_UNCONFIRMED                  1
-+/* When MAC type is "none" (proto initiation phase) all packets are deemed "confirmed" */
-+#define LIBSSH2_MAC_CONFIRMED                    0
-+/* Something very bad is going on */
-+#define LIBSSH2_MAC_INVALID                     -1
-+
-+/* SSH Packet Types -- Defined by internet draft */
-+/* Transport Layer */
-+#define SSH_MSG_DISCONNECT                          1
-+#define SSH_MSG_IGNORE                              2
-+#define SSH_MSG_UNIMPLEMENTED                       3
-+#define SSH_MSG_DEBUG                               4
-+#define SSH_MSG_SERVICE_REQUEST                     5
-+#define SSH_MSG_SERVICE_ACCEPT                      6
-+
-+#define SSH_MSG_KEXINIT                             20
-+#define SSH_MSG_NEWKEYS                             21
-+
-+/* diffie-hellman-group1-sha1 */
-+#define SSH_MSG_KEXDH_INIT                          30
-+#define SSH_MSG_KEXDH_REPLY                         31
-+
-+/* diffie-hellman-group-exchange-sha1 */
-+#define SSH_MSG_KEX_DH_GEX_REQUEST_OLD              30
-+#define SSH_MSG_KEX_DH_GEX_REQUEST                  34
-+#define SSH_MSG_KEX_DH_GEX_GROUP                    31
-+#define SSH_MSG_KEX_DH_GEX_INIT                     32
-+#define SSH_MSG_KEX_DH_GEX_REPLY                    33
-+
-+/* User Authentication */
-+#define SSH_MSG_USERAUTH_REQUEST                    50
-+#define SSH_MSG_USERAUTH_FAILURE                    51
-+#define SSH_MSG_USERAUTH_SUCCESS                    52
-+#define SSH_MSG_USERAUTH_BANNER                     53
-+
-+/* "public key" method */
-+#define SSH_MSG_USERAUTH_PK_OK                      60
-+/* "password" method */
-+#define SSH_MSG_USERAUTH_PASSWD_CHANGEREQ           60
-+/* "keyboard-interactive" method */
-+#define SSH_MSG_USERAUTH_INFO_REQUEST               60
-+#define SSH_MSG_USERAUTH_INFO_RESPONSE              61
-+
-+/* Channels */
-+#define SSH_MSG_GLOBAL_REQUEST                      80
-+#define SSH_MSG_REQUEST_SUCCESS                     81
-+#define SSH_MSG_REQUEST_FAILURE                     82
-+
-+#define SSH_MSG_CHANNEL_OPEN                        90
-+#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION           91
-+#define SSH_MSG_CHANNEL_OPEN_FAILURE                92
-+#define SSH_MSG_CHANNEL_WINDOW_ADJUST               93
-+#define SSH_MSG_CHANNEL_DATA                        94
-+#define SSH_MSG_CHANNEL_EXTENDED_DATA               95
-+#define SSH_MSG_CHANNEL_EOF                         96
-+#define SSH_MSG_CHANNEL_CLOSE                       97
-+#define SSH_MSG_CHANNEL_REQUEST                     98
-+#define SSH_MSG_CHANNEL_SUCCESS                     99
-+#define SSH_MSG_CHANNEL_FAILURE                     100
-+
-+void libssh2_session_shutdown(LIBSSH2_SESSION * session);
-+
-+unsigned long libssh2_ntohu32(const unsigned char *buf);
-+libssh2_uint64_t libssh2_ntohu64(const unsigned char *buf);
-+void libssh2_htonu32(unsigned char *buf, unsigned long val);
-+void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t val);
-+
-+#define LIBSSH2_READ_TIMEOUT 60 /* generic timeout in seconds used when
-+                                   waiting for more data to arrive */
-+int libssh2_waitsocket(LIBSSH2_SESSION * session, long seconds);
-+
-+
-+/* CAUTION: some of these error codes are returned in the public API and is
-+   there known with other #defined names from the public header file. They
-+   should not be changed. */
-+
-+#define PACKET_TIMEOUT  -7
-+#define PACKET_BADUSE   -6
-+#define PACKET_COMPRESS -5
-+#define PACKET_TOOBIG   -4
-+#define PACKET_ENOMEM   -3
-+#define PACKET_EAGAIN   LIBSSH2_ERROR_EAGAIN
-+#define PACKET_FAIL     -1
-+#define PACKET_NONE      0
-+
-+libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION * session);
-+
-+int libssh2_packet_ask_ex(LIBSSH2_SESSION * session, unsigned char packet_type,
-+                          unsigned char **data, unsigned long *data_len,
-+                          unsigned long match_ofs,
-+                          const unsigned char *match_buf,
-+                          unsigned long match_len, int poll_socket);
-+
-+int libssh2_packet_askv_ex(LIBSSH2_SESSION * session,
-+                           const unsigned char *packet_types,
-+                           unsigned char **data, unsigned long *data_len,
-+                           unsigned long match_ofs,
-+                           const unsigned char *match_buf,
-+                           unsigned long match_len, int poll_socket);
-+int libssh2_packet_require_ex(LIBSSH2_SESSION * session,
-+                              unsigned char packet_type, unsigned char **data,
-+                              unsigned long *data_len, unsigned long match_ofs,
-+                              const unsigned char *match_buf,
-+                              unsigned long match_len,
-+                              packet_require_state_t * state);
-+int libssh2_packet_requirev_ex(LIBSSH2_SESSION * session,
-+                               const unsigned char *packet_types,
-+                               unsigned char **data, unsigned long *data_len,
-+                               unsigned long match_ofs,
-+                               const unsigned char *match_buf,
-+                               unsigned long match_len,
-+                               packet_requirev_state_t * state);
-+int libssh2_packet_burn(LIBSSH2_SESSION * session,
-+                        libssh2_nonblocking_states * state);
-+int libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
-+                         unsigned long data_len);
-+int libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
-+                       size_t datalen, int macstate);
-+int libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
-+                         key_exchange_state_t * state);
-+unsigned long libssh2_channel_nextid(LIBSSH2_SESSION * session);
-+LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION * session,
-+                                        unsigned long channel_id);
-+unsigned long libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel,
-+                                              int stream_id);
-+
-+/* this is the lib-internal set blocking function */
-+int _libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking);
-+
-+/* Let crypt.c/hostkey.c/comp.c/mac.c expose their method structs */
-+const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void);
-+const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void);
-+const LIBSSH2_COMP_METHOD **libssh2_comp_methods(void);
-+const LIBSSH2_MAC_METHOD **libssh2_mac_methods(void);
-+
-+/* Language API doesn't exist yet.  Just act like we've agreed on a language */
-+#define libssh2_kex_agree_lang(session, endpoint, str, str_len) 0
-+
-+/* pem.c */
-+int _libssh2_pem_parse(LIBSSH2_SESSION * session,
-+                       const char *headerbegin,
-+                       const char *headerend,
-+                       FILE * fp, unsigned char **data, unsigned int *datalen);
-+int _libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen);
-+int _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
-+                                unsigned char **i, unsigned int *ilen);
-+
-+#endif /* LIBSSH2_H */
-
-Property changes on: libssh2/src/libssh2_priv.h
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.1
-Added: svn:eol-style
-   + native
-Added: svn:executable
-   + *
-
-Index: libssh2/src/sftp.c
-===================================================================
---- libssh2/src/sftp.c (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/sftp.c (.../trunk)
-@@ -0,0 +1,2358 @@
-+/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#include "libssh2_priv.h"
-+#include "libssh2_sftp.h"
-+
-+/* Note: Version 6 was documented at the time of writing
-+ * However it was marked as "DO NOT IMPLEMENT" due to pending changes
-+ *
-+ * This release of libssh2 implements Version 5 with automatic downgrade
-+ * based on server's declaration
-+ */
-+
-+/* SFTP packet types */
-+#define SSH_FXP_INIT                            1
-+#define SSH_FXP_VERSION                         2
-+#define SSH_FXP_OPEN                            3
-+#define SSH_FXP_CLOSE                           4
-+#define SSH_FXP_READ                            5
-+#define SSH_FXP_WRITE                           6
-+#define SSH_FXP_LSTAT                           7
-+#define SSH_FXP_FSTAT                           8
-+#define SSH_FXP_SETSTAT                         9
-+#define SSH_FXP_FSETSTAT                        10
-+#define SSH_FXP_OPENDIR                         11
-+#define SSH_FXP_READDIR                         12
-+#define SSH_FXP_REMOVE                          13
-+#define SSH_FXP_MKDIR                           14
-+#define SSH_FXP_RMDIR                           15
-+#define SSH_FXP_REALPATH                        16
-+#define SSH_FXP_STAT                            17
-+#define SSH_FXP_RENAME                          18
-+#define SSH_FXP_READLINK                        19
-+#define SSH_FXP_SYMLINK                         20
-+#define SSH_FXP_STATUS                          101
-+#define SSH_FXP_HANDLE                          102
-+#define SSH_FXP_DATA                            103
-+#define SSH_FXP_NAME                            104
-+#define SSH_FXP_ATTRS                           105
-+#define SSH_FXP_EXTENDED                        200
-+#define SSH_FXP_EXTENDED_REPLY                  201
-+
-+#define LIBSSH2_SFTP_HANDLE_FILE        0
-+#define LIBSSH2_SFTP_HANDLE_DIR         1
-+
-+/* S_IFREG */
-+#define LIBSSH2_SFTP_ATTR_PFILETYPE_FILE        0100000
-+/* S_IFDIR */
-+#define LIBSSH2_SFTP_ATTR_PFILETYPE_DIR         0040000
-+
-+/* {{{ sftp_packet_add
-+ * Add a packet to the SFTP packet brigade
-+ */
-+static int
-+sftp_packet_add(LIBSSH2_SFTP * sftp, unsigned char *data,
-+                unsigned long data_len)
-+{
-+    LIBSSH2_SESSION *session = sftp->channel->session;
-+    LIBSSH2_PACKET *packet;
-+
-+    _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Received packet %d (len %d)",
-+                   (int) data[0], data_len);
-+    packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
-+    if (!packet) {
-+        libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                      "Unable to allocate datablock for SFTP packet", 0);
-+        return -1;
-+    }
-+    memset(packet, 0, sizeof(LIBSSH2_PACKET));
-+
-+    packet->data = data;
-+    packet->data_len = data_len;
-+    packet->data_head = 5;
-+    packet->brigade = &sftp->packets;
-+    packet->next = NULL;
-+    packet->prev = sftp->packets.tail;
-+    if (packet->prev) {
-+        packet->prev->next = packet;
-+    } else {
-+        sftp->packets.head = packet;
-+    }
-+    sftp->packets.tail = packet;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ sftp_packet_read
-+ * Frame an SFTP packet off the channel
-+ */
-+static int
-+sftp_packet_read(LIBSSH2_SFTP * sftp)
-+{
-+    LIBSSH2_CHANNEL *channel = sftp->channel;
-+    LIBSSH2_SESSION *session = channel->session;
-+    unsigned char buffer[4];    /* To store the packet length */
-+    unsigned char *packet;
-+    unsigned long packet_len, packet_received;
-+    ssize_t bytes_received;
-+    int rc;
-+
-+    _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Waiting for packet");
-+
-+
-+    /* If there was a previous partial, start using it */
-+    if (sftp->partial_packet) {
-+
-+        packet = sftp->partial_packet;
-+        packet_len = sftp->partial_len;
-+        packet_received = sftp->partial_received;
-+        sftp->partial_packet = NULL;
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_SFTP,
-+                       "partial read cont, len: %lu", packet_len);
-+    }
-+    else {
-+        rc = libssh2_channel_read_ex(channel, 0, (char *) buffer, 4);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        }
-+        else if (4 != rc) {
-+            /* TODO: this is stupid since we can in fact get 1-3 bytes in a
-+               legitimate working case as well if the connection happens to be
-+               super slow or something */
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                          "Timeout waiting for FXP packet", 0);
-+            return -1;
-+        }
-+
-+        packet_len = libssh2_ntohu32(buffer);
-+        _libssh2_debug(session, LIBSSH2_DBG_SFTP,
-+                       "Data begin - Packet Length: %lu", packet_len);
-+        if (packet_len > LIBSSH2_SFTP_PACKET_MAXLEN) {
-+            libssh2_error(session, LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED,
-+                          "SFTP packet too large", 0);
-+            return -1;
-+        }
-+
-+        packet = LIBSSH2_ALLOC(session, packet_len);
-+        if (!packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate SFTP packet", 0);
-+            return -1;
-+        }
-+
-+        packet_received = 0;
-+    }
-+
-+    /* Read as much of the packet as we can */
-+    while (packet_len > packet_received) {
-+        bytes_received =
-+            libssh2_channel_read_ex(channel, 0,
-+                                    (char *) packet + packet_received,
-+                                    packet_len - packet_received);
-+
-+        if (bytes_received == PACKET_EAGAIN) {
-+            /*
-+             * We received EAGAIN, save what we have and
-+             * return to EAGAIN to the caller
-+             */
-+            sftp->partial_packet = packet;
-+            sftp->partial_len = packet_len;
-+            sftp->partial_received = packet_received;
-+            packet = NULL;
-+
-+            return PACKET_EAGAIN;
-+        }
-+        else if (bytes_received < 0) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                          "Receive error waiting for SFTP packet", 0);
-+            LIBSSH2_FREE(session, packet);
-+            return -1;
-+        }
-+        packet_received += bytes_received;
-+    }
-+
-+    if (sftp_packet_add(sftp, packet, packet_len)) {
-+        LIBSSH2_FREE(session, packet);
-+        return -1;
-+    }
-+
-+    return packet[0];
-+}
-+
-+/* }}} */
-+
-+/* {{{ sftp_packet_ask
-+ * A la libssh2_packet_ask()
-+ */
-+static int
-+sftp_packet_ask(LIBSSH2_SFTP * sftp, unsigned char packet_type,
-+                unsigned long request_id, unsigned char **data,
-+                unsigned long *data_len, int poll_channel)
-+{
-+    LIBSSH2_SESSION *session = sftp->channel->session;
-+    LIBSSH2_PACKET *packet = sftp->packets.head;
-+    unsigned char match_buf[5];
-+    int match_len = 5;
-+
-+    _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Asking for %d packet",
-+                   (int) packet_type);
-+    if (poll_channel) {
-+        int ret = sftp_packet_read(sftp);
-+        if (ret == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (ret < 0) {
-+            return -1;
-+        }
-+    }
-+
-+    match_buf[0] = packet_type;
-+    if (packet_type == SSH_FXP_VERSION) {
-+        /* Special consideration when matching VERSION packet */
-+        match_len = 1;
-+    } else {
-+        libssh2_htonu32(match_buf + 1, request_id);
-+    }
-+
-+    while (packet) {
-+        if (strncmp((char *) packet->data, (char *) match_buf, match_len) == 0) {
-+            *data = packet->data;
-+            *data_len = packet->data_len;
-+
-+            if (packet->prev) {
-+                packet->prev->next = packet->next;
-+            } else {
-+                sftp->packets.head = packet->next;
-+            }
-+
-+            if (packet->next) {
-+                packet->next->prev = packet->prev;
-+            } else {
-+                sftp->packets.tail = packet->prev;
-+            }
-+
-+            LIBSSH2_FREE(session, packet);
-+
-+            return 0;
-+        }
-+        packet = packet->next;
-+    }
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ sftp_packet_require
-+ * A la libssh2_packet_require
-+ */
-+static int
-+sftp_packet_require(LIBSSH2_SFTP * sftp, unsigned char packet_type,
-+                    unsigned long request_id, unsigned char **data,
-+                    unsigned long *data_len)
-+{
-+    LIBSSH2_SESSION *session = sftp->channel->session;
-+    int ret;
-+
-+    _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Requiring %d packet",
-+                   (int) packet_type);
-+
-+    if (sftp_packet_ask(sftp, packet_type, request_id, data,
-+                        data_len, 0) == 0) {
-+        /* The right packet was available in the packet brigade */
-+        return 0;
-+    }
-+
-+    while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
-+        ret = sftp_packet_read(sftp);
-+        if (ret == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (ret <= 0) {
-+            return -1;
-+        }
-+
-+        if (packet_type == ret) {
-+            /* Be lazy, let packet_ask pull it out of the brigade */
-+            return sftp_packet_ask(sftp, packet_type, request_id, data,
-+                                   data_len, 0);
-+        }
-+    }
-+
-+    /* Only reached if the socket died */
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ sftp_packet_requirev
-+ * Require one of N possible reponses
-+ */
-+static int
-+sftp_packet_requirev(LIBSSH2_SFTP * sftp, int num_valid_responses,
-+                     const unsigned char *valid_responses,
-+                     unsigned long request_id, unsigned char **data,
-+                     unsigned long *data_len)
-+{
-+    int i;
-+    int ret;
-+
-+    /* If no timeout is active, start a new one */
-+    if (sftp->requirev_start == 0) {
-+        sftp->requirev_start = time(NULL);
-+    }
-+
-+    while (sftp->channel->session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
-+        for(i = 0; i < num_valid_responses; i++) {
-+            if (sftp_packet_ask(sftp, valid_responses[i], request_id,
-+                                data, data_len, 0) == 0) {
-+                /*
-+                 * Set to zero before all returns to say
-+                 * the timeout is not active
-+                 */
-+                sftp->requirev_start = 0;
-+                return 0;
-+            }
-+        }
-+
-+        ret = sftp_packet_read(sftp);
-+        if ((ret < 0) && (ret != PACKET_EAGAIN)) {
-+            sftp->requirev_start = 0;
-+            return -1;
-+        } else if (ret <= 0) {
-+            /* prevent busy-looping */
-+            long left =
-+                LIBSSH2_READ_TIMEOUT - (time(NULL) - sftp->requirev_start);
-+
-+            if (left <= 0) {
-+                sftp->requirev_start = 0;
-+                return PACKET_TIMEOUT;
-+            } else if (sftp->channel->session->socket_block
-+                       && (libssh2_waitsocket(sftp->channel->session, left) <=
-+                           0)) {
-+                sftp->requirev_start = 0;
-+                return PACKET_TIMEOUT;
-+            } else if (ret == PACKET_EAGAIN) {
-+                return PACKET_EAGAIN;
-+            }
-+        }
-+    }
-+
-+    sftp->requirev_start = 0;
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_sftp_attrsize
-+ * Size that attr will occupy when turned into a bin struct
-+ */
-+static int
-+libssh2_sftp_attrsize(const LIBSSH2_SFTP_ATTRIBUTES * attrs)
-+{
-+    int attrsize = 4;           /* flags(4) */
-+
-+    if (!attrs) {
-+        return attrsize;
-+    }
-+
-+    if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE)
-+        attrsize += 8;
-+    if (attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID)
-+        attrsize += 8;
-+    if (attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS)
-+        attrsize += 4;
-+    if (attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME)
-+        attrsize += 8;          /* atime + mtime as u32 */
-+
-+    return attrsize;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_sftp_attr2bin
-+ * Populate attributes into an SFTP block
-+ */
-+static int
-+libssh2_sftp_attr2bin(unsigned char *p, const LIBSSH2_SFTP_ATTRIBUTES * attrs)
-+{
-+    unsigned char *s = p;
-+    unsigned long flag_mask =
-+        LIBSSH2_SFTP_ATTR_SIZE | LIBSSH2_SFTP_ATTR_UIDGID |
-+        LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME;
-+
-+    /* TODO: When we add SFTP4+ functionality flag_mask can get additional bits */
-+
-+    if (!attrs) {
-+        libssh2_htonu32(s, 0);
-+        return 4;
-+    }
-+
-+    libssh2_htonu32(s, attrs->flags & flag_mask);
-+    s += 4;
-+
-+    if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) {
-+        libssh2_htonu64(s, attrs->filesize);
-+        s += 8;
-+    }
-+
-+    if (attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) {
-+        libssh2_htonu32(s, attrs->uid);
-+        s += 4;
-+        libssh2_htonu32(s, attrs->gid);
-+        s += 4;
-+    }
-+
-+    if (attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) {
-+        libssh2_htonu32(s, attrs->permissions);
-+        s += 4;
-+    }
-+
-+    if (attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) {
-+        libssh2_htonu32(s, attrs->atime);
-+        s += 4;
-+        libssh2_htonu32(s, attrs->mtime);
-+        s += 4;
-+    }
-+
-+    return (s - p);
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_sftp_bin2attr
-+ */
-+static int
-+libssh2_sftp_bin2attr(LIBSSH2_SFTP_ATTRIBUTES * attrs, const unsigned char *p)
-+{
-+    const unsigned char *s = p;
-+
-+    memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
-+    attrs->flags = libssh2_ntohu32(s);
-+    s += 4;
-+
-+    if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) {
-+        attrs->filesize = libssh2_ntohu64(s);
-+        s += 8;
-+    }
-+
-+    if (attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) {
-+        attrs->uid = libssh2_ntohu32(s);
-+        s += 4;
-+        attrs->gid = libssh2_ntohu32(s);
-+        s += 4;
-+    }
-+
-+    if (attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) {
-+        attrs->permissions = libssh2_ntohu32(s);
-+        s += 4;
-+    }
-+
-+    if (attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) {
-+        attrs->atime = libssh2_ntohu32(s);
-+        s += 4;
-+        attrs->mtime = libssh2_ntohu32(s);
-+        s += 4;
-+    }
-+
-+    return (s - p);
-+}
-+
-+/* }}} */
-+
-+/* ************
-+   * SFTP API *
-+   ************ */
-+
-+LIBSSH2_CHANNEL_CLOSE_FUNC(libssh2_sftp_dtor);
-+
-+/* {{{ libssh2_sftp_dtor
-+ * Shutdown an SFTP stream when the channel closes
-+ */
-+LIBSSH2_CHANNEL_CLOSE_FUNC(libssh2_sftp_dtor)
-+{
-+    LIBSSH2_SFTP *sftp = (LIBSSH2_SFTP *) (*channel_abstract);
-+
-+    (void) session_abstract;
-+    (void) channel;
-+
-+    /* Loop through handles closing them */
-+    while (sftp->handles) {
-+        libssh2_sftp_close_handle(sftp->handles);
-+    }
-+
-+    /* Free the partial packet storage for sftp_packet_read */
-+    if (sftp->partial_packet) {
-+        LIBSSH2_FREE(session, sftp->partial_packet);
-+    }
-+
-+    /* Free the packet storage for _libssh2_sftp_packet_readdir */
-+    if (sftp->readdir_packet) {
-+        LIBSSH2_FREE(session, sftp->readdir_packet);
-+    }
-+
-+    LIBSSH2_FREE(session, sftp);
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_sftp_init
-+ * Startup an SFTP session
-+ *
-+ * NOTE:  Will block in a busy loop on error.  This has to be done,
-+ *        otherwise the blocking error code would erase the true
-+ *        cause of the error.
-+ */
-+LIBSSH2_API LIBSSH2_SFTP *
-+libssh2_sftp_init(LIBSSH2_SESSION * session)
-+{
-+    unsigned char *data, *s;
-+    unsigned long data_len;
-+    int rc;
-+
-+    if (session->sftpInit_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_SFTP,
-+                       "Initializing SFTP subsystem");
-+
-+        session->sftpInit_sftp = NULL;
-+
-+        session->sftpInit_state = libssh2_NB_state_created;
-+    }
-+
-+    if (session->sftpInit_state == libssh2_NB_state_created) {
-+        session->sftpInit_channel =
-+            libssh2_channel_open_ex(session, "session", sizeof("session") - 1,
-+                                    LIBSSH2_CHANNEL_WINDOW_DEFAULT,
-+                                    LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0);
-+        if (!session->sftpInit_channel) {
-+            if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
-+                libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                              "Would block starting up channel", 0);
-+                return NULL;
-+            } else if (libssh2_session_last_errno(session) !=
-+                       LIBSSH2_ERROR_EAGAIN) {
-+                libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
-+                              "Unable to startup channel", 0);
-+                session->sftpInit_state = libssh2_NB_state_idle;
-+                return NULL;
-+            }
-+        }
-+
-+        session->sftpInit_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (session->sftpInit_state == libssh2_NB_state_sent) {
-+        rc = libssh2_channel_process_startup(session->sftpInit_channel,
-+                                             "subsystem",
-+                                             sizeof("subsystem") - 1, "sftp",
-+                                             strlen("sftp"));
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block to request SFTP subsystem", 0);
-+            return NULL;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
-+                          "Unable to request SFTP subsystem", 0);
-+            goto sftp_init_error;
-+        }
-+
-+        session->sftpInit_state = libssh2_NB_state_sent1;
-+    }
-+
-+    if (session->sftpInit_state == libssh2_NB_state_sent1) {
-+        rc = libssh2_channel_handle_extended_data2(session->sftpInit_channel,
-+                                                   LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block requesting handle extended data", 0);
-+            return NULL;
-+        }
-+
-+        session->sftpInit_sftp = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP));
-+        if (!session->sftpInit_sftp) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate a new SFTP structure", 0);
-+            goto sftp_init_error;
-+        }
-+        memset(session->sftpInit_sftp, 0, sizeof(LIBSSH2_SFTP));
-+        session->sftpInit_sftp->channel = session->sftpInit_channel;
-+        session->sftpInit_sftp->request_id = 0;
-+
-+        libssh2_htonu32(session->sftpInit_buffer, 5);
-+        session->sftpInit_buffer[4] = SSH_FXP_INIT;
-+        libssh2_htonu32(session->sftpInit_buffer + 5, LIBSSH2_SFTP_VERSION);
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_SFTP,
-+                       "Sending FXP_INIT packet advertising version %d support",
-+                       (int) LIBSSH2_SFTP_VERSION);
-+
-+        session->sftpInit_state = libssh2_NB_state_sent2;
-+    }
-+
-+    if (session->sftpInit_state == libssh2_NB_state_sent2) {
-+        rc = libssh2_channel_write_ex(session->sftpInit_channel, 0,
-+                                      (char *) session->sftpInit_buffer, 9);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block sending SSH_FXP_INIT", 0);
-+            return NULL;
-+        } else if (9 != rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send SSH_FXP_INIT", 0);
-+            goto sftp_init_error;
-+        }
-+
-+        session->sftpInit_state = libssh2_NB_state_sent3;
-+    }
-+
-+    /* For initiallization we are requiring blocking, probably reasonable */
-+    rc = sftp_packet_require(session->sftpInit_sftp, SSH_FXP_VERSION,
-+                             0, &data, &data_len);
-+    if (rc == PACKET_EAGAIN) {
-+        libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                      "Would block waiting for response from SFTP subsystem",
-+                      0);
-+        return NULL;
-+    } else if (rc) {
-+        libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                      "Timeout waiting for response from SFTP subsystem", 0);
-+        goto sftp_init_error;
-+    }
-+    if (data_len < 5) {
-+        libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
-+                      "Invalid SSH_FXP_VERSION response", 0);
-+        goto sftp_init_error;
-+    }
-+
-+    s = data + 1;
-+    session->sftpInit_sftp->version = libssh2_ntohu32(s);
-+    s += 4;
-+    if (session->sftpInit_sftp->version > LIBSSH2_SFTP_VERSION) {
-+        _libssh2_debug(session, LIBSSH2_DBG_SFTP,
-+                       "Truncating remote SFTP version from %lu",
-+                       session->sftpInit_sftp->version);
-+        session->sftpInit_sftp->version = LIBSSH2_SFTP_VERSION;
-+    }
-+    _libssh2_debug(session, LIBSSH2_DBG_SFTP,
-+                   "Enabling SFTP version %lu compatability",
-+                   session->sftpInit_sftp->version);
-+    while (s < (data + data_len)) {
-+        unsigned char *extension_name, *extension_data;
-+        unsigned long extname_len, extdata_len;
-+
-+        extname_len = libssh2_ntohu32(s);
-+        s += 4;
-+        extension_name = s;
-+        s += extname_len;
-+
-+        extdata_len = libssh2_ntohu32(s);
-+        s += 4;
-+        extension_data = s;
-+        s += extdata_len;
-+
-+        /* TODO: Actually process extensions */
-+    }
-+    LIBSSH2_FREE(session, data);
-+
-+    /* Make sure that when the channel gets closed, the SFTP service is shut down too */
-+    session->sftpInit_sftp->channel->abstract = session->sftpInit_sftp;
-+    session->sftpInit_sftp->channel->close_cb = libssh2_sftp_dtor;
-+
-+    session->sftpInit_state = libssh2_NB_state_idle;
-+    return session->sftpInit_sftp;
-+
-+  sftp_init_error:
-+    while (libssh2_channel_free(session->sftpInit_channel) == PACKET_EAGAIN);
-+    session->sftpInit_channel = NULL;
-+    if (session->sftpInit_sftp) {
-+        LIBSSH2_FREE(session, session->sftpInit_sftp);
-+        session->sftpInit_sftp = NULL;
-+    }
-+    session->sftpInit_state = libssh2_NB_state_idle;
-+    return NULL;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_sftp_shutdown
-+ * Shutsdown the SFTP subsystem
-+ */
-+LIBSSH2_API int
-+libssh2_sftp_shutdown(LIBSSH2_SFTP * sftp)
-+{
-+    /*
-+     * Make sure all memory used in the state variables are free
-+     */
-+    if (sftp->partial_packet) {
-+        LIBSSH2_FREE(sftp->channel->session, sftp->partial_packet);
-+        sftp->partial_packet = NULL;
-+    }
-+    if (sftp->open_packet) {
-+        LIBSSH2_FREE(sftp->channel->session, sftp->open_packet);
-+        sftp->open_packet = NULL;
-+    }
-+    if (sftp->readdir_packet) {
-+        LIBSSH2_FREE(sftp->channel->session, sftp->readdir_packet);
-+        sftp->readdir_packet = NULL;
-+    }
-+    if (sftp->write_packet) {
-+        LIBSSH2_FREE(sftp->channel->session, sftp->write_packet);
-+        sftp->write_packet = NULL;
-+    }
-+    if (sftp->fstat_packet) {
-+        LIBSSH2_FREE(sftp->channel->session, sftp->fstat_packet);
-+        sftp->fstat_packet = NULL;
-+    }
-+    if (sftp->unlink_packet) {
-+        LIBSSH2_FREE(sftp->channel->session, sftp->unlink_packet);
-+        sftp->unlink_packet = NULL;
-+    }
-+    if (sftp->rename_packet) {
-+        LIBSSH2_FREE(sftp->channel->session, sftp->rename_packet);
-+        sftp->rename_packet = NULL;
-+    }
-+    if (sftp->mkdir_packet) {
-+        LIBSSH2_FREE(sftp->channel->session, sftp->mkdir_packet);
-+        sftp->mkdir_packet = NULL;
-+    }
-+    if (sftp->rmdir_packet) {
-+        LIBSSH2_FREE(sftp->channel->session, sftp->rmdir_packet);
-+        sftp->rmdir_packet = NULL;
-+    }
-+    if (sftp->stat_packet) {
-+        LIBSSH2_FREE(sftp->channel->session, sftp->stat_packet);
-+        sftp->stat_packet = NULL;
-+    }
-+    if (sftp->symlink_packet) {
-+        LIBSSH2_FREE(sftp->channel->session, sftp->symlink_packet);
-+        sftp->symlink_packet = NULL;
-+    }
-+
-+    return libssh2_channel_free(sftp->channel);
-+}
-+
-+/* }}} */
-+
-+/* *******************************
-+   * SFTP File and Directory Ops *
-+   ******************************* */
-+
-+/* {{{ libssh2_sftp_open_ex
-+ */
-+LIBSSH2_API LIBSSH2_SFTP_HANDLE *
-+libssh2_sftp_open_ex(LIBSSH2_SFTP * sftp, const char *filename,
-+                     unsigned int filename_len, unsigned long flags, long mode,
-+                     int open_type)
-+{
-+    LIBSSH2_CHANNEL *channel = sftp->channel;
-+    LIBSSH2_SESSION *session = channel->session;
-+    LIBSSH2_SFTP_HANDLE *fp;
-+    LIBSSH2_SFTP_ATTRIBUTES attrs = {
-+        LIBSSH2_SFTP_ATTR_PERMISSIONS, 0, 0, 0, 0, 0, 0
-+    };
-+    unsigned long data_len;
-+    unsigned char *data, *s;
-+    static const unsigned char fopen_responses[2] =
-+        { SSH_FXP_HANDLE, SSH_FXP_STATUS };
-+    int rc;
-+
-+    if (sftp->open_state == libssh2_NB_state_idle) {
-+        /* packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) +
-+           flags(4) */
-+        sftp->open_packet_len = filename_len + 13 +
-+            ((open_type ==
-+              LIBSSH2_SFTP_OPENFILE) ? (4 +
-+                                        libssh2_sftp_attrsize(&attrs)) : 0);
-+
-+        s = sftp->open_packet = LIBSSH2_ALLOC(session, sftp->open_packet_len);
-+        if (!sftp->open_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for FXP_OPEN or "
-+                          "FXP_OPENDIR packet",
-+                          0);
-+            return NULL;
-+        }
-+        /* Filetype in SFTP 3 and earlier */
-+        attrs.permissions = mode |
-+            ((open_type ==
-+              LIBSSH2_SFTP_OPENFILE) ? LIBSSH2_SFTP_ATTR_PFILETYPE_FILE :
-+             LIBSSH2_SFTP_ATTR_PFILETYPE_DIR);
-+
-+        libssh2_htonu32(s, sftp->open_packet_len - 4);
-+        s += 4;
-+        *(s++) =
-+            (open_type ==
-+             LIBSSH2_SFTP_OPENFILE) ? SSH_FXP_OPEN : SSH_FXP_OPENDIR;
-+        sftp->open_request_id = sftp->request_id++;
-+        libssh2_htonu32(s, sftp->open_request_id);
-+        s += 4;
-+        libssh2_htonu32(s, filename_len);
-+        s += 4;
-+        memcpy(s, filename, filename_len);
-+        s += filename_len;
-+        if (open_type == LIBSSH2_SFTP_OPENFILE) {
-+            libssh2_htonu32(s, flags);
-+            s += 4;
-+            s += libssh2_sftp_attr2bin(s, &attrs);
-+        }
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Sending %s open request",
-+                       (open_type ==
-+                        LIBSSH2_SFTP_OPENFILE) ? "file" : "directory");
-+
-+        sftp->open_state = libssh2_NB_state_created;
-+    }
-+
-+    if (sftp->open_state == libssh2_NB_state_created) {
-+        rc = libssh2_channel_write_ex(channel, 0, (char *) sftp->open_packet,
-+                                      sftp->open_packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block sending FXP_OPEN or FXP_OPENDIR command",
-+                          0);
-+            return NULL;
-+        }
-+        else if (sftp->open_packet_len != rc) {
-+            /* TODO: partial writes should be fine too and is not a sign of
-+               an error when in non-blocking mode! */
-+
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send FXP_OPEN or FXP_OPENDIR command", 0);
-+            LIBSSH2_FREE(session, sftp->open_packet);
-+            sftp->open_packet = NULL;
-+            sftp->open_state = libssh2_NB_state_idle;
-+            return NULL;
-+        }
-+        LIBSSH2_FREE(session, sftp->open_packet);
-+        sftp->open_packet = NULL;
-+
-+        sftp->open_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (sftp->open_state == libssh2_NB_state_sent) {
-+        rc = sftp_packet_requirev(sftp, 2, fopen_responses,
-+                                  sftp->open_request_id, &data,
-+                                  &data_len);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block waiting for status message", 0);
-+            return NULL;
-+        }
-+        else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                          "Timeout waiting for status message", 0);
-+            sftp->open_state = libssh2_NB_state_idle;
-+            return NULL;
-+        }
-+    }
-+
-+    sftp->open_state = libssh2_NB_state_idle;
-+
-+    /* OPEN can basically get STATUS or HANDLE back, where HANDLE implies a
-+       fine response while STATUS means error. It seems though that at times
-+       we get an SSH_FX_OK back in a STATUS, followed the "real" HANDLE so
-+       we need to properly deal with that. */
-+    if (data[0] == SSH_FXP_STATUS) {
-+        int badness = 1;
-+        sftp->last_errno = libssh2_ntohu32(data + 5);
-+
-+        if(LIBSSH2_FX_OK == sftp->last_errno) {
-+            _libssh2_debug(session, LIBSSH2_DBG_SFTP, "got HANDLE FXOK!");
-+
-+            /* silly situation, but check for a HANDLE */
-+            rc = sftp_packet_require(sftp, SSH_FXP_HANDLE,
-+                                     sftp->open_request_id, &data, &data_len);
-+            if(rc == PACKET_EAGAIN) {
-+                /* go back to sent state and wait for something else */
-+                sftp->open_state = libssh2_NB_state_sent;
-+                return NULL;
-+            }
-+            else if(!rc)
-+                /* we got the handle so this is not a bad situation */
-+                badness = 0;
-+        }
-+
-+        if(badness) {
-+            libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
-+                          "Failed opening remote file", 0);
-+            _libssh2_debug(session, LIBSSH2_DBG_SFTP, "got FXP_STATUS %d",
-+                           sftp->last_errno);
-+            LIBSSH2_FREE(session, data);
-+            return NULL;
-+        }
-+    }
-+
-+    fp = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP_HANDLE));
-+    if (!fp) {
-+        libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                      "Unable to allocate new SFTP handle structure", 0);
-+        LIBSSH2_FREE(session, data);
-+        return NULL;
-+    }
-+    memset(fp, 0, sizeof(LIBSSH2_SFTP_HANDLE));
-+    fp->handle_type =
-+        (open_type ==
-+         LIBSSH2_SFTP_OPENFILE) ? LIBSSH2_SFTP_HANDLE_FILE :
-+        LIBSSH2_SFTP_HANDLE_DIR;
-+
-+    fp->handle_len = libssh2_ntohu32(data + 5);
-+    if (fp->handle_len > SFTP_HANDLE_MAXLEN) {
-+        /* SFTP doesn't allow handles longer than 256 characters */
-+        fp->handle_len = SFTP_HANDLE_MAXLEN;
-+    }
-+
-+    memcpy(fp->handle, data + 9, fp->handle_len);
-+    LIBSSH2_FREE(session, data);
-+
-+    /* Link the file and the sftp session together */
-+    fp->next = sftp->handles;
-+    if (fp->next) {
-+        fp->next->prev = fp;
-+    }
-+    fp->sftp = sftp;
-+
-+    fp->u.file.offset = 0;
-+
-+    _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Open command successful");
-+    return fp;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_sftp_read
-+ * Read from an SFTP file handle
-+ */
-+LIBSSH2_API ssize_t
-+libssh2_sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
-+                  size_t buffer_maxlen)
-+{
-+    LIBSSH2_SFTP *sftp = handle->sftp;
-+    LIBSSH2_CHANNEL *channel = sftp->channel;
-+    LIBSSH2_SESSION *session = channel->session;
-+    unsigned long data_len, request_id = 0;
-+    /* 25 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) +
-+       offset(8) + length(4) */
-+    ssize_t packet_len = handle->handle_len + 25;
-+    unsigned char *packet, *s, *data;
-+    static const unsigned char read_responses[2] =
-+        { SSH_FXP_DATA, SSH_FXP_STATUS };
-+    size_t bytes_read = 0;
-+    size_t bytes_requested = 0;
-+    size_t total_read = 0;
-+    int retcode;
-+
-+    if (sftp->read_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_SFTP,
-+                       "Reading %lu bytes from SFTP handle",
-+                       (unsigned long) buffer_maxlen);
-+        packet = handle->request_packet;
-+        sftp->read_state = libssh2_NB_state_allocated;
-+    } else {
-+        packet = sftp->read_packet;
-+        request_id = sftp->read_request_id;
-+        total_read = sftp->read_total_read;
-+    }
-+
-+    while (total_read < buffer_maxlen) {
-+        s = packet;
-+        /*
-+         * If buffer_maxlen bytes will be requested, server may return all
-+         * with one packet.  But libssh2 have packet length limit.
-+         * So we request data by pieces.
-+         */
-+        bytes_requested = buffer_maxlen - total_read;
-+        /* 10 = packet_type(1) + request_id(4) + data_length(4) +
-+           end_of_line_flag(1)
-+
-+           10 is changed to 13 below simple because it seems there's a
-+           "GlobalScape" SFTP server that responds with a slightly too big
-+           buffer at times and we can apparently compensate for that by doing
-+           this trick.
-+
-+           Further details on this issue:
-+
-+           https://sourceforge.net/mailarchive/forum.php?thread_name=9c3275a90811261517v6c0b1da2u918cc1b8370abf83%40mail.gmail.com&forum_name=libssh2-devel
-+
-+           http://forums.globalscape.com/tm.aspx?m=15249
-+
-+        */
-+        if (bytes_requested > LIBSSH2_SFTP_PACKET_MAXLEN - 13) {
-+            bytes_requested = LIBSSH2_SFTP_PACKET_MAXLEN - 13;
-+        }
-+#ifdef LIBSSH2_DEBUG_SFTP
-+        _libssh2_debug(session, LIBSSH2_DBG_SFTP,
-+                       "Requesting %lu bytes from SFTP handle",
-+                       (unsigned long) bytes_requested);
-+#endif
-+
-+        if (sftp->read_state == libssh2_NB_state_allocated) {
-+            libssh2_htonu32(s, packet_len - 4);
-+            s += 4;
-+            *(s++) = SSH_FXP_READ;
-+            request_id = sftp->request_id++;
-+            libssh2_htonu32(s, request_id);
-+            s += 4;
-+            libssh2_htonu32(s, handle->handle_len);
-+            s += 4;
-+
-+            memcpy(s, handle->handle, handle->handle_len);
-+            s += handle->handle_len;
-+
-+            libssh2_htonu64(s, handle->u.file.offset);
-+            s += 8;
-+
-+            libssh2_htonu32(s, bytes_requested);
-+            s += 4;
-+
-+            sftp->read_state = libssh2_NB_state_created;
-+        }
-+
-+        if (sftp->read_state == libssh2_NB_state_created) {
-+            retcode =
-+                libssh2_channel_write_ex(channel, 0, (char *) packet,
-+                                         packet_len);
-+            if (retcode == PACKET_EAGAIN) {
-+                sftp->read_packet = packet;
-+                sftp->read_request_id = request_id;
-+                sftp->read_total_read = total_read;
-+                return PACKET_EAGAIN;
-+            } else if (packet_len != retcode) {
-+                /* TODO: a partial write is not a critical error when in
-+                   non-blocking mode! */
-+                libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                              "Unable to send FXP_READ command", 0);
-+                sftp->read_packet = NULL;
-+                sftp->read_state = libssh2_NB_state_idle;
-+                return -1;
-+            }
-+            sftp->read_packet = packet;
-+            sftp->read_request_id = request_id;
-+            sftp->read_total_read = total_read;
-+            sftp->read_state = libssh2_NB_state_sent;
-+        }
-+
-+        if (sftp->read_state == libssh2_NB_state_sent) {
-+            retcode =
-+                sftp_packet_requirev(sftp, 2, read_responses,
-+                                     request_id, &data, &data_len);
-+            if (retcode == PACKET_EAGAIN) {
-+                return PACKET_EAGAIN;
-+            } else if (retcode) {
-+                libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                              "Timeout waiting for status message", 0);
-+                sftp->read_packet = NULL;
-+                sftp->read_state = libssh2_NB_state_idle;
-+                return -1;
-+            }
-+
-+            sftp->read_state = libssh2_NB_state_sent1;
-+        }
-+
-+        switch (data[0]) {
-+        case SSH_FXP_STATUS:
-+            retcode = libssh2_ntohu32(data + 5);
-+            LIBSSH2_FREE(session, data);
-+            sftp->read_packet = NULL;
-+            sftp->read_state = libssh2_NB_state_idle;
-+
-+            if (retcode == LIBSSH2_FX_EOF) {
-+                return total_read;
-+            } else {
-+                sftp->last_errno = retcode;
-+                libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
-+                              "SFTP Protocol Error", 0);
-+                return -1;
-+            }
-+
-+        case SSH_FXP_DATA:
-+            bytes_read = libssh2_ntohu32(data + 5);
-+            if (bytes_read > (data_len - 9)) {
-+                sftp->read_packet = NULL;
-+                sftp->read_state = libssh2_NB_state_idle;
-+                return -1;
-+            }
-+#ifdef LIBSSH2_DEBUG_SFTP
-+            _libssh2_debug(session, LIBSSH2_DBG_SFTP, "%lu bytes returned",
-+                           (unsigned long) bytes_read);
-+#endif
-+            memcpy(buffer + total_read, data + 9, bytes_read);
-+            handle->u.file.offset += bytes_read;
-+            total_read += bytes_read;
-+            LIBSSH2_FREE(session, data);
-+            /*
-+             * Set the state back to allocated, so a new one will be
-+             * created to either request more data or get EOF
-+             */
-+            sftp->read_state = libssh2_NB_state_allocated;
-+        }
-+    }
-+
-+    sftp->read_packet = NULL;
-+    sftp->read_state = libssh2_NB_state_idle;
-+    return total_read;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_sftp_readdir
-+ * Read from an SFTP directory handle
-+ */
-+LIBSSH2_API int
-+libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
-+                        size_t buffer_maxlen, char *longentry,
-+                        size_t longentry_maxlen,
-+                        LIBSSH2_SFTP_ATTRIBUTES * attrs)
-+{
-+    LIBSSH2_SFTP *sftp = handle->sftp;
-+    LIBSSH2_CHANNEL *channel = sftp->channel;
-+    LIBSSH2_SESSION *session = channel->session;
-+    LIBSSH2_SFTP_ATTRIBUTES attrs_dummy;
-+    unsigned long data_len, filename_len, longentry_len, num_names;
-+    /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */
-+    ssize_t packet_len = handle->handle_len + 13;
-+    unsigned char *s, *data;
-+    unsigned char read_responses[2] = { SSH_FXP_NAME, SSH_FXP_STATUS };
-+    int retcode;
-+
-+    if (sftp->readdir_state == libssh2_NB_state_idle) {
-+        if (handle->u.dir.names_left) {
-+            /*
-+             * A prior request returned more than one directory entry,
-+             * feed it back from the buffer
-+             */
-+            unsigned char *s = (unsigned char *) handle->u.dir.next_name;
-+            unsigned long real_filename_len = libssh2_ntohu32(s);
-+
-+            filename_len = real_filename_len;
-+            s += 4;
-+            if (filename_len > buffer_maxlen) {
-+                filename_len = buffer_maxlen;
-+            }
-+            memcpy(buffer, s, filename_len);
-+            s += real_filename_len;
-+
-+            /* The filename is not null terminated, make it so if possible */
-+            if (filename_len < buffer_maxlen) {
-+                buffer[filename_len] = '\0';
-+            }
-+
-+            if ((longentry == NULL) || (longentry_maxlen == 0)) {
-+                /* Skip longname */
-+                s += 4 + libssh2_ntohu32(s);
-+            } else {
-+                unsigned long real_longentry_len = libssh2_ntohu32(s);
-+
-+                longentry_len = real_longentry_len;
-+                s += 4;
-+                if (longentry_len > longentry_maxlen) {
-+                    longentry_len = longentry_maxlen;
-+                }
-+                memcpy(longentry, s, longentry_len);
-+                s += real_longentry_len;
-+
-+                /* The longentry is not null terminated, make it so if possible */
-+                if (longentry_len < longentry_maxlen) {
-+                    longentry[longentry_len] = '\0';
-+                }
-+            }
-+
-+            if (attrs) {
-+                memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
-+            }
-+            s += libssh2_sftp_bin2attr(attrs ? attrs : &attrs_dummy, s);
-+
-+            handle->u.dir.next_name = (char *) s;
-+            if ((--handle->u.dir.names_left) == 0) {
-+                LIBSSH2_FREE(session, handle->u.dir.names_packet);
-+            }
-+
-+            _libssh2_debug(session, LIBSSH2_DBG_SFTP,
-+                           "libssh2_sftp_readdir_ex() return %d",
-+                           filename_len);
-+            return filename_len;
-+        }
-+
-+        /* Request another entry(entries?) */
-+
-+        s = sftp->readdir_packet = LIBSSH2_ALLOC(session, packet_len);
-+        if (!sftp->readdir_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for FXP_READDIR packet",
-+                          0);
-+            return -1;
-+        }
-+
-+        libssh2_htonu32(s, packet_len - 4);
-+        s += 4;
-+        *(s++) = SSH_FXP_READDIR;
-+        sftp->readdir_request_id = sftp->request_id++;
-+        libssh2_htonu32(s, sftp->readdir_request_id);
-+        s += 4;
-+        libssh2_htonu32(s, handle->handle_len);
-+        s += 4;
-+        memcpy(s, handle->handle, handle->handle_len);
-+        s += handle->handle_len;
-+
-+        sftp->readdir_state = libssh2_NB_state_created;
-+    }
-+
-+    if (sftp->readdir_state == libssh2_NB_state_created) {
-+        _libssh2_debug(session, LIBSSH2_DBG_SFTP,
-+                       "Reading entries from directory handle");
-+        if ((retcode =
-+             libssh2_channel_write_ex(channel, 0,
-+                                      (char *) sftp->readdir_packet,
-+                                      packet_len)) == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (packet_len != retcode) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send FXP_READ command", 0);
-+            LIBSSH2_FREE(session, sftp->readdir_packet);
-+            sftp->readdir_packet = NULL;
-+            sftp->readdir_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+
-+        LIBSSH2_FREE(session, sftp->readdir_packet);
-+        sftp->readdir_packet = NULL;
-+
-+        sftp->readdir_state = libssh2_NB_state_sent;
-+    }
-+
-+    retcode =
-+        sftp_packet_requirev(sftp, 2, read_responses,
-+                             sftp->readdir_request_id, &data,
-+                             &data_len);
-+    if (retcode == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    } else if (retcode) {
-+        libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                      "Timeout waiting for status message", 0);
-+        sftp->readdir_state = libssh2_NB_state_idle;
-+        return -1;
-+    }
-+
-+    if (data[0] == SSH_FXP_STATUS) {
-+        retcode = libssh2_ntohu32(data + 5);
-+        LIBSSH2_FREE(session, data);
-+        if (retcode == LIBSSH2_FX_EOF) {
-+            sftp->readdir_state = libssh2_NB_state_idle;
-+            return 0;
-+        } else {
-+            sftp->last_errno = retcode;
-+            libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
-+                          "SFTP Protocol Error", 0);
-+            sftp->readdir_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+    }
-+
-+    num_names = libssh2_ntohu32(data + 5);
-+    _libssh2_debug(session, LIBSSH2_DBG_SFTP, "%lu entries returned",
-+                   num_names);
-+    if (num_names <= 0) {
-+        LIBSSH2_FREE(session, data);
-+        sftp->readdir_state = libssh2_NB_state_idle;
-+        return (num_names == 0) ? 0 : -1;
-+    }
-+
-+    if (num_names == 1) {
-+        unsigned long real_filename_len = libssh2_ntohu32(data + 9);
-+
-+        filename_len = real_filename_len;
-+        if (filename_len > buffer_maxlen) {
-+            filename_len = buffer_maxlen;
-+        }
-+        memcpy(buffer, data + 13, filename_len);
-+
-+        /* The filename is not null terminated, make it so if possible */
-+        if (filename_len < buffer_maxlen) {
-+            buffer[filename_len] = '\0';
-+        }
-+
-+        if (attrs) {
-+            memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
-+            libssh2_sftp_bin2attr(attrs, data + 13 + real_filename_len +
-+                                  (4 +
-+                                   libssh2_ntohu32(data + 13 +
-+                                                   real_filename_len)));
-+        }
-+        LIBSSH2_FREE(session, data);
-+
-+        sftp->readdir_state = libssh2_NB_state_idle;
-+        return filename_len;
-+    }
-+
-+    handle->u.dir.names_left = num_names;
-+    handle->u.dir.names_packet = data;
-+    handle->u.dir.next_name = (char *) data + 9;
-+
-+    sftp->readdir_state = libssh2_NB_state_idle;
-+
-+    /* Be lazy, just use the name popping mechanism from the start of the function */
-+    return libssh2_sftp_readdir_ex(handle, buffer, buffer_maxlen, longentry,
-+                                   longentry_maxlen, attrs);
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_sftp_write
-+ * Write data to a file handle
-+ */
-+LIBSSH2_API ssize_t
-+libssh2_sftp_write(LIBSSH2_SFTP_HANDLE * handle, const char *buffer,
-+                   size_t count)
-+{
-+    LIBSSH2_SFTP *sftp = handle->sftp;
-+    LIBSSH2_CHANNEL *channel = sftp->channel;
-+    LIBSSH2_SESSION *session = channel->session;
-+    unsigned long data_len, retcode;
-+    /* 25 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) +
-+       offset(8) + count(4) */
-+    ssize_t packet_len = handle->handle_len + count + 25;
-+    unsigned char *s, *data;
-+    int rc;
-+
-+    if (sftp->write_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Writing %lu bytes",
-+                       (unsigned long) count);
-+        s = sftp->write_packet = LIBSSH2_ALLOC(session, packet_len);
-+        if (!sftp->write_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for FXP_WRITE packet", 0);
-+            return -1;
-+        }
-+
-+        libssh2_htonu32(s, packet_len - 4);
-+        s += 4;
-+        *(s++) = SSH_FXP_WRITE;
-+        sftp->write_request_id = sftp->request_id++;
-+        libssh2_htonu32(s, sftp->write_request_id);
-+        s += 4;
-+        libssh2_htonu32(s, handle->handle_len);
-+        s += 4;
-+        memcpy(s, handle->handle, handle->handle_len);
-+        s += handle->handle_len;
-+        libssh2_htonu64(s, handle->u.file.offset);
-+        s += 8;
-+        libssh2_htonu32(s, count);
-+        s += 4;
-+        memcpy(s, buffer, count);
-+        s += count;
-+
-+        sftp->write_state = libssh2_NB_state_created;
-+    }
-+
-+    if (sftp->write_state == libssh2_NB_state_created) {
-+        if ((rc =
-+             libssh2_channel_write_ex(channel, 0, (char *) sftp->write_packet,
-+                                      packet_len)) == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        }
-+        if (packet_len != rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send FXP_READ command", 0);
-+            LIBSSH2_FREE(session, sftp->write_packet);
-+            sftp->write_packet = NULL;
-+            sftp->write_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, sftp->write_packet);
-+        sftp->write_packet = NULL;
-+        sftp->write_state = libssh2_NB_state_sent;
-+    }
-+
-+    rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
-+                             sftp->write_request_id, &data, &data_len);
-+    if (rc == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    } else if (rc) {
-+        libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                      "Timeout waiting for status message", 0);
-+        sftp->write_state = libssh2_NB_state_idle;
-+        return -1;
-+    }
-+
-+    sftp->write_state = libssh2_NB_state_idle;
-+
-+    retcode = libssh2_ntohu32(data + 5);
-+    LIBSSH2_FREE(session, data);
-+
-+    if (retcode == LIBSSH2_FX_OK) {
-+        handle->u.file.offset += count;
-+        return count;
-+    }
-+    libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error",
-+                  0);
-+    sftp->last_errno = retcode;
-+
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_sftp_fstat_ex
-+ * Get or Set stat on a file
-+ */
-+LIBSSH2_API int
-+libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE * handle,
-+                      LIBSSH2_SFTP_ATTRIBUTES * attrs, int setstat)
-+{
-+    LIBSSH2_SFTP *sftp = handle->sftp;
-+    LIBSSH2_CHANNEL *channel = sftp->channel;
-+    LIBSSH2_SESSION *session = channel->session;
-+    unsigned long data_len;
-+    /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */
-+    ssize_t packet_len =
-+        handle->handle_len + 13 + (setstat ? libssh2_sftp_attrsize(attrs) : 0);
-+    unsigned char *s, *data;
-+    static const unsigned char fstat_responses[2] =
-+        { SSH_FXP_ATTRS, SSH_FXP_STATUS };
-+    int rc;
-+
-+    if (sftp->fstat_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Issuing %s command",
-+                       setstat ? "set-stat" : "stat");
-+        s = sftp->fstat_packet = LIBSSH2_ALLOC(session, packet_len);
-+        if (!sftp->fstat_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for FSTAT/FSETSTAT packet",
-+                          0);
-+            return -1;
-+        }
-+
-+        libssh2_htonu32(s, packet_len - 4);
-+        s += 4;
-+        *(s++) = setstat ? SSH_FXP_FSETSTAT : SSH_FXP_FSTAT;
-+        sftp->fstat_request_id = sftp->request_id++;
-+        libssh2_htonu32(s, sftp->fstat_request_id);
-+        s += 4;
-+        libssh2_htonu32(s, handle->handle_len);
-+        s += 4;
-+        memcpy(s, handle->handle, handle->handle_len);
-+        s += handle->handle_len;
-+        if (setstat) {
-+            s += libssh2_sftp_attr2bin(s, attrs);
-+        }
-+
-+        sftp->fstat_state = libssh2_NB_state_created;
-+    }
-+
-+    if (sftp->fstat_state == libssh2_NB_state_created) {
-+        rc = libssh2_channel_write_ex(channel, 0, (char *) sftp->fstat_packet,
-+                                      packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (packet_len != rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          (setstat ? "Unable to send FXP_FSETSTAT"
-+                           : "Unable to send FXP_FSTAT command"), 0);
-+            LIBSSH2_FREE(session, sftp->fstat_packet);
-+            sftp->fstat_packet = NULL;
-+            sftp->fstat_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, sftp->fstat_packet);
-+        sftp->fstat_packet = NULL;
-+
-+        sftp->fstat_state = libssh2_NB_state_sent;
-+    }
-+
-+    rc = sftp_packet_requirev(sftp, 2, fstat_responses,
-+                              sftp->fstat_request_id, &data,
-+                              &data_len);
-+    if (rc == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    } else if (rc) {
-+        libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                      "Timeout waiting for status message", 0);
-+        sftp->fstat_state = libssh2_NB_state_idle;
-+        return -1;
-+    }
-+
-+    sftp->fstat_state = libssh2_NB_state_idle;
-+
-+    if (data[0] == SSH_FXP_STATUS) {
-+        int retcode;
-+
-+        retcode = libssh2_ntohu32(data + 5);
-+        LIBSSH2_FREE(session, data);
-+        if (retcode == LIBSSH2_FX_OK) {
-+            return 0;
-+        } else {
-+            sftp->last_errno = retcode;
-+            libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
-+                          "SFTP Protocol Error", 0);
-+            return -1;
-+        }
-+    }
-+
-+    libssh2_sftp_bin2attr(attrs, data + 5);
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_sftp_seek
-+ * Set the read/write pointer to an arbitrary position within the file
-+ */
-+LIBSSH2_API void
-+libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE * handle, size_t offset)
-+{
-+    handle->u.file.offset = offset;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_sftp_seek64
-+ * Set the read/write pointer to an arbitrary position within the file
-+ */
-+LIBSSH2_API void
-+libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE * handle, libssh2_uint64_t offset)
-+{
-+    handle->u.file.offset = offset;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_sftp_tell
-+ * Return the current read/write pointer's offset
-+ */
-+LIBSSH2_API size_t
-+libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE * handle)
-+{
-+    return handle->u.file.offset;
-+}
-+
-+/* {{{ libssh2_sftp_tell64
-+ * Return the current read/write pointer's offset
-+ */
-+LIBSSH2_API libssh2_uint64_t
-+libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE * handle)
-+{
-+    return handle->u.file.offset;
-+}
-+
-+/* }}} */
-+
-+
-+/* {{{ libssh2_sftp_close_handle
-+ * Close a file or directory handle
-+ * Also frees handle resource and unlinks it from the SFTP structure
-+ */
-+LIBSSH2_API int
-+libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE * handle)
-+{
-+    LIBSSH2_SFTP *sftp = handle->sftp;
-+    LIBSSH2_CHANNEL *channel = sftp->channel;
-+    LIBSSH2_SESSION *session = channel->session;
-+    unsigned long data_len, retcode;
-+    /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */
-+    ssize_t packet_len = handle->handle_len + 13;
-+    unsigned char *s, *data;
-+    int rc;
-+
-+    if (handle->close_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Closing handle");
-+        s = handle->close_packet = LIBSSH2_ALLOC(session, packet_len);
-+        if (!handle->close_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for FXP_CLOSE packet", 0);
-+            return -1;
-+        }
-+
-+        libssh2_htonu32(s, packet_len - 4);
-+        s += 4;
-+        *(s++) = SSH_FXP_CLOSE;
-+        handle->close_request_id = sftp->request_id++;
-+        libssh2_htonu32(s, handle->close_request_id);
-+        s += 4;
-+        libssh2_htonu32(s, handle->handle_len);
-+        s += 4;
-+        memcpy(s, handle->handle, handle->handle_len);
-+        s += handle->handle_len;
-+
-+        handle->close_state = libssh2_NB_state_created;
-+    }
-+
-+    if (handle->close_state == libssh2_NB_state_created) {
-+        rc = libssh2_channel_write_ex(channel, 0,
-+                                      (char *) handle->close_packet,
-+                                      packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (packet_len != rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send FXP_CLOSE command", 0);
-+            LIBSSH2_FREE(session, handle->close_packet);
-+            handle->close_packet = NULL;
-+            handle->close_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, handle->close_packet);
-+        handle->close_packet = NULL;
-+
-+        handle->close_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (handle->close_state == libssh2_NB_state_sent) {
-+        rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
-+                                 handle->close_request_id, &data,
-+                                 &data_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                          "Timeout waiting for status message", 0);
-+            handle->close_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+
-+        handle->close_state = libssh2_NB_state_sent1;
-+    }
-+
-+    retcode = libssh2_ntohu32(data + 5);
-+    LIBSSH2_FREE(session, data);
-+
-+    if (retcode != LIBSSH2_FX_OK) {
-+        sftp->last_errno = retcode;
-+        libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
-+                      "SFTP Protocol Error", 0);
-+        handle->close_state = libssh2_NB_state_idle;
-+        return -1;
-+    }
-+
-+    if (handle == sftp->handles) {
-+        sftp->handles = handle->next;
-+    }
-+    if (handle->next) {
-+        handle->next->prev = NULL;
-+    }
-+
-+    if ((handle->handle_type == LIBSSH2_SFTP_HANDLE_DIR)
-+        && handle->u.dir.names_left) {
-+        LIBSSH2_FREE(session, handle->u.dir.names_packet);
-+    }
-+
-+    handle->close_state = libssh2_NB_state_idle;
-+
-+    LIBSSH2_FREE(session, handle);
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* **********************
-+   * SFTP Miscellaneous *
-+   ********************** */
-+
-+/* {{{ libssh2_sftp_unlink_ex
-+ * Delete a file from the remote server
-+ */
-+/* libssh2_sftp_unlink_ex - NB-UNSAFE?? */
-+LIBSSH2_API int
-+libssh2_sftp_unlink_ex(LIBSSH2_SFTP * sftp, const char *filename,
-+                       unsigned int filename_len)
-+{
-+    LIBSSH2_CHANNEL *channel = sftp->channel;
-+    LIBSSH2_SESSION *session = channel->session;
-+    unsigned long data_len, retcode;
-+    /* 13 = packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) */
-+    ssize_t packet_len = filename_len + 13;
-+    unsigned char *s, *data;
-+    int rc;
-+
-+    if (sftp->unlink_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Unlinking %s", filename);
-+        s = sftp->unlink_packet = LIBSSH2_ALLOC(session, packet_len);
-+        if (!sftp->unlink_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for FXP_REMOVE packet",
-+                          0);
-+            return -1;
-+        }
-+
-+        libssh2_htonu32(s, packet_len - 4);
-+        s += 4;
-+        *(s++) = SSH_FXP_REMOVE;
-+        sftp->unlink_request_id = sftp->request_id++;
-+        libssh2_htonu32(s, sftp->unlink_request_id);
-+        s += 4;
-+        libssh2_htonu32(s, filename_len);
-+        s += 4;
-+        memcpy(s, filename, filename_len);
-+        s += filename_len;
-+
-+        sftp->unlink_state = libssh2_NB_state_created;
-+    }
-+
-+    if (sftp->unlink_state == libssh2_NB_state_created) {
-+        rc = libssh2_channel_write_ex(channel, 0, (char *) sftp->unlink_packet,
-+                                      packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (packet_len != rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send FXP_REMOVE command", 0);
-+            LIBSSH2_FREE(session, sftp->unlink_packet);
-+            sftp->unlink_packet = NULL;
-+            sftp->unlink_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, sftp->unlink_packet);
-+        sftp->unlink_packet = NULL;
-+
-+        sftp->unlink_state = libssh2_NB_state_sent;
-+    }
-+
-+    rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
-+                             sftp->unlink_request_id, &data,
-+                             &data_len);
-+    if (rc == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    }
-+    else if (rc) {
-+        libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                      "Timeout waiting for status message", 0);
-+        sftp->unlink_state = libssh2_NB_state_idle;
-+        return -1;
-+    }
-+
-+    sftp->unlink_state = libssh2_NB_state_idle;
-+
-+    retcode = libssh2_ntohu32(data + 5);
-+    LIBSSH2_FREE(session, data);
-+
-+    if (retcode == LIBSSH2_FX_OK) {
-+        return 0;
-+    } else {
-+        sftp->last_errno = retcode;
-+        libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
-+                      "SFTP Protocol Error", 0);
-+        return -1;
-+    }
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_sftp_rename_ex
-+ * Rename a file on the remote server
-+ */
-+LIBSSH2_API int
-+libssh2_sftp_rename_ex(LIBSSH2_SFTP * sftp, const char *source_filename,
-+                       unsigned int source_filename_len,
-+                       const char *dest_filename,
-+                       unsigned int dest_filename_len, long flags)
-+{
-+    LIBSSH2_CHANNEL *channel = sftp->channel;
-+    LIBSSH2_SESSION *session = channel->session;
-+    unsigned long data_len, retcode;
-+    ssize_t packet_len =
-+        source_filename_len + dest_filename_len + 17 + (sftp->version >=
-+                                                        5 ? 4 : 0);
-+    /* packet_len(4) + packet_type(1) + request_id(4) +
-+       source_filename_len(4) + dest_filename_len(4) + flags(4){SFTP5+) */
-+    unsigned char *data;
-+    int rc;
-+
-+    if (sftp->version < 2) {
-+        libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
-+                      "Server does not support RENAME", 0);
-+        return -1;
-+    }
-+
-+    if (sftp->rename_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Renaming %s to %s",
-+                       source_filename, dest_filename);
-+        sftp->rename_s = sftp->rename_packet =
-+            LIBSSH2_ALLOC(session, packet_len);
-+        if (!sftp->rename_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for FXP_RENAME packet",
-+                          0);
-+            return -1;
-+        }
-+
-+        libssh2_htonu32(sftp->rename_s, packet_len - 4);
-+        sftp->rename_s += 4;
-+        *(sftp->rename_s++) = SSH_FXP_RENAME;
-+        sftp->rename_request_id = sftp->request_id++;
-+        libssh2_htonu32(sftp->rename_s, sftp->rename_request_id);
-+        sftp->rename_s += 4;
-+        libssh2_htonu32(sftp->rename_s, source_filename_len);
-+        sftp->rename_s += 4;
-+        memcpy(sftp->rename_s, source_filename, source_filename_len);
-+        sftp->rename_s += source_filename_len;
-+        libssh2_htonu32(sftp->rename_s, dest_filename_len);
-+        sftp->rename_s += 4;
-+        memcpy(sftp->rename_s, dest_filename, dest_filename_len);
-+        sftp->rename_s += dest_filename_len;
-+
-+        if (sftp->version >= 5) {
-+            libssh2_htonu32(sftp->rename_s, flags);
-+            sftp->rename_s += 4;
-+        }
-+
-+        sftp->rename_state = libssh2_NB_state_created;
-+    }
-+
-+    if (sftp->rename_state == libssh2_NB_state_created) {
-+        rc = libssh2_channel_write_ex(channel, 0, (char *) sftp->rename_packet,
-+                                      sftp->rename_s - sftp->rename_packet);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (packet_len != rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send FXP_RENAME command", 0);
-+            LIBSSH2_FREE(session, sftp->rename_packet);
-+            sftp->rename_packet = NULL;
-+            sftp->rename_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, sftp->rename_packet);
-+        sftp->rename_packet = NULL;
-+
-+        sftp->rename_state = libssh2_NB_state_sent;
-+    }
-+
-+    rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
-+                             sftp->rename_request_id, &data,
-+                             &data_len);
-+    if (rc == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    } else if (rc) {
-+        libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                      "Timeout waiting for status message", 0);
-+        sftp->rename_state = libssh2_NB_state_idle;
-+        return -1;
-+    }
-+
-+    sftp->rename_state = libssh2_NB_state_idle;
-+
-+    retcode = libssh2_ntohu32(data + 5);
-+    LIBSSH2_FREE(session, data);
-+
-+    switch (retcode) {
-+    case LIBSSH2_FX_OK:
-+        retcode = 0;
-+        break;
-+
-+    case LIBSSH2_FX_FILE_ALREADY_EXISTS:
-+        libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
-+                      "File already exists and SSH_FXP_RENAME_OVERWRITE not specified",
-+                      0);
-+        sftp->last_errno = retcode;
-+        retcode = -1;
-+        break;
-+
-+    case LIBSSH2_FX_OP_UNSUPPORTED:
-+        libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
-+                      "Operation Not Supported", 0);
-+        sftp->last_errno = retcode;
-+        retcode = -1;
-+        break;
-+
-+    default:
-+        libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
-+                      "SFTP Protocol Error", 0);
-+        sftp->last_errno = retcode;
-+        retcode = -1;
-+    }
-+
-+    return retcode;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_sftp_mkdir_ex
-+ * Create an SFTP directory
-+ */
-+LIBSSH2_API int
-+libssh2_sftp_mkdir_ex(LIBSSH2_SFTP * sftp, const char *path,
-+                      unsigned int path_len, long mode)
-+{
-+    LIBSSH2_CHANNEL *channel = sftp->channel;
-+    LIBSSH2_SESSION *session = channel->session;
-+    LIBSSH2_SFTP_ATTRIBUTES attrs = {
-+        LIBSSH2_SFTP_ATTR_PERMISSIONS, 0, 0, 0, 0, 0, 0
-+    };
-+    unsigned long data_len, retcode, request_id;
-+    /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */
-+    ssize_t packet_len = path_len + 13 + libssh2_sftp_attrsize(&attrs);
-+    unsigned char *packet, *s, *data;
-+    int rc;
-+
-+    if (sftp->mkdir_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_SFTP,
-+                       "Creating directory %s with mode 0%lo", path, mode);
-+        s = packet = LIBSSH2_ALLOC(session, packet_len);
-+        if (!packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for FXP_MKDIR packet", 0);
-+            return -1;
-+        }
-+        /* Filetype in SFTP 3 and earlier */
-+        attrs.permissions = mode | LIBSSH2_SFTP_ATTR_PFILETYPE_DIR;
-+
-+        libssh2_htonu32(s, packet_len - 4);
-+        s += 4;
-+        *(s++) = SSH_FXP_MKDIR;
-+        request_id = sftp->request_id++;
-+        libssh2_htonu32(s, request_id);
-+        s += 4;
-+        libssh2_htonu32(s, path_len);
-+        s += 4;
-+        memcpy(s, path, path_len);
-+        s += path_len;
-+        s += libssh2_sftp_attr2bin(s, &attrs);
-+
-+        sftp->mkdir_state = libssh2_NB_state_created;
-+    } else {
-+        packet = sftp->mkdir_packet;
-+        request_id = sftp->mkdir_request_id;
-+    }
-+
-+    if (sftp->mkdir_state == libssh2_NB_state_created) {
-+        rc = libssh2_channel_write_ex(channel, 0, (char *) packet, packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            sftp->mkdir_packet = packet;
-+            sftp->mkdir_request_id = request_id;
-+            return PACKET_EAGAIN;
-+        }
-+        if (packet_len != rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send FXP_READ command", 0);
-+            LIBSSH2_FREE(session, packet);
-+            sftp->mkdir_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, packet);
-+        sftp->mkdir_state = libssh2_NB_state_sent;
-+        sftp->mkdir_packet = NULL;
-+    }
-+
-+    rc = sftp_packet_require(sftp, SSH_FXP_STATUS, request_id, &data,
-+                             &data_len);
-+    if (rc == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    } else if (rc) {
-+        libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                      "Timeout waiting for status message", 0);
-+        sftp->mkdir_state = libssh2_NB_state_idle;
-+        return -1;
-+    }
-+
-+    sftp->mkdir_state = libssh2_NB_state_idle;
-+
-+    retcode = libssh2_ntohu32(data + 5);
-+    LIBSSH2_FREE(session, data);
-+
-+    if (retcode == LIBSSH2_FX_OK) {
-+        return 0;
-+    } else {
-+        libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
-+                      "SFTP Protocol Error", 0);
-+        sftp->last_errno = retcode;
-+        return -1;
-+    }
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_sftp_rmdir_ex
-+ * Remove a directory
-+ */
-+/* libssh2_sftp_rmdir_ex - NB-UNSAFE?? */
-+LIBSSH2_API int
-+libssh2_sftp_rmdir_ex(LIBSSH2_SFTP * sftp, const char *path,
-+                      unsigned int path_len)
-+{
-+    LIBSSH2_CHANNEL *channel = sftp->channel;
-+    LIBSSH2_SESSION *session = channel->session;
-+    unsigned long data_len, retcode;
-+    /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */
-+    ssize_t packet_len = path_len + 13;
-+    unsigned char *s, *data;
-+    int rc;
-+
-+    if (sftp->rmdir_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Removing directory: %s",
-+                       path);
-+        s = sftp->rmdir_packet = LIBSSH2_ALLOC(session, packet_len);
-+        if (!sftp->rmdir_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for FXP_MKDIR packet", 0);
-+            return -1;
-+        }
-+
-+        libssh2_htonu32(s, packet_len - 4);
-+        s += 4;
-+        *(s++) = SSH_FXP_RMDIR;
-+        sftp->rmdir_request_id = sftp->request_id++;
-+        libssh2_htonu32(s, sftp->rmdir_request_id);
-+        s += 4;
-+        libssh2_htonu32(s, path_len);
-+        s += 4;
-+        memcpy(s, path, path_len);
-+        s += path_len;
-+
-+        sftp->rmdir_state = libssh2_NB_state_created;
-+    }
-+
-+    if (sftp->rmdir_state == libssh2_NB_state_created) {
-+        rc = libssh2_channel_write_ex(channel, 0, (char *) sftp->rmdir_packet,
-+                                      packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (packet_len != rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send FXP_MKDIR command", 0);
-+            LIBSSH2_FREE(session, sftp->rmdir_packet);
-+            sftp->rmdir_packet = NULL;
-+            sftp->rmdir_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, sftp->rmdir_packet);
-+        sftp->rmdir_packet = NULL;
-+
-+        sftp->rmdir_state = libssh2_NB_state_sent;
-+    }
-+
-+    rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
-+                             sftp->rmdir_request_id, &data, &data_len);
-+    if (rc == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    } else if (rc) {
-+        libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                      "Timeout waiting for status message", 0);
-+        sftp->rmdir_state = libssh2_NB_state_idle;
-+        return -1;
-+    }
-+
-+    sftp->rmdir_state = libssh2_NB_state_idle;
-+
-+    retcode = libssh2_ntohu32(data + 5);
-+    LIBSSH2_FREE(session, data);
-+
-+    if (retcode == LIBSSH2_FX_OK) {
-+        return 0;
-+    } else {
-+        sftp->last_errno = retcode;
-+        libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
-+                      "SFTP Protocol Error", 0);
-+        return -1;
-+    }
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_sftp_stat_ex
-+ * Stat a file or symbolic link
-+ */
-+/* libssh2_sftp_stat_ex - NB-UNSAFE?? */
-+LIBSSH2_API int
-+libssh2_sftp_stat_ex(LIBSSH2_SFTP * sftp, const char *path,
-+                     unsigned int path_len, int stat_type,
-+                     LIBSSH2_SFTP_ATTRIBUTES * attrs)
-+{
-+    LIBSSH2_CHANNEL *channel = sftp->channel;
-+    LIBSSH2_SESSION *session = channel->session;
-+    unsigned long data_len;
-+    /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */
-+    ssize_t packet_len =
-+        path_len + 13 +
-+        ((stat_type ==
-+          LIBSSH2_SFTP_SETSTAT) ? libssh2_sftp_attrsize(attrs) : 0);
-+    unsigned char *s, *data;
-+    static const unsigned char stat_responses[2] =
-+        { SSH_FXP_ATTRS, SSH_FXP_STATUS };
-+    int rc;
-+
-+    if (sftp->stat_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_SFTP, "%s %s",
-+                       (stat_type == LIBSSH2_SFTP_SETSTAT) ? "Set-statting" :
-+                       (stat_type ==
-+                        LIBSSH2_SFTP_LSTAT ? "LStatting" : "Statting"), path);
-+        s = sftp->stat_packet = LIBSSH2_ALLOC(session, packet_len);
-+        if (!sftp->stat_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for FXP_MKDIR packet", 0);
-+            return -1;
-+        }
-+
-+        libssh2_htonu32(s, packet_len - 4);
-+        s += 4;
-+        switch (stat_type) {
-+        case LIBSSH2_SFTP_SETSTAT:
-+            *(s++) = SSH_FXP_SETSTAT;
-+            break;
-+
-+        case LIBSSH2_SFTP_LSTAT:
-+            *(s++) = SSH_FXP_LSTAT;
-+            break;
-+
-+        case LIBSSH2_SFTP_STAT:
-+        default:
-+            *(s++) = SSH_FXP_STAT;
-+        }
-+        sftp->stat_request_id = sftp->request_id++;
-+        libssh2_htonu32(s, sftp->stat_request_id);
-+        s += 4;
-+        libssh2_htonu32(s, path_len);
-+        s += 4;
-+        memcpy(s, path, path_len);
-+        s += path_len;
-+        if (stat_type == LIBSSH2_SFTP_SETSTAT) {
-+            s += libssh2_sftp_attr2bin(s, attrs);
-+        }
-+
-+        sftp->stat_state = libssh2_NB_state_created;
-+    }
-+
-+    if (sftp->stat_state == libssh2_NB_state_created) {
-+        rc = libssh2_channel_write_ex(channel, 0, (char *) sftp->stat_packet,
-+                                      packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (packet_len != rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send STAT/LSTAT/SETSTAT command", 0);
-+            LIBSSH2_FREE(session, sftp->stat_packet);
-+            sftp->stat_packet = NULL;
-+            sftp->stat_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, sftp->stat_packet);
-+        sftp->stat_packet = NULL;
-+
-+        sftp->stat_state = libssh2_NB_state_sent;
-+    }
-+
-+    rc = sftp_packet_requirev(sftp, 2, stat_responses,
-+                              sftp->stat_request_id, &data, &data_len);
-+    if (rc == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    } else if (rc) {
-+        libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                      "Timeout waiting for status message", 0);
-+        sftp->stat_state = libssh2_NB_state_idle;
-+        return -1;
-+    }
-+
-+    sftp->stat_state = libssh2_NB_state_idle;
-+
-+    if (data[0] == SSH_FXP_STATUS) {
-+        int retcode;
-+
-+        retcode = libssh2_ntohu32(data + 5);
-+        LIBSSH2_FREE(session, data);
-+        if (retcode == LIBSSH2_FX_OK) {
-+            return 0;
-+        } else {
-+            sftp->last_errno = retcode;
-+            libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
-+                          "SFTP Protocol Error", 0);
-+            return -1;
-+        }
-+    }
-+
-+    memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
-+    libssh2_sftp_bin2attr(attrs, data + 5);
-+    LIBSSH2_FREE(session, data);
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_sftp_symlink_ex
-+ * Read or set a symlink
-+ */
-+LIBSSH2_API int
-+libssh2_sftp_symlink_ex(LIBSSH2_SFTP * sftp, const char *path,
-+                        unsigned int path_len, char *target,
-+                        unsigned int target_len, int link_type)
-+{
-+    LIBSSH2_CHANNEL *channel = sftp->channel;
-+    LIBSSH2_SESSION *session = channel->session;
-+    unsigned long data_len, link_len;
-+    /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */
-+    ssize_t packet_len =
-+        path_len + 13 +
-+        ((link_type == LIBSSH2_SFTP_SYMLINK) ? (4 + target_len) : 0);
-+    unsigned char *s, *data;
-+    static const unsigned char link_responses[2] =
-+        { SSH_FXP_NAME, SSH_FXP_STATUS };
-+    int rc;
-+
-+    if ((sftp->version < 3) && (link_type != LIBSSH2_SFTP_REALPATH)) {
-+        libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
-+                      "Server does not support SYMLINK or READLINK", 0);
-+        return -1;
-+    }
-+
-+    if (sftp->symlink_state == libssh2_NB_state_idle) {
-+        s = sftp->symlink_packet = LIBSSH2_ALLOC(session, packet_len);
-+        if (!sftp->symlink_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for SYMLINK/READLINK"
-+                          "/REALPATH packet", 0);
-+            return -1;
-+        }
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_SFTP, "%s %s on %s",
-+                       (link_type ==
-+                        LIBSSH2_SFTP_SYMLINK) ? "Creating" : "Reading",
-+                       (link_type ==
-+                        LIBSSH2_SFTP_REALPATH) ? "realpath" : "symlink", path);
-+
-+        libssh2_htonu32(s, packet_len - 4);
-+        s += 4;
-+        switch (link_type) {
-+        case LIBSSH2_SFTP_REALPATH:
-+            *(s++) = SSH_FXP_REALPATH;
-+            break;
-+
-+        case LIBSSH2_SFTP_SYMLINK:
-+            *(s++) = SSH_FXP_SYMLINK;
-+            break;
-+
-+        case LIBSSH2_SFTP_READLINK:
-+        default:
-+            *(s++) = SSH_FXP_READLINK;
-+        }
-+        sftp->symlink_request_id = sftp->request_id++;
-+        libssh2_htonu32(s, sftp->symlink_request_id);
-+        s += 4;
-+        libssh2_htonu32(s, path_len);
-+        s += 4;
-+        memcpy(s, path, path_len);
-+        s += path_len;
-+        if (link_type == LIBSSH2_SFTP_SYMLINK) {
-+            libssh2_htonu32(s, target_len);
-+            s += 4;
-+            memcpy(s, target, target_len);
-+            s += target_len;
-+        }
-+
-+        sftp->symlink_state = libssh2_NB_state_created;
-+    }
-+
-+    if (sftp->symlink_state == libssh2_NB_state_created) {
-+        rc = libssh2_channel_write_ex(channel, 0,
-+                                      (char *) sftp->symlink_packet,
-+                                      packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (packet_len != rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send SYMLINK/READLINK command", 0);
-+            LIBSSH2_FREE(session, sftp->symlink_packet);
-+            sftp->symlink_packet = NULL;
-+            sftp->symlink_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, sftp->symlink_packet);
-+        sftp->symlink_packet = NULL;
-+
-+        sftp->symlink_state = libssh2_NB_state_sent;
-+    }
-+
-+    rc = sftp_packet_requirev(sftp, 2, link_responses,
-+                              sftp->symlink_request_id, &data,
-+                              &data_len);
-+    if (rc == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    }
-+    else if (rc) {
-+        libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                      "Timeout waiting for status message", 0);
-+        sftp->symlink_state = libssh2_NB_state_idle;
-+        return -1;
-+    }
-+
-+    sftp->symlink_state = libssh2_NB_state_idle;
-+
-+    if (data[0] == SSH_FXP_STATUS) {
-+        int retcode;
-+
-+        retcode = libssh2_ntohu32(data + 5);
-+        LIBSSH2_FREE(session, data);
-+        if (retcode == LIBSSH2_FX_OK) {
-+            return 0;
-+        } else {
-+            sftp->last_errno = retcode;
-+            libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
-+                          "SFTP Protocol Error", 0);
-+            return -1;
-+        }
-+    }
-+
-+    if (libssh2_ntohu32(data + 5) < 1) {
-+        libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
-+                      "Invalid READLINK/REALPATH response, no name entries",
-+                      0);
-+        LIBSSH2_FREE(session, data);
-+        return -1;
-+    }
-+
-+    link_len = libssh2_ntohu32(data + 9);
-+    if (link_len >= target_len) {
-+        link_len = target_len - 1;
-+    }
-+    memcpy(target, data + 13, link_len);
-+    target[link_len] = 0;
-+    LIBSSH2_FREE(session, data);
-+
-+    return link_len;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_sftp_last_error
-+ * Returns the last error code reported by SFTP
-+ */
-+LIBSSH2_API unsigned long
-+libssh2_sftp_last_error(LIBSSH2_SFTP * sftp)
-+{
-+    return sftp->last_errno;
-+}
-+
-+/* }}} */
-
-Property changes on: libssh2/src/sftp.c
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.2
-Added: svn:eol-style
-   + native
-
-Index: libssh2/src/libssh2_config.h.in.w32
-===================================================================
---- libssh2/src/libssh2_config.h.in.w32        (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/libssh2_config.h.in.w32        (.../trunk)
-@@ -0,0 +1,44 @@
-+#ifndef LIBSSH2_CONFIG_H
-+#define LIBSSH2_CONFIG_H
-+
-+#ifndef WIN32
-+#define WIN32
-+#endif
-+#include <winsock2.h>
-+#include <mswsock.h>
-+#include <ws2tcpip.h>
-+
-+#ifdef __MINGW32__
-+#define HAVE_UNISTD_H
-+#define HAVE_INTTYPES_H
-+#define HAVE_SYS_TIME_H
-+#endif
-+
-+#define HAVE_WINSOCK2_H
-+#define HAVE_IOCTLSOCKET
-+#define HAVE_SELECT
-+
-+#ifdef _MSC_VER
-+#define snprintf _snprintf
-+#if _MSC_VER < 1500
-+#define vsnprintf _vsnprintf
-+#else
-+#define ssize_t SSIZE_T
-+#define uint32_t UINT32
-+#endif
-+#define strncasecmp _strnicmp
-+#define strcasecmp _stricmp
-+#else
-+#define strncasecmp strnicmp
-+#define strcasecmp stricmp
-+#endif /* _MSC_VER */
-+
-+/* Compile in zlib support */
-+#define LIBSSH2_HAVE_ZLIB 1
-+
-+/* Enable newer diffie-hellman-group-exchange-sha1 syntax */
-+#define LIBSSH2_DH_GEX_NEW 1
-+
-+#endif /* LIBSSH2_CONFIG_H */
-+
-+
-
-Property changes on: libssh2/src/libssh2_config.h.in.w32
-___________________________________________________________________
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.1
-Added: svn:eol-style
-   + native
-Added: svn:executable
-   + *
-
-Index: libssh2/src/pem.c
-===================================================================
---- libssh2/src/pem.c  (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/pem.c  (.../trunk)
-@@ -0,0 +1,209 @@
-+/* Copyright (C) 2007 The Written Word, Inc.
-+ * Copyright (C) 2008, Simon Josefsson
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#include "libssh2_priv.h"
-+
-+static int
-+readline(char *line, int line_size, FILE * fp)
-+{
-+    if (!fgets(line, line_size, fp)) {
-+        return -1;
-+    }
-+    if (*line && line[strlen(line) - 1] == '\n') {
-+        line[strlen(line) - 1] = '\0';
-+    }
-+    if (*line && line[strlen(line) - 1] == '\r') {
-+        line[strlen(line) - 1] = '\0';
-+    }
-+    return 0;
-+}
-+
-+#define LINE_SIZE 128
-+
-+int
-+_libssh2_pem_parse(LIBSSH2_SESSION * session,
-+                   const char *headerbegin,
-+                   const char *headerend,
-+                   FILE * fp, unsigned char **data, unsigned int *datalen)
-+{
-+    char line[LINE_SIZE];
-+    char *b64data = NULL;
-+    unsigned int b64datalen = 0;
-+    int ret;
-+
-+    do {
-+        if (readline(line, LINE_SIZE, fp)) {
-+            return -1;
-+        }
-+    }
-+    while (strcmp(line, headerbegin) != 0);
-+
-+    *line = '\0';
-+
-+    do {
-+        if (*line) {
-+            char *tmp;
-+            size_t linelen;
-+
-+            linelen = strlen(line);
-+            tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
-+            if (!tmp) {
-+                ret = -1;
-+                goto out;
-+            }
-+            memcpy(tmp + b64datalen, line, linelen);
-+            b64data = tmp;
-+            b64datalen += linelen;
-+        }
-+
-+        if (readline(line, LINE_SIZE, fp)) {
-+            ret = -1;
-+            goto out;
-+        }
-+    } while (strcmp(line, headerend) != 0);
-+
-+    if (libssh2_base64_decode(session, (char**) data, datalen,
-+                              b64data, b64datalen)) {
-+        ret = -1;
-+        goto out;
-+    }
-+
-+    ret = 0;
-+  out:
-+    if (b64data) {
-+        LIBSSH2_FREE(session, b64data);
-+    }
-+    return ret;
-+}
-+
-+static int
-+read_asn1_length(const unsigned char *data,
-+                 unsigned int datalen, unsigned int *len)
-+{
-+    unsigned int lenlen;
-+    int nextpos;
-+
-+    if (datalen < 1) {
-+        return -1;
-+    }
-+    *len = data[0];
-+
-+    if (*len >= 0x80) {
-+        lenlen = *len & 0x7F;
-+        *len = data[1];
-+        if (1 + lenlen > datalen) {
-+            return -1;
-+        }
-+        if (lenlen > 1) {
-+            *len <<= 8;
-+            *len |= data[2];
-+        }
-+    } else {
-+        lenlen = 0;
-+    }
-+
-+    nextpos = 1 + lenlen;
-+    if (lenlen > 2 || 1 + lenlen + *len > datalen) {
-+        return -1;
-+    }
-+
-+    return nextpos;
-+}
-+
-+int
-+_libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen)
-+{
-+    unsigned int len;
-+    int lenlen;
-+
-+    if (*datalen < 1) {
-+        return -1;
-+    }
-+
-+    if ((*data)[0] != '\x30') {
-+        return -1;
-+    }
-+
-+    (*data)++;
-+    (*datalen)--;
-+
-+    lenlen = read_asn1_length(*data, *datalen, &len);
-+    if (lenlen < 0 || lenlen + len != *datalen) {
-+        return -1;
-+    }
-+
-+    *data += lenlen;
-+    *datalen -= lenlen;
-+
-+    return 0;
-+}
-+
-+int
-+_libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
-+                            unsigned char **i, unsigned int *ilen)
-+{
-+    unsigned int len;
-+    int lenlen;
-+
-+    if (*datalen < 1) {
-+        return -1;
-+    }
-+
-+    if ((*data)[0] != '\x02') {
-+        return -1;
-+    }
-+
-+    (*data)++;
-+    (*datalen)--;
-+
-+    lenlen = read_asn1_length(*data, *datalen, &len);
-+    if (lenlen < 0 || lenlen + len > *datalen) {
-+        return -1;
-+    }
-+
-+    *data += lenlen;
-+    *datalen -= lenlen;
-+
-+    *i = *data;
-+    *ilen = len;
-+
-+    *data += len;
-+    *datalen -= len;
-+
-+    return 0;
-+}
-
-Property changes on: libssh2/src/pem.c
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.1
-Added: svn:eol-style
-   + native
-Added: svn:executable
-   + *
-
-Index: libssh2/src/session.c
-===================================================================
---- libssh2/src/session.c      (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/session.c      (.../trunk)
-@@ -0,0 +1,1554 @@
-+/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#include "libssh2_priv.h"
-+#include <errno.h>
-+#ifdef HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <stdlib.h>
-+#include <fcntl.h>
-+
-+#ifdef HAVE_GETTIMEOFDAY
-+#include <sys/time.h>
-+#endif
-+#ifdef HAVE_ALLOCA_H
-+#include <alloca.h>
-+#endif
-+
-+/* {{{ libssh2_default_alloc
-+ */
-+static
-+LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)
-+{
-+    (void) abstract;
-+    return malloc(count);
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_default_free
-+ */
-+static
-+LIBSSH2_FREE_FUNC(libssh2_default_free)
-+{
-+    (void) abstract;
-+    free(ptr);
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_default_realloc
-+ */
-+static
-+LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
-+{
-+    (void) abstract;
-+    return realloc(ptr, count);
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_banner_receive
-+ * Wait for a hello from the remote host
-+ * Allocate a buffer and store the banner in session->remote.banner
-+ * Returns: 0 on success, PACKET_EAGAIN if read would block, 1 on failure
-+ */
-+static int
-+libssh2_banner_receive(LIBSSH2_SESSION * session)
-+{
-+    int ret;
-+    int banner_len;
-+
-+    if (session->banner_TxRx_state == libssh2_NB_state_idle) {
-+        banner_len = 0;
-+
-+        session->banner_TxRx_state = libssh2_NB_state_created;
-+    } else {
-+        banner_len = session->banner_TxRx_total_send;
-+    }
-+
-+    while ((banner_len < (int) sizeof(session->banner_TxRx_banner)) &&
-+           ((banner_len == 0)
-+            || (session->banner_TxRx_banner[banner_len - 1] != '\n'))) {
-+        char c = '\0';
-+
-+        ret =
-+            recv(session->socket_fd, &c, 1,
-+                 LIBSSH2_SOCKET_RECV_FLAGS(session));
-+
-+        if (ret < 0) {
-+#ifdef WIN32
-+            switch (WSAGetLastError()) {
-+            case WSAEWOULDBLOCK:
-+                errno = EAGAIN;
-+                break;
-+
-+            case WSAENOTSOCK:
-+                errno = EBADF;
-+                break;
-+
-+            case WSAENOTCONN:
-+            case WSAECONNABORTED:
-+                errno = WSAENOTCONN;
-+                break;
-+
-+            case WSAEINTR:
-+                errno = EINTR;
-+                break;
-+            }
-+#endif /* WIN32 */
-+            if (errno == EAGAIN) {
-+                session->socket_block_directions =
-+                    LIBSSH2_SESSION_BLOCK_INBOUND;
-+                session->banner_TxRx_total_send = banner_len;
-+                return PACKET_EAGAIN;
-+            }
-+
-+            /* Some kinda error */
-+            session->banner_TxRx_state = libssh2_NB_state_idle;
-+            session->banner_TxRx_total_send = 0;
-+            return 1;
-+        }
-+
-+        if (ret == 0) {
-+            session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
-+            return PACKET_FAIL;
-+        }
-+
-+        if (c == '\0') {
-+            /* NULLs are not allowed in SSH banners */
-+            session->banner_TxRx_state = libssh2_NB_state_idle;
-+            session->banner_TxRx_total_send = 0;
-+            return 1;
-+        }
-+
-+        session->banner_TxRx_banner[banner_len++] = c;
-+    }
-+
-+    while (banner_len &&
-+           ((session->banner_TxRx_banner[banner_len - 1] == '\n') ||
-+            (session->banner_TxRx_banner[banner_len - 1] == '\r'))) {
-+        banner_len--;
-+    }
-+
-+    /* From this point on, we are done here */
-+    session->banner_TxRx_state = libssh2_NB_state_idle;
-+    session->banner_TxRx_total_send = 0;
-+
-+    if (!banner_len)
-+        return 1;
-+
-+    session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1);
-+    if (!session->remote.banner) {
-+        libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                      "Error allocating space for remote banner", 0);
-+        return 1;
-+    }
-+    memcpy(session->remote.banner, session->banner_TxRx_banner, banner_len);
-+    session->remote.banner[banner_len] = '\0';
-+    _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Received Banner: %s",
-+                   session->remote.banner);
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_banner_send
-+ * Send the default banner, or the one set via libssh2_setopt_string
-+ *
-+ * Returns PACKET_EAGAIN if it would block - and if it does so, you should
-+ * call this function again as soon as it is likely that more data can be
-+ * sent, and this function should then be called with the same argument set
-+ * (same data pointer and same data_len) until zero or failure is returned.
-+ */
-+static int
-+libssh2_banner_send(LIBSSH2_SESSION * session)
-+{
-+    char *banner = (char *) LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF;
-+    int banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1;
-+    ssize_t ret;
-+#ifdef LIBSSH2DEBUG
-+    char banner_dup[256];
-+#endif
-+
-+    if (session->banner_TxRx_state == libssh2_NB_state_idle) {
-+        if (session->local.banner) {
-+            /* setopt_string will have given us our \r\n characters */
-+            banner_len = strlen((char *) session->local.banner);
-+            banner = (char *) session->local.banner;
-+        }
-+#ifdef LIBSSH2DEBUG
-+        /* Hack and slash to avoid sending CRLF in debug output */
-+        if (banner_len < 256) {
-+            memcpy(banner_dup, banner, banner_len - 2);
-+            banner_dup[banner_len - 2] = '\0';
-+        } else {
-+            memcpy(banner_dup, banner, 255);
-+            banner[255] = '\0';
-+        }
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Sending Banner: %s",
-+                       banner_dup);
-+#endif
-+
-+        session->banner_TxRx_state = libssh2_NB_state_created;
-+    }
-+
-+    ret =
-+        send(session->socket_fd, banner + session->banner_TxRx_total_send,
-+             banner_len - session->banner_TxRx_total_send,
-+             LIBSSH2_SOCKET_SEND_FLAGS(session));
-+
-+    if (ret != (banner_len - session->banner_TxRx_total_send)) {
-+        if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
-+            /* the whole packet could not be sent, save the what was */
-+            session->socket_block_directions =
-+                LIBSSH2_SESSION_BLOCK_OUTBOUND;
-+            session->banner_TxRx_total_send += ret;
-+            return PACKET_EAGAIN;
-+        }
-+        session->banner_TxRx_state = libssh2_NB_state_idle;
-+        session->banner_TxRx_total_send = 0;
-+        return PACKET_FAIL;
-+    }
-+
-+    /* Set the state back to idle */
-+    session->banner_TxRx_state = libssh2_NB_state_idle;
-+    session->banner_TxRx_total_send = 0;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/*
-+ * _libssh2_nonblock() sets the given socket to either blocking or
-+ * non-blocking mode based on the 'nonblock' boolean argument. This function
-+ * is copied from the libcurl sources with permission.
-+ */
-+static int
-+_libssh2_nonblock(int sockfd,   /* operate on this */
-+                  int nonblock /* TRUE or FALSE */ )
-+{
-+#undef SETBLOCK
-+#define SETBLOCK 0
-+#ifdef HAVE_O_NONBLOCK
-+    /* most recent unix versions */
-+    int flags;
-+
-+    flags = fcntl(sockfd, F_GETFL, 0);
-+    if (nonblock)
-+        return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
-+    else
-+        return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
-+#undef SETBLOCK
-+#define SETBLOCK 1
-+#endif
-+
-+#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
-+    /* older unix versions */
-+    int flags;
-+
-+    flags = nonblock;
-+    return ioctl(sockfd, FIONBIO, &flags);
-+#undef SETBLOCK
-+#define SETBLOCK 2
-+#endif
-+
-+#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
-+    /* Windows? */
-+    unsigned long flags;
-+    flags = nonblock;
-+
-+    return ioctlsocket(sockfd, FIONBIO, &flags);
-+#undef SETBLOCK
-+#define SETBLOCK 3
-+#endif
-+
-+#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
-+    /* presumably for Amiga */
-+    return IoctlSocket(sockfd, FIONBIO, (long) nonblock);
-+#undef SETBLOCK
-+#define SETBLOCK 4
-+#endif
-+
-+#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
-+    /* BeOS */
-+    long b = nonblock ? 1 : 0;
-+    return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
-+#undef SETBLOCK
-+#define SETBLOCK 5
-+#endif
-+
-+#ifdef HAVE_DISABLED_NONBLOCKING
-+    return 0;                   /* returns success */
-+#undef SETBLOCK
-+#define SETBLOCK 6
-+#endif
-+
-+#if (SETBLOCK == 0)
-+#error "no non-blocking method was found/used/set"
-+#endif
-+}
-+
-+/*
-+ * _libssh2_get_socket_nonblocking() gets the given blocking or non-blocking
-+ * state of the socket.
-+ */
-+static int
-+_libssh2_get_socket_nonblocking(int sockfd)
-+{                               /* operate on this */
-+#undef GETBLOCK
-+#define GETBLOCK 0
-+#ifdef HAVE_O_NONBLOCK
-+    /* most recent unix versions */
-+    int flags;
-+
-+    if ((flags = fcntl(sockfd, F_GETFL, 0)) == -1) {
-+        /* Assume blocking on error */
-+        return 1;
-+    }
-+    return (flags & O_NONBLOCK);
-+#undef GETBLOCK
-+#define GETBLOCK 1
-+#endif
-+
-+#if defined(WSAEWOULDBLOCK) && (GETBLOCK == 0)
-+    /* Windows? */
-+    unsigned int option_value;
-+    socklen_t option_len = sizeof(option_value);
-+
-+    if (getsockopt
-+        (sockfd, SOL_SOCKET, SO_ERROR, (void *) &option_value, &option_len)) {
-+        /* Assume blocking on error */
-+        return 1;
-+    }
-+    return (int) option_value;
-+#undef GETBLOCK
-+#define GETBLOCK 2
-+#endif
-+
-+#if defined(HAVE_SO_NONBLOCK) && (GETBLOCK == 0)
-+    /* BeOS */
-+    long b;
-+    if (getsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b))) {
-+        /* Assume blocking on error */
-+        return 1;
-+    }
-+    return (int) b;
-+#undef GETBLOCK
-+#define GETBLOCK 5
-+#endif
-+
-+#ifdef HAVE_DISABLED_NONBLOCKING
-+    return 1;                   /* returns blocking */
-+#undef GETBLOCK
-+#define GETBLOCK 6
-+#endif
-+
-+#if (GETBLOCK == 0)
-+#error "no non-blocking method was found/used/get"
-+#endif
-+}
-+
-+/* {{{ libssh2_banner_set
-+ * Set the local banner
-+ */
-+LIBSSH2_API int
-+libssh2_banner_set(LIBSSH2_SESSION * session, const char *banner)
-+{
-+    int banner_len = banner ? strlen(banner) : 0;
-+
-+    if (session->local.banner) {
-+        LIBSSH2_FREE(session, session->local.banner);
-+        session->local.banner = NULL;
-+    }
-+
-+    if (!banner_len) {
-+        return 0;
-+    }
-+
-+    session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3);
-+    if (!session->local.banner) {
-+        libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                      "Unable to allocate memory for local banner", 0);
-+        return -1;
-+    }
-+
-+    memcpy(session->local.banner, banner, banner_len);
-+    session->local.banner[banner_len] = '\0';
-+    _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting local Banner: %s",
-+                   session->local.banner);
-+    session->local.banner[banner_len++] = '\r';
-+    session->local.banner[banner_len++] = '\n';
-+    session->local.banner[banner_len++] = '\0';
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ proto libssh2_session_init
-+ * Allocate and initialize a libssh2 session structure
-+ * Allows for malloc callbacks in case the calling program has its own memory manager
-+ * It's allowable (but unadvisable) to define some but not all of the malloc callbacks
-+ * An additional pointer value may be optionally passed to be sent to the callbacks (so they know who's asking)
-+ */
-+LIBSSH2_API LIBSSH2_SESSION *
-+libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
-+                        LIBSSH2_FREE_FUNC((*my_free)),
-+                        LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract)
-+{
-+    LIBSSH2_ALLOC_FUNC((*local_alloc)) = libssh2_default_alloc;
-+    LIBSSH2_FREE_FUNC((*local_free)) = libssh2_default_free;
-+    LIBSSH2_REALLOC_FUNC((*local_realloc)) = libssh2_default_realloc;
-+    LIBSSH2_SESSION *session;
-+
-+    if (my_alloc) {
-+        local_alloc = my_alloc;
-+    }
-+    if (my_free) {
-+        local_free = my_free;
-+    }
-+    if (my_realloc) {
-+        local_realloc = my_realloc;
-+    }
-+
-+    session = local_alloc(sizeof(LIBSSH2_SESSION), abstract);
-+    if (session) {
-+        memset(session, 0, sizeof(LIBSSH2_SESSION));
-+        session->alloc = local_alloc;
-+        session->free = local_free;
-+        session->realloc = local_realloc;
-+        session->abstract = abstract;
-+        _libssh2_debug(session, LIBSSH2_DBG_TRANS,
-+                       "New session resource allocated");
-+        libssh2_crypto_init();
-+    }
-+    return session;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_session_callback_set
-+ * Set (or reset) a callback function
-+ * Returns the prior address
-+ *
-+ * FIXME: this function relies on that we can typecast function pointers
-+ * to void pointers, which isn't allowed in ISO C!
-+ */
-+LIBSSH2_API void *
-+libssh2_session_callback_set(LIBSSH2_SESSION * session,
-+                             int cbtype, void *callback)
-+{
-+    void *oldcb;
-+
-+    switch (cbtype) {
-+    case LIBSSH2_CALLBACK_IGNORE:
-+        oldcb = session->ssh_msg_ignore;
-+        session->ssh_msg_ignore = callback;
-+        return oldcb;
-+
-+    case LIBSSH2_CALLBACK_DEBUG:
-+        oldcb = session->ssh_msg_debug;
-+        session->ssh_msg_debug = callback;
-+        return oldcb;
-+
-+    case LIBSSH2_CALLBACK_DISCONNECT:
-+        oldcb = session->ssh_msg_disconnect;
-+        session->ssh_msg_disconnect = callback;
-+        return oldcb;
-+
-+    case LIBSSH2_CALLBACK_MACERROR:
-+        oldcb = session->macerror;
-+        session->macerror = callback;
-+        return oldcb;
-+
-+    case LIBSSH2_CALLBACK_X11:
-+        oldcb = session->x11;
-+        session->x11 = callback;
-+        return oldcb;
-+
-+    }
-+    _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting Callback %d", cbtype);
-+
-+    return NULL;
-+}
-+
-+/* }}} */
-+
-+/* {{{ proto libssh2_session_startup
-+ * session: LIBSSH2_SESSION struct allocated and owned by the calling program
-+ * Returns: 0 on success, or non-zero on failure
-+ * Any memory allocated by libssh2 will use alloc/realloc/free
-+ * callbacks in session
-+ * socket *must* be populated with an opened and connected socket.
-+ */
-+LIBSSH2_API int
-+libssh2_session_startup(LIBSSH2_SESSION * session, int sock)
-+{
-+    int rc;
-+
-+    if (session->startup_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_TRANS,
-+                       "session_startup for socket %d", sock);
-+        /* FIXME: on some platforms (like win32) sockets are unsigned */
-+        if (sock < 0) {
-+            /* Did we forget something? */
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE,
-+                          "Bad socket provided", 0);
-+            return LIBSSH2_ERROR_SOCKET_NONE;
-+        }
-+        session->socket_fd = sock;
-+
-+        session->socket_block =
-+            !_libssh2_get_socket_nonblocking(session->socket_fd);
-+        if (session->socket_block) {
-+            /*
-+             * Since we can't be sure that we are in blocking or there
-+             * was an error detecting the state, so set to blocking to
-+             * be sure
-+             */
-+            _libssh2_nonblock(session->socket_fd, 0);
-+        }
-+
-+        session->startup_state = libssh2_NB_state_created;
-+    }
-+
-+    /* TODO: Liveness check */
-+
-+    if (session->startup_state == libssh2_NB_state_created) {
-+        rc = libssh2_banner_send(session);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block sending banner to remote host", 0);
-+            return LIBSSH2_ERROR_EAGAIN;
-+        } else if (rc) {
-+            /* Unable to send banner? */
-+            libssh2_error(session, LIBSSH2_ERROR_BANNER_SEND,
-+                          "Error sending banner to remote host", 0);
-+            return LIBSSH2_ERROR_BANNER_SEND;
-+        }
-+
-+        session->startup_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (session->startup_state == libssh2_NB_state_sent) {
-+        rc = libssh2_banner_receive(session);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block waiting for banner", 0);
-+            return LIBSSH2_ERROR_EAGAIN;
-+        } else if (rc) {
-+            /* Unable to receive banner from remote */
-+            libssh2_error(session, LIBSSH2_ERROR_BANNER_NONE,
-+                          "Timeout waiting for banner", 0);
-+            return LIBSSH2_ERROR_BANNER_NONE;
-+        }
-+
-+        session->startup_state = libssh2_NB_state_sent1;
-+    }
-+
-+    if (session->startup_state == libssh2_NB_state_sent1) {
-+        rc = libssh2_kex_exchange(session, 0, &session->startup_key_state);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block exchanging encryption keys", 0);
-+            return LIBSSH2_ERROR_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE,
-+                          "Unable to exchange encryption keys", 0);
-+            return LIBSSH2_ERROR_KEX_FAILURE;
-+        }
-+
-+        session->startup_state = libssh2_NB_state_sent2;
-+    }
-+
-+    if (session->startup_state == libssh2_NB_state_sent2) {
-+        _libssh2_debug(session, LIBSSH2_DBG_TRANS,
-+                       "Requesting userauth service");
-+
-+        /* Request the userauth service */
-+        session->startup_service[0] = SSH_MSG_SERVICE_REQUEST;
-+        libssh2_htonu32(session->startup_service + 1,
-+                        sizeof("ssh-userauth") - 1);
-+        memcpy(session->startup_service + 5, "ssh-userauth",
-+               sizeof("ssh-userauth") - 1);
-+
-+        session->startup_state = libssh2_NB_state_sent3;
-+    }
-+
-+    if (session->startup_state == libssh2_NB_state_sent3) {
-+        rc = libssh2_packet_write(session, session->startup_service,
-+                                  sizeof("ssh-userauth") + 5 - 1);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block asking for ssh-userauth service", 0);
-+            return LIBSSH2_ERROR_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to ask for ssh-userauth service", 0);
-+            return LIBSSH2_ERROR_SOCKET_SEND;
-+        }
-+
-+        session->startup_state = libssh2_NB_state_sent4;
-+    }
-+
-+    if (session->startup_state == libssh2_NB_state_sent4) {
-+        rc = libssh2_packet_require_ex(session, SSH_MSG_SERVICE_ACCEPT,
-+                                       &session->startup_data,
-+                                       &session->startup_data_len, 0, NULL, 0,
-+                                       &session->startup_req_state);
-+        if (rc == PACKET_EAGAIN) {
-+            return LIBSSH2_ERROR_EAGAIN;
-+        } else if (rc) {
-+            return LIBSSH2_ERROR_SOCKET_DISCONNECT;
-+        }
-+        session->startup_service_length =
-+            libssh2_ntohu32(session->startup_data + 1);
-+
-+        if ((session->startup_service_length != (sizeof("ssh-userauth") - 1))
-+            || strncmp("ssh-userauth", (char *) session->startup_data + 5,
-+                       session->startup_service_length)) {
-+            LIBSSH2_FREE(session, session->startup_data);
-+            session->startup_data = NULL;
-+            libssh2_error(session, LIBSSH2_ERROR_PROTO,
-+                          "Invalid response received from server", 0);
-+            return LIBSSH2_ERROR_PROTO;
-+        }
-+        LIBSSH2_FREE(session, session->startup_data);
-+        session->startup_data = NULL;
-+
-+        session->startup_state = libssh2_NB_state_idle;
-+
-+        return 0;
-+    }
-+
-+    /* just for safety return some error */
-+    return LIBSSH2_ERROR_INVAL;
-+}
-+
-+/* }}} */
-+
-+/* {{{ proto libssh2_session_free
-+ * Frees the memory allocated to the session
-+ * Also closes and frees any channels attached to this session
-+ */
-+LIBSSH2_API int
-+libssh2_session_free(LIBSSH2_SESSION * session)
-+{
-+    int rc;
-+
-+    if (session->free_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource",
-+                       session->remote.banner);
-+
-+        session->state = libssh2_NB_state_created;
-+    }
-+
-+    if (session->free_state == libssh2_NB_state_created) {
-+        while (session->channels.head) {
-+            LIBSSH2_CHANNEL *tmp = session->channels.head;
-+
-+            rc = libssh2_channel_free(session->channels.head);
-+            if (rc == PACKET_EAGAIN) {
-+                return PACKET_EAGAIN;
-+            }
-+            if (tmp == session->channels.head) {
-+                /* channel_free couldn't do it's job, perform a messy cleanup */
-+                tmp = session->channels.head;
-+
-+                /* unlink */
-+                session->channels.head = tmp->next;
-+
-+                /* free */
-+                LIBSSH2_FREE(session, tmp);
-+
-+                /* reverse linking isn't important here, we're killing the structure */
-+            }
-+        }
-+
-+        session->state = libssh2_NB_state_sent;
-+    }
-+
-+    if (session->state == libssh2_NB_state_sent) {
-+        while (session->listeners) {
-+            rc = libssh2_channel_forward_cancel(session->listeners);
-+            if (rc == PACKET_EAGAIN) {
-+                return PACKET_EAGAIN;
-+            }
-+        }
-+
-+        session->state = libssh2_NB_state_sent1;
-+    }
-+
-+    if (session->state & LIBSSH2_STATE_NEWKEYS) {
-+        /* hostkey */
-+        if (session->hostkey && session->hostkey->dtor) {
-+            session->hostkey->dtor(session, &session->server_hostkey_abstract);
-+        }
-+
-+        /* Client to Server */
-+        /* crypt */
-+        if (session->local.crypt && session->local.crypt->dtor) {
-+            session->local.crypt->dtor(session,
-+                                       &session->local.crypt_abstract);
-+        }
-+        /* comp */
-+        if (session->local.comp && session->local.comp->dtor) {
-+            session->local.comp->dtor(session, 1,
-+                                      &session->local.comp_abstract);
-+        }
-+        /* mac */
-+        if (session->local.mac && session->local.mac->dtor) {
-+            session->local.mac->dtor(session, &session->local.mac_abstract);
-+        }
-+
-+        /* Server to Client */
-+        /* crypt */
-+        if (session->remote.crypt && session->remote.crypt->dtor) {
-+            session->remote.crypt->dtor(session,
-+                                        &session->remote.crypt_abstract);
-+        }
-+        /* comp */
-+        if (session->remote.comp && session->remote.comp->dtor) {
-+            session->remote.comp->dtor(session, 0,
-+                                       &session->remote.comp_abstract);
-+        }
-+        /* mac */
-+        if (session->remote.mac && session->remote.mac->dtor) {
-+            session->remote.mac->dtor(session, &session->remote.mac_abstract);
-+        }
-+
-+        /* session_id */
-+        if (session->session_id) {
-+            LIBSSH2_FREE(session, session->session_id);
-+        }
-+    }
-+
-+    /* Free banner(s) */
-+    if (session->remote.banner) {
-+        LIBSSH2_FREE(session, session->remote.banner);
-+    }
-+    if (session->local.banner) {
-+        LIBSSH2_FREE(session, session->local.banner);
-+    }
-+
-+    /* Free preference(s) */
-+    if (session->kex_prefs) {
-+        LIBSSH2_FREE(session, session->kex_prefs);
-+    }
-+    if (session->hostkey_prefs) {
-+        LIBSSH2_FREE(session, session->hostkey_prefs);
-+    }
-+
-+    if (session->local.crypt_prefs) {
-+        LIBSSH2_FREE(session, session->local.crypt_prefs);
-+    }
-+    if (session->local.mac_prefs) {
-+        LIBSSH2_FREE(session, session->local.mac_prefs);
-+    }
-+    if (session->local.comp_prefs) {
-+        LIBSSH2_FREE(session, session->local.comp_prefs);
-+    }
-+    if (session->local.lang_prefs) {
-+        LIBSSH2_FREE(session, session->local.lang_prefs);
-+    }
-+
-+    if (session->remote.crypt_prefs) {
-+        LIBSSH2_FREE(session, session->remote.crypt_prefs);
-+    }
-+    if (session->remote.mac_prefs) {
-+        LIBSSH2_FREE(session, session->remote.mac_prefs);
-+    }
-+    if (session->remote.comp_prefs) {
-+        LIBSSH2_FREE(session, session->remote.comp_prefs);
-+    }
-+    if (session->remote.lang_prefs) {
-+        LIBSSH2_FREE(session, session->remote.lang_prefs);
-+    }
-+
-+    /*
-+     * Make sure all memory used in the state variables are free
-+     */
-+    if (session->startup_data) {
-+        LIBSSH2_FREE(session, session->startup_data);
-+    }
-+    if (session->disconnect_data) {
-+        LIBSSH2_FREE(session, session->disconnect_data);
-+    }
-+    if (session->userauth_list_data) {
-+        LIBSSH2_FREE(session, session->userauth_list_data);
-+    }
-+    if (session->userauth_pswd_data) {
-+        LIBSSH2_FREE(session, session->userauth_pswd_data);
-+    }
-+    if (session->userauth_pswd_newpw) {
-+        LIBSSH2_FREE(session, session->userauth_pswd_newpw);
-+    }
-+    if (session->userauth_host_packet) {
-+        LIBSSH2_FREE(session, session->userauth_host_packet);
-+    }
-+    if (session->userauth_host_method) {
-+        LIBSSH2_FREE(session, session->userauth_host_method);
-+    }
-+    if (session->userauth_host_data) {
-+        LIBSSH2_FREE(session, session->userauth_host_data);
-+    }
-+    if (session->userauth_pblc_data) {
-+        LIBSSH2_FREE(session, session->userauth_pblc_data);
-+    }
-+    if (session->userauth_pblc_packet) {
-+        LIBSSH2_FREE(session, session->userauth_pblc_packet);
-+    }
-+    if (session->userauth_pblc_method) {
-+        LIBSSH2_FREE(session, session->userauth_pblc_method);
-+    }
-+    if (session->userauth_kybd_data) {
-+        LIBSSH2_FREE(session, session->userauth_kybd_data);
-+    }
-+    if (session->userauth_kybd_packet) {
-+        LIBSSH2_FREE(session, session->userauth_kybd_packet);
-+    }
-+    if (session->userauth_kybd_auth_instruction) {
-+        LIBSSH2_FREE(session, session->userauth_kybd_auth_instruction);
-+    }
-+    if (session->open_packet) {
-+        LIBSSH2_FREE(session, session->open_packet);
-+    }
-+    if (session->open_data) {
-+        LIBSSH2_FREE(session, session->open_data);
-+    }
-+    if (session->direct_message) {
-+        LIBSSH2_FREE(session, session->direct_message);
-+    }
-+    if (session->fwdLstn_packet) {
-+        LIBSSH2_FREE(session, session->fwdLstn_packet);
-+    }
-+    if (session->pkeyInit_data) {
-+        LIBSSH2_FREE(session, session->pkeyInit_data);
-+    }
-+    if (session->scpRecv_command) {
-+        LIBSSH2_FREE(session, session->scpRecv_command);
-+    }
-+    if (session->scpSend_command) {
-+        LIBSSH2_FREE(session, session->scpSend_command);
-+    }
-+    if (session->scpRecv_err_msg) {
-+        LIBSSH2_FREE(session, session->scpRecv_err_msg);
-+    }
-+    if (session->scpSend_err_msg) {
-+        LIBSSH2_FREE(session, session->scpSend_err_msg);
-+    }
-+
-+    /* Free the error message, if we ar supposed to */
-+    if (session->err_msg && session->err_should_free) {
-+        LIBSSH2_FREE(session, session->err_msg);
-+    }
-+
-+    /* Cleanup any remaining packets */
-+    while (session->packets.head) {
-+        LIBSSH2_PACKET *tmp = session->packets.head;
-+
-+        /* unlink */
-+        session->packets.head = tmp->next;
-+
-+        /* free */
-+        LIBSSH2_FREE(session, tmp->data);
-+        LIBSSH2_FREE(session, tmp);
-+    }
-+
-+    LIBSSH2_FREE(session, session);
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_session_disconnect_ex
-+ */
-+LIBSSH2_API int
-+libssh2_session_disconnect_ex(LIBSSH2_SESSION * session, int reason,
-+                              const char *description, const char *lang)
-+{
-+    unsigned char *s;
-+    unsigned long descr_len = 0, lang_len = 0;
-+    int rc;
-+
-+    if (session->disconnect_state == libssh2_NB_state_idle) {
-+        _libssh2_debug(session, LIBSSH2_DBG_TRANS,
-+                       "Disconnecting: reason=%d, desc=%s, lang=%s", reason,
-+                       description, lang);
-+        if (description) {
-+            descr_len = strlen(description);
-+        }
-+        if (lang) {
-+            lang_len = strlen(lang);
-+        }
-+        /* 13 = packet_type(1) + reason code(4) + descr_len(4) + lang_len(4) */
-+        session->disconnect_data_len = descr_len + lang_len + 13;
-+
-+        s = session->disconnect_data =
-+            LIBSSH2_ALLOC(session, session->disconnect_data_len);
-+        if (!session->disconnect_data) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for disconnect packet",
-+                          0);
-+            session->disconnect_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+
-+        *(s++) = SSH_MSG_DISCONNECT;
-+        libssh2_htonu32(s, reason);
-+        s += 4;
-+
-+        libssh2_htonu32(s, descr_len);
-+        s += 4;
-+        if (description) {
-+            memcpy(s, description, descr_len);
-+            s += descr_len;
-+        }
-+
-+        libssh2_htonu32(s, lang_len);
-+        s += 4;
-+        if (lang) {
-+            memcpy(s, lang, lang_len);
-+            s += lang_len;
-+        }
-+
-+        session->disconnect_state = libssh2_NB_state_created;
-+    }
-+
-+    rc = libssh2_packet_write(session, session->disconnect_data,
-+                              session->disconnect_data_len);
-+    if (rc == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    }
-+
-+    LIBSSH2_FREE(session, session->disconnect_data);
-+    session->disconnect_data = NULL;
-+    session->disconnect_state = libssh2_NB_state_idle;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_session_methods
-+ * Return the currently active methods for method_type
-+ * NOTE: Currently lang_cs and lang_sc are ALWAYS set to empty string regardless of actual negotiation
-+ * Strings should NOT be freed
-+ */
-+LIBSSH2_API const char *
-+libssh2_session_methods(LIBSSH2_SESSION * session, int method_type)
-+{
-+    /* All methods have char *name as their first element */
-+    const LIBSSH2_KEX_METHOD *method = NULL;
-+
-+    switch (method_type) {
-+    case LIBSSH2_METHOD_KEX:
-+        method = session->kex;
-+        break;
-+
-+    case LIBSSH2_METHOD_HOSTKEY:
-+        method = (LIBSSH2_KEX_METHOD *) session->hostkey;
-+        break;
-+
-+    case LIBSSH2_METHOD_CRYPT_CS:
-+        method = (LIBSSH2_KEX_METHOD *) session->local.crypt;
-+        break;
-+
-+    case LIBSSH2_METHOD_CRYPT_SC:
-+        method = (LIBSSH2_KEX_METHOD *) session->remote.crypt;
-+        break;
-+
-+    case LIBSSH2_METHOD_MAC_CS:
-+        method = (LIBSSH2_KEX_METHOD *) session->local.mac;
-+        break;
-+
-+    case LIBSSH2_METHOD_MAC_SC:
-+        method = (LIBSSH2_KEX_METHOD *) session->remote.mac;
-+        break;
-+
-+    case LIBSSH2_METHOD_COMP_CS:
-+        method = (LIBSSH2_KEX_METHOD *) session->local.comp;
-+        break;
-+
-+    case LIBSSH2_METHOD_COMP_SC:
-+        method = (LIBSSH2_KEX_METHOD *) session->remote.comp;
-+        break;
-+
-+    case LIBSSH2_METHOD_LANG_CS:
-+        return "";
-+        break;
-+
-+    case LIBSSH2_METHOD_LANG_SC:
-+        return "";
-+        break;
-+
-+    default:
-+        libssh2_error(session, LIBSSH2_ERROR_INVAL,
-+                      "Invalid parameter specified for method_type", 0);
-+        return NULL;
-+        break;
-+    }
-+
-+    if (!method) {
-+        libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE,
-+                      "No method negotiated", 0);
-+        return NULL;
-+    }
-+
-+    return method->name;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_session_abstract
-+ * Retrieve a pointer to the abstract property
-+ */
-+LIBSSH2_API void **
-+libssh2_session_abstract(LIBSSH2_SESSION * session)
-+{
-+    return &session->abstract;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_session_last_error
-+ * Returns error code and populates an error string into errmsg
-+ * If want_buf is non-zero then the string placed into errmsg must be freed by the calling program
-+ * Otherwise it is assumed to be owned by libssh2
-+ */
-+LIBSSH2_API int
-+libssh2_session_last_error(LIBSSH2_SESSION * session, char **errmsg,
-+                           int *errmsg_len, int want_buf)
-+{
-+    /* No error to report */
-+    if (!session->err_code) {
-+        if (errmsg) {
-+            if (want_buf) {
-+                *errmsg = LIBSSH2_ALLOC(session, 1);
-+                if (*errmsg) {
-+                    **errmsg = 0;
-+                }
-+            } else {
-+                *errmsg = (char *) "";
-+            }
-+        }
-+        if (errmsg_len) {
-+            *errmsg_len = 0;
-+        }
-+        return 0;
-+    }
-+
-+    if (errmsg) {
-+        char *serrmsg = session->err_msg ? session->err_msg : (char *) "";
-+        int ownbuf = session->err_msg ? session->err_should_free : 0;
-+
-+        if (want_buf) {
-+            if (ownbuf) {
-+                /* Just give the calling program the buffer */
-+                *errmsg = serrmsg;
-+                session->err_should_free = 0;
-+            } else {
-+                /* Make a copy so the calling program can own it */
-+                *errmsg = LIBSSH2_ALLOC(session, session->err_msglen + 1);
-+                if (*errmsg) {
-+                    memcpy(*errmsg, session->err_msg, session->err_msglen);
-+                    (*errmsg)[session->err_msglen] = 0;
-+                }
-+            }
-+        } else {
-+            *errmsg = serrmsg;
-+        }
-+    }
-+
-+    if (errmsg_len) {
-+        *errmsg_len = session->err_msglen;
-+    }
-+
-+    return session->err_code;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_session_last_error
-+* Returns error code
-+*/
-+LIBSSH2_API int
-+libssh2_session_last_errno(LIBSSH2_SESSION * session)
-+{
-+    return session->err_code;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_session_flag
-+ * Set/Get session flags
-+ * Passing flag==0 will avoid changing session->flags while still returning its current value
-+ */
-+LIBSSH2_API int
-+libssh2_session_flag(LIBSSH2_SESSION * session, int flag, int value)
-+{
-+    if (value) {
-+        session->flags |= flag;
-+    } else {
-+        session->flags &= ~flag;
-+    }
-+
-+    return session->flags;
-+}
-+
-+/* }}} */
-+
-+/* {{{ _libssh2_session_set_blocking
-+ * Set a session's blocking mode on or off, return the previous status
-+ * when this function is called.
-+ */
-+int
-+_libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking)
-+{
-+    int bl = session->socket_block;
-+    _libssh2_debug(session, LIBSSH2_DBG_CONN,
-+                   "Setting blocking mode on session %d", blocking);
-+    if (blocking == session->socket_block) {
-+        /* avoid if already correct */
-+        return bl;
-+    }
-+    session->socket_block = blocking;
-+
-+    _libssh2_nonblock(session->socket_fd, !blocking);
-+
-+    return bl;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_session_set_blocking
-+ * Set a channel's blocking mode on or off, similar to a socket's
-+ * fcntl(fd, F_SETFL, O_NONBLOCK); type command
-+ */
-+LIBSSH2_API void
-+libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking)
-+{
-+    (void) _libssh2_session_set_blocking(session, blocking);
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_session_get_blocking
-+* Returns a session's blocking mode on or off
-+*/
-+LIBSSH2_API int
-+libssh2_session_get_blocking(LIBSSH2_SESSION * session)
-+{
-+    return session->socket_block;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_poll_channel_read
-+ * Returns 0 if no data is waiting on channel,
-+ * non-0 if data is available
-+ */
-+LIBSSH2_API int
-+libssh2_poll_channel_read(LIBSSH2_CHANNEL * channel, int extended)
-+{
-+    LIBSSH2_SESSION *session = channel->session;
-+    LIBSSH2_PACKET *packet = session->packets.head;
-+
-+    while (packet) 
-+      {
-+              if ( channel->local.id == libssh2_ntohu32(packet->data + 1)) {
-+                      if ( extended == 1 &&
-+                              (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA 
-+                              || packet->data[0] == SSH_MSG_CHANNEL_DATA )) {
-+                              return 1;
-+                      } else if ( extended == 0 && 
-+                              packet->data[0] == SSH_MSG_CHANNEL_DATA) {
-+                              return 1;
-+                      }
-+                      /* else - no data of any type is ready to be read */
-+        }
-+        packet = packet->next;
-+    }
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_poll_channel_write
-+ * Returns 0 if writing to channel would block,
-+ * non-0 if data can be written without blocking
-+ */
-+static inline int
-+libssh2_poll_channel_write(LIBSSH2_CHANNEL * channel)
-+{
-+    return channel->local.window_size ? 1 : 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_poll_listener_queued
-+ * Returns 0 if no connections are waiting to be accepted
-+ * non-0 if one or more connections are available
-+ */
-+static inline int
-+libssh2_poll_listener_queued(LIBSSH2_LISTENER * listener)
-+{
-+    return listener->queue ? 1 : 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_poll
-+ * Poll sockets, channels, and listeners for activity
-+ */
-+LIBSSH2_API int
-+libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
-+{
-+    long timeout_remaining;
-+    unsigned int i, active_fds;
-+#ifdef HAVE_POLL
-+    LIBSSH2_SESSION *session = NULL;
-+#ifdef HAVE_ALLOCA
-+    struct pollfd *sockets = alloca(sizeof(struct pollfd) * nfds);
-+#else
-+    struct pollfd sockets[256];
-+
-+    if (nfds > 256)
-+        /* systems without alloca use a fixed-size array, this can be fixed
-+           if we really want to, at least if the compiler is a C99 capable one */
-+        return -1;
-+#endif
-+    /* Setup sockets for polling */
-+    for(i = 0; i < nfds; i++) {
-+        fds[i].revents = 0;
-+        switch (fds[i].type) {
-+        case LIBSSH2_POLLFD_SOCKET:
-+            sockets[i].fd = fds[i].fd.socket;
-+            sockets[i].events = fds[i].events;
-+            sockets[i].revents = 0;
-+            break;
-+
-+        case LIBSSH2_POLLFD_CHANNEL:
-+            sockets[i].fd = fds[i].fd.channel->session->socket_fd;
-+            sockets[i].events = POLLIN;
-+            sockets[i].revents = 0;
-+            if (!session)
-+                session = fds[i].fd.channel->session;
-+            break;
-+
-+        case LIBSSH2_POLLFD_LISTENER:
-+            sockets[i].fd = fds[i].fd.listener->session->socket_fd;
-+            sockets[i].events = POLLIN;
-+            sockets[i].revents = 0;
-+            if (!session)
-+                session = fds[i].fd.listener->session;
-+            break;
-+
-+        default:
-+            if (session)
-+                libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
-+                              "Invalid descriptor passed to libssh2_poll()",
-+                              0);
-+            return -1;
-+        }
-+    }
-+#elif defined(HAVE_SELECT)
-+    LIBSSH2_SESSION *session = NULL;
-+    int maxfd = 0;
-+    fd_set rfds, wfds;
-+    struct timeval tv;
-+
-+    FD_ZERO(&rfds);
-+    FD_ZERO(&wfds);
-+    for(i = 0; i < nfds; i++) {
-+        fds[i].revents = 0;
-+        switch (fds[i].type) {
-+        case LIBSSH2_POLLFD_SOCKET:
-+            if (fds[i].events & LIBSSH2_POLLFD_POLLIN) {
-+                FD_SET(fds[i].fd.socket, &rfds);
-+                if (fds[i].fd.socket > maxfd)
-+                    maxfd = fds[i].fd.socket;
-+            }
-+            if (fds[i].events & LIBSSH2_POLLFD_POLLOUT) {
-+                FD_SET(fds[i].fd.socket, &wfds);
-+                if (fds[i].fd.socket > maxfd)
-+                    maxfd = fds[i].fd.socket;
-+            }
-+            break;
-+
-+        case LIBSSH2_POLLFD_CHANNEL:
-+            FD_SET(fds[i].fd.channel->session->socket_fd, &rfds);
-+            if (fds[i].fd.channel->session->socket_fd > maxfd)
-+                maxfd = fds[i].fd.channel->session->socket_fd;
-+            if (!session)
-+                session = fds[i].fd.channel->session;
-+            break;
-+
-+        case LIBSSH2_POLLFD_LISTENER:
-+            FD_SET(fds[i].fd.listener->session->socket_fd, &rfds);
-+            if (fds[i].fd.listener->session->socket_fd > maxfd)
-+                maxfd = fds[i].fd.listener->session->socket_fd;
-+            if (!session)
-+                session = fds[i].fd.listener->session;
-+            break;
-+
-+        default:
-+            if (session)
-+                libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
-+                              "Invalid descriptor passed to libssh2_poll()",
-+                              0);
-+            return -1;
-+        }
-+    }
-+#else
-+    /* No select() or poll()
-+     * no sockets sturcture to setup
-+     */
-+
-+    timeout = 0;
-+#endif /* HAVE_POLL or HAVE_SELECT */
-+
-+    timeout_remaining = timeout;
-+    do {
-+#if defined(HAVE_POLL) || defined(HAVE_SELECT)
-+        int sysret;
-+#endif
-+
-+        active_fds = 0;
-+
-+        for(i = 0; i < nfds; i++) {
-+            if (fds[i].events != fds[i].revents) {
-+                switch (fds[i].type) {
-+                case LIBSSH2_POLLFD_CHANNEL:
-+                    if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) &&      /* Want to be ready for read */
-+                        ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) {      /* Not yet known to be ready for read */
-+                        fds[i].revents |=
-+                            libssh2_poll_channel_read(fds[i].fd.channel,
-+                                                      0) ?
-+                            LIBSSH2_POLLFD_POLLIN : 0;
-+                    }
-+                    if ((fds[i].events & LIBSSH2_POLLFD_POLLEXT) &&     /* Want to be ready for extended read */
-+                        ((fds[i].revents & LIBSSH2_POLLFD_POLLEXT) == 0)) {     /* Not yet known to be ready for extended read */
-+                        fds[i].revents |=
-+                            libssh2_poll_channel_read(fds[i].fd.channel,
-+                                                      1) ?
-+                            LIBSSH2_POLLFD_POLLEXT : 0;
-+                    }
-+                    if ((fds[i].events & LIBSSH2_POLLFD_POLLOUT) &&     /* Want to be ready for write */
-+                        ((fds[i].revents & LIBSSH2_POLLFD_POLLOUT) == 0)) {     /* Not yet known to be ready for write */
-+                        fds[i].revents |=
-+                            libssh2_poll_channel_write(fds[i].fd.
-+                                                       channel) ?
-+                            LIBSSH2_POLLFD_POLLOUT : 0;
-+                    }
-+                    if (fds[i].fd.channel->remote.close
-+                        || fds[i].fd.channel->local.close) {
-+                        fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED;
-+                    }
-+                    if (fds[i].fd.channel->session->socket_state ==
-+                        LIBSSH2_SOCKET_DISCONNECTED) {
-+                        fds[i].revents |=
-+                            LIBSSH2_POLLFD_CHANNEL_CLOSED |
-+                            LIBSSH2_POLLFD_SESSION_CLOSED;
-+                    }
-+                    break;
-+
-+                case LIBSSH2_POLLFD_LISTENER:
-+                    if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) &&      /* Want a connection */
-+                        ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) {      /* No connections known of yet */
-+                        fds[i].revents |=
-+                            libssh2_poll_listener_queued(fds[i].fd.
-+                                                         listener) ?
-+                            LIBSSH2_POLLFD_POLLIN : 0;
-+                    }
-+                    if (fds[i].fd.listener->session->socket_state ==
-+                        LIBSSH2_SOCKET_DISCONNECTED) {
-+                        fds[i].revents |=
-+                            LIBSSH2_POLLFD_LISTENER_CLOSED |
-+                            LIBSSH2_POLLFD_SESSION_CLOSED;
-+                    }
-+                    break;
-+                }
-+            }
-+            if (fds[i].revents) {
-+                active_fds++;
-+            }
-+        }
-+
-+        if (active_fds) {
-+            /* Don't block on the sockets if we have channels/listeners which are ready */
-+            timeout_remaining = 0;
-+        }
-+#ifdef HAVE_POLL
-+
-+#ifdef HAVE_GETTIMEOFDAY
-+        {
-+            struct timeval tv_begin, tv_end;
-+
-+            gettimeofday((struct timeval *) &tv_begin, NULL);
-+            sysret = poll(sockets, nfds, timeout_remaining);
-+            gettimeofday((struct timeval *) &tv_end, NULL);
-+            timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000;
-+            timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000;
-+        }
-+#else
-+        /* If the platform doesn't support gettimeofday,
-+         * then just make the call non-blocking and walk away
-+         */
-+        sysret = poll(sockets, nfds, timeout_remaining);
-+        timeout_remaining = 0;
-+#endif /* HAVE_GETTIMEOFDAY */
-+
-+        if (sysret > 0) {
-+            for(i = 0; i < nfds; i++) {
-+                switch (fds[i].type) {
-+                case LIBSSH2_POLLFD_SOCKET:
-+                    fds[i].revents = sockets[i].revents;
-+                    sockets[i].revents = 0;     /* In case we loop again, be nice */
-+                    if (fds[i].revents) {
-+                        active_fds++;
-+                    }
-+                    break;
-+                case LIBSSH2_POLLFD_CHANNEL:
-+                    if (sockets[i].events & POLLIN) {
-+                        /* Spin session until no data available */
-+                        while (libssh2_packet_read(fds[i].fd.channel->session)
-+                               > 0);
-+                    }
-+                    if (sockets[i].revents & POLLHUP) {
-+                        fds[i].revents |=
-+                            LIBSSH2_POLLFD_CHANNEL_CLOSED |
-+                            LIBSSH2_POLLFD_SESSION_CLOSED;
-+                    }
-+                    sockets[i].revents = 0;
-+                    break;
-+                case LIBSSH2_POLLFD_LISTENER:
-+                    if (sockets[i].events & POLLIN) {
-+                        /* Spin session until no data available */
-+                        while (libssh2_packet_read(fds[i].fd.listener->session)
-+                               > 0);
-+                    }
-+                    if (sockets[i].revents & POLLHUP) {
-+                        fds[i].revents |=
-+                            LIBSSH2_POLLFD_LISTENER_CLOSED |
-+                            LIBSSH2_POLLFD_SESSION_CLOSED;
-+                    }
-+                    sockets[i].revents = 0;
-+                    break;
-+                }
-+            }
-+        }
-+#elif defined(HAVE_SELECT)
-+        tv.tv_sec = timeout_remaining / 1000;
-+        tv.tv_usec = (timeout_remaining % 1000) * 1000;
-+#ifdef HAVE_GETTIMEOFDAY
-+        {
-+            struct timeval tv_begin, tv_end;
-+
-+            gettimeofday((struct timeval *) &tv_begin, NULL);
-+            sysret = select(maxfd+1, &rfds, &wfds, NULL, &tv);
-+            gettimeofday((struct timeval *) &tv_end, NULL);
-+
-+            timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000;
-+            timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000;
-+        }
-+#else
-+        /* If the platform doesn't support gettimeofday,
-+         * then just make the call non-blocking and walk away
-+         */
-+        sysret = select(maxfd+1, &rfds, &wfds, NULL, &tv);
-+        timeout_remaining = 0;
-+#endif
-+
-+        if (sysret > 0) {
-+            for(i = 0; i < nfds; i++) {
-+                switch (fds[i].type) {
-+                case LIBSSH2_POLLFD_SOCKET:
-+                    if (FD_ISSET(fds[i].fd.socket, &rfds)) {
-+                        fds[i].revents |= LIBSSH2_POLLFD_POLLIN;
-+                    }
-+                    if (FD_ISSET(fds[i].fd.socket, &wfds)) {
-+                        fds[i].revents |= LIBSSH2_POLLFD_POLLOUT;
-+                    }
-+                    if (fds[i].revents) {
-+                        active_fds++;
-+                    }
-+                    break;
-+
-+                case LIBSSH2_POLLFD_CHANNEL:
-+                    if (FD_ISSET(fds[i].fd.channel->session->socket_fd, &rfds)) {
-+                        /* Spin session until no data available */
-+                        while (libssh2_packet_read(fds[i].fd.channel->session)
-+                               > 0);
-+                    }
-+                    break;
-+
-+                case LIBSSH2_POLLFD_LISTENER:
-+                    if (FD_ISSET
-+                        (fds[i].fd.listener->session->socket_fd, &rfds)) {
-+                        /* Spin session until no data available */
-+                        while (libssh2_packet_read(fds[i].fd.listener->session)
-+                               > 0);
-+                    }
-+                    break;
-+                }
-+            }
-+        }
-+#endif /* else no select() or poll() -- timeout (and by extension timeout_remaining) will be equal to 0 */
-+    } while ((timeout_remaining > 0) && !active_fds);
-+
-+    return active_fds;
-+}
-+
-+/* {{{ libssh2_session_block_direction
-+ * Get blocked direction when a function returns LIBSSH2_ERROR_EAGAIN
-+ * Returns LIBSSH2_SOCKET_BLOCK_INBOUND if recv() blocked
-+ * or LIBSSH2_SOCKET_BLOCK_OUTBOUND if send() blocked
-+ */
-+LIBSSH2_API int
-+libssh2_session_block_directions(LIBSSH2_SESSION *session)
-+{
-+    return session->socket_block_directions;
-+}
-+
-+/* }}} */
-
-Property changes on: libssh2/src/session.c
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.3
-Added: svn:eol-style
-   + native
-
-Index: libssh2/src/openssl.c
-===================================================================
---- libssh2/src/openssl.c      (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/openssl.c      (.../trunk)
-@@ -0,0 +1,316 @@
-+/* Copyright (C) 2006, 2007 The Written Word, Inc.  All rights reserved.
-+ * Author: Simon Josefsson
-+ * Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#include "libssh2_priv.h"
-+#include <string.h>
-+
-+#ifndef EVP_MAX_BLOCK_LENGTH
-+#define EVP_MAX_BLOCK_LENGTH 32
-+#endif
-+
-+int
-+_libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
-+                 const unsigned char *edata,
-+                 unsigned long elen,
-+                 const unsigned char *ndata,
-+                 unsigned long nlen,
-+                 const unsigned char *ddata,
-+                 unsigned long dlen,
-+                 const unsigned char *pdata,
-+                 unsigned long plen,
-+                 const unsigned char *qdata,
-+                 unsigned long qlen,
-+                 const unsigned char *e1data,
-+                 unsigned long e1len,
-+                 const unsigned char *e2data,
-+                 unsigned long e2len,
-+                 const unsigned char *coeffdata, unsigned long coefflen)
-+{
-+    *rsa = RSA_new();
-+
-+    (*rsa)->e = BN_new();
-+    BN_bin2bn(edata, elen, (*rsa)->e);
-+
-+    (*rsa)->n = BN_new();
-+    BN_bin2bn(ndata, nlen, (*rsa)->n);
-+
-+    if (ddata) {
-+        (*rsa)->d = BN_new();
-+        BN_bin2bn(ddata, dlen, (*rsa)->d);
-+
-+        (*rsa)->p = BN_new();
-+        BN_bin2bn(pdata, plen, (*rsa)->p);
-+
-+        (*rsa)->q = BN_new();
-+        BN_bin2bn(qdata, qlen, (*rsa)->q);
-+
-+        (*rsa)->dmp1 = BN_new();
-+        BN_bin2bn(e1data, e1len, (*rsa)->dmp1);
-+
-+        (*rsa)->dmq1 = BN_new();
-+        BN_bin2bn(e2data, e2len, (*rsa)->dmq1);
-+
-+        (*rsa)->iqmp = BN_new();
-+        BN_bin2bn(coeffdata, coefflen, (*rsa)->iqmp);
-+    }
-+    return 0;
-+}
-+
-+int
-+_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsactx,
-+                         const unsigned char *sig,
-+                         unsigned long sig_len,
-+                         const unsigned char *m, unsigned long m_len)
-+{
-+    unsigned char hash[SHA_DIGEST_LENGTH];
-+    int ret;
-+
-+    SHA1(m, m_len, hash);
-+    ret = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH,
-+                     (unsigned char *) sig, sig_len, rsactx);
-+    return (ret == 1) ? 0 : -1;
-+}
-+
-+int
-+_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
-+                 const unsigned char *p,
-+                 unsigned long p_len,
-+                 const unsigned char *q,
-+                 unsigned long q_len,
-+                 const unsigned char *g,
-+                 unsigned long g_len,
-+                 const unsigned char *y,
-+                 unsigned long y_len,
-+                 const unsigned char *x, unsigned long x_len)
-+{
-+    *dsactx = DSA_new();
-+
-+    (*dsactx)->p = BN_new();
-+    BN_bin2bn(p, p_len, (*dsactx)->p);
-+
-+    (*dsactx)->q = BN_new();
-+    BN_bin2bn(q, q_len, (*dsactx)->q);
-+
-+    (*dsactx)->g = BN_new();
-+    BN_bin2bn(g, g_len, (*dsactx)->g);
-+
-+    (*dsactx)->pub_key = BN_new();
-+    BN_bin2bn(y, y_len, (*dsactx)->pub_key);
-+
-+    if (x_len) {
-+        (*dsactx)->priv_key = BN_new();
-+        BN_bin2bn(x, x_len, (*dsactx)->priv_key);
-+    }
-+
-+    return 0;
-+}
-+
-+int
-+_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
-+                         const unsigned char *sig,
-+                         const unsigned char *m, unsigned long m_len)
-+{
-+    unsigned char hash[SHA_DIGEST_LENGTH];
-+    DSA_SIG dsasig;
-+    int ret;
-+
-+    dsasig.r = BN_new();
-+    BN_bin2bn(sig, 20, dsasig.r);
-+    dsasig.s = BN_new();
-+    BN_bin2bn(sig + 20, 20, dsasig.s);
-+
-+    libssh2_sha1(m, m_len, hash);
-+    ret = DSA_do_verify(hash, SHA_DIGEST_LENGTH, &dsasig, dsactx);
-+    BN_clear_free(dsasig.s);
-+    BN_clear_free(dsasig.r);
-+
-+    return (ret == 1) ? 0 : -1;
-+}
-+
-+int
-+_libssh2_cipher_init(_libssh2_cipher_ctx * h,
-+                     _libssh2_cipher_type(algo),
-+                     unsigned char *iv, unsigned char *secret, int encrypt)
-+{
-+    EVP_CIPHER_CTX_init(h);
-+    EVP_CipherInit(h, algo(), secret, iv, encrypt);
-+    return 0;
-+}
-+
-+int
-+_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
-+                      _libssh2_cipher_type(algo),
-+                      int encrypt, unsigned char *block)
-+{
-+    int blocksize = ctx->cipher->block_size;
-+    unsigned char buf[EVP_MAX_BLOCK_LENGTH];
-+    int ret;
-+    (void) algo;
-+    (void) encrypt;
-+
-+    if (blocksize == 1) {
-+/* Hack for arcfour. */
-+        blocksize = 8;
-+    }
-+    ret = EVP_Cipher(ctx, buf, block, blocksize);
-+    if (ret == 1) {
-+        memcpy(block, buf, blocksize);
-+    }
-+    return ret == 1 ? 0 : 1;
-+}
-+
-+/* TODO: Optionally call a passphrase callback specified by the
-+ * calling program
-+ */
-+static int
-+passphrase_cb(char *buf, int size, int rwflag, char *passphrase)
-+{
-+    int passphrase_len = strlen(passphrase);
-+    (void) rwflag;
-+
-+    if (passphrase_len > (size - 1)) {
-+        passphrase_len = size - 1;
-+    }
-+    memcpy(buf, passphrase, passphrase_len);
-+    buf[passphrase_len] = '\0';
-+
-+    return passphrase_len;
-+}
-+
-+int
-+_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
-+                         LIBSSH2_SESSION * session,
-+                         FILE * fp, unsigned const char *passphrase)
-+{
-+    (void) session;
-+    if (!EVP_get_cipherbyname("des")) {
-+/* If this cipher isn't loaded it's a pretty good indication that none are.
-+ * I have *NO DOUBT* that there's a better way to deal with this ($#&%#$(%$#(
-+ * Someone buy me an OpenSSL manual and I'll read up on it.
-+ */
-+        OpenSSL_add_all_ciphers();
-+    }
-+    *rsa = PEM_read_RSAPrivateKey(fp, NULL, (void *) passphrase_cb,
-+                                  (void *) passphrase);
-+    if (!*rsa) {
-+        return -1;
-+    }
-+    return 0;
-+}
-+
-+int
-+_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
-+                         LIBSSH2_SESSION * session,
-+                         FILE * fp, unsigned const char *passphrase)
-+{
-+    (void) session;
-+    if (!EVP_get_cipherbyname("des")) {
-+/* If this cipher isn't loaded it's a pretty good indication that none are.
-+ * I have *NO DOUBT* that there's a better way to deal with this ($#&%#$(%$#(
-+ * Someone buy me an OpenSSL manual and I'll read up on it.
-+ */
-+        OpenSSL_add_all_ciphers();
-+    }
-+    *dsa = PEM_read_DSAPrivateKey(fp, NULL, (void *) passphrase_cb,
-+                                  (void *) passphrase);
-+    if (!*dsa) {
-+        return -1;
-+    }
-+    return 0;
-+}
-+
-+int
-+_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
-+                       libssh2_rsa_ctx * rsactx,
-+                       const unsigned char *hash,
-+                       unsigned long hash_len,
-+                       unsigned char **signature, unsigned long *signature_len)
-+{
-+    int ret;
-+    unsigned char *sig;
-+    unsigned int sig_len;
-+
-+    sig_len = RSA_size(rsactx);
-+    sig = LIBSSH2_ALLOC(session, sig_len);
-+
-+    if (!sig) {
-+        return -1;
-+    }
-+
-+    ret = RSA_sign(NID_sha1, hash, hash_len, sig, &sig_len, rsactx);
-+
-+    if (!ret) {
-+        LIBSSH2_FREE(session, sig);
-+        return -1;
-+    }
-+
-+    *signature = sig;
-+    *signature_len = sig_len;
-+
-+    return 0;
-+}
-+
-+int
-+_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
-+                       const unsigned char *hash,
-+                       unsigned long hash_len, unsigned char *signature)
-+{
-+    DSA_SIG *sig;
-+    int r_len, s_len, rs_pad;
-+    (void) hash_len;
-+
-+    sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx);
-+    if (!sig) {
-+        return -1;
-+    }
-+
-+    r_len = BN_num_bytes(sig->r);
-+    s_len = BN_num_bytes(sig->s);
-+    rs_pad = (2 * SHA_DIGEST_LENGTH) - (r_len + s_len);
-+    if (rs_pad < 0) {
-+        DSA_SIG_free(sig);
-+        return -1;
-+    }
-+
-+    BN_bn2bin(sig->r, signature + rs_pad);
-+    BN_bn2bin(sig->s, signature + rs_pad + r_len);
-+
-+    DSA_SIG_free(sig);
-+
-+    return 0;
-+}
-
-Property changes on: libssh2/src/openssl.c
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.1
-Added: svn:eol-style
-   + native
-Added: svn:executable
-   + *
-
-Index: libssh2/src/scp.c
-===================================================================
---- libssh2/src/scp.c  (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/scp.c  (.../trunk)
-@@ -0,0 +1,811 @@
-+/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#include "libssh2_priv.h"
-+#include <errno.h>
-+#include <stdlib.h>
-+
-+/* {{{ libssh2_scp_recv
-+ * Open a channel and request a remote file via SCP
-+ *
-+ * NOTE:  Will block in a busy loop on error.  This has to be done,
-+ *        otherwise the blocking error code would erase the true
-+ *        cause of the error.
-+ */
-+LIBSSH2_API LIBSSH2_CHANNEL *
-+libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
-+{
-+    int path_len = strlen(path);
-+    int rc;
-+
-+    if (session->scpRecv_state == libssh2_NB_state_idle) {
-+        session->scpRecv_mode = 0;
-+        session->scpRecv_size = 0;
-+        session->scpRecv_mtime = 0;
-+        session->scpRecv_atime = 0;
-+
-+        session->scpRecv_command_len = path_len + sizeof("scp -f ");
-+
-+        if (sb) {
-+            session->scpRecv_command_len++;
-+        }
-+
-+        session->scpRecv_command =
-+            LIBSSH2_ALLOC(session, session->scpRecv_command_len);
-+        if (!session->scpRecv_command) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate a command buffer for SCP session",
-+                          0);
-+            return NULL;
-+        }
-+        if (sb) {
-+            memcpy(session->scpRecv_command, "scp -pf ",
-+                   sizeof("scp -pf ") - 1);
-+            memcpy(session->scpRecv_command + sizeof("scp -pf ") - 1, path,
-+                   path_len);
-+        } else {
-+            memcpy(session->scpRecv_command, "scp -f ", sizeof("scp -f ") - 1);
-+            memcpy(session->scpRecv_command + sizeof("scp -f ") - 1, path,
-+                   path_len);
-+        }
-+        session->scpRecv_command[session->scpRecv_command_len - 1] = '\0';
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_SCP,
-+                       "Opening channel for SCP receive");
-+
-+        session->scpRecv_state = libssh2_NB_state_created;
-+    }
-+
-+    if (session->scpRecv_state == libssh2_NB_state_created) {
-+        /* Allocate a channel */
-+        do {
-+            session->scpRecv_channel =
-+                libssh2_channel_open_ex(session, "session",
-+                                        sizeof("session") - 1,
-+                                        LIBSSH2_CHANNEL_WINDOW_DEFAULT,
-+                                        LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL,
-+                                        0);
-+            if (!session->scpRecv_channel) {
-+                if (libssh2_session_last_errno(session) !=
-+                    LIBSSH2_ERROR_EAGAIN) {
-+                    LIBSSH2_FREE(session, session->scpRecv_command);
-+                    session->scpRecv_command = NULL;
-+                    session->scpRecv_state = libssh2_NB_state_idle;
-+                    return NULL;
-+                } else if (libssh2_session_last_errno(session) ==
-+                           LIBSSH2_ERROR_EAGAIN) {
-+                    libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                                  "Would block starting up channel", 0);
-+                    return NULL;
-+                }
-+            }
-+        } while (!session->scpRecv_channel);
-+
-+        session->scpRecv_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (session->scpRecv_state == libssh2_NB_state_sent) {
-+        /* Request SCP for the desired file */
-+        rc = libssh2_channel_process_startup(session->scpRecv_channel, "exec",
-+                                             sizeof("exec") - 1,
-+                                             (char *) session->scpRecv_command,
-+                                             session->scpRecv_command_len);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block requesting SCP startup", 0);
-+            return NULL;
-+        } else if (rc) {
-+            LIBSSH2_FREE(session, session->scpRecv_command);
-+            session->scpRecv_command = NULL;
-+            goto scp_recv_error;
-+        }
-+        LIBSSH2_FREE(session, session->scpRecv_command);
-+        session->scpRecv_command = NULL;
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sending initial wakeup");
-+        /* SCP ACK */
-+        session->scpRecv_response[0] = '\0';
-+
-+        session->scpRecv_state = libssh2_NB_state_sent1;
-+    }
-+
-+    if (session->scpRecv_state == libssh2_NB_state_sent1) {
-+        rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
-+                                      (char *) session->scpRecv_response, 1);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block sending initial wakeup", 0);
-+            return NULL;
-+        } else if (rc != 1) {
-+            goto scp_recv_error;
-+        }
-+
-+        /* Parse SCP response */
-+        session->scpRecv_response_len = 0;
-+
-+        session->scpRecv_state = libssh2_NB_state_sent2;
-+    }
-+
-+    if ((session->scpRecv_state == libssh2_NB_state_sent2)
-+        || (session->scpRecv_state == libssh2_NB_state_sent3)) {
-+        while (sb
-+               && (session->scpRecv_response_len <
-+                   LIBSSH2_SCP_RESPONSE_BUFLEN)) {
-+            unsigned char *s, *p;
-+
-+            if (session->scpRecv_state == libssh2_NB_state_sent2) {
-+                rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
-+                                             (char *) session->
-+                                             scpRecv_response +
-+                                             session->scpRecv_response_len, 1);
-+                if (rc == PACKET_EAGAIN) {
-+                    libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                                  "Would block waiting for SCP response", 0);
-+                    return NULL;
-+                } else if (rc <= 0) {
-+                    /* Timeout, give up */
-+                    libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                  "Timed out waiting for SCP response", 0);
-+                    goto scp_recv_error;
-+                }
-+                session->scpRecv_response_len++;
-+
-+                if (session->scpRecv_response[0] != 'T') {
-+                    /*
-+                     * Set this as the default error for here, if
-+                     * we are successful it will be replaced
-+                     */
-+                    libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                  "Invalid data in SCP response, missing Time data",
-+                                  0);
-+
-+                    session->scpRecv_err_len =
-+                        libssh2_channel_packet_data_len(session->
-+                                                        scpRecv_channel, 0);
-+                    session->scpRecv_err_msg =
-+                        LIBSSH2_ALLOC(session, session->scpRecv_err_len + 1);
-+                    if (!session->scpRecv_err_msg) {
-+                        goto scp_recv_error;
-+                    }
-+                    memset(session->scpRecv_err_msg, 0,
-+                           session->scpRecv_err_len + 1);
-+
-+                    /* Read the remote error message */
-+                    rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
-+                                                 session->scpRecv_err_msg,
-+                                                 session->scpRecv_err_len);
-+                    if (rc <= 0) {
-+                        /*
-+                         * Since we have alread started reading this packet, it is
-+                         * already in the systems so it can't return PACKET_EAGAIN
-+                         */
-+                        LIBSSH2_FREE(session, session->scpRecv_err_msg);
-+                        session->scpRecv_err_msg = NULL;
-+                        libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                      "Unknown error while getting error string",
-+                                      0);
-+                        goto scp_recv_error;
-+                    }
-+
-+                    libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                  session->scpRecv_err_msg, 1);
-+                    session->scpRecv_err_msg = NULL;
-+                    goto scp_recv_error;
-+                }
-+
-+                if ((session->scpRecv_response_len > 1) &&
-+                    ((session->
-+                      scpRecv_response[session->scpRecv_response_len - 1] <
-+                      '0')
-+                     || (session->
-+                         scpRecv_response[session->scpRecv_response_len - 1] >
-+                         '9'))
-+                    && (session->
-+                        scpRecv_response[session->scpRecv_response_len - 1] !=
-+                        ' ')
-+                    && (session->
-+                        scpRecv_response[session->scpRecv_response_len - 1] !=
-+                        '\r')
-+                    && (session->
-+                        scpRecv_response[session->scpRecv_response_len - 1] !=
-+                        '\n')) {
-+                    libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                  "Invalid data in SCP response", 0);
-+                    goto scp_recv_error;
-+                }
-+
-+                if ((session->scpRecv_response_len < 9)
-+                    || (session->
-+                        scpRecv_response[session->scpRecv_response_len - 1] !=
-+                        '\n')) {
-+                    if (session->scpRecv_response_len ==
-+                        LIBSSH2_SCP_RESPONSE_BUFLEN) {
-+                        /* You had your chance */
-+                        libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                      "Unterminated response from SCP server",
-+                                      0);
-+                        goto scp_recv_error;
-+                    }
-+                    /* Way too short to be an SCP response,  or not done yet, short circuit */
-+                    continue;
-+                }
-+
-+                /* We're guaranteed not to go under response_len == 0 by the logic above */
-+                while ((session->
-+                        scpRecv_response[session->scpRecv_response_len - 1] ==
-+                        '\r')
-+                       || (session->
-+                           scpRecv_response[session->scpRecv_response_len -
-+                                            1] == '\n'))
-+                    session->scpRecv_response_len--;
-+                session->scpRecv_response[session->scpRecv_response_len] =
-+                    '\0';
-+
-+                if (session->scpRecv_response_len < 8) {
-+                    /* EOL came too soon */
-+                    libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                  "Invalid response from SCP server, too short",
-+                                  0);
-+                    goto scp_recv_error;
-+                }
-+
-+                s = session->scpRecv_response + 1;
-+
-+                p = (unsigned char *) strchr((char *) s, ' ');
-+                if (!p || ((p - s) <= 0)) {
-+                    /* No spaces or space in the wrong spot */
-+                    libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                  "Invalid response from SCP server, malformed mtime",
-+                                  0);
-+                    goto scp_recv_error;
-+                }
-+
-+                *(p++) = '\0';
-+                /* Make sure we don't get fooled by leftover values */
-+                errno = 0;
-+                session->scpRecv_mtime = strtol((char *) s, NULL, 10);
-+                if (errno) {
-+                    libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                  "Invalid response from SCP server, invalid mtime",
-+                                  0);
-+                    goto scp_recv_error;
-+                }
-+                s = (unsigned char *) strchr((char *) p, ' ');
-+                if (!s || ((s - p) <= 0)) {
-+                    /* No spaces or space in the wrong spot */
-+                    libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                  "Invalid response from SCP server, malformed mtime.usec",
-+                                  0);
-+                    goto scp_recv_error;
-+                }
-+
-+                /* Ignore mtime.usec */
-+                s++;
-+                p = (unsigned char *) strchr((char *) s, ' ');
-+                if (!p || ((p - s) <= 0)) {
-+                    /* No spaces or space in the wrong spot */
-+                    libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                  "Invalid response from SCP server, too short or malformed",
-+                                  0);
-+                    goto scp_recv_error;
-+                }
-+
-+                *(p++) = '\0';
-+                /* Make sure we don't get fooled by leftover values */
-+                errno = 0;
-+                session->scpRecv_atime = strtol((char *) s, NULL, 10);
-+                if (errno) {
-+                    libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                  "Invalid response from SCP server, invalid atime",
-+                                  0);
-+                    goto scp_recv_error;
-+                }
-+
-+                /* SCP ACK */
-+                session->scpRecv_response[0] = '\0';
-+
-+                session->scpRecv_state = libssh2_NB_state_sent3;
-+            }
-+
-+            if (session->scpRecv_state == libssh2_NB_state_sent3) {
-+                rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
-+                                              (char *) session->
-+                                              scpRecv_response, 1);
-+                if (rc == PACKET_EAGAIN) {
-+                    libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                                  "Would block waiting to send SCP ACK", 0);
-+                    return NULL;
-+                } else if (rc != 1) {
-+                    goto scp_recv_error;
-+                }
-+
-+                _libssh2_debug(session, LIBSSH2_DBG_SCP,
-+                               "mtime = %ld, atime = %ld",
-+                               session->scpRecv_mtime, session->scpRecv_atime);
-+
-+                /* We *should* check that atime.usec is valid, but why let that stop use? */
-+                break;
-+            }
-+        }
-+
-+        session->scpRecv_state = libssh2_NB_state_sent4;
-+    }
-+
-+    if (session->scpRecv_state == libssh2_NB_state_sent4) {
-+        session->scpRecv_response_len = 0;
-+
-+        session->scpRecv_state = libssh2_NB_state_sent5;
-+    }
-+
-+    if ((session->scpRecv_state == libssh2_NB_state_sent5)
-+        || (session->scpRecv_state == libssh2_NB_state_sent6)) {
-+        while (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) {
-+            char *s, *p, *e = NULL;
-+
-+            if (session->scpRecv_state == libssh2_NB_state_sent5) {
-+                rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
-+                                             (char *) session->
-+                                             scpRecv_response +
-+                                             session->scpRecv_response_len, 1);
-+                if (rc == PACKET_EAGAIN) {
-+                    libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                                  "Would block waiting for SCP response", 0);
-+                    return NULL;
-+                } else if (rc <= 0) {
-+                    /* Timeout, give up */
-+                    libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                  "Timed out waiting for SCP response", 0);
-+                    goto scp_recv_error;
-+                }
-+                session->scpRecv_response_len++;
-+
-+                if (session->scpRecv_response[0] != 'C') {
-+                    libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                  "Invalid response from SCP server", 0);
-+                    goto scp_recv_error;
-+                }
-+
-+                if ((session->scpRecv_response_len > 1) &&
-+                    (session->
-+                     scpRecv_response[session->scpRecv_response_len - 1] !=
-+                     '\r')
-+                    && (session->
-+                        scpRecv_response[session->scpRecv_response_len - 1] !=
-+                        '\n')
-+                    &&
-+                    ((session->
-+                      scpRecv_response[session->scpRecv_response_len - 1] < 32)
-+                     || (session->
-+                         scpRecv_response[session->scpRecv_response_len - 1] >
-+                         126))) {
-+                    libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                  "Invalid data in SCP response", 0);
-+                    goto scp_recv_error;
-+                }
-+
-+                if ((session->scpRecv_response_len < 7)
-+                    || (session->
-+                        scpRecv_response[session->scpRecv_response_len - 1] !=
-+                        '\n')) {
-+                    if (session->scpRecv_response_len ==
-+                        LIBSSH2_SCP_RESPONSE_BUFLEN) {
-+                        /* You had your chance */
-+                        libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                      "Unterminated response from SCP server",
-+                                      0);
-+                        goto scp_recv_error;
-+                    }
-+                    /* Way too short to be an SCP response,  or not done yet, short circuit */
-+                    continue;
-+                }
-+
-+                /* We're guaranteed not to go under response_len == 0 by the logic above */
-+                while ((session->
-+                        scpRecv_response[session->scpRecv_response_len - 1] ==
-+                        '\r')
-+                       || (session->
-+                           scpRecv_response[session->scpRecv_response_len -
-+                                            1] == '\n')) {
-+                    session->scpRecv_response_len--;
-+                }
-+                session->scpRecv_response[session->scpRecv_response_len] =
-+                    '\0';
-+
-+                if (session->scpRecv_response_len < 6) {
-+                    /* EOL came too soon */
-+                    libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                  "Invalid response from SCP server, too short",
-+                                  0);
-+                    goto scp_recv_error;
-+                }
-+
-+                s = (char *) session->scpRecv_response + 1;
-+
-+                p = strchr(s, ' ');
-+                if (!p || ((p - s) <= 0)) {
-+                    /* No spaces or space in the wrong spot */
-+                    libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                  "Invalid response from SCP server, malformed mode",
-+                                  0);
-+                    goto scp_recv_error;
-+                }
-+
-+                *(p++) = '\0';
-+                /* Make sure we don't get fooled by leftover values */
-+                errno = 0;
-+                session->scpRecv_mode = strtol(s, &e, 8);
-+                if ((e && *e) || errno) {
-+                    libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                  "Invalid response from SCP server, invalid mode",
-+                                  0);
-+                    goto scp_recv_error;
-+                }
-+
-+                s = strchr(p, ' ');
-+                if (!s || ((s - p) <= 0)) {
-+                    /* No spaces or space in the wrong spot */
-+                    libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                  "Invalid response from SCP server, too short or malformed",
-+                                  0);
-+                    goto scp_recv_error;
-+                }
-+
-+                *(s++) = '\0';
-+                /* Make sure we don't get fooled by leftover values */
-+                errno = 0;
-+                session->scpRecv_size = scpsize_strtol(p, &e, 10);
-+                if ((e && *e) || errno) {
-+                    libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                                  "Invalid response from SCP server, invalid size",
-+                                  0);
-+                    goto scp_recv_error;
-+                }
-+
-+                /* SCP ACK */
-+                session->scpRecv_response[0] = '\0';
-+
-+                session->scpRecv_state = libssh2_NB_state_sent6;
-+            }
-+
-+            if (session->scpRecv_state == libssh2_NB_state_sent6) {
-+                rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
-+                                              (char *) session->
-+                                              scpRecv_response, 1);
-+                if (rc == PACKET_EAGAIN) {
-+                    libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                                  "Would block sending SCP ACK", 0);
-+                    return NULL;
-+                } else if (rc != 1) {
-+                    goto scp_recv_error;
-+                }
-+                _libssh2_debug(session, LIBSSH2_DBG_SCP,
-+                               "mode = 0%lo size = %ld", session->scpRecv_mode,
-+                               session->scpRecv_size);
-+
-+                /* We *should* check that basename is valid, but why let that stop us? */
-+                break;
-+            }
-+        }
-+
-+        session->scpRecv_state = libssh2_NB_state_sent7;
-+    }
-+
-+    if (sb) {
-+        memset(sb, 0, sizeof(struct stat));
-+
-+        sb->st_mtime = session->scpRecv_mtime;
-+        sb->st_atime = session->scpRecv_atime;
-+        sb->st_size = session->scpRecv_size;
-+        sb->st_mode = session->scpRecv_mode;
-+    }
-+
-+    session->scpRecv_state = libssh2_NB_state_idle;
-+    return session->scpRecv_channel;
-+
-+  scp_recv_error:
-+    while (libssh2_channel_free(session->scpRecv_channel) == PACKET_EAGAIN);
-+    session->scpRecv_channel = NULL;
-+    session->scpRecv_state = libssh2_NB_state_idle;
-+    return NULL;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_scp_send_ex
-+ * Send a file using SCP
-+ *
-+ * NOTE:  Will block in a busy loop on error.  This has to be done,
-+ *        otherwise the blocking error code would erase the true
-+ *        cause of the error.
-+ */
-+LIBSSH2_API LIBSSH2_CHANNEL *
-+libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
-+                    size_t size, long mtime, long atime)
-+{
-+    int path_len = strlen(path);
-+    unsigned const char *base;
-+    int rc;
-+
-+    if (session->scpSend_state == libssh2_NB_state_idle) {
-+        session->scpSend_command_len = path_len + sizeof("scp -t ");
-+
-+        if (mtime || atime) {
-+            session->scpSend_command_len++;
-+        }
-+
-+        session->scpSend_command =
-+            LIBSSH2_ALLOC(session, session->scpSend_command_len);
-+        if (!session->scpSend_command) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate a command buffer for scp session",
-+                          0);
-+            return NULL;
-+        }
-+
-+        if (mtime || atime) {
-+            memcpy(session->scpSend_command, "scp -pt ",
-+                   sizeof("scp -pt ") - 1);
-+            memcpy(session->scpSend_command + sizeof("scp -pt ") - 1, path,
-+                   path_len);
-+        } else {
-+            memcpy(session->scpSend_command, "scp -t ", sizeof("scp -t ") - 1);
-+            memcpy(session->scpSend_command + sizeof("scp -t ") - 1, path,
-+                   path_len);
-+        }
-+        session->scpSend_command[session->scpSend_command_len - 1] = '\0';
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_SCP,
-+                       "Opening channel for SCP send");
-+        /* Allocate a channel */
-+
-+        session->scpSend_state = libssh2_NB_state_created;
-+    }
-+
-+    if (session->scpSend_state == libssh2_NB_state_created) {
-+        session->scpSend_channel =
-+            libssh2_channel_open_ex(session, "session", sizeof("session") - 1,
-+                                    LIBSSH2_CHANNEL_WINDOW_DEFAULT,
-+                                    LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0);
-+        if (!session->scpSend_channel) {
-+            if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
-+                /* previous call set libssh2_session_last_error(), pass it through */
-+                LIBSSH2_FREE(session, session->scpSend_command);
-+                session->scpSend_command = NULL;
-+                session->scpSend_state = libssh2_NB_state_idle;
-+                return NULL;
-+            } else if (libssh2_session_last_errno(session) ==
-+                       LIBSSH2_ERROR_EAGAIN) {
-+                libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                              "Would block starting up channel", 0);
-+                return NULL;
-+            }
-+        }
-+
-+        session->scpSend_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (session->scpSend_state == libssh2_NB_state_sent) {
-+        /* Request SCP for the desired file */
-+        rc = libssh2_channel_process_startup(session->scpSend_channel, "exec",
-+                                             sizeof("exec") - 1,
-+                                             (char *) session->scpSend_command,
-+                                             session->scpSend_command_len);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block requesting SCP startup", 0);
-+            return NULL;
-+        } else if (rc) {
-+            /* previous call set libssh2_session_last_error(), pass it through */
-+            LIBSSH2_FREE(session, session->scpSend_command);
-+            session->scpSend_command = NULL;
-+            libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                          "Unknown error while getting error string", 0);
-+            goto scp_send_error;
-+        }
-+        LIBSSH2_FREE(session, session->scpSend_command);
-+        session->scpSend_command = NULL;
-+
-+        session->scpSend_state = libssh2_NB_state_sent1;
-+    }
-+
-+    if (session->scpSend_state == libssh2_NB_state_sent1) {
-+        /* Wait for ACK */
-+        rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
-+                                     (char *) session->scpSend_response, 1);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block waiting for response from remote", 0);
-+            return NULL;
-+        } else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
-+            libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                          "Invalid ACK response from remote", 0);
-+            goto scp_send_error;
-+        }
-+
-+        if (mtime || atime) {
-+            /* Send mtime and atime to be used for file */
-+            session->scpSend_response_len =
-+                snprintf((char *) session->scpSend_response,
-+                         LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", mtime,
-+                         atime);
-+            _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s",
-+                           session->scpSend_response);
-+        }
-+
-+        session->scpSend_state = libssh2_NB_state_sent2;
-+    }
-+
-+    /* Send mtime and atime to be used for file */
-+    if (mtime || atime) {
-+        if (session->scpSend_state == libssh2_NB_state_sent2) {
-+            rc = libssh2_channel_write_ex(session->scpSend_channel, 0,
-+                                          (char *) session->scpSend_response,
-+                                          session->scpSend_response_len);
-+            if (rc == PACKET_EAGAIN) {
-+                libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                              "Would block sending time data for SCP file", 0);
-+                return NULL;
-+            } else if (rc != session->scpSend_response_len) {
-+                libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                              "Unable to send time data for SCP file", 0);
-+                goto scp_send_error;
-+            }
-+
-+            session->scpSend_state = libssh2_NB_state_sent3;
-+        }
-+
-+        if (session->scpSend_state == libssh2_NB_state_sent3) {
-+            /* Wait for ACK */
-+            rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
-+                                         (char *) session->scpSend_response,
-+                                         1);
-+            if (rc == PACKET_EAGAIN) {
-+                libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                              "Would block waiting for response", 0);
-+                return NULL;
-+            } else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
-+                libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                              "Invalid ACK response from remote", 0);
-+                goto scp_send_error;
-+            }
-+
-+            session->scpSend_state = libssh2_NB_state_sent4;
-+        }
-+    } else {
-+        if (session->scpSend_state == libssh2_NB_state_sent2) {
-+            session->scpSend_state = libssh2_NB_state_sent4;
-+        }
-+    }
-+
-+    if (session->scpSend_state == libssh2_NB_state_sent4) {
-+        /* Send mode, size, and basename */
-+        base = (unsigned char *) strrchr(path, '/');
-+        if (base) {
-+            base++;
-+        } else {
-+            base = (unsigned char *) path;
-+        }
-+
-+        session->scpSend_response_len =
-+            snprintf((char *) session->scpSend_response,
-+                     LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %lu %s\n", mode,
-+                     (unsigned long) size, base);
-+        _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s",
-+                       session->scpSend_response);
-+
-+        session->scpSend_state = libssh2_NB_state_sent5;
-+    }
-+
-+    if (session->scpSend_state == libssh2_NB_state_sent5) {
-+        rc = libssh2_channel_write_ex(session->scpSend_channel, 0,
-+                                      (char *) session->scpSend_response,
-+                                      session->scpSend_response_len);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block send core file data for SCP file", 0);
-+            return NULL;
-+        } else if (rc != session->scpSend_response_len) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send core file data for SCP file", 0);
-+            goto scp_send_error;
-+        }
-+
-+        session->scpSend_state = libssh2_NB_state_sent6;
-+    }
-+
-+    if (session->scpSend_state == libssh2_NB_state_sent6) {
-+        /* Wait for ACK */
-+        rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
-+                                     (char *) session->scpSend_response, 1);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block waiting for response", 0);
-+            return NULL;
-+        } else if (rc <= 0) {
-+            libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                          "Invalid ACK response from remote", 0);
-+            goto scp_send_error;
-+        } else if (session->scpSend_response[0] != 0) {
-+            /*
-+             * Set this as the default error for here, if
-+             * we are successful it will be replaced
-+             */
-+            libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                          "Invalid ACK response from remote", 0);
-+
-+            session->scpSend_err_len =
-+                libssh2_channel_packet_data_len(session->scpSend_channel, 0);
-+            session->scpSend_err_msg =
-+                LIBSSH2_ALLOC(session, session->scpSend_err_len + 1);
-+            if (!session->scpSend_err_msg) {
-+                goto scp_send_error;
-+            }
-+            memset(session->scpSend_err_msg, 0, session->scpSend_err_len + 1);
-+
-+            /* Read the remote error message */
-+            rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
-+                                         session->scpSend_err_msg,
-+                                         session->scpSend_err_len);
-+            if (rc <= 0) {
-+                /*
-+                 * Since we have alread started reading this packet, it is
-+                 * already in the systems so it can't return PACKET_EAGAIN
-+                 */
-+                LIBSSH2_FREE(session, session->scpSend_err_msg);
-+                session->scpSend_err_msg = NULL;
-+                goto scp_send_error;
-+            }
-+
-+            libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
-+                          session->scpSend_err_msg, 1);
-+            session->scpSend_err_msg = NULL;
-+            goto scp_send_error;
-+        }
-+    }
-+
-+    session->scpSend_state = libssh2_NB_state_idle;
-+
-+    return session->scpSend_channel;
-+
-+  scp_send_error:
-+    while (libssh2_channel_free(session->scpSend_channel) == PACKET_EAGAIN);
-+    session->scpSend_channel = NULL;
-+    session->scpSend_state = libssh2_NB_state_idle;
-+    return NULL;
-+}
-+
-+/* }}} */
-
-Property changes on: libssh2/src/scp.c
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.2
-Added: svn:eol-style
-   + native
-
-Index: libssh2/src/hostkey.c
-===================================================================
---- libssh2/src/hostkey.c      (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/hostkey.c      (.../trunk)
-@@ -0,0 +1,455 @@
-+/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#include "libssh2_priv.h"
-+
-+/* Needed for struct iovec on some platforms */
-+#ifdef HAVE_SYS_UIO_H
-+#include <sys/uio.h>
-+#endif
-+
-+#if LIBSSH2_RSA
-+/* ***********
-+   * ssh-rsa *
-+   *********** */
-+
-+static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session,
-+                                               void **abstract);
-+
-+/* {{{ libssh2_hostkey_method_ssh_rsa_init
-+ * Initialize the server hostkey working area with e/n pair
-+ */
-+static int
-+libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
-+                                    const unsigned char *hostkey_data,
-+                                    unsigned long hostkey_data_len,
-+                                    void **abstract)
-+{
-+    libssh2_rsa_ctx *rsactx;
-+    const unsigned char *s, *e, *n;
-+    unsigned long len, e_len, n_len;
-+
-+    (void) hostkey_data_len;
-+
-+    if (*abstract) {
-+        libssh2_hostkey_method_ssh_rsa_dtor(session, abstract);
-+        *abstract = NULL;
-+    }
-+
-+    s = hostkey_data;
-+    len = libssh2_ntohu32(s);
-+    s += 4;
-+
-+    if (len != 7 || strncmp((char *) s, "ssh-rsa", 7) != 0) {
-+        return -1;
-+    }
-+    s += 7;
-+
-+    e_len = libssh2_ntohu32(s);
-+    s += 4;
-+
-+    e = s;
-+    s += e_len;
-+    n_len = libssh2_ntohu32(s);
-+    s += 4;
-+    n = s;
-+    s += n_len;
-+
-+    if (_libssh2_rsa_new(&rsactx, e, e_len, n, n_len, NULL, 0,
-+                         NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0))
-+        return -1;
-+
-+    *abstract = rsactx;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_hostkey_method_ssh_rsa_initPEM
-+ * Load a Private Key from a PEM file
-+ */
-+static int
-+libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
-+                                       const char *privkeyfile,
-+                                       unsigned const char *passphrase,
-+                                       void **abstract)
-+{
-+    libssh2_rsa_ctx *rsactx;
-+    FILE *fp;
-+    int ret;
-+
-+    if (*abstract) {
-+        libssh2_hostkey_method_ssh_rsa_dtor(session, abstract);
-+        *abstract = NULL;
-+    }
-+
-+    fp = fopen(privkeyfile, "r");
-+    if (!fp) {
-+        return -1;
-+    }
-+
-+    ret = _libssh2_rsa_new_private(&rsactx, session, fp, passphrase);
-+    fclose(fp);
-+    if (ret) {
-+        return -1;
-+    }
-+
-+    *abstract = rsactx;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_hostkey_method_ssh_rsa_sign
-+ * Verify signature created by remote
-+ */
-+static int
-+libssh2_hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION * session,
-+                                          const unsigned char *sig,
-+                                          unsigned long sig_len,
-+                                          const unsigned char *m,
-+                                          unsigned long m_len, void **abstract)
-+{
-+    libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
-+    (void) session;
-+
-+    /* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */
-+    sig += 15;
-+    sig_len -= 15;
-+    return _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len);
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_hostkey_method_ssh_rsa_signv
-+ * Construct a signature from an array of vectors
-+ */
-+static int
-+libssh2_hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session,
-+                                     unsigned char **signature,
-+                                     unsigned long *signature_len,
-+                                     unsigned long veccount,
-+                                     const struct iovec datavec[],
-+                                     void **abstract)
-+{
-+    libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
-+    int ret;
-+    unsigned int i;
-+    unsigned char hash[SHA_DIGEST_LENGTH];
-+    libssh2_sha1_ctx ctx;
-+
-+    libssh2_sha1_init(&ctx);
-+    for(i = 0; i < veccount; i++) {
-+        libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
-+    }
-+    libssh2_sha1_final(ctx, hash);
-+
-+    ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH,
-+                                 signature, signature_len);
-+    if (ret) {
-+        return -1;
-+    }
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_hostkey_method_ssh_rsa_dtor
-+ * Shutdown the hostkey
-+ */
-+static int
-+libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, void **abstract)
-+{
-+    libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
-+    (void) session;
-+
-+    _libssh2_rsa_free(rsactx);
-+
-+    *abstract = NULL;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = {
-+    "ssh-rsa",
-+    MD5_DIGEST_LENGTH,
-+    libssh2_hostkey_method_ssh_rsa_init,
-+    libssh2_hostkey_method_ssh_rsa_initPEM,
-+    libssh2_hostkey_method_ssh_rsa_sig_verify,
-+    libssh2_hostkey_method_ssh_rsa_signv,
-+    NULL,                       /* encrypt */
-+    libssh2_hostkey_method_ssh_rsa_dtor,
-+};
-+#endif /* LIBSSH2_RSA */
-+
-+#if LIBSSH2_DSA
-+/* ***********
-+   * ssh-dss *
-+   *********** */
-+
-+static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session,
-+                                               void **abstract);
-+
-+/* {{{ libssh2_hostkey_method_ssh_dss_init
-+ * Initialize the server hostkey working area with p/q/g/y set
-+ */
-+static int
-+libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
-+                                    const unsigned char *hostkey_data,
-+                                    unsigned long hostkey_data_len,
-+                                    void **abstract)
-+{
-+    libssh2_dsa_ctx *dsactx;
-+    const unsigned char *p, *q, *g, *y, *s;
-+    unsigned long p_len, q_len, g_len, y_len, len;
-+    (void) hostkey_data_len;
-+
-+    if (*abstract) {
-+        libssh2_hostkey_method_ssh_dss_dtor(session, abstract);
-+        *abstract = NULL;
-+    }
-+
-+    s = hostkey_data;
-+    len = libssh2_ntohu32(s);
-+    s += 4;
-+    if (len != 7 || strncmp((char *) s, "ssh-dss", 7) != 0) {
-+        return -1;
-+    }
-+    s += 7;
-+
-+    p_len = libssh2_ntohu32(s);
-+    s += 4;
-+    p = s;
-+    s += p_len;
-+    q_len = libssh2_ntohu32(s);
-+    s += 4;
-+    q = s;
-+    s += q_len;
-+    g_len = libssh2_ntohu32(s);
-+    s += 4;
-+    g = s;
-+    s += g_len;
-+    y_len = libssh2_ntohu32(s);
-+    s += 4;
-+    y = s;
-+    s += y_len;
-+
-+    _libssh2_dsa_new(&dsactx, p, p_len, q, q_len, g, g_len, y, y_len, NULL, 0);
-+
-+    *abstract = dsactx;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_hostkey_method_ssh_dss_initPEM
-+ * Load a Private Key from a PEM file
-+ */
-+static int
-+libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
-+                                       const char *privkeyfile,
-+                                       unsigned const char *passphrase,
-+                                       void **abstract)
-+{
-+    libssh2_dsa_ctx *dsactx;
-+    FILE *fp;
-+    int ret;
-+
-+    if (*abstract) {
-+        libssh2_hostkey_method_ssh_dss_dtor(session, abstract);
-+        *abstract = NULL;
-+    }
-+
-+    fp = fopen(privkeyfile, "r");
-+    if (!fp) {
-+        return -1;
-+    }
-+
-+    ret = _libssh2_dsa_new_private(&dsactx, session, fp, passphrase);
-+    fclose(fp);
-+    if (ret) {
-+        return -1;
-+    }
-+
-+    *abstract = dsactx;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_hostkey_method_ssh_dss_sign
-+ * Verify signature created by remote
-+ */
-+static int
-+libssh2_hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION * session,
-+                                          const unsigned char *sig,
-+                                          unsigned long sig_len,
-+                                          const unsigned char *m,
-+                                          unsigned long m_len, void **abstract)
-+{
-+    libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
-+
-+    /* Skip past keyname_len(4) + keyname(7){"ssh-dss"} + signature_len(4) */
-+    sig += 15;
-+    sig_len -= 15;
-+    if (sig_len != 40) {
-+        libssh2_error(session, LIBSSH2_ERROR_PROTO,
-+                      "Invalid DSS signature length", 0);
-+        return -1;
-+    }
-+    return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len);
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_hostkey_method_ssh_dss_signv
-+ * Construct a signature from an array of vectors
-+ */
-+static int
-+libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
-+                                     unsigned char **signature,
-+                                     unsigned long *signature_len,
-+                                     unsigned long veccount,
-+                                     const struct iovec datavec[],
-+                                     void **abstract)
-+{
-+    libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
-+    unsigned char hash[SHA_DIGEST_LENGTH];
-+    libssh2_sha1_ctx ctx;
-+    unsigned int i;
-+
-+    *signature = LIBSSH2_ALLOC(session, 2 * SHA_DIGEST_LENGTH);
-+    if (!*signature) {
-+        return -1;
-+    }
-+
-+    *signature_len = 2 * SHA_DIGEST_LENGTH;
-+    memset(*signature, 0, 2 * SHA_DIGEST_LENGTH);
-+
-+    libssh2_sha1_init(&ctx);
-+    for(i = 0; i < veccount; i++) {
-+        libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
-+    }
-+    libssh2_sha1_final(ctx, hash);
-+
-+    if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, *signature)) {
-+        LIBSSH2_FREE(session, *signature);
-+        return -1;
-+    }
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_hostkey_method_ssh_dss_dtor
-+ * Shutdown the hostkey method
-+ */
-+static int
-+libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, void **abstract)
-+{
-+    libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
-+    (void) session;
-+
-+    _libssh2_dsa_free(dsactx);
-+
-+    *abstract = NULL;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = {
-+    "ssh-dss",
-+    MD5_DIGEST_LENGTH,
-+    libssh2_hostkey_method_ssh_dss_init,
-+    libssh2_hostkey_method_ssh_dss_initPEM,
-+    libssh2_hostkey_method_ssh_dss_sig_verify,
-+    libssh2_hostkey_method_ssh_dss_signv,
-+    NULL,                       /* encrypt */
-+    libssh2_hostkey_method_ssh_dss_dtor,
-+};
-+#endif /* LIBSSH2_DSA */
-+
-+static const LIBSSH2_HOSTKEY_METHOD *_libssh2_hostkey_methods[] = {
-+#if LIBSSH2_RSA
-+    &libssh2_hostkey_method_ssh_rsa,
-+#endif /* LIBSSH2_RSA */
-+#if LIBSSH2_DSA
-+    &libssh2_hostkey_method_ssh_dss,
-+#endif /* LIBSSH2_DSA */
-+    NULL
-+};
-+
-+const LIBSSH2_HOSTKEY_METHOD **
-+libssh2_hostkey_methods(void)
-+{
-+    return _libssh2_hostkey_methods;
-+}
-+
-+/* {{{ libssh2_hostkey_hash
-+ * Returns hash signature
-+ * Returned buffer should NOT be freed
-+ * Length of buffer is determined by hash type
-+ * i.e. MD5 == 16, SHA1 == 20
-+ */
-+LIBSSH2_API const char *
-+libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type)
-+{
-+    switch (hash_type) {
-+#if LIBSSH2_MD5
-+    case LIBSSH2_HOSTKEY_HASH_MD5:
-+        return (char *) session->server_hostkey_md5;
-+        break;
-+#endif /* LIBSSH2_MD5 */
-+    case LIBSSH2_HOSTKEY_HASH_SHA1:
-+        return (char *) session->server_hostkey_sha1;
-+        break;
-+    default:
-+        return NULL;
-+    }
-+}
-+
-+/* }}} */
-
-Property changes on: libssh2/src/hostkey.c
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.2
-Added: svn:eol-style
-   + native
-
-Index: libssh2/src/publickey.c
-===================================================================
---- libssh2/src/publickey.c    (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/publickey.c    (.../trunk)
-@@ -0,0 +1,1094 @@
-+/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#include "libssh2_priv.h"
-+#include "libssh2_publickey.h"
-+
-+#define LIBSSH2_PUBLICKEY_VERSION               2
-+
-+/* Numericised response codes -- Not IETF standard, just a local representation */
-+#define LIBSSH2_PUBLICKEY_RESPONSE_STATUS       0
-+#define LIBSSH2_PUBLICKEY_RESPONSE_VERSION      1
-+#define LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY    2
-+
-+typedef struct _LIBSSH2_PUBLICKEY_CODE_LIST
-+{
-+    int code;
-+    const char *name;
-+    int name_len;
-+} LIBSSH2_PUBLICKEY_CODE_LIST;
-+
-+static const LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_response_codes[] = {
-+    {LIBSSH2_PUBLICKEY_RESPONSE_STATUS, "status", sizeof("status") - 1}
-+    ,
-+    {LIBSSH2_PUBLICKEY_RESPONSE_VERSION, "version", sizeof("version") - 1}
-+    ,
-+    {LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY, "publickey", sizeof("publickey") - 1}
-+    ,
-+    {0, NULL, 0}
-+};
-+
-+/* PUBLICKEY status codes -- IETF defined */
-+#define LIBSSH2_PUBLICKEY_SUCCESS               0
-+#define LIBSSH2_PUBLICKEY_ACCESS_DENIED         1
-+#define LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED      2
-+#define LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED 3
-+#define LIBSSH2_PUBLICKEY_KEY_NOT_FOUND         4
-+#define LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED     5
-+#define LIBSSH2_PUBLICKEY_KEY_ALREADY_PRESENT   6
-+#define LIBSSH2_PUBLICKEY_GENERAL_FAILURE       7
-+#define LIBSSH2_PUBLICKEY_REQUEST_NOT_SUPPORTED 8
-+
-+#define LIBSSH2_PUBLICKEY_STATUS_CODE_MAX       8
-+
-+static const LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_status_codes[] = {
-+    {LIBSSH2_PUBLICKEY_SUCCESS, "success", sizeof("success") - 1}
-+    ,
-+    {LIBSSH2_PUBLICKEY_ACCESS_DENIED, "access denied",
-+     sizeof("access denied") - 1}
-+    ,
-+    {LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED, "storage exceeded",
-+     sizeof("storage exceeded") - 1}
-+    ,
-+    {LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED, "version not supported",
-+     sizeof("version not supported") - 1}
-+    ,
-+    {LIBSSH2_PUBLICKEY_KEY_NOT_FOUND, "key not found",
-+     sizeof("key not found") - 1}
-+    ,
-+    {LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED, "key not supported",
-+     sizeof("key not supported") - 1}
-+    ,
-+    {LIBSSH2_PUBLICKEY_KEY_ALREADY_PRESENT, "key already present",
-+     sizeof("key already present") - 1}
-+    ,
-+    {LIBSSH2_PUBLICKEY_GENERAL_FAILURE, "general failure",
-+     sizeof("general failure") - 1}
-+    ,
-+    {LIBSSH2_PUBLICKEY_REQUEST_NOT_SUPPORTED, "request not supported",
-+     sizeof("request not supported") - 1}
-+    ,
-+    {0, NULL, 0}
-+};
-+
-+/* {{{ libssh2_publickey_status_error
-+ * Format an error message from a status code
-+ */
-+#define LIBSSH2_PUBLICKEY_STATUS_TEXT_START     "Publickey Subsystem Error: \""
-+#define LIBSSH2_PUBLICKEY_STATUS_TEXT_MID       "\" Server Reports: \""
-+#define LIBSSH2_PUBLICKEY_STATUS_TEXT_END       "\""
-+static void
-+libssh2_publickey_status_error(const LIBSSH2_PUBLICKEY * pkey,
-+                               LIBSSH2_SESSION * session, int status,
-+                               const unsigned char *message, int message_len)
-+{
-+    const char *status_text;
-+    int status_text_len;
-+    char *m, *s;
-+    int m_len;
-+
-+    /* GENERAL_FAILURE got remapped between version 1 and 2 */
-+    if (status == 6 && pkey && pkey->version == 1) {
-+        status = 7;
-+    }
-+
-+    if (status < 0 || status > LIBSSH2_PUBLICKEY_STATUS_CODE_MAX) {
-+        status_text = "unknown";
-+        status_text_len = sizeof("unknown") - 1;
-+    } else {
-+        status_text = libssh2_publickey_status_codes[status].name;
-+        status_text_len = libssh2_publickey_status_codes[status].name_len;
-+    }
-+
-+    m_len =
-+        (sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_START) - 1) + status_text_len +
-+        (sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_MID) - 1) + message_len +
-+        (sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_END) - 1);
-+    m = LIBSSH2_ALLOC(session, m_len + 1);
-+    if (!m) {
-+        libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                      "Unable to allocate memory for status message", 0);
-+        return;
-+    }
-+    s = m;
-+    memcpy(s, LIBSSH2_PUBLICKEY_STATUS_TEXT_START,
-+           sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_START) - 1);
-+    s += sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_START) - 1;
-+    memcpy(s, status_text, status_text_len);
-+    s += status_text_len;
-+    memcpy(s, LIBSSH2_PUBLICKEY_STATUS_TEXT_MID,
-+           sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_MID) - 1);
-+    s += sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_MID) - 1;
-+    memcpy(s, message, message_len);
-+    s += message_len;
-+    memcpy(s, LIBSSH2_PUBLICKEY_STATUS_TEXT_END,
-+           sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_END) - 1);
-+    s += sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_END);
-+    libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, m, 1);
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_publickey_packet_receive
-+ * Read a packet from the subsystem
-+ */
-+static int
-+libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
-+                                 unsigned char **data, unsigned long *data_len)
-+{
-+    LIBSSH2_CHANNEL *channel = pkey->channel;
-+    LIBSSH2_SESSION *session = channel->session;
-+    unsigned char buffer[4];
-+    int rc;
-+
-+    if (pkey->receive_state == libssh2_NB_state_idle) {
-+        rc = libssh2_channel_read_ex(channel, 0, (char *) buffer, 4);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc != 4) {
-+            libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
-+                          "Invalid response from publickey subsystem", 0);
-+            return -1;
-+        }
-+
-+        pkey->receive_packet_len = libssh2_ntohu32(buffer);
-+        pkey->receive_packet =
-+            LIBSSH2_ALLOC(session, pkey->receive_packet_len);
-+        if (!pkey->receive_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate publickey response buffer", 0);
-+            return -1;
-+        }
-+
-+        pkey->receive_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (pkey->receive_state == libssh2_NB_state_sent) {
-+        rc = libssh2_channel_read_ex(channel, 0, (char *) pkey->receive_packet,
-+                                     pkey->receive_packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc != (int)pkey->receive_packet_len) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                          "Timeout waiting for publickey subsystem response packet",
-+                          0);
-+            LIBSSH2_FREE(session, pkey->receive_packet);
-+            pkey->receive_packet = NULL;
-+            pkey->receive_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+
-+        *data = pkey->receive_packet;
-+        *data_len = pkey->receive_packet_len;
-+    }
-+
-+    pkey->receive_state = libssh2_NB_state_idle;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_publickey_response_id
-+ * Translate a string response name to a numeric code
-+ * Data will be incremented by 4 + response_len on success only
-+ */
-+static int
-+libssh2_publickey_response_id(unsigned char **pdata, int data_len)
-+{
-+    unsigned long response_len;
-+    unsigned char *data = *pdata;
-+    const LIBSSH2_PUBLICKEY_CODE_LIST *codes =
-+        libssh2_publickey_response_codes;
-+
-+    if (data_len < 4) {
-+        /* Malformed response */
-+        return -1;
-+    }
-+    response_len = libssh2_ntohu32(data);
-+    data += 4;
-+    data_len -= 4;
-+    if (data_len < (int)response_len) {
-+        /* Malformed response */
-+        return -1;
-+    }
-+
-+    while (codes->name) {
-+        if ((unsigned long)codes->name_len == response_len &&
-+            strncmp(codes->name, (char *) data, response_len) == 0) {
-+            *pdata = data + response_len;
-+            return codes->code;
-+        }
-+        codes++;
-+    }
-+
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_publickey_response_success
-+ * Generic helper routine to wait for success response and nothing else
-+ */
-+static int
-+libssh2_publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
-+{
-+    LIBSSH2_SESSION *session = pkey->channel->session;
-+    unsigned char *data, *s;
-+    unsigned long data_len;
-+    int response;
-+    int rc;
-+
-+    while (1) {
-+        rc = libssh2_publickey_packet_receive(pkey, &data, &data_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                          "Timeout waiting for response from publickey subsystem",
-+                          0);
-+            return -1;
-+        }
-+
-+        s = data;
-+        if ((response = libssh2_publickey_response_id(&s, data_len)) < 0) {
-+            libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
-+                          "Invalid publickey subsystem response code", 0);
-+            LIBSSH2_FREE(session, data);
-+            return -1;
-+        }
-+
-+        switch (response) {
-+        case LIBSSH2_PUBLICKEY_RESPONSE_STATUS:
-+            /* Error, or processing complete */
-+            {
-+                unsigned long status, descr_len, lang_len;
-+                unsigned char *descr, *lang;
-+
-+                status = libssh2_ntohu32(s);
-+                s += 4;
-+                descr_len = libssh2_ntohu32(s);
-+                s += 4;
-+                descr = s;
-+                s += descr_len;
-+                lang_len = libssh2_ntohu32(s);
-+                s += 4;
-+                lang = s;
-+                s += lang_len;
-+
-+                if (s > data + data_len) {
-+                    libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
-+                                  "Malformed publickey subsystem packet", 0);
-+                    LIBSSH2_FREE(session, data);
-+                    return -1;
-+                }
-+
-+                if (status == LIBSSH2_PUBLICKEY_SUCCESS) {
-+                    LIBSSH2_FREE(session, data);
-+                    return 0;
-+                }
-+
-+                libssh2_publickey_status_error(pkey, session, status, descr,
-+                                               descr_len);
-+                LIBSSH2_FREE(session, data);
-+                return -1;
-+            }
-+        default:
-+            /* Unknown/Unexpected */
-+            libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
-+                          "Unexpected publickey subsystem response, ignoring",
-+                          0);
-+            LIBSSH2_FREE(session, data);
-+            data = NULL;
-+        }
-+    }
-+    /* never reached, but include `return` to silence compiler warnings */
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+
-+/* *****************
-+   * Publickey API *
-+   ***************** */
-+
-+/* {{{ libssh2_publickey_init
-+ * Startup the publickey subsystem
-+ */
-+LIBSSH2_API LIBSSH2_PUBLICKEY *
-+libssh2_publickey_init(LIBSSH2_SESSION * session)
-+{
-+    /* 19 = packet_len(4) + version_len(4) + "version"(7) + version_num(4) */
-+    unsigned char buffer[19];
-+    unsigned char *s;
-+    int response;
-+    int rc;
-+
-+    if (session->pkeyInit_state == libssh2_NB_state_idle) {
-+        session->pkeyInit_data = NULL;
-+        session->pkeyInit_pkey = NULL;
-+        session->pkeyInit_channel = NULL;
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
-+                       "Initializing publickey subsystem");
-+
-+        session->pkeyInit_state = libssh2_NB_state_allocated;
-+    }
-+
-+    if (session->pkeyInit_state == libssh2_NB_state_allocated) {
-+        do {
-+            session->pkeyInit_channel =
-+                libssh2_channel_open_ex(session, "session",
-+                                        sizeof("session") - 1,
-+                                        LIBSSH2_CHANNEL_WINDOW_DEFAULT,
-+                                        LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL,
-+                                        0);
-+            if (!session->pkeyInit_channel
-+                && (libssh2_session_last_errno(session) ==
-+                    LIBSSH2_ERROR_EAGAIN)) {
-+                /* The error state is already set, so leave it */
-+                libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                              "Would block to startup channel", 0);
-+                return NULL;
-+            } else if (!session->pkeyInit_channel
-+                       && (libssh2_session_last_errno(session) !=
-+                           LIBSSH2_ERROR_EAGAIN)) {
-+                libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
-+                              "Unable to startup channel", 0);
-+                goto err_exit;
-+            }
-+        } while (!session->pkeyInit_channel);
-+
-+        session->pkeyInit_state = libssh2_NB_state_sent;
-+    }
-+
-+    if (session->pkeyInit_state == libssh2_NB_state_sent) {
-+        rc = libssh2_channel_process_startup(session->pkeyInit_channel,
-+                                             "subsystem",
-+                                             sizeof("subsystem") - 1,
-+                                             "publickey", strlen("publickey"));
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block starting publickey subsystem", 0);
-+            return NULL;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
-+                          "Unable to request publickey subsystem", 0);
-+            goto err_exit;
-+        }
-+
-+        session->pkeyInit_state = libssh2_NB_state_sent1;
-+    }
-+
-+    if (session->pkeyInit_state == libssh2_NB_state_sent1) {
-+        rc = libssh2_channel_handle_extended_data2(session->pkeyInit_channel,
-+                                                   LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block starting publickey subsystem", 0);
-+            return NULL;
-+        }
-+
-+        session->pkeyInit_pkey =
-+            LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PUBLICKEY));
-+        if (!session->pkeyInit_pkey) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate a new publickey structure", 0);
-+            goto err_exit;
-+        }
-+        memset(session->pkeyInit_pkey, 0, sizeof(LIBSSH2_PUBLICKEY));
-+        session->pkeyInit_pkey->channel = session->pkeyInit_channel;
-+        session->pkeyInit_pkey->version = 0;
-+
-+        s = buffer;
-+        libssh2_htonu32(s, 4 + (sizeof("version") - 1) + 4);
-+        s += 4;
-+        libssh2_htonu32(s, sizeof("version") - 1);
-+        s += 4;
-+        memcpy(s, "version", sizeof("version") - 1);
-+        s += sizeof("version") - 1;
-+        libssh2_htonu32(s, LIBSSH2_PUBLICKEY_VERSION);
-+        s += 4;
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
-+                       "Sending publickey version packet advertising version %d support",
-+                       (int) LIBSSH2_PUBLICKEY_VERSION);
-+
-+        session->pkeyInit_state = libssh2_NB_state_sent2;
-+    }
-+
-+    if (session->pkeyInit_state == libssh2_NB_state_sent2) {
-+        rc = libssh2_channel_write_ex(session->pkeyInit_channel, 0,
-+                                      (char *) buffer, (s - buffer));
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block sending publickey version packet", 0);
-+            return NULL;
-+        } else if ((s - buffer) != rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send publickey version packet", 0);
-+            goto err_exit;
-+        }
-+
-+        session->pkeyInit_state = libssh2_NB_state_sent3;
-+    }
-+
-+    if (session->pkeyInit_state == libssh2_NB_state_sent3) {
-+        while (1) {
-+            rc = libssh2_publickey_packet_receive(session->pkeyInit_pkey,
-+                                                  &session->pkeyInit_data,
-+                                                  &session->pkeyInit_data_len);
-+            if (rc == PACKET_EAGAIN) {
-+                libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                              "Would block waiting for response from publickey subsystem",
-+                              0);
-+                return NULL;
-+            } else if (rc) {
-+                libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                              "Timeout waiting for response from publickey subsystem",
-+                              0);
-+                goto err_exit;
-+            }
-+
-+            s = session->pkeyInit_data;
-+            if ((response =
-+                 libssh2_publickey_response_id(&s,
-+                                               session->pkeyInit_data_len)) <
-+                0) {
-+                libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
-+                              "Invalid publickey subsystem response code", 0);
-+                goto err_exit;
-+            }
-+
-+            switch (response) {
-+            case LIBSSH2_PUBLICKEY_RESPONSE_STATUS:
-+                /* Error */
-+                {
-+                    unsigned long status, descr_len, lang_len;
-+                    unsigned char *descr, *lang;
-+
-+                    status = libssh2_ntohu32(s);
-+                    s += 4;
-+                    descr_len = libssh2_ntohu32(s);
-+                    s += 4;
-+                    descr = s;
-+                    s += descr_len;
-+                    lang_len = libssh2_ntohu32(s);
-+                    s += 4;
-+                    lang = s;
-+                    s += lang_len;
-+
-+                    if (s >
-+                        session->pkeyInit_data + session->pkeyInit_data_len) {
-+                        libssh2_error(session,
-+                                      LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
-+                                      "Malformed publickey subsystem packet",
-+                                      0);
-+                        goto err_exit;
-+                    }
-+
-+                    libssh2_publickey_status_error(NULL, session, status,
-+                                                   descr, descr_len);
-+                    goto err_exit;
-+                }
-+
-+            case LIBSSH2_PUBLICKEY_RESPONSE_VERSION:
-+                /* What we want */
-+                session->pkeyInit_pkey->version = libssh2_ntohu32(s);
-+                if (session->pkeyInit_pkey->version >
-+                    LIBSSH2_PUBLICKEY_VERSION) {
-+                    _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
-+                                   "Truncating remote publickey version from %lu",
-+                                   session->pkeyInit_pkey->version);
-+                    session->pkeyInit_pkey->version =
-+                        LIBSSH2_PUBLICKEY_VERSION;
-+                }
-+                _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
-+                               "Enabling publickey subsystem version %lu",
-+                               session->pkeyInit_pkey->version);
-+                LIBSSH2_FREE(session, session->pkeyInit_data);
-+                session->pkeyInit_data = NULL;
-+                session->pkeyInit_state = libssh2_NB_state_idle;
-+                return session->pkeyInit_pkey;
-+
-+            default:
-+                /* Unknown/Unexpected */
-+                libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
-+                              "Unexpected publickey subsystem response, ignoring",
-+                              0);
-+                LIBSSH2_FREE(session, session->pkeyInit_data);
-+                session->pkeyInit_data = NULL;
-+            }
-+        }
-+    }
-+
-+    /* Never reached except by direct goto */
-+  err_exit:
-+    session->pkeyInit_state = libssh2_NB_state_sent4;
-+    if (session->pkeyInit_channel) {
-+        rc = libssh2_channel_close(session->pkeyInit_channel);
-+        if (rc == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                          "Would block closing channel", 0);
-+            return NULL;
-+        }
-+    }
-+    if (session->pkeyInit_pkey) {
-+        LIBSSH2_FREE(session, session->pkeyInit_pkey);
-+        session->pkeyInit_pkey = NULL;
-+    }
-+    if (session->pkeyInit_data) {
-+        LIBSSH2_FREE(session, session->pkeyInit_data);
-+        session->pkeyInit_data = NULL;
-+    }
-+    session->pkeyInit_state = libssh2_NB_state_idle;
-+    return NULL;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_publickey_add_ex
-+ * Add a new public key entry
-+ */
-+LIBSSH2_API int
-+libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY * pkey, const unsigned char *name,
-+                         unsigned long name_len, const unsigned char *blob,
-+                         unsigned long blob_len, char overwrite,
-+                         unsigned long num_attrs,
-+                         const libssh2_publickey_attribute attrs[])
-+{
-+    LIBSSH2_CHANNEL *channel = pkey->channel;
-+    LIBSSH2_SESSION *session = channel->session;
-+    /*  19 = packet_len(4) + add_len(4) + "add"(3) + name_len(4) + {name} blob_len(4) + {blob} */
-+    unsigned long i, packet_len = 19 + name_len + blob_len;
-+    unsigned char *comment = NULL;
-+    unsigned long comment_len = 0;
-+    int rc;
-+
-+    if (pkey->add_state == libssh2_NB_state_idle) {
-+        pkey->add_packet = NULL;
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Adding %s publickey",
-+                       name);
-+
-+        if (pkey->version == 1) {
-+            for(i = 0; i < num_attrs; i++) {
-+                /* Search for a comment attribute */
-+                if (attrs[i].name_len == (sizeof("comment") - 1) &&
-+                    strncmp(attrs[i].name, "comment",
-+                            sizeof("comment") - 1) == 0) {
-+                    comment = (unsigned char *) attrs[i].value;
-+                    comment_len = attrs[i].value_len;
-+                    break;
-+                }
-+            }
-+            packet_len += 4 + comment_len;
-+        } else {
-+            packet_len += 5;    /* overwrite(1) + attribute_count(4) */
-+            for(i = 0; i < num_attrs; i++) {
-+                packet_len += 9 + attrs[i].name_len + attrs[i].value_len;
-+                /* name_len(4) + value_len(4) + mandatory(1) */
-+            }
-+        }
-+
-+        pkey->add_packet = LIBSSH2_ALLOC(session, packet_len);
-+        if (!pkey->add_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for publickey \"add\" packet",
-+                          0);
-+            return -1;
-+        }
-+
-+        pkey->add_s = pkey->add_packet;
-+        libssh2_htonu32(pkey->add_s, packet_len - 4);
-+        pkey->add_s += 4;
-+        libssh2_htonu32(pkey->add_s, sizeof("add") - 1);
-+        pkey->add_s += 4;
-+        memcpy(pkey->add_s, "add", sizeof("add") - 1);
-+        pkey->add_s += sizeof("add") - 1;
-+        if (pkey->version == 1) {
-+            libssh2_htonu32(pkey->add_s, comment_len);
-+            pkey->add_s += 4;
-+            if (comment) {
-+                memcpy(pkey->add_s, comment, comment_len);
-+                pkey->add_s += comment_len;
-+            }
-+
-+            libssh2_htonu32(pkey->add_s, name_len);
-+            pkey->add_s += 4;
-+            memcpy(pkey->add_s, name, name_len);
-+            pkey->add_s += name_len;
-+            libssh2_htonu32(pkey->add_s, blob_len);
-+            pkey->add_s += 4;
-+            memcpy(pkey->add_s, blob, blob_len);
-+            pkey->add_s += blob_len;
-+        } else {
-+            /* Version == 2 */
-+
-+            libssh2_htonu32(pkey->add_s, name_len);
-+            pkey->add_s += 4;
-+            memcpy(pkey->add_s, name, name_len);
-+            pkey->add_s += name_len;
-+            libssh2_htonu32(pkey->add_s, blob_len);
-+            pkey->add_s += 4;
-+            memcpy(pkey->add_s, blob, blob_len);
-+            pkey->add_s += blob_len;
-+            *(pkey->add_s++) = overwrite ? 0x01 : 0;
-+            libssh2_htonu32(pkey->add_s, num_attrs);
-+            pkey->add_s += 4;
-+            for(i = 0; i < num_attrs; i++) {
-+                libssh2_htonu32(pkey->add_s, attrs[i].name_len);
-+                pkey->add_s += 4;
-+                memcpy(pkey->add_s, attrs[i].name, attrs[i].name_len);
-+                pkey->add_s += attrs[i].name_len;
-+                libssh2_htonu32(pkey->add_s, attrs[i].value_len);
-+                pkey->add_s += 4;
-+                memcpy(pkey->add_s, attrs[i].value, attrs[i].value_len);
-+                pkey->add_s += attrs[i].value_len;
-+                *(pkey->add_s++) = attrs[i].mandatory ? 0x01 : 0;
-+            }
-+        }
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
-+                       "Sending publickey \"add\" packet: type=%s blob_len=%ld num_attrs=%ld",
-+                       name, blob_len, num_attrs);
-+
-+        pkey->add_state = libssh2_NB_state_created;
-+    }
-+
-+    if (pkey->add_state == libssh2_NB_state_created) {
-+        rc = libssh2_channel_write_ex(channel, 0, (char *) pkey->add_packet,
-+                                      (pkey->add_s - pkey->add_packet));
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if ((pkey->add_s - pkey->add_packet) != rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send publickey add packet", 0);
-+            LIBSSH2_FREE(session, pkey->add_packet);
-+            pkey->add_packet = NULL;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, pkey->add_packet);
-+        pkey->add_packet = NULL;
-+
-+        pkey->add_state = libssh2_NB_state_sent;
-+    }
-+
-+    rc = libssh2_publickey_response_success(pkey);
-+    if (rc == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    }
-+
-+    pkey->add_state = libssh2_NB_state_idle;
-+
-+    return rc;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_publickey_remove_ex
-+ * Remove an existing publickey so that authentication can no longer be performed using it
-+ */
-+LIBSSH2_API int
-+libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
-+                            const unsigned char *name, unsigned long name_len,
-+                            const unsigned char *blob, unsigned long blob_len)
-+{
-+    LIBSSH2_CHANNEL *channel = pkey->channel;
-+    LIBSSH2_SESSION *session = channel->session;
-+    /* 22 = packet_len(4) + remove_len(4) + "remove"(6) + name_len(4) + {name} + blob_len(4) + {blob} */
-+    unsigned long packet_len = 22 + name_len + blob_len;
-+    int rc;
-+
-+    if (pkey->remove_state == libssh2_NB_state_idle) {
-+        pkey->remove_packet = NULL;
-+
-+        pkey->remove_packet = LIBSSH2_ALLOC(session, packet_len);
-+        if (!pkey->remove_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for publickey \"remove\" packet",
-+                          0);
-+            return -1;
-+        }
-+
-+        pkey->remove_s = pkey->remove_packet;
-+        libssh2_htonu32(pkey->remove_s, packet_len - 4);
-+        pkey->remove_s += 4;
-+        libssh2_htonu32(pkey->remove_s, sizeof("remove") - 1);
-+        pkey->remove_s += 4;
-+        memcpy(pkey->remove_s, "remove", sizeof("remove") - 1);
-+        pkey->remove_s += sizeof("remove") - 1;
-+        libssh2_htonu32(pkey->remove_s, name_len);
-+        pkey->remove_s += 4;
-+        memcpy(pkey->remove_s, name, name_len);
-+        pkey->remove_s += name_len;
-+        libssh2_htonu32(pkey->remove_s, blob_len);
-+        pkey->remove_s += 4;
-+        memcpy(pkey->remove_s, blob, blob_len);
-+        pkey->remove_s += blob_len;
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
-+                       "Sending publickey \"remove\" packet: type=%s blob_len=%ld",
-+                       name, blob_len);
-+
-+        pkey->remove_state = libssh2_NB_state_created;
-+    }
-+
-+    if (pkey->remove_state == libssh2_NB_state_created) {
-+        rc = libssh2_channel_write_ex(channel, 0, (char *) pkey->remove_packet,
-+                                      (pkey->remove_s - pkey->remove_packet));
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if ((pkey->remove_s - pkey->remove_packet) != rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send publickey remove packet", 0);
-+            LIBSSH2_FREE(session, pkey->remove_packet);
-+            pkey->remove_packet = NULL;
-+            pkey->remove_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+        LIBSSH2_FREE(session, pkey->remove_packet);
-+        pkey->remove_packet = NULL;
-+
-+        pkey->remove_state = libssh2_NB_state_sent;
-+    }
-+
-+    rc = libssh2_publickey_response_success(pkey);
-+    if (rc == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    }
-+
-+    pkey->remove_state = libssh2_NB_state_idle;
-+
-+    return rc;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_publickey_list_fetch
-+ * Fetch a list of supported public key from a server
-+ */
-+LIBSSH2_API int
-+libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
-+                             libssh2_publickey_list ** pkey_list)
-+{
-+    LIBSSH2_CHANNEL *channel = pkey->channel;
-+    LIBSSH2_SESSION *session = channel->session;
-+    libssh2_publickey_list *list = NULL;
-+    unsigned long buffer_len = 12, keys = 0, max_keys = 0, i;
-+    /* 12 = packet_len(4) + list_len(4) + "list"(4) */
-+    int response;
-+    int rc;
-+
-+    if (pkey->listFetch_state == libssh2_NB_state_idle) {
-+        pkey->listFetch_data = NULL;
-+
-+        pkey->listFetch_s = pkey->listFetch_buffer;
-+        libssh2_htonu32(pkey->listFetch_s, buffer_len - 4);
-+        pkey->listFetch_s += 4;
-+        libssh2_htonu32(pkey->listFetch_s, sizeof("list") - 1);
-+        pkey->listFetch_s += 4;
-+        memcpy(pkey->listFetch_s, "list", sizeof("list") - 1);
-+        pkey->listFetch_s += sizeof("list") - 1;
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
-+                       "Sending publickey \"list\" packet");
-+
-+        pkey->listFetch_state = libssh2_NB_state_created;
-+    }
-+
-+    if (pkey->listFetch_state == libssh2_NB_state_created) {
-+        rc = libssh2_channel_write_ex(channel, 0,
-+                                      (char *) pkey->listFetch_buffer,
-+                                      (pkey->listFetch_s -
-+                                       pkey->listFetch_buffer));
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if ((pkey->listFetch_s - pkey->listFetch_buffer) != rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send publickey list packet", 0);
-+            pkey->listFetch_state = libssh2_NB_state_idle;
-+            return -1;
-+        }
-+
-+        pkey->listFetch_state = libssh2_NB_state_sent;
-+    }
-+
-+    while (1) {
-+        rc = libssh2_publickey_packet_receive(pkey, &pkey->listFetch_data,
-+                                              &pkey->listFetch_data_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
-+                          "Timeout waiting for response from publickey subsystem",
-+                          0);
-+            goto err_exit;
-+        }
-+
-+        pkey->listFetch_s = pkey->listFetch_data;
-+        if ((response =
-+             libssh2_publickey_response_id(&pkey->listFetch_s,
-+                                           pkey->listFetch_data_len)) < 0) {
-+            libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
-+                          "Invalid publickey subsystem response code", 0);
-+            goto err_exit;
-+        }
-+
-+        switch (response) {
-+        case LIBSSH2_PUBLICKEY_RESPONSE_STATUS:
-+            /* Error, or processing complete */
-+            {
-+                unsigned long status, descr_len, lang_len;
-+                unsigned char *descr, *lang;
-+
-+                status = libssh2_ntohu32(pkey->listFetch_s);
-+                pkey->listFetch_s += 4;
-+                descr_len = libssh2_ntohu32(pkey->listFetch_s);
-+                pkey->listFetch_s += 4;
-+                descr = pkey->listFetch_s;
-+                pkey->listFetch_s += descr_len;
-+                lang_len = libssh2_ntohu32(pkey->listFetch_s);
-+                pkey->listFetch_s += 4;
-+                lang = pkey->listFetch_s;
-+                pkey->listFetch_s += lang_len;
-+
-+                if (pkey->listFetch_s >
-+                    pkey->listFetch_data + pkey->listFetch_data_len) {
-+                    libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
-+                                  "Malformed publickey subsystem packet", 0);
-+                    goto err_exit;
-+                }
-+
-+                if (status == LIBSSH2_PUBLICKEY_SUCCESS) {
-+                    LIBSSH2_FREE(session, pkey->listFetch_data);
-+                    pkey->listFetch_data = NULL;
-+                    *pkey_list = list;
-+                    *num_keys = keys;
-+                    pkey->listFetch_state = libssh2_NB_state_idle;
-+                    return 0;
-+                }
-+
-+                libssh2_publickey_status_error(pkey, session, status, descr,
-+                                               descr_len);
-+                goto err_exit;
-+            }
-+        case LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY:
-+            /* What we want */
-+            if (keys >= max_keys) {
-+                libssh2_publickey_list *newlist;
-+                /* Grow the key list if necessary */
-+                max_keys += 8;
-+                newlist =
-+                    LIBSSH2_REALLOC(session, list,
-+                                    (max_keys +
-+                                     1) * sizeof(libssh2_publickey_list));
-+                if (!newlist) {
-+                    libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                                  "Unable to allocate memory for publickey list",
-+                                  0);
-+                    goto err_exit;
-+                }
-+                list = newlist;
-+            }
-+            if (pkey->version == 1) {
-+                unsigned long comment_len;
-+
-+                comment_len = libssh2_ntohu32(pkey->listFetch_s);
-+                pkey->listFetch_s += 4;
-+                if (comment_len) {
-+                    list[keys].num_attrs = 1;
-+                    list[keys].attrs =
-+                        LIBSSH2_ALLOC(session,
-+                                      sizeof(libssh2_publickey_attribute));
-+                    if (!list[keys].attrs) {
-+                        libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                                      "Unable to allocate memory for publickey attributes",
-+                                      0);
-+                        goto err_exit;
-+                    }
-+                    list[keys].attrs[0].name = "comment";
-+                    list[keys].attrs[0].name_len = sizeof("comment") - 1;
-+                    list[keys].attrs[0].value = (char *) pkey->listFetch_s;
-+                    list[keys].attrs[0].value_len = comment_len;
-+                    list[keys].attrs[0].mandatory = 0;
-+
-+                    pkey->listFetch_s += comment_len;
-+                } else {
-+                    list[keys].num_attrs = 0;
-+                    list[keys].attrs = NULL;
-+                }
-+                list[keys].name_len = libssh2_ntohu32(pkey->listFetch_s);
-+                pkey->listFetch_s += 4;
-+                list[keys].name = pkey->listFetch_s;
-+                pkey->listFetch_s += list[keys].name_len;
-+                list[keys].blob_len = libssh2_ntohu32(pkey->listFetch_s);
-+                pkey->listFetch_s += 4;
-+                list[keys].blob = pkey->listFetch_s;
-+                pkey->listFetch_s += list[keys].blob_len;
-+            } else {
-+                /* Version == 2 */
-+                list[keys].name_len = libssh2_ntohu32(pkey->listFetch_s);
-+                pkey->listFetch_s += 4;
-+                list[keys].name = pkey->listFetch_s;
-+                pkey->listFetch_s += list[keys].name_len;
-+                list[keys].blob_len = libssh2_ntohu32(pkey->listFetch_s);
-+                pkey->listFetch_s += 4;
-+                list[keys].blob = pkey->listFetch_s;
-+                pkey->listFetch_s += list[keys].blob_len;
-+                list[keys].num_attrs = libssh2_ntohu32(pkey->listFetch_s);
-+                pkey->listFetch_s += 4;
-+                if (list[keys].num_attrs) {
-+                    list[keys].attrs =
-+                        LIBSSH2_ALLOC(session,
-+                                      list[keys].num_attrs *
-+                                      sizeof(libssh2_publickey_attribute));
-+                    if (!list[keys].attrs) {
-+                        libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                                      "Unable to allocate memory for publickey attributes",
-+                                      0);
-+                        goto err_exit;
-+                    }
-+                    for(i = 0; i < list[keys].num_attrs; i++) {
-+                        list[keys].attrs[i].name_len =
-+                            libssh2_ntohu32(pkey->listFetch_s);
-+                        pkey->listFetch_s += 4;
-+                        list[keys].attrs[i].name = (char *) pkey->listFetch_s;
-+                        pkey->listFetch_s += list[keys].attrs[i].name_len;
-+                        list[keys].attrs[i].value_len =
-+                            libssh2_ntohu32(pkey->listFetch_s);
-+                        pkey->listFetch_s += 4;
-+                        list[keys].attrs[i].value = (char *) pkey->listFetch_s;
-+                        pkey->listFetch_s += list[keys].attrs[i].value_len;
-+                        list[keys].attrs[i].mandatory = 0;      /* actually an ignored value */
-+                    }
-+                } else {
-+                    list[keys].attrs = NULL;
-+                }
-+            }
-+            list[keys].packet = pkey->listFetch_data;   /* To be FREEd in libssh2_publickey_list_free() */
-+            keys++;
-+
-+            list[keys].packet = NULL;   /* Terminate the list */
-+            pkey->listFetch_data = NULL;
-+            break;
-+        default:
-+            /* Unknown/Unexpected */
-+            libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
-+                          "Unexpected publickey subsystem response, ignoring",
-+                          0);
-+            LIBSSH2_FREE(session, pkey->listFetch_data);
-+            pkey->listFetch_data = NULL;
-+        }
-+    }
-+
-+    /* Only reached via explicit goto */
-+  err_exit:
-+    if (pkey->listFetch_data) {
-+        LIBSSH2_FREE(session, pkey->listFetch_data);
-+        pkey->listFetch_data = NULL;
-+    }
-+    if (list) {
-+        libssh2_publickey_list_free(pkey, list);
-+    }
-+    pkey->listFetch_state = libssh2_NB_state_idle;
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_publickey_list_free
-+ * Free a previously fetched list of public keys
-+ */
-+LIBSSH2_API void
-+libssh2_publickey_list_free(LIBSSH2_PUBLICKEY * pkey,
-+                            libssh2_publickey_list * pkey_list)
-+{
-+    LIBSSH2_SESSION *session = pkey->channel->session;
-+    libssh2_publickey_list *p = pkey_list;
-+
-+    while (p->packet) {
-+        if (p->attrs) {
-+            LIBSSH2_FREE(session, p->attrs);
-+        }
-+        LIBSSH2_FREE(session, p->packet);
-+        p++;
-+    }
-+
-+    LIBSSH2_FREE(session, pkey_list);
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_publickey_shutdown
-+ * Shutdown the publickey subsystem
-+ */
-+LIBSSH2_API int
-+libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY * pkey)
-+{
-+    LIBSSH2_SESSION *session = pkey->channel->session;
-+
-+    /*
-+     * Make sure all memory used in the state variables are free
-+     */
-+    if (pkey->receive_packet) {
-+        LIBSSH2_FREE(session, pkey->receive_packet);
-+        pkey->receive_packet = NULL;
-+    }
-+    if (pkey->add_packet) {
-+        LIBSSH2_FREE(session, pkey->add_packet);
-+        pkey->add_packet = NULL;
-+    }
-+    if (pkey->remove_packet) {
-+        LIBSSH2_FREE(session, pkey->remove_packet);
-+        pkey->remove_packet = NULL;
-+    }
-+    if (pkey->listFetch_data) {
-+        LIBSSH2_FREE(session, pkey->listFetch_data);
-+        pkey->listFetch_data = NULL;
-+    }
-+
-+    if (libssh2_channel_free(pkey->channel) == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    }
-+
-+    LIBSSH2_FREE(session, pkey);
-+    return 0;
-+}
-+
-+/* }}} */
-
-Property changes on: libssh2/src/publickey.c
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.4
-Added: svn:eol-style
-   + native
-
-Index: libssh2/src/kex.c
-===================================================================
---- libssh2/src/kex.c  (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/kex.c  (.../trunk)
-@@ -0,0 +1,1916 @@
-+/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#include "libssh2_priv.h"
-+
-+/* TODO: Switch this to an inline and handle alloc() failures */
-+/* Helper macro called from libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange */
-+#define LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(value, reqlen, version) \
-+{                                                                           \
-+    libssh2_sha1_ctx hash;                                                  \
-+    unsigned long len = 0;                                                  \
-+    if (!(value)) {                                                         \
-+        value = LIBSSH2_ALLOC(session, reqlen + SHA_DIGEST_LENGTH);         \
-+    }                                                                       \
-+    if (value)                                                              \
-+        while (len < (unsigned long)reqlen) {                               \
-+            libssh2_sha1_init(&hash);                                       \
-+            libssh2_sha1_update(hash, exchange_state->k_value,              \
-+                                exchange_state->k_value_len);               \
-+            libssh2_sha1_update(hash, exchange_state->h_sig_comp,           \
-+                                SHA_DIGEST_LENGTH);                         \
-+            if (len > 0) {                                                  \
-+                libssh2_sha1_update(hash, value, len);                      \
-+            }    else {                                                     \
-+                libssh2_sha1_update(hash, (version), 1);                    \
-+                libssh2_sha1_update(hash, session->session_id,              \
-+                                    session->session_id_len);               \
-+            }                                                               \
-+            libssh2_sha1_final(hash, (value) + len);                        \
-+            len += SHA_DIGEST_LENGTH;                                       \
-+        }                                                                   \
-+}
-+
-+/* {{{ libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange
-+ * Diffie Hellman Key Exchange, Group Agnostic
-+ */
-+static int
-+libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *
-+                                                            session,
-+                                                            _libssh2_bn * g,
-+                                                            _libssh2_bn * p,
-+                                                            int group_order,
-+                                                            unsigned char
-+                                                            packet_type_init,
-+                                                            unsigned char
-+                                                            packet_type_reply,
-+                                                            unsigned char
-+                                                            *midhash,
-+                                                            unsigned long
-+                                                            midhash_len,
-+                                                            kmdhgGPsha1kex_state_t
-+                                                            * exchange_state)
-+{
-+    int ret = 0;
-+    int rc;
-+
-+    if (exchange_state->state == libssh2_NB_state_idle) {
-+        /* Setup initial values */
-+        exchange_state->e_packet = NULL;
-+        exchange_state->s_packet = NULL;
-+        exchange_state->k_value = NULL;
-+        exchange_state->ctx = _libssh2_bn_ctx_new();
-+        exchange_state->x = _libssh2_bn_init(); /* Random from client */
-+        exchange_state->e = _libssh2_bn_init(); /* g^x mod p */
-+        exchange_state->f = _libssh2_bn_init(); /* g^(Random from server) mod p */
-+        exchange_state->k = _libssh2_bn_init(); /* The shared secret: f^x mod p */
-+
-+        /* Zero the whole thing out */
-+        memset(&exchange_state->req_state, 0, sizeof(packet_require_state_t));
-+
-+        /* Generate x and e */
-+        _libssh2_bn_rand(exchange_state->x, group_order, 0, -1);
-+        _libssh2_bn_mod_exp(exchange_state->e, g, exchange_state->x, p,
-+                            exchange_state->ctx);
-+
-+        /* Send KEX init */
-+        /* packet_type(1) + String Length(4) + leading 0(1) */
-+        exchange_state->e_packet_len =
-+            _libssh2_bn_bytes(exchange_state->e) + 6;
-+        if (_libssh2_bn_bits(exchange_state->e) % 8) {
-+            /* Leading 00 not needed */
-+            exchange_state->e_packet_len--;
-+        }
-+
-+        exchange_state->e_packet =
-+            LIBSSH2_ALLOC(session, exchange_state->e_packet_len);
-+        if (!exchange_state->e_packet) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Out of memory error",
-+                          0);
-+            ret = -1;
-+            goto clean_exit;
-+        }
-+        exchange_state->e_packet[0] = packet_type_init;
-+        libssh2_htonu32(exchange_state->e_packet + 1,
-+                        exchange_state->e_packet_len - 5);
-+        if (_libssh2_bn_bits(exchange_state->e) % 8) {
-+            _libssh2_bn_to_bin(exchange_state->e,
-+                               exchange_state->e_packet + 5);
-+        } else {
-+            exchange_state->e_packet[5] = 0;
-+            _libssh2_bn_to_bin(exchange_state->e,
-+                               exchange_state->e_packet + 6);
-+        }
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sending KEX packet %d",
-+                       (int) packet_type_init);
-+        exchange_state->state = libssh2_NB_state_created;
-+    }
-+
-+    if (exchange_state->state == libssh2_NB_state_created) {
-+        rc = libssh2_packet_write(session, exchange_state->e_packet,
-+                                  exchange_state->e_packet_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send KEX init message", 0);
-+            ret = -1;
-+            goto clean_exit;
-+        }
-+        exchange_state->state = libssh2_NB_state_sent;
-+    }
-+
-+    if (exchange_state->state == libssh2_NB_state_sent) {
-+        if (session->burn_optimistic_kexinit) {
-+            /* The first KEX packet to come along will be the guess initially 
-+             * sent by the server.  That guess turned out to be wrong so we
-+             * need to silently ignore it */
-+            int burn_type;
-+
-+            _libssh2_debug(session, LIBSSH2_DBG_KEX,
-+                           "Waiting for badly guessed KEX packet (to be ignored)");
-+            burn_type =
-+                libssh2_packet_burn(session, &exchange_state->burn_state);
-+            if (burn_type == PACKET_EAGAIN) {
-+                return PACKET_EAGAIN;
-+            } else if (burn_type <= 0) {
-+                /* Failed to receive a packet */
-+                ret = -1;
-+                goto clean_exit;
-+            }
-+            session->burn_optimistic_kexinit = 0;
-+
-+            _libssh2_debug(session, LIBSSH2_DBG_KEX,
-+                           "Burnt packet of type: %02x",
-+                           (unsigned int) burn_type);
-+        }
-+
-+        exchange_state->state = libssh2_NB_state_sent1;
-+    }
-+
-+    if (exchange_state->state == libssh2_NB_state_sent1) {
-+        /* Wait for KEX reply */
-+        rc = libssh2_packet_require_ex(session, packet_type_reply,
-+                                       &exchange_state->s_packet,
-+                                       &exchange_state->s_packet_len, 0, NULL,
-+                                       0, &exchange_state->req_state);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        }
-+        if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
-+                          "Timed out waiting for KEX reply", 0);
-+            ret = -1;
-+            goto clean_exit;
-+        }
-+
-+        /* Parse KEXDH_REPLY */
-+        exchange_state->s = exchange_state->s_packet + 1;
-+
-+        session->server_hostkey_len = libssh2_ntohu32(exchange_state->s);
-+        exchange_state->s += 4;
-+        session->server_hostkey =
-+            LIBSSH2_ALLOC(session, session->server_hostkey_len);
-+        if (!session->server_hostkey) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory for a copy of the host key",
-+                          0);
-+            ret = -1;
-+            goto clean_exit;
-+        }
-+        memcpy(session->server_hostkey, exchange_state->s,
-+               session->server_hostkey_len);
-+        exchange_state->s += session->server_hostkey_len;
-+
-+#if LIBSSH2_MD5
-+        {
-+            libssh2_md5_ctx fingerprint_ctx;
-+
-+            libssh2_md5_init(&fingerprint_ctx);
-+            libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
-+                               session->server_hostkey_len);
-+            libssh2_md5_final(fingerprint_ctx, session->server_hostkey_md5);
-+        }
-+#ifdef LIBSSH2DEBUG
-+        {
-+            char fingerprint[50], *fprint = fingerprint;
-+            int i;
-+            for(i = 0; i < 16; i++, fprint += 3) {
-+                snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]);
-+            }
-+            *(--fprint) = '\0';
-+            _libssh2_debug(session, LIBSSH2_DBG_KEX,
-+                           "Server's MD5 Fingerprint: %s", fingerprint);
-+        }
-+#endif /* LIBSSH2DEBUG */
-+#endif /* ! LIBSSH2_MD5 */
-+
-+        {
-+            libssh2_sha1_ctx fingerprint_ctx;
-+
-+            libssh2_sha1_init(&fingerprint_ctx);
-+            libssh2_sha1_update(fingerprint_ctx, session->server_hostkey,
-+                                session->server_hostkey_len);
-+            libssh2_sha1_final(fingerprint_ctx, session->server_hostkey_sha1);
-+        }
-+#ifdef LIBSSH2DEBUG
-+        {
-+            char fingerprint[64], *fprint = fingerprint;
-+            int i;
-+
-+            for(i = 0; i < 20; i++, fprint += 3) {
-+                snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]);
-+            }
-+            *(--fprint) = '\0';
-+            _libssh2_debug(session, LIBSSH2_DBG_KEX,
-+                           "Server's SHA1 Fingerprint: %s", fingerprint);
-+        }
-+#endif /* LIBSSH2DEBUG */
-+
-+        if (session->hostkey->
-+            init(session, session->server_hostkey, session->server_hostkey_len,
-+                 &session->server_hostkey_abstract)) {
-+            libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
-+                          "Unable to initialize hostkey importer", 0);
-+            ret = -1;
-+            goto clean_exit;
-+        }
-+
-+        exchange_state->f_value_len = libssh2_ntohu32(exchange_state->s);
-+        exchange_state->s += 4;
-+        exchange_state->f_value = exchange_state->s;
-+        exchange_state->s += exchange_state->f_value_len;
-+        _libssh2_bn_from_bin(exchange_state->f, exchange_state->f_value_len,
-+                             exchange_state->f_value);
-+
-+        exchange_state->h_sig_len = libssh2_ntohu32(exchange_state->s);
-+        exchange_state->s += 4;
-+        exchange_state->h_sig = exchange_state->s;
-+
-+        /* Compute the shared secret */
-+        _libssh2_bn_mod_exp(exchange_state->k, exchange_state->f,
-+                            exchange_state->x, p, exchange_state->ctx);
-+        exchange_state->k_value_len = _libssh2_bn_bytes(exchange_state->k) + 5;
-+        if (_libssh2_bn_bits(exchange_state->k) % 8) {
-+            /* don't need leading 00 */
-+            exchange_state->k_value_len--;
-+        }
-+        exchange_state->k_value =
-+            LIBSSH2_ALLOC(session, exchange_state->k_value_len);
-+        if (!exchange_state->k_value) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate buffer for K", 0);
-+            ret = -1;
-+            goto clean_exit;
-+        }
-+        libssh2_htonu32(exchange_state->k_value,
-+                        exchange_state->k_value_len - 4);
-+        if (_libssh2_bn_bits(exchange_state->k) % 8) {
-+            _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 4);
-+        } else {
-+            exchange_state->k_value[4] = 0;
-+            _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 5);
-+        }
-+
-+        libssh2_sha1_init(&exchange_state->exchange_hash);
-+        if (session->local.banner) {
-+            libssh2_htonu32(exchange_state->h_sig_comp,
-+                            strlen((char *) session->local.banner) - 2);
-+            libssh2_sha1_update(exchange_state->exchange_hash,
-+                                exchange_state->h_sig_comp, 4);
-+            libssh2_sha1_update(exchange_state->exchange_hash,
-+                                (char *) session->local.banner,
-+                                strlen((char *) session->local.banner) - 2);
-+        } else {
-+            libssh2_htonu32(exchange_state->h_sig_comp,
-+                            sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1);
-+            libssh2_sha1_update(exchange_state->exchange_hash,
-+                                exchange_state->h_sig_comp, 4);
-+            libssh2_sha1_update(exchange_state->exchange_hash,
-+                                LIBSSH2_SSH_DEFAULT_BANNER,
-+                                sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1);
-+        }
-+
-+        libssh2_htonu32(exchange_state->h_sig_comp,
-+                        strlen((char *) session->remote.banner));
-+        libssh2_sha1_update(exchange_state->exchange_hash,
-+                            exchange_state->h_sig_comp, 4);
-+        libssh2_sha1_update(exchange_state->exchange_hash,
-+                            session->remote.banner,
-+                            strlen((char *) session->remote.banner));
-+
-+        libssh2_htonu32(exchange_state->h_sig_comp,
-+                        session->local.kexinit_len);
-+        libssh2_sha1_update(exchange_state->exchange_hash,
-+                            exchange_state->h_sig_comp, 4);
-+        libssh2_sha1_update(exchange_state->exchange_hash,
-+                            session->local.kexinit,
-+                            session->local.kexinit_len);
-+
-+        libssh2_htonu32(exchange_state->h_sig_comp,
-+                        session->remote.kexinit_len);
-+        libssh2_sha1_update(exchange_state->exchange_hash,
-+                            exchange_state->h_sig_comp, 4);
-+        libssh2_sha1_update(exchange_state->exchange_hash,
-+                            session->remote.kexinit,
-+                            session->remote.kexinit_len);
-+
-+        libssh2_htonu32(exchange_state->h_sig_comp,
-+                        session->server_hostkey_len);
-+        libssh2_sha1_update(exchange_state->exchange_hash,
-+                            exchange_state->h_sig_comp, 4);
-+        libssh2_sha1_update(exchange_state->exchange_hash,
-+                            session->server_hostkey,
-+                            session->server_hostkey_len);
-+
-+        if (packet_type_init == SSH_MSG_KEX_DH_GEX_INIT) {
-+            /* diffie-hellman-group-exchange hashes additional fields */
-+#ifdef LIBSSH2_DH_GEX_NEW
-+            libssh2_htonu32(exchange_state->h_sig_comp,
-+                            LIBSSH2_DH_GEX_MINGROUP);
-+            libssh2_htonu32(exchange_state->h_sig_comp + 4,
-+                            LIBSSH2_DH_GEX_OPTGROUP);
-+            libssh2_htonu32(exchange_state->h_sig_comp + 8,
-+                            LIBSSH2_DH_GEX_MAXGROUP);
-+            libssh2_sha1_update(exchange_state->exchange_hash,
-+                                exchange_state->h_sig_comp, 12);
-+#else
-+            libssh2_htonu32(exchange_state->h_sig_comp,
-+                            LIBSSH2_DH_GEX_OPTGROUP);
-+            libssh2_sha1_update(exchange_state->exchange_hash,
-+                                exchange_state->h_sig_comp, 4);
-+#endif
-+        }
-+
-+        if (midhash) {
-+            libssh2_sha1_update(exchange_state->exchange_hash, midhash,
-+                                midhash_len);
-+        }
-+
-+        libssh2_sha1_update(exchange_state->exchange_hash,
-+                            exchange_state->e_packet + 1,
-+                            exchange_state->e_packet_len - 1);
-+
-+        libssh2_htonu32(exchange_state->h_sig_comp,
-+                        exchange_state->f_value_len);
-+        libssh2_sha1_update(exchange_state->exchange_hash,
-+                            exchange_state->h_sig_comp, 4);
-+        libssh2_sha1_update(exchange_state->exchange_hash,
-+                            exchange_state->f_value,
-+                            exchange_state->f_value_len);
-+
-+        libssh2_sha1_update(exchange_state->exchange_hash,
-+                            exchange_state->k_value,
-+                            exchange_state->k_value_len);
-+
-+        libssh2_sha1_final(exchange_state->exchange_hash,
-+                           exchange_state->h_sig_comp);
-+
-+        if (session->hostkey->
-+            sig_verify(session, exchange_state->h_sig,
-+                       exchange_state->h_sig_len, exchange_state->h_sig_comp,
-+                       20, &session->server_hostkey_abstract)) {
-+            libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN,
-+                          "Unable to verify hostkey signature", 0);
-+            ret = -1;
-+            goto clean_exit;
-+        }
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sending NEWKEYS message");
-+        exchange_state->c = SSH_MSG_NEWKEYS;
-+
-+        exchange_state->state = libssh2_NB_state_sent2;
-+    }
-+
-+    if (exchange_state->state == libssh2_NB_state_sent2) {
-+        rc = libssh2_packet_write(session, &exchange_state->c, 1);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send NEWKEYS message", 0);
-+            ret = -1;
-+            goto clean_exit;
-+        }
-+
-+        exchange_state->state = libssh2_NB_state_sent3;
-+    }
-+
-+    if (exchange_state->state == libssh2_NB_state_sent3) {
-+        rc = libssh2_packet_require_ex(session, SSH_MSG_NEWKEYS,
-+                                       &exchange_state->tmp,
-+                                       &exchange_state->tmp_len, 0, NULL, 0,
-+                                       &exchange_state->req_state);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
-+                          "Timed out waiting for NEWKEYS", 0);
-+            ret = -1;
-+            goto clean_exit;
-+        }
-+        /* The first key exchange has been performed, 
-+           switch to active crypt/comp/mac mode */
-+        session->state |= LIBSSH2_STATE_NEWKEYS;
-+        _libssh2_debug(session, LIBSSH2_DBG_KEX, "Received NEWKEYS message");
-+
-+        /* This will actually end up being just packet_type(1) 
-+           for this packet type anyway */
-+        LIBSSH2_FREE(session, exchange_state->tmp);
-+
-+        if (!session->session_id) {
-+            session->session_id = LIBSSH2_ALLOC(session, SHA_DIGEST_LENGTH);
-+            if (!session->session_id) {
-+                ret = -1;
-+                goto clean_exit;
-+            }
-+            memcpy(session->session_id, exchange_state->h_sig_comp,
-+                   SHA_DIGEST_LENGTH);
-+            session->session_id_len = SHA_DIGEST_LENGTH;
-+            _libssh2_debug(session, LIBSSH2_DBG_KEX, "session_id calculated");
-+        }
-+
-+        /* Cleanup any existing cipher */
-+        if (session->local.crypt->dtor) {
-+            session->local.crypt->dtor(session,
-+                                       &session->local.crypt_abstract);
-+        }
-+
-+        /* Calculate IV/Secret/Key for each direction */
-+        if (session->local.crypt->init) {
-+            unsigned char *iv = NULL, *secret = NULL;
-+            int free_iv = 0, free_secret = 0;
-+
-+            LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv,
-+                                                        session->local.crypt->
-+                                                        iv_len, "A");
-+            if (!iv) {
-+                ret = -1;
-+                goto clean_exit;
-+            }
-+            LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret,
-+                                                        session->local.crypt->
-+                                                        secret_len, "C");
-+            if (!secret) {
-+                LIBSSH2_FREE(session, iv);
-+                ret = -1;
-+                goto clean_exit;
-+            }
-+            if (session->local.crypt->
-+                init(session, session->local.crypt, iv, &free_iv, secret,
-+                     &free_secret, 1, &session->local.crypt_abstract)) {
-+                LIBSSH2_FREE(session, iv);
-+                LIBSSH2_FREE(session, secret);
-+                ret = -1;
-+                goto clean_exit;
-+            }
-+
-+            if (free_iv) {
-+                memset(iv, 0, session->local.crypt->iv_len);
-+                LIBSSH2_FREE(session, iv);
-+            }
-+
-+            if (free_secret) {
-+                memset(secret, 0, session->local.crypt->secret_len);
-+                LIBSSH2_FREE(session, secret);
-+            }
-+        }
-+        _libssh2_debug(session, LIBSSH2_DBG_KEX,
-+                       "Client to Server IV and Key calculated");
-+
-+        if (session->remote.crypt->dtor) {
-+            /* Cleanup any existing cipher */
-+            session->remote.crypt->dtor(session,
-+                                        &session->remote.crypt_abstract);
-+        }
-+
-+        if (session->remote.crypt->init) {
-+            unsigned char *iv = NULL, *secret = NULL;
-+            int free_iv = 0, free_secret = 0;
-+
-+            LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv,
-+                                                        session->remote.crypt->
-+                                                        iv_len, "B");
-+            if (!iv) {
-+                ret = -1;
-+                goto clean_exit;
-+            }
-+            LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret,
-+                                                        session->remote.crypt->
-+                                                        secret_len, "D");
-+            if (!secret) {
-+                LIBSSH2_FREE(session, iv);
-+                ret = -1;
-+                goto clean_exit;
-+            }
-+            if (session->remote.crypt->
-+                init(session, session->remote.crypt, iv, &free_iv, secret,
-+                     &free_secret, 0, &session->remote.crypt_abstract)) {
-+                LIBSSH2_FREE(session, iv);
-+                LIBSSH2_FREE(session, secret);
-+                ret = -1;
-+                goto clean_exit;
-+            }
-+
-+            if (free_iv) {
-+                memset(iv, 0, session->remote.crypt->iv_len);
-+                LIBSSH2_FREE(session, iv);
-+            }
-+
-+            if (free_secret) {
-+                memset(secret, 0, session->remote.crypt->secret_len);
-+                LIBSSH2_FREE(session, secret);
-+            }
-+        }
-+        _libssh2_debug(session, LIBSSH2_DBG_KEX,
-+                       "Server to Client IV and Key calculated");
-+
-+        if (session->local.mac->dtor) {
-+            session->local.mac->dtor(session, &session->local.mac_abstract);
-+        }
-+
-+        if (session->local.mac->init) {
-+            unsigned char *key = NULL;
-+            int free_key = 0;
-+
-+            LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key,
-+                                                        session->local.mac->
-+                                                        key_len, "E");
-+            if (!key) {
-+                ret = -1;
-+                goto clean_exit;
-+            }
-+            session->local.mac->init(session, key, &free_key,
-+                                     &session->local.mac_abstract);
-+
-+            if (free_key) {
-+                memset(key, 0, session->local.mac->key_len);
-+                LIBSSH2_FREE(session, key);
-+            }
-+        }
-+        _libssh2_debug(session, LIBSSH2_DBG_KEX,
-+                       "Client to Server HMAC Key calculated");
-+
-+        if (session->remote.mac->dtor) {
-+            session->remote.mac->dtor(session, &session->remote.mac_abstract);
-+        }
-+
-+        if (session->remote.mac->init) {
-+            unsigned char *key = NULL;
-+            int free_key = 0;
-+
-+            LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key,
-+                                                        session->remote.mac->
-+                                                        key_len, "F");
-+            if (!key) {
-+                ret = -1;
-+                goto clean_exit;
-+            }
-+            session->remote.mac->init(session, key, &free_key,
-+                                      &session->remote.mac_abstract);
-+
-+            if (free_key) {
-+                memset(key, 0, session->remote.mac->key_len);
-+                LIBSSH2_FREE(session, key);
-+            }
-+        }
-+        _libssh2_debug(session, LIBSSH2_DBG_KEX,
-+                       "Server to Client HMAC Key calculated");
-+    }
-+
-+  clean_exit:
-+    _libssh2_bn_free(exchange_state->x);
-+    exchange_state->x = NULL;
-+    _libssh2_bn_free(exchange_state->e);
-+    exchange_state->e = NULL;
-+    _libssh2_bn_free(exchange_state->f);
-+    exchange_state->f = NULL;
-+    _libssh2_bn_free(exchange_state->k);
-+    exchange_state->k = NULL;
-+    _libssh2_bn_ctx_free(exchange_state->ctx);
-+    exchange_state->ctx = NULL;
-+
-+    if (exchange_state->e_packet) {
-+        LIBSSH2_FREE(session, exchange_state->e_packet);
-+        exchange_state->e_packet = NULL;
-+    }
-+
-+    if (exchange_state->s_packet) {
-+        LIBSSH2_FREE(session, exchange_state->s_packet);
-+        exchange_state->s_packet = NULL;
-+    }
-+
-+    if (exchange_state->k_value) {
-+        LIBSSH2_FREE(session, exchange_state->k_value);
-+        exchange_state->k_value = NULL;
-+    }
-+
-+    if (session->server_hostkey) {
-+        LIBSSH2_FREE(session, session->server_hostkey);
-+        session->server_hostkey = NULL;
-+    }
-+
-+    exchange_state->state = libssh2_NB_state_idle;
-+
-+    return ret;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange
-+ * Diffie-Hellman Group1 (Actually Group2) Key Exchange using SHA1
-+ */
-+static int
-+libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION *
-+                                                           session,
-+                                                           key_exchange_state_low_t
-+                                                           * key_state)
-+{
-+    static const unsigned char p_value[128] = {
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+        0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
-+        0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
-+        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
-+        0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
-+        0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
-+        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
-+        0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
-+        0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
-+        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
-+        0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
-+        0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
-+        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
-+        0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
-+        0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
-+    };
-+
-+    int ret;
-+
-+    if (key_state->state == libssh2_NB_state_idle) {
-+        /* g == 2 */
-+        key_state->p = _libssh2_bn_init();      /* SSH2 defined value (p_value) */
-+        key_state->g = _libssh2_bn_init();      /* SSH2 defined value (2) */
-+
-+        /* Initialize P and G */
-+        _libssh2_bn_set_word(key_state->g, 2);
-+        _libssh2_bn_from_bin(key_state->p, 128, p_value);
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_KEX,
-+                       "Initiating Diffie-Hellman Group1 Key Exchange");
-+
-+        key_state->state = libssh2_NB_state_created;
-+    }
-+
-+    ret =
-+        libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(session,
-+                                                                    key_state->
-+                                                                    g,
-+                                                                    key_state->
-+                                                                    p, 128,
-+                                                                    SSH_MSG_KEXDH_INIT,
-+                                                                    SSH_MSG_KEXDH_REPLY,
-+                                                                    NULL, 0,
-+                                                                    &key_state->
-+                                                                    exchange_state);
-+    if (ret == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    }
-+
-+    _libssh2_bn_free(key_state->p);
-+    key_state->p = NULL;
-+    _libssh2_bn_free(key_state->g);
-+    key_state->g = NULL;
-+    key_state->state = libssh2_NB_state_idle;
-+
-+    return ret;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange
-+ * Diffie-Hellman Group14 Key Exchange using SHA1
-+ */
-+static int
-+libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *
-+                                                            session,
-+                                                            key_exchange_state_low_t
-+                                                            * key_state)
-+{
-+    static const unsigned char p_value[256] = {
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+        0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
-+        0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
-+        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
-+        0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
-+        0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
-+        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
-+        0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
-+        0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
-+        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
-+        0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
-+        0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
-+        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
-+        0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
-+        0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
-+        0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
-+        0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
-+        0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
-+        0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
-+        0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
-+        0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
-+        0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
-+        0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
-+        0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
-+        0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
-+        0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
-+        0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
-+        0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
-+        0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
-+        0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
-+        0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68,
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
-+    };
-+    int ret;
-+
-+    if (key_state->state == libssh2_NB_state_idle) {
-+        key_state->p = _libssh2_bn_init();      /* SSH2 defined value (p_value) */
-+        key_state->g = _libssh2_bn_init();      /* SSH2 defined value (2) */
-+
-+        /* g == 2 */
-+        /* Initialize P and G */
-+        _libssh2_bn_set_word(key_state->g, 2);
-+        _libssh2_bn_from_bin(key_state->p, 256, p_value);
-+
-+        _libssh2_debug(session, LIBSSH2_DBG_KEX,
-+                       "Initiating Diffie-Hellman Group14 Key Exchange");
-+
-+        key_state->state = libssh2_NB_state_created;
-+    }
-+    ret =
-+        libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(session,
-+                                                                    key_state->
-+                                                                    g,
-+                                                                    key_state->
-+                                                                    p, 256,
-+                                                                    SSH_MSG_KEXDH_INIT,
-+                                                                    SSH_MSG_KEXDH_REPLY,
-+                                                                    NULL, 0,
-+                                                                    &key_state->
-+                                                                    exchange_state);
-+    if (ret == PACKET_EAGAIN) {
-+        return PACKET_EAGAIN;
-+    }
-+
-+    key_state->state = libssh2_NB_state_idle;
-+    _libssh2_bn_free(key_state->p);
-+    key_state->p = NULL;
-+    _libssh2_bn_free(key_state->g);
-+    key_state->g = NULL;
-+
-+    return ret;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange
-+ * Diffie-Hellman Group Exchange Key Exchange using SHA1
-+ * Negotiates random(ish) group for secret derivation
-+ */
-+static int
-+    libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange
-+    (LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state)
-+{
-+    unsigned char *s;
-+    unsigned long p_len, g_len;
-+    int ret = 0;
-+    int rc;
-+
-+    if (key_state->state == libssh2_NB_state_idle) {
-+        key_state->p = _libssh2_bn_init();
-+        key_state->g = _libssh2_bn_init();
-+        /* Ask for a P and G pair */
-+#ifdef LIBSSH2_DH_GEX_NEW
-+        key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST;
-+        libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_MINGROUP);
-+        libssh2_htonu32(key_state->request + 5, LIBSSH2_DH_GEX_OPTGROUP);
-+        libssh2_htonu32(key_state->request + 9, LIBSSH2_DH_GEX_MAXGROUP);
-+        key_state->request_len = 13;
-+        _libssh2_debug(session, LIBSSH2_DBG_KEX,
-+                       "Initiating Diffie-Hellman Group-Exchange (New Method)");
-+#else
-+        key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST_OLD;
-+        libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_OPTGROUP);
-+        key_state->request_len = 5;
-+        _libssh2_debug(session, LIBSSH2_DBG_KEX,
-+                       "Initiating Diffie-Hellman Group-Exchange (Old Method)");
-+#endif
-+
-+        key_state->state = libssh2_NB_state_created;
-+    }
-+
-+    if (key_state->state == libssh2_NB_state_created) {
-+        rc = libssh2_packet_write(session, key_state->request,
-+                                  key_state->request_len);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                          "Unable to send Group Exchange Request", 0);
-+            ret = -1;
-+            goto dh_gex_clean_exit;
-+        }
-+
-+        key_state->state = libssh2_NB_state_sent;
-+    }
-+
-+    if (key_state->state == libssh2_NB_state_sent) {
-+        rc = libssh2_packet_require_ex(session, SSH_MSG_KEX_DH_GEX_GROUP,
-+                                       &key_state->data, &key_state->data_len,
-+                                       0, NULL, 0, &key_state->req_state);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc) {
-+            libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
-+                          "Timeout waiting for GEX_GROUP reply", 0);
-+            ret = -1;
-+            goto dh_gex_clean_exit;
-+        }
-+
-+        key_state->state = libssh2_NB_state_sent1;
-+    }
-+
-+    if (key_state->state == libssh2_NB_state_sent1) {
-+        s = key_state->data + 1;
-+        p_len = libssh2_ntohu32(s);
-+        s += 4;
-+        _libssh2_bn_from_bin(key_state->p, p_len, s);
-+        s += p_len;
-+
-+        g_len = libssh2_ntohu32(s);
-+        s += 4;
-+        _libssh2_bn_from_bin(key_state->g, g_len, s);
-+        s += g_len;
-+
-+        ret =
-+            libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange
-+            (session, key_state->g, key_state->p, p_len,
-+             SSH_MSG_KEX_DH_GEX_INIT, SSH_MSG_KEX_DH_GEX_REPLY,
-+             key_state->data + 1, key_state->data_len - 1,
-+             &key_state->exchange_state);
-+        if (ret == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        }
-+
-+        LIBSSH2_FREE(session, key_state->data);
-+    }
-+
-+  dh_gex_clean_exit:
-+    key_state->state = libssh2_NB_state_idle;
-+    _libssh2_bn_free(key_state->g);
-+    key_state->g = NULL;
-+    _libssh2_bn_free(key_state->p);
-+    key_state->p = NULL;
-+
-+    return ret;
-+}
-+
-+/* }}} */
-+
-+#define LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY     0x0001
-+#define LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY    0x0002
-+
-+static const LIBSSH2_KEX_METHOD libssh2_kex_method_diffie_helman_group1_sha1 = {
-+    "diffie-hellman-group1-sha1",
-+    libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange,
-+    LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
-+};
-+
-+static const LIBSSH2_KEX_METHOD libssh2_kex_method_diffie_helman_group14_sha1 = {
-+    "diffie-hellman-group14-sha1",
-+    libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange,
-+    LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
-+};
-+
-+static const LIBSSH2_KEX_METHOD
-+    libssh2_kex_method_diffie_helman_group_exchange_sha1 = {
-+    "diffie-hellman-group-exchange-sha1",
-+    libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange,
-+    LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
-+};
-+
-+static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = {
-+    &libssh2_kex_method_diffie_helman_group14_sha1,
-+    &libssh2_kex_method_diffie_helman_group_exchange_sha1,
-+    &libssh2_kex_method_diffie_helman_group1_sha1,
-+    NULL
-+};
-+
-+typedef struct _LIBSSH2_COMMON_METHOD
-+{
-+    const char *name;
-+} LIBSSH2_COMMON_METHOD;
-+
-+/* {{{ libssh2_kex_method_strlen
-+ * Calculate the length of a particular method list's resulting string
-+ * Includes SUM(strlen() of each individual method plus 1 (for coma)) - 1 (because the last coma isn't used)
-+ * Another sign of bad coding practices gone mad.  Pretend you don't see this.
-+ */
-+static size_t
-+libssh2_kex_method_strlen(LIBSSH2_COMMON_METHOD ** method)
-+{
-+    size_t len = 0;
-+
-+    if (!method || !*method) {
-+        return 0;
-+    }
-+
-+    while (*method && (*method)->name) {
-+        len += strlen((*method)->name) + 1;
-+        method++;
-+    }
-+
-+    return len - 1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_kex_method_list
-+ * Generate formatted preference list in buf
-+ */
-+static size_t
-+libssh2_kex_method_list(unsigned char *buf, size_t list_strlen,
-+                        LIBSSH2_COMMON_METHOD ** method)
-+{
-+    libssh2_htonu32(buf, list_strlen);
-+    buf += 4;
-+
-+    if (!method || !*method) {
-+        return 4;
-+    }
-+
-+    while (*method && (*method)->name) {
-+        int mlen = strlen((*method)->name);
-+        memcpy(buf, (*method)->name, mlen);
-+        buf += mlen;
-+        *(buf++) = ',';
-+        method++;
-+    }
-+
-+    return list_strlen + 4;
-+}
-+
-+/* }}} */
-+
-+#define LIBSSH2_METHOD_PREFS_LEN(prefvar, defaultvar)   ((prefvar) ? strlen(prefvar) : libssh2_kex_method_strlen((LIBSSH2_COMMON_METHOD**)(defaultvar)))
-+#define LIBSSH2_METHOD_PREFS_STR(buf, prefvarlen, prefvar, defaultvar)                              \
-+    if (prefvar) {                                                                                  \
-+        libssh2_htonu32((buf), (prefvarlen));                                                       \
-+        buf += 4;                                                                                   \
-+        memcpy((buf), (prefvar), (prefvarlen));                                                     \
-+        buf += (prefvarlen);                                                                        \
-+    } else {                                                                                        \
-+        buf += libssh2_kex_method_list((buf), (prefvarlen), (LIBSSH2_COMMON_METHOD**)(defaultvar)); \
-+    }
-+
-+/* {{{ libssh2_kexinit
-+ * Send SSH_MSG_KEXINIT packet
-+ */
-+static int
-+libssh2_kexinit(LIBSSH2_SESSION * session)
-+{
-+    /* 62 = packet_type(1) + cookie(16) + first_packet_follows(1) + 
-+       reserved(4) + length longs(40) */
-+    size_t data_len = 62;
-+    size_t kex_len, hostkey_len = 0;
-+    size_t crypt_cs_len, crypt_sc_len;
-+    size_t comp_cs_len, comp_sc_len;
-+    size_t mac_cs_len, mac_sc_len;
-+    size_t lang_cs_len, lang_sc_len;
-+    unsigned char *data, *s;
-+    int rc;
-+
-+    if (session->kexinit_state == libssh2_NB_state_idle) {
-+        kex_len =
-+            LIBSSH2_METHOD_PREFS_LEN(session->kex_prefs, libssh2_kex_methods);
-+        hostkey_len =
-+            LIBSSH2_METHOD_PREFS_LEN(session->hostkey_prefs,
-+                                     libssh2_hostkey_methods());
-+        crypt_cs_len =
-+            LIBSSH2_METHOD_PREFS_LEN(session->local.crypt_prefs,
-+                                     libssh2_crypt_methods());
-+        crypt_sc_len =
-+            LIBSSH2_METHOD_PREFS_LEN(session->remote.crypt_prefs,
-+                                     libssh2_crypt_methods());
-+        mac_cs_len =
-+            LIBSSH2_METHOD_PREFS_LEN(session->local.mac_prefs,
-+                                     libssh2_mac_methods());
-+        mac_sc_len =
-+            LIBSSH2_METHOD_PREFS_LEN(session->remote.mac_prefs,
-+                                     libssh2_mac_methods());
-+        comp_cs_len =
-+            LIBSSH2_METHOD_PREFS_LEN(session->local.comp_prefs,
-+                                     libssh2_comp_methods());
-+        comp_sc_len =
-+            LIBSSH2_METHOD_PREFS_LEN(session->remote.comp_prefs,
-+                                     libssh2_comp_methods());
-+        lang_cs_len =
-+            LIBSSH2_METHOD_PREFS_LEN(session->local.lang_prefs, NULL);
-+        lang_sc_len =
-+            LIBSSH2_METHOD_PREFS_LEN(session->remote.lang_prefs, NULL);
-+
-+        data_len += kex_len + hostkey_len + crypt_cs_len + crypt_sc_len +
-+            comp_cs_len + comp_sc_len + mac_cs_len + mac_sc_len +
-+            lang_cs_len + lang_sc_len;
-+
-+        s = data = LIBSSH2_ALLOC(session, data_len);
-+        if (!data) {
-+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                          "Unable to allocate memory", 0);
-+            return -1;
-+        }
-+
-+        *(s++) = SSH_MSG_KEXINIT;
-+
-+        libssh2_random(s, 16);
-+        s += 16;
-+
-+        /* Ennumerating through these lists twice is probably (certainly?) 
-+           inefficient from a CPU standpoint, but it saves multiple 
-+           malloc/realloc calls */
-+        LIBSSH2_METHOD_PREFS_STR(s, kex_len, session->kex_prefs,
-+                                 libssh2_kex_methods);
-+        LIBSSH2_METHOD_PREFS_STR(s, hostkey_len, session->hostkey_prefs,
-+                                 libssh2_hostkey_methods());
-+        LIBSSH2_METHOD_PREFS_STR(s, crypt_cs_len, session->local.crypt_prefs,
-+                                 libssh2_crypt_methods());
-+        LIBSSH2_METHOD_PREFS_STR(s, crypt_sc_len, session->remote.crypt_prefs,
-+                                 libssh2_crypt_methods());
-+        LIBSSH2_METHOD_PREFS_STR(s, mac_cs_len, session->local.mac_prefs,
-+                                 libssh2_mac_methods());
-+        LIBSSH2_METHOD_PREFS_STR(s, mac_sc_len, session->remote.mac_prefs,
-+                                 libssh2_mac_methods());
-+        LIBSSH2_METHOD_PREFS_STR(s, comp_cs_len, session->local.comp_prefs,
-+                                 libssh2_comp_methods());
-+        LIBSSH2_METHOD_PREFS_STR(s, comp_sc_len, session->remote.comp_prefs,
-+                                 libssh2_comp_methods());
-+        LIBSSH2_METHOD_PREFS_STR(s, lang_cs_len, session->local.lang_prefs,
-+                                 NULL);
-+        LIBSSH2_METHOD_PREFS_STR(s, lang_sc_len, session->remote.lang_prefs,
-+                                 NULL);
-+
-+        /* No optimistic KEX packet follows */
-+        /* Deal with optimistic packets
-+         * session->flags |= KEXINIT_OPTIMISTIC
-+         * session->flags |= KEXINIT_METHODSMATCH
-+         */
-+        *(s++) = 0;
-+
-+        /* Reserved == 0 */
-+        *(s++) = 0;
-+        *(s++) = 0;
-+        *(s++) = 0;
-+        *(s++) = 0;
-+
-+#ifdef LIBSSH2DEBUG
-+        {
-+            /* Funnily enough, they'll all "appear" to be '\0' terminated */
-+            unsigned char *p = data + 21;       /* type(1) + cookie(16) + len(4) */
-+
-+            _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent KEX: %s", p);
-+            p += kex_len + 4;
-+            _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent HOSTKEY: %s", p);
-+            p += hostkey_len + 4;
-+            _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent CRYPT_CS: %s", p);
-+            p += crypt_cs_len + 4;
-+            _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent CRYPT_SC: %s", p);
-+            p += crypt_sc_len + 4;
-+            _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent MAC_CS: %s", p);
-+            p += mac_cs_len + 4;
-+            _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent MAC_SC: %s", p);
-+            p += mac_sc_len + 4;
-+            _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent COMP_CS: %s", p);
-+            p += comp_cs_len + 4;
-+            _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent COMP_SC: %s", p);
-+            p += comp_sc_len + 4;
-+            _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent LANG_CS: %s", p);
-+            p += lang_cs_len + 4;
-+            _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent LANG_SC: %s", p);
-+            p += lang_sc_len + 4;
-+        }
-+#endif /* LIBSSH2DEBUG */
-+
-+        session->kexinit_state = libssh2_NB_state_created;
-+    } else {
-+        data = session->kexinit_data;
-+        data_len = session->kexinit_data_len;
-+    }
-+
-+    if ((rc = libssh2_packet_write(session, data, data_len)) == PACKET_EAGAIN) {
-+        session->kexinit_data = data;
-+        session->kexinit_data_len = data_len;
-+        return PACKET_EAGAIN;
-+    } else if (rc) {
-+        LIBSSH2_FREE(session, data);
-+        libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
-+                      "Unable to send KEXINIT packet to remote host", 0);
-+        session->kexinit_state = libssh2_NB_state_idle;
-+        return -1;
-+    }
-+
-+    if (session->local.kexinit) {
-+        LIBSSH2_FREE(session, session->local.kexinit);
-+    }
-+
-+    session->local.kexinit = data;
-+    session->local.kexinit_len = data_len;
-+
-+    session->kexinit_state = libssh2_NB_state_idle;
-+
-+    return 0;
-+}
-+
-+/* }}}  */
-+
-+/* {{{ libssh2_kex_agree_instr
-+ * Kex specific variant of strstr()
-+ * Needle must be preceed by BOL or ',', and followed by ',' or EOL
-+ */
-+static unsigned char *
-+libssh2_kex_agree_instr(unsigned char *haystack, unsigned long haystack_len,
-+                        const unsigned char *needle, unsigned long needle_len)
-+{
-+    unsigned char *s;
-+
-+    /* Haystack too short to bother trying */
-+    if (haystack_len < needle_len) {
-+        return NULL;
-+    }
-+
-+    /* Needle at start of haystack */
-+    if ((strncmp((char *) haystack, (char *) needle, needle_len) == 0) &&
-+        (needle_len == haystack_len || haystack[needle_len] == ',')) {
-+        return haystack;
-+    }
-+
-+    s = haystack;
-+    /* Search until we run out of comas or we run out of haystack,
-+       whichever comes first */
-+    while ((s = (unsigned char *) strchr((char *) s, ','))
-+           && ((haystack_len - (s - haystack)) > needle_len)) {
-+        s++;
-+        /* Needle at X position */
-+        if ((strncmp((char *) s, (char *) needle, needle_len) == 0) &&
-+            (((s - haystack) + needle_len) == haystack_len
-+             || s[needle_len] == ',')) {
-+            return s;
-+        }
-+    }
-+
-+    return NULL;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_get_method_by_name
-+ */
-+static const LIBSSH2_COMMON_METHOD *
-+libssh2_get_method_by_name(const char *name, int name_len,
-+                           const LIBSSH2_COMMON_METHOD ** methodlist)
-+{
-+    while (*methodlist) {
-+        if ((strlen((*methodlist)->name) == name_len) &&
-+            (strncmp((*methodlist)->name, name, name_len) == 0)) {
-+            return *methodlist;
-+        }
-+        methodlist++;
-+    }
-+    return NULL;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_kex_agree_hostkey
-+ * Agree on a Hostkey which works with this kex
-+ */
-+static int
-+libssh2_kex_agree_hostkey(LIBSSH2_SESSION * session, unsigned long kex_flags,
-+                          unsigned char *hostkey, unsigned long hostkey_len)
-+{
-+    const LIBSSH2_HOSTKEY_METHOD **hostkeyp = libssh2_hostkey_methods();
-+    unsigned char *s;
-+
-+    if (session->hostkey_prefs) {
-+        s = (unsigned char *) session->hostkey_prefs;
-+
-+        while (s && *s) {
-+            unsigned char *p = (unsigned char *) strchr((char *) s, ',');
-+            int method_len = (p ? (p - s) : strlen((char *) s));
-+            if (libssh2_kex_agree_instr(hostkey, hostkey_len, s, method_len)) {
-+                const LIBSSH2_HOSTKEY_METHOD *method =
-+                    (const LIBSSH2_HOSTKEY_METHOD *)
-+                    libssh2_get_method_by_name((char *) s, method_len,
-+                                               (const LIBSSH2_COMMON_METHOD **)
-+                                               hostkeyp);
-+
-+                if (!method) {
-+                    /* Invalid method -- Should never be reached */
-+                    return -1;
-+                }
-+
-+                /* So far so good, but does it suit our purposes? (Encrypting vs Signing) */
-+                if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) ==
-+                     0) || (method->encrypt)) {
-+                    /* Either this hostkey can do encryption or this kex just doesn't require it */
-+                    if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY)
-+                         == 0) || (method->sig_verify)) {
-+                        /* Either this hostkey can do signing or this kex just doesn't require it */
-+                        session->hostkey = method;
-+                        return 0;
-+                    }
-+                }
-+            }
-+
-+            s = p ? p + 1 : NULL;
-+        }
-+        return -1;
-+    }
-+
-+    while (hostkeyp && (*hostkeyp)->name) {
-+        s = libssh2_kex_agree_instr(hostkey, hostkey_len,
-+                                    (unsigned char *) (*hostkeyp)->name,
-+                                    strlen((*hostkeyp)->name));
-+        if (s) {
-+            /* So far so good, but does it suit our purposes? (Encrypting vs Signing) */
-+            if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) == 0) ||
-+                ((*hostkeyp)->encrypt)) {
-+                /* Either this hostkey can do encryption or this kex just doesn't require it */
-+                if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY) ==
-+                     0) || ((*hostkeyp)->sig_verify)) {
-+                    /* Either this hostkey can do signing or this kex just doesn't require it */
-+                    session->hostkey = *hostkeyp;
-+                    return 0;
-+                }
-+            }
-+        }
-+        hostkeyp++;
-+    }
-+
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_kex_agree_kex_hostkey
-+ * Agree on a Key Exchange method and a hostkey encoding type
-+ */
-+static int
-+libssh2_kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex,
-+                              unsigned long kex_len, unsigned char *hostkey,
-+                              unsigned long hostkey_len)
-+{
-+    const LIBSSH2_KEX_METHOD **kexp = libssh2_kex_methods;
-+    unsigned char *s;
-+
-+    if (session->kex_prefs) {
-+        s = (unsigned char *) session->kex_prefs;
-+
-+        while (s && *s) {
-+            unsigned char *q, *p = (unsigned char *) strchr((char *) s, ',');
-+            int method_len = (p ? (p - s) : strlen((char *) s));
-+            if ((q = libssh2_kex_agree_instr(kex, kex_len, s, method_len))) {
-+                const LIBSSH2_KEX_METHOD *method = (const LIBSSH2_KEX_METHOD *)
-+                    libssh2_get_method_by_name((char *) s, method_len,
-+                                               (const LIBSSH2_COMMON_METHOD **)
-+                                               kexp);
-+
-+                if (!method) {
-+                    /* Invalid method -- Should never be reached */
-+                    return -1;
-+                }
-+
-+                /* We've agreed on a key exchange method,
-+                 * Can we agree on a hostkey that works with this kex?
-+                 */
-+                if (libssh2_kex_agree_hostkey
-+                    (session, method->flags, hostkey, hostkey_len) == 0) {
-+                    session->kex = method;
-+                    if (session->burn_optimistic_kexinit && (kex == q)) {
-+                        /* Server sent an optimistic packet,
-+                         * and client agrees with preference
-+                         * cancel burning the first KEX_INIT packet that comes in */
-+                        session->burn_optimistic_kexinit = 0;
-+                    }
-+                    return 0;
-+                }
-+            }
-+
-+            s = p ? p + 1 : NULL;
-+        }
-+        return -1;
-+    }
-+
-+    while (*kexp && (*kexp)->name) {
-+        s = libssh2_kex_agree_instr(kex, kex_len,
-+                                    (unsigned char *) (*kexp)->name,
-+                                    strlen((*kexp)->name));
-+        if (s) {
-+            /* We've agreed on a key exchange method,
-+             * Can we agree on a hostkey that works with this kex?
-+             */
-+            if (libssh2_kex_agree_hostkey
-+                (session, (*kexp)->flags, hostkey, hostkey_len) == 0) {
-+                session->kex = *kexp;
-+                if (session->burn_optimistic_kexinit && (kex == s)) {
-+                    /* Server sent an optimistic packet,
-+                     * and client agrees with preference
-+                     * cancel burning the first KEX_INIT packet that comes in */
-+                    session->burn_optimistic_kexinit = 0;
-+                }
-+                return 0;
-+            }
-+        }
-+        kexp++;
-+    }
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_kex_agree_crypt
-+ * Agree on a cipher algo
-+ */
-+static int
-+libssh2_kex_agree_crypt(LIBSSH2_SESSION * session,
-+                        libssh2_endpoint_data * endpoint, unsigned char *crypt,
-+                        unsigned long crypt_len)
-+{
-+    const LIBSSH2_CRYPT_METHOD **cryptp = libssh2_crypt_methods();
-+    unsigned char *s;
-+
-+    (void) session;
-+
-+    if (endpoint->crypt_prefs) {
-+        s = (unsigned char *) endpoint->crypt_prefs;
-+
-+        while (s && *s) {
-+            unsigned char *p = (unsigned char *) strchr((char *) s, ',');
-+            int method_len = (p ? (p - s) : strlen((char *) s));
-+
-+            if (libssh2_kex_agree_instr(crypt, crypt_len, s, method_len)) {
-+                const LIBSSH2_CRYPT_METHOD *method =
-+                    (const LIBSSH2_CRYPT_METHOD *)
-+                    libssh2_get_method_by_name((char *) s, method_len,
-+                                               (const LIBSSH2_COMMON_METHOD **)
-+                                               cryptp);
-+
-+                if (!method) {
-+                    /* Invalid method -- Should never be reached */
-+                    return -1;
-+                }
-+
-+                endpoint->crypt = method;
-+                return 0;
-+            }
-+
-+            s = p ? p + 1 : NULL;
-+        }
-+        return -1;
-+    }
-+
-+    while (*cryptp && (*cryptp)->name) {
-+        s = libssh2_kex_agree_instr(crypt, crypt_len,
-+                                    (unsigned char *) (*cryptp)->name,
-+                                    strlen((*cryptp)->name));
-+        if (s) {
-+            endpoint->crypt = *cryptp;
-+            return 0;
-+        }
-+        cryptp++;
-+    }
-+
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_kex_agree_mac
-+ * Agree on a message authentication hash
-+ */
-+static int
-+libssh2_kex_agree_mac(LIBSSH2_SESSION * session,
-+                      libssh2_endpoint_data * endpoint, unsigned char *mac,
-+                      unsigned long mac_len)
-+{
-+    const LIBSSH2_MAC_METHOD **macp = libssh2_mac_methods();
-+    unsigned char *s;
-+    (void) session;
-+
-+    if (endpoint->mac_prefs) {
-+        s = (unsigned char *) endpoint->mac_prefs;
-+
-+        while (s && *s) {
-+            unsigned char *p = (unsigned char *) strchr((char *) s, ',');
-+            int method_len = (p ? (p - s) : strlen((char *) s));
-+
-+            if (libssh2_kex_agree_instr(mac, mac_len, s, method_len)) {
-+                const LIBSSH2_MAC_METHOD *method = (const LIBSSH2_MAC_METHOD *)
-+                    libssh2_get_method_by_name((char *) s, method_len,
-+                                               (const LIBSSH2_COMMON_METHOD **)
-+                                               macp);
-+
-+                if (!method) {
-+                    /* Invalid method -- Should never be reached */
-+                    return -1;
-+                }
-+
-+                endpoint->mac = method;
-+                return 0;
-+            }
-+
-+            s = p ? p + 1 : NULL;
-+        }
-+        return -1;
-+    }
-+
-+    while (*macp && (*macp)->name) {
-+        s = libssh2_kex_agree_instr(mac, mac_len,
-+                                    (unsigned char *) (*macp)->name,
-+                                    strlen((*macp)->name));
-+        if (s) {
-+            endpoint->mac = *macp;
-+            return 0;
-+        }
-+        macp++;
-+    }
-+
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_kex_agree_comp
-+ * Agree on a compression scheme
-+ */
-+static int
-+libssh2_kex_agree_comp(LIBSSH2_SESSION * session,
-+                       libssh2_endpoint_data * endpoint, unsigned char *comp,
-+                       unsigned long comp_len)
-+{
-+    const LIBSSH2_COMP_METHOD **compp = libssh2_comp_methods();
-+    unsigned char *s;
-+    (void) session;
-+
-+    if (endpoint->comp_prefs) {
-+        s = (unsigned char *) endpoint->comp_prefs;
-+
-+        while (s && *s) {
-+            unsigned char *p = (unsigned char *) strchr((char *) s, ',');
-+            int method_len = (p ? (p - s) : strlen((char *) s));
-+
-+            if (libssh2_kex_agree_instr(comp, comp_len, s, method_len)) {
-+                const LIBSSH2_COMP_METHOD *method =
-+                    (const LIBSSH2_COMP_METHOD *)
-+                    libssh2_get_method_by_name((char *) s, method_len,
-+                                               (const LIBSSH2_COMMON_METHOD **)
-+                                               compp);
-+
-+                if (!method) {
-+                    /* Invalid method -- Should never be reached */
-+                    return -1;
-+                }
-+
-+                endpoint->comp = method;
-+                return 0;
-+            }
-+
-+            s = p ? p + 1 : NULL;
-+        }
-+        return -1;
-+    }
-+
-+    while (*compp && (*compp)->name) {
-+        s = libssh2_kex_agree_instr(comp, comp_len,
-+                                    (unsigned char *) (*compp)->name,
-+                                    strlen((*compp)->name));
-+        if (s) {
-+            endpoint->comp = *compp;
-+            return 0;
-+        }
-+        compp++;
-+    }
-+
-+    return -1;
-+}
-+
-+/* }}} */
-+
-+/* TODO: When in server mode we need to turn this logic on its head
-+ * The Client gets to make the final call on "agreed methods"
-+ */
-+
-+/* {{{ libssh2_kex_agree_methods
-+ * Decide which specific method to use of the methods offered by each party
-+ */
-+static int
-+libssh2_kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data,
-+                          unsigned data_len)
-+{
-+    unsigned char *kex, *hostkey, *crypt_cs, *crypt_sc, *comp_cs, *comp_sc,
-+        *mac_cs, *mac_sc, *lang_cs, *lang_sc;
-+    size_t kex_len, hostkey_len, crypt_cs_len, crypt_sc_len, comp_cs_len;
-+    size_t comp_sc_len, mac_cs_len, mac_sc_len, lang_cs_len, lang_sc_len;
-+    unsigned char *s = data;
-+
-+    /* Skip packet_type, we know it already */
-+    s++;
-+
-+    /* Skip cookie, don't worry, it's preserved in the kexinit field */
-+    s += 16;
-+
-+    /* Locate each string */
-+    kex_len = libssh2_ntohu32(s);
-+    kex = s + 4;
-+    s += 4 + kex_len;
-+    hostkey_len = libssh2_ntohu32(s);
-+    hostkey = s + 4;
-+    s += 4 + hostkey_len;
-+    crypt_cs_len = libssh2_ntohu32(s);
-+    crypt_cs = s + 4;
-+    s += 4 + crypt_cs_len;
-+    crypt_sc_len = libssh2_ntohu32(s);
-+    crypt_sc = s + 4;
-+    s += 4 + crypt_sc_len;
-+    mac_cs_len = libssh2_ntohu32(s);
-+    mac_cs = s + 4;
-+    s += 4 + mac_cs_len;
-+    mac_sc_len = libssh2_ntohu32(s);
-+    mac_sc = s + 4;
-+    s += 4 + mac_sc_len;
-+    comp_cs_len = libssh2_ntohu32(s);
-+    comp_cs = s + 4;
-+    s += 4 + comp_cs_len;
-+    comp_sc_len = libssh2_ntohu32(s);
-+    comp_sc = s + 4;
-+    s += 4 + comp_sc_len;
-+    lang_cs_len = libssh2_ntohu32(s);
-+    lang_cs = s + 4;
-+    s += 4 + lang_cs_len;
-+    lang_sc_len = libssh2_ntohu32(s);
-+    lang_sc = s + 4;
-+    s += 4 + lang_sc_len;
-+
-+    /* If the server sent an optimistic packet, assume that it guessed wrong.
-+     * If the guess is determined to be right (by libssh2_kex_agree_kex_hostkey)
-+     * This flag will be reset to zero so that it's not ignored */
-+    session->burn_optimistic_kexinit = *(s++);
-+    /* Next uint32 in packet is all zeros (reserved) */
-+
-+    if (data_len < (unsigned) (s - data))
-+        return -1;              /* short packet */
-+
-+    if (libssh2_kex_agree_kex_hostkey
-+        (session, kex, kex_len, hostkey, hostkey_len)) {
-+        return -1;
-+    }
-+
-+    if (libssh2_kex_agree_crypt
-+        (session, &session->local, crypt_cs, crypt_cs_len)
-+        || libssh2_kex_agree_crypt(session, &session->remote, crypt_sc,
-+                                   crypt_sc_len)) {
-+        return -1;
-+    }
-+
-+    if (libssh2_kex_agree_mac(session, &session->local, mac_cs, mac_cs_len) ||
-+        libssh2_kex_agree_mac(session, &session->remote, mac_sc, mac_sc_len)) {
-+        return -1;
-+    }
-+
-+    if (libssh2_kex_agree_comp(session, &session->local, comp_cs, comp_cs_len)
-+        || libssh2_kex_agree_comp(session, &session->remote, comp_sc,
-+                                  comp_sc_len)) {
-+        return -1;
-+    }
-+
-+    if (libssh2_kex_agree_lang(session, &session->local, lang_cs, lang_cs_len)
-+        || libssh2_kex_agree_lang(session, &session->remote, lang_sc,
-+                                  lang_sc_len)) {
-+        return -1;
-+    }
-+
-+    _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on KEX method: %s",
-+                   session->kex->name);
-+    _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on HOSTKEY method: %s",
-+                   session->hostkey->name);
-+    _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on CRYPT_CS method: %s",
-+                   session->local.crypt->name);
-+    _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on CRYPT_SC method: %s",
-+                   session->remote.crypt->name);
-+    _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on MAC_CS method: %s",
-+                   session->local.mac->name);
-+    _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on MAC_SC method: %s",
-+                   session->remote.mac->name);
-+    _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on COMP_CS method: %s",
-+                   session->local.comp->name);
-+    _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on COMP_SC method: %s",
-+                   session->remote.comp->name);
-+    _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on LANG_CS method:");      /* None yet */
-+    _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on LANG_SC method:");      /* None yet */
-+
-+    /* Initialize compression layer */
-+    if (session->local.comp && session->local.comp->init &&
-+        session->local.comp->init(session, 1, &session->local.comp_abstract)) {
-+        return -1;
-+    }
-+
-+    if (session->remote.comp && session->remote.comp->init &&
-+        session->remote.comp->init(session, 0,
-+                                   &session->remote.comp_abstract)) {
-+        return -1;
-+    }
-+
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_kex_exchange
-+ * Exchange keys
-+ * Returns 0 on success, non-zero on failure
-+ */
-+int
-+libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
-+                     key_exchange_state_t * key_state)
-+{
-+    int rc = 0;
-+    int retcode;
-+
-+    session->state |= LIBSSH2_STATE_KEX_ACTIVE;
-+
-+    if (key_state->state == libssh2_NB_state_idle) {
-+        /* Prevent loop in packet_add() */
-+        session->state |= LIBSSH2_STATE_EXCHANGING_KEYS;
-+
-+        if (reexchange) {
-+            session->kex = NULL;
-+
-+            if (session->hostkey && session->hostkey->dtor) {
-+                session->hostkey->dtor(session,
-+                                       &session->server_hostkey_abstract);
-+            }
-+            session->hostkey = NULL;
-+        }
-+
-+        key_state->state = libssh2_NB_state_created;
-+    }
-+
-+    if (!session->kex || !session->hostkey) {
-+        if (key_state->state == libssh2_NB_state_created) {
-+            /* Preserve in case of failure */
-+            key_state->oldlocal = session->local.kexinit;
-+            key_state->oldlocal_len = session->local.kexinit_len;
-+
-+            session->local.kexinit = NULL;
-+
-+            key_state->state = libssh2_NB_state_sent;
-+        }
-+
-+        if (key_state->state == libssh2_NB_state_sent) {
-+            retcode = libssh2_kexinit(session);
-+            if (retcode == PACKET_EAGAIN) {
-+                session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
-+                return PACKET_EAGAIN;
-+            } else if (retcode) {
-+                session->local.kexinit = key_state->oldlocal;
-+                session->local.kexinit_len = key_state->oldlocal_len;
-+                key_state->state = libssh2_NB_state_idle;
-+                session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
-+                session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
-+                return -1;
-+            }
-+
-+            key_state->state = libssh2_NB_state_sent1;
-+        }
-+
-+        if (key_state->state == libssh2_NB_state_sent1) {
-+            retcode =
-+                libssh2_packet_require_ex(session, SSH_MSG_KEXINIT,
-+                                          &key_state->data,
-+                                          &key_state->data_len, 0, NULL, 0,
-+                                          &key_state->req_state);
-+            if (retcode == PACKET_EAGAIN) {
-+                session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
-+                return PACKET_EAGAIN;
-+            } else if (retcode) {
-+                if (session->local.kexinit) {
-+                    LIBSSH2_FREE(session, session->local.kexinit);
-+                }
-+                session->local.kexinit = key_state->oldlocal;
-+                session->local.kexinit_len = key_state->oldlocal_len;
-+                key_state->state = libssh2_NB_state_idle;
-+                session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
-+                session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
-+                return -1;
-+            }
-+
-+            if (session->remote.kexinit) {
-+                LIBSSH2_FREE(session, session->remote.kexinit);
-+            }
-+            session->remote.kexinit = key_state->data;
-+            session->remote.kexinit_len = key_state->data_len;
-+
-+            if (libssh2_kex_agree_methods
-+                (session, key_state->data, key_state->data_len)) {
-+                rc = -1;
-+            }
-+
-+            key_state->state = libssh2_NB_state_sent2;
-+        }
-+    } else {
-+        key_state->state = libssh2_NB_state_sent2;
-+    }
-+
-+    if (rc == 0) {
-+        if (key_state->state == libssh2_NB_state_sent2) {
-+            retcode =
-+                session->kex->exchange_keys(session,
-+                                            &key_state->key_state_low);
-+            if (retcode == PACKET_EAGAIN) {
-+                session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
-+                return PACKET_EAGAIN;
-+            } else if (retcode) {
-+                libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE,
-+                              "Unrecoverable error exchanging keys", 0);
-+                rc = -1;
-+            }
-+        }
-+    }
-+
-+    /* Done with kexinit buffers */
-+    if (session->local.kexinit) {
-+        LIBSSH2_FREE(session, session->local.kexinit);
-+        session->local.kexinit = NULL;
-+    }
-+    if (session->remote.kexinit) {
-+        LIBSSH2_FREE(session, session->remote.kexinit);
-+        session->remote.kexinit = NULL;
-+    }
-+
-+    session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
-+    session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
-+
-+    key_state->state = libssh2_NB_state_idle;
-+
-+    return rc;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_session_method_pref
-+ * Set preferred method
-+ */
-+LIBSSH2_API int
-+libssh2_session_method_pref(LIBSSH2_SESSION * session, int method_type,
-+                            const char *prefs)
-+{
-+    char **prefvar, *s, *newprefs;
-+    int prefs_len = strlen(prefs);
-+    const LIBSSH2_COMMON_METHOD **mlist;
-+
-+    switch (method_type) {
-+    case LIBSSH2_METHOD_KEX:
-+        prefvar = &session->kex_prefs;
-+        mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_kex_methods;
-+        break;
-+
-+    case LIBSSH2_METHOD_HOSTKEY:
-+        prefvar = &session->hostkey_prefs;
-+        mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_hostkey_methods();
-+        break;
-+
-+    case LIBSSH2_METHOD_CRYPT_CS:
-+        prefvar = &session->local.crypt_prefs;
-+        mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods();
-+        break;
-+
-+    case LIBSSH2_METHOD_CRYPT_SC:
-+        prefvar = &session->remote.crypt_prefs;
-+        mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods();
-+        break;
-+
-+    case LIBSSH2_METHOD_MAC_CS:
-+        prefvar = &session->local.mac_prefs;
-+        mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_mac_methods();
-+        break;
-+
-+    case LIBSSH2_METHOD_MAC_SC:
-+        prefvar = &session->remote.mac_prefs;
-+        mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_mac_methods();
-+        break;
-+
-+    case LIBSSH2_METHOD_COMP_CS:
-+        prefvar = &session->local.comp_prefs;
-+        mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_comp_methods();
-+        break;
-+
-+    case LIBSSH2_METHOD_COMP_SC:
-+        prefvar = &session->remote.comp_prefs;
-+        mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_comp_methods();
-+        break;
-+
-+    case LIBSSH2_METHOD_LANG_CS:
-+        prefvar = &session->local.lang_prefs;
-+        mlist = NULL;
-+        break;
-+
-+    case LIBSSH2_METHOD_LANG_SC:
-+        prefvar = &session->remote.lang_prefs;
-+        mlist = NULL;
-+        break;
-+
-+    default:
-+        libssh2_error(session, LIBSSH2_ERROR_INVAL,
-+                      "Invalid parameter specified for method_type", 0);
-+        return -1;
-+    }
-+
-+    s = newprefs = LIBSSH2_ALLOC(session, prefs_len + 1);
-+    if (!newprefs) {
-+        libssh2_error(session, LIBSSH2_ERROR_ALLOC,
-+                      "Error allocated space for method preferences", 0);
-+        return -1;
-+    }
-+    memcpy(s, prefs, prefs_len + 1);
-+
-+    while (s && *s) {
-+        char *p = strchr(s, ',');
-+        int method_len = p ? (p - s) : (int) strlen(s);
-+
-+        if (!libssh2_get_method_by_name(s, method_len, mlist)) {
-+            /* Strip out unsupported method */
-+            if (p) {
-+                memcpy(s, p + 1, strlen(s) - method_len);
-+            } else {
-+                if (s > newprefs) {
-+                    *(--s) = '\0';
-+                } else {
-+                    *s = '\0';
-+                }
-+            }
-+        }
-+
-+        s = p ? (p + 1) : NULL;
-+    }
-+
-+    if (strlen(newprefs) == 0) {
-+        libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
-+                      "The requested method(s) are not currently supported",
-+                      0);
-+        LIBSSH2_FREE(session, newprefs);
-+        return -1;
-+    }
-+
-+    if (*prefvar) {
-+        LIBSSH2_FREE(session, *prefvar);
-+    }
-+    *prefvar = newprefs;
-+
-+    return 0;
-+}
-+
-+/* }}} */
-
-Property changes on: libssh2/src/kex.c
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.3
-Added: svn:eol-style
-   + native
-
-Index: libssh2/src/openssl.h
-===================================================================
---- libssh2/src/openssl.h      (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/openssl.h      (.../trunk)
-@@ -0,0 +1,224 @@
-+/* Copyright (C) 2006, 2007 The Written Word, Inc.  All rights reserved.
-+ * Author: Simon Josefsson
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#include <openssl/opensslconf.h>
-+#include <openssl/sha.h>
-+#ifndef OPENSSL_NO_MD5
-+#include <openssl/md5.h>
-+#endif
-+#include <openssl/evp.h>
-+#include <openssl/hmac.h>
-+#include <openssl/bn.h>
-+#include <openssl/pem.h>
-+#include <openssl/rand.h>
-+
-+#ifdef OPENSSL_NO_RSA
-+# define LIBSSH2_RSA 0
-+#else
-+# define LIBSSH2_RSA 1
-+#endif
-+
-+#ifdef OPENSSL_NO_DSA
-+# define LIBSSH2_DSA 0
-+#else
-+# define LIBSSH2_DSA 1
-+#endif
-+
-+#ifdef OPENSSL_NO_MD5
-+# define LIBSSH2_MD5 0
-+#else
-+# define LIBSSH2_MD5 1
-+#endif
-+
-+#ifdef OPENSSL_NO_RIPEMD
-+# define LIBSSH2_HMAC_RIPEMD 0
-+#else
-+# define LIBSSH2_HMAC_RIPEMD 1
-+#endif
-+
-+#if OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES)
-+# define LIBSSH2_AES 1
-+#else
-+# define LIBSSH2_AES 0
-+#endif
-+
-+#ifdef OPENSSL_NO_BLOWFISH
-+# define LIBSSH2_BLOWFISH 0
-+#else
-+# define LIBSSH2_BLOWFISH 1
-+#endif
-+
-+#ifdef OPENSSL_NO_RC4
-+# define LIBSSH2_RC4 0
-+#else
-+# define LIBSSH2_RC4 1
-+#endif
-+
-+#ifdef OPENSSL_NO_CAST
-+# define LIBSSH2_CAST 0
-+#else
-+# define LIBSSH2_CAST 1
-+#endif
-+
-+#ifdef OPENSSL_NO_DES
-+# define LIBSSH2_3DES 0
-+#else
-+# define LIBSSH2_3DES 1
-+#endif
-+
-+#define libssh2_random(buf, len)        \
-+  RAND_bytes ((buf), (len))
-+
-+#define libssh2_sha1_ctx SHA_CTX
-+#define libssh2_sha1_init(ctx) SHA1_Init(ctx)
-+#define libssh2_sha1_update(ctx, data, len) SHA1_Update(&(ctx), data, len)
-+#define libssh2_sha1_final(ctx, out) SHA1_Final(out, &(ctx))
-+#define libssh2_sha1(message, len, out) SHA1(message, len, out)
-+
-+#define libssh2_md5_ctx MD5_CTX
-+#define libssh2_md5_init(ctx) MD5_Init(ctx)
-+#define libssh2_md5_update(ctx, data, len) MD5_Update(&(ctx), data, len)
-+#define libssh2_md5_final(ctx, out) MD5_Final(out, &(ctx))
-+#define libssh2_md5(message, len, out) MD5(message, len, out)
-+
-+#define libssh2_hmac_ctx HMAC_CTX
-+#define libssh2_hmac_sha1_init(ctx, key, keylen) \
-+  HMAC_Init(ctx, key, keylen, EVP_sha1())
-+#define libssh2_hmac_md5_init(ctx, key, keylen) \
-+  HMAC_Init(ctx, key, keylen, EVP_md5())
-+#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
-+  HMAC_Init(ctx, key, keylen, EVP_ripemd160())
-+#define libssh2_hmac_update(ctx, data, datalen) \
-+  HMAC_Update(&(ctx), data, datalen)
-+#define libssh2_hmac_final(ctx, data) HMAC_Final(&(ctx), data, NULL)
-+#define libssh2_hmac_cleanup(ctx) HMAC_cleanup(ctx)
-+
-+#define libssh2_crypto_init()
-+
-+#define libssh2_rsa_ctx RSA
-+
-+int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
-+                     const unsigned char *edata,
-+                     unsigned long elen,
-+                     const unsigned char *ndata,
-+                     unsigned long nlen,
-+                     const unsigned char *ddata,
-+                     unsigned long dlen,
-+                     const unsigned char *pdata,
-+                     unsigned long plen,
-+                     const unsigned char *qdata,
-+                     unsigned long qlen,
-+                     const unsigned char *e1data,
-+                     unsigned long e1len,
-+                     const unsigned char *e2data,
-+                     unsigned long e2len,
-+                     const unsigned char *coeffdata, unsigned long coefflen);
-+int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
-+                             LIBSSH2_SESSION * session,
-+                             FILE * fp, unsigned const char *passphrase);
-+int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
-+                             const unsigned char *sig,
-+                             unsigned long sig_len,
-+                             const unsigned char *m, unsigned long m_len);
-+int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
-+                           libssh2_rsa_ctx * rsactx,
-+                           const unsigned char *hash,
-+                           unsigned long hash_len,
-+                           unsigned char **signature,
-+                           unsigned long *signature_len);
-+
-+#define _libssh2_rsa_free(rsactx) RSA_free(rsactx)
-+
-+#define libssh2_dsa_ctx DSA
-+
-+int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
-+                     const unsigned char *pdata,
-+                     unsigned long plen,
-+                     const unsigned char *qdata,
-+                     unsigned long qlen,
-+                     const unsigned char *gdata,
-+                     unsigned long glen,
-+                     const unsigned char *ydata,
-+                     unsigned long ylen,
-+                     const unsigned char *x, unsigned long x_len);
-+int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
-+                             LIBSSH2_SESSION * session,
-+                             FILE * fp, unsigned const char *passphrase);
-+int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
-+                             const unsigned char *sig,
-+                             const unsigned char *m, unsigned long m_len);
-+int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
-+                           const unsigned char *hash,
-+                           unsigned long hash_len, unsigned char *sig);
-+
-+#define _libssh2_dsa_free(dsactx) DSA_free(dsactx)
-+
-+#define _libssh2_cipher_type(name) const EVP_CIPHER *(*name)(void)
-+#define _libssh2_cipher_ctx EVP_CIPHER_CTX
-+
-+#define _libssh2_cipher_aes256 EVP_aes_256_cbc
-+#define _libssh2_cipher_aes192 EVP_aes_192_cbc
-+#define _libssh2_cipher_aes128 EVP_aes_128_cbc
-+#define _libssh2_cipher_blowfish EVP_bf_cbc
-+#define _libssh2_cipher_arcfour EVP_rc4
-+#define _libssh2_cipher_cast5 EVP_cast5_cbc
-+#define _libssh2_cipher_3des EVP_des_ede3_cbc
-+
-+int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
-+                         _libssh2_cipher_type(algo),
-+                         unsigned char *iv,
-+                         unsigned char *secret, int encrypt);
-+
-+int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
-+                          _libssh2_cipher_type(algo),
-+                          int encrypt, unsigned char *block);
-+
-+#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx)
-+
-+#define _libssh2_bn BIGNUM
-+#define _libssh2_bn_ctx BN_CTX
-+#define _libssh2_bn_ctx_new() BN_CTX_new()
-+#define _libssh2_bn_ctx_free(bnctx) BN_CTX_free(bnctx)
-+#define _libssh2_bn_init() BN_new()
-+#define _libssh2_bn_rand(bn, bits, top, bottom) BN_rand(bn, bits, top, bottom)
-+#define _libssh2_bn_mod_exp(r, a, p, m, ctx) BN_mod_exp(r, a, p, m, ctx)
-+#define _libssh2_bn_set_word(bn, val) BN_set_word(bn, val)
-+#define _libssh2_bn_from_bin(bn, len, val) BN_bin2bn(val, len, bn)
-+#define _libssh2_bn_to_bin(bn, val) BN_bn2bin(bn, val)
-+#define _libssh2_bn_bytes(bn) BN_num_bytes(bn)
-+#define _libssh2_bn_bits(bn) BN_num_bits(bn)
-+#define _libssh2_bn_free(bn) BN_clear_free(bn)
-
-Property changes on: libssh2/src/openssl.h
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.1
-Added: svn:eol-style
-   + native
-Added: svn:executable
-   + *
-
-Index: libssh2/src/misc.c
-===================================================================
---- libssh2/src/misc.c (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/misc.c (.../trunk)
-@@ -0,0 +1,240 @@
-+/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ */
-+
-+#include "libssh2_priv.h"
-+#ifdef HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+/* {{{ libssh2_ntohu32
-+ */
-+unsigned long
-+libssh2_ntohu32(const unsigned char *buf)
-+{
-+    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_ntohu64
-+ *
-+ */
-+libssh2_uint64_t
-+libssh2_ntohu64(const unsigned char *buf)
-+{
-+    unsigned long msl, lsl;
-+
-+    msl = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
-+    lsl = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
-+
-+    return ((libssh2_uint64_t)msl <<32) | lsl;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_htonu32
-+ */
-+void
-+libssh2_htonu32(unsigned char *buf, unsigned long value)
-+{
-+    buf[0] = (value >> 24) & 0xFF;
-+    buf[1] = (value >> 16) & 0xFF;
-+    buf[2] = (value >> 8) & 0xFF;
-+    buf[3] = value & 0xFF;
-+}
-+
-+/* }}} */
-+
-+/* {{{ libssh2_htonu64
-+ */
-+void
-+libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value)
-+{
-+    unsigned long msl = ((libssh2_uint64_t)value >> 32);
-+
-+    buf[0] = (msl >> 24) & 0xFF;
-+    buf[1] = (msl >> 16) & 0xFF;
-+    buf[2] = (msl >> 8) & 0xFF;
-+    buf[3] = msl & 0xFF;
-+
-+    buf[4] = (value >> 24) & 0xFF;
-+    buf[5] = (value >> 16) & 0xFF;
-+    buf[6] = (value >> 8) & 0xFF;
-+    buf[7] = value & 0xFF;
-+}
-+
-+/* }}} */
-+
-+/* Base64 Conversion */
-+
-+/* {{{ */
-+static const char libssh2_base64_table[] =
-+    { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
-+    'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
-+    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
-+    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-+    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
-+};
-+
-+static const char libssh2_base64_pad = '=';
-+
-+static const short libssh2_base64_reverse_table[256] = {
-+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
-+    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-+    -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
-+    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-+    -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
-+    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
-+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
-+};
-+
-+/* }}} */
-+
-+
-+/* {{{ libssh2_base64_decode
-+ * Decode a base64 chunk and store it into a newly alloc'd buffer
-+ */
-+LIBSSH2_API int
-+libssh2_base64_decode(LIBSSH2_SESSION * session, char **data,
-+                      unsigned int *datalen, const char *src,
-+                      unsigned int src_len)
-+{
-+    unsigned char *s, *d;
-+    short v;
-+    int i = 0, len = 0;
-+
-+    *data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1);
-+    d = (unsigned char *) *data;
-+    if (!d) {
-+        return -1;
-+    }
-+
-+    for(s = (unsigned char *) src; ((char *) s) < (src + src_len); s++) {
-+        if ((v = libssh2_base64_reverse_table[*s]) < 0)
-+            continue;
-+        switch (i % 4) {
-+        case 0:
-+            d[len] = v << 2;
-+            break;
-+        case 1:
-+            d[len++] |= v >> 4;
-+            d[len] = v << 4;
-+            break;
-+        case 2:
-+            d[len++] |= v >> 2;
-+            d[len] = v << 6;
-+            break;
-+        case 3:
-+            d[len++] |= v;
-+            break;
-+        }
-+        i++;
-+    }
-+    if ((i % 4) == 1) {
-+        /* Invalid -- We have a byte which belongs exclusively to a partial octet */
-+        LIBSSH2_FREE(session, *data);
-+        return -1;
-+    }
-+
-+    *datalen = len;
-+    return 0;
-+}
-+
-+/* }}} */
-+
-+#ifdef LIBSSH2DEBUG
-+LIBSSH2_API int
-+libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
-+{
-+    session->showmask = bitmask;
-+    return 0;
-+}
-+
-+void
-+_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
-+{
-+    char buffer[1536];
-+    int len;
-+    va_list vargs;
-+    static const char *const contexts[9] = {
-+        "Unknown",
-+        "Transport",
-+        "Key Exchange",
-+        "Userauth",
-+        "Connection",
-+        "scp",
-+        "SFTP Subsystem",
-+        "Failure Event",
-+        "Publickey Subsystem",
-+    };
-+
-+    if (context < 1 || context > 8) {
-+        context = 0;
-+    }
-+    if (!(session->showmask & (1 << context))) {
-+        /* no such output asked for */
-+        return;
-+    }
-+
-+    len = snprintf(buffer, 1535, "[libssh2] %s: ", contexts[context]);
-+
-+    va_start(vargs, format);
-+    len += vsnprintf(buffer + len, 1535 - len, format, vargs);
-+    buffer[len] = '\n';
-+    va_end(vargs);
-+    write(2, buffer, len + 1);
-+
-+}
-+
-+#else
-+LIBSSH2_API int
-+libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
-+{
-+    (void) session;
-+    (void) bitmask;
-+    return 0;
-+}
-+#endif
-
-Property changes on: libssh2/src/misc.c
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.3
-Added: svn:eol-style
-   + native
-
-Index: libssh2/src/transport.c
-===================================================================
---- libssh2/src/transport.c    (.../tags/RELEASE_0_11_0)
-+++ libssh2/src/transport.c    (.../trunk)
-@@ -0,0 +1,815 @@
-+/* Copyright (C) 2007 The Written Word, Inc.  All rights reserved.
-+ * Author: Daniel Stenberg <daniel@haxx.se>
-+ *
-+ * Redistribution and use in source and binary forms,
-+ * with or without modification, are permitted provided
-+ * that the following conditions are met:
-+ *
-+ *   Redistributions of source code must retain the above
-+ *   copyright notice, this list of conditions and the
-+ *   following disclaimer.
-+ *
-+ *   Redistributions in binary form must reproduce the above
-+ *   copyright notice, this list of conditions and the following
-+ *   disclaimer in the documentation and/or other materials
-+ *   provided with the distribution.
-+ *
-+ *   Neither the name of the copyright holder nor the names
-+ *   of any other contributors may be used to endorse or
-+ *   promote products derived from this software without
-+ *   specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ *
-+ * This file handles reading and writing to the SECSH transport layer. RFC4253.
-+ */
-+
-+#include "libssh2_priv.h"
-+#include <errno.h>
-+#include <fcntl.h>
-+
-+#include <assert.h>
-+
-+#define MAX_BLOCKSIZE 32        /* MUST fit biggest crypto block size we use/get */
-+#define MAX_MACSIZE 20          /* MUST fit biggest MAC length we support */
-+
-+#ifdef LIBSSH2DEBUG
-+#define UNPRINTABLE_CHAR '.'
-+static void
-+debugdump(LIBSSH2_SESSION * session,
-+          const char *desc, unsigned char *ptr, unsigned long size)
-+{
-+    size_t i;
-+    size_t c;
-+    FILE *stream = stdout;
-+    unsigned int width = 0x10;
-+
-+    if (!(session->showmask & (1 << LIBSSH2_DBG_TRANS))) {
-+        /* not asked for, bail out */
-+        return;
-+    }
-+
-+    fprintf(stream, "=> %s (%d bytes)\n", desc, (int) size);
-+
-+    for(i = 0; i < size; i += width) {
-+
-+        fprintf(stream, "%04lx: ", (long)i);
-+
-+        /* hex not disabled, show it */
-+        for(c = 0; c < width; c++) {
-+            if (i + c < size)
-+                fprintf(stream, "%02x ", ptr[i + c]);
-+            else
-+                fputs("   ", stream);
-+        }
-+
-+        for(c = 0; (c < width) && (i + c < size); c++) {
-+            fprintf(stream, "%c",
-+                    (ptr[i + c] >= 0x20) &&
-+                    (ptr[i + c] < 0x80) ? ptr[i + c] : UNPRINTABLE_CHAR);
-+        }
-+        fputc('\n', stream);    /* newline */
-+    }
-+    fflush(stream);
-+}
-+#else
-+#define debugdump(a,x,y,z)
-+#endif
-+
-+
-+/* decrypt() decrypts 'len' bytes from 'source' to 'dest'.
-+ *
-+ * returns PACKET_NONE on success and PACKET_FAIL on failure
-+ */
-+
-+static libssh2pack_t
-+decrypt(LIBSSH2_SESSION * session, unsigned char *source,
-+        unsigned char *dest, int len)
-+{
-+    struct transportpacket *p = &session->packet;
-+    int blocksize = session->remote.crypt->blocksize;
-+
-+    /* if we get called with a len that isn't an even number of blocksizes
-+       we risk losing those extra bytes */
-+    assert((len % blocksize) == 0);
-+
-+    while (len >= blocksize) {
-+        if (session->remote.crypt->crypt(session, source,
-+                                         &session->remote.crypt_abstract)) {
-+            libssh2_error(session, LIBSSH2_ERROR_DECRYPT,
-+                          (char *) "Error decrypting packet", 0);
-+            LIBSSH2_FREE(session, p->payload);
-+            return PACKET_FAIL;
-+        }
-+
-+        /* if the crypt() function would write to a given address it
-+           wouldn't have to memcpy() and we could avoid this memcpy()
-+           too */
-+        memcpy(dest, source, blocksize);
-+
-+        len -= blocksize;       /* less bytes left */
-+        dest += blocksize;      /* advance write pointer */
-+        source += blocksize;    /* advance read pointer */
-+    }
-+    return PACKET_NONE;         /* all is fine */
-+}
-+
-+/*
-+ * fullpacket() gets called when a full packet has been received and properly
-+ * collected.
-+ */
-+static libssh2pack_t
-+fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
-+{
-+    unsigned char macbuf[MAX_MACSIZE];
-+    struct transportpacket *p = &session->packet;
-+    int rc;
-+
-+    if (session->fullpacket_state == libssh2_NB_state_idle) {
-+        session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED;
-+        session->fullpacket_payload_len = p->packet_length - 1;
-+
-+        if (encrypted) {
-+
-+            /* Calculate MAC hash */
-+            session->remote.mac->hash(session, macbuf,  /* store hash here */
-+                                      session->remote.seqno,
-+                                      p->init, 5,
-+                                      p->payload,
-+                                      session->fullpacket_payload_len,
-+                                      &session->remote.mac_abstract);
-+
-+            /* Compare the calculated hash with the MAC we just read from
-+             * the network. The read one is at the very end of the payload
-+             * buffer. Note that 'payload_len' here is the packet_length
-+             * field which includes the padding but not the MAC.
-+             */
-+            if (memcmp(macbuf, p->payload + session->fullpacket_payload_len,
-+                       session->remote.mac->mac_len)) {
-+                session->fullpacket_macstate = LIBSSH2_MAC_INVALID;
-+            }
-+        }
-+
-+        session->remote.seqno++;
-+
-+        /* ignore the padding */
-+        session->fullpacket_payload_len -= p->padding_length;
-+
-+        /* Check for and deal with decompression */
-+        if (session->remote.comp && strcmp(session->remote.comp->name, "none")) {
-+            unsigned char *data;
-+            unsigned long data_len;
-+            int free_payload = 1;
-+
-+            if (session->remote.comp->comp(session, 0,
-+                                           &data, &data_len,
-+                                           LIBSSH2_PACKET_MAXDECOMP,
-+                                           &free_payload,
-+                                           p->payload,
-+                                           session->fullpacket_payload_len,
-+                                           &session->remote.comp_abstract)) {
-+                LIBSSH2_FREE(session, p->payload);
-+                return PACKET_FAIL;
-+            }
-+
-+            if (free_payload) {
-+                LIBSSH2_FREE(session, p->payload);
-+                p->payload = data;
-+                session->fullpacket_payload_len = data_len;
-+            } else {
-+                if (data == p->payload) {
-+                    /* It's not to be freed, because the
-+                     * compression layer reused payload, So let's
-+                     * do the same!
-+                     */
-+                    session->fullpacket_payload_len = data_len;
-+                } else {
-+                    /* No comp_method actually lets this happen,
-+                     * but let's prepare for the future */
-+
-+                    LIBSSH2_FREE(session, p->payload);
-+
-+                    /* We need a freeable struct otherwise the
-+                     * brigade won't know what to do with it */
-+                    p->payload = LIBSSH2_ALLOC(session, data_len);
-+                    if (!p->payload) {
-+                        libssh2_error(session, LIBSSH2_ERROR_ALLOC, (char *)
-+                                      "Unable to allocate memory for copy of uncompressed data",
-+                                      0);
-+                        return PACKET_ENOMEM;
-+                    }
-+                    memcpy(p->payload, data, data_len);
-+                    session->fullpacket_payload_len = data_len;
-+                }
-+            }
-+        }
-+
-+        session->fullpacket_packet_type = p->payload[0];
-+
-+        debugdump(session, "libssh2_packet_read() plain",
-+                  p->payload, session->fullpacket_payload_len);
-+
-+        session->fullpacket_state = libssh2_NB_state_created;
-+    }
-+
-+    if (session->fullpacket_state == libssh2_NB_state_created) {
-+        rc = libssh2_packet_add(session, p->payload,
-+                                session->fullpacket_payload_len,
-+                                session->fullpacket_macstate);
-+        if (rc == PACKET_EAGAIN) {
-+            return PACKET_EAGAIN;
-+        } else if (rc < 0) {
-+            return PACKET_FAIL;
-+        }
-+    }
-+
-+    session->fullpacket_state = libssh2_NB_state_idle;
-+
-+    return session->fullpacket_packet_type;
-+}
-+
-+
-+/* {{{ libssh2_packet_read
-+ * Collect a packet into the input brigade
-+ * block only controls whether or not to wait for a packet to start,
-+ * Once a packet starts, libssh2 will block until it is complete
-+ *
-+ * Returns packet type added to input brigade (PACKET_NONE if nothing added),
-+ * or PACKET_FAIL on failure and PACKET_EAGAIN if it couldn't process a full
-+ * packet.
-+ */
-+
-+/*
-+ * This function reads the binary stream as specified in chapter 6 of RFC4253
-+ * "The Secure Shell (SSH) Transport Layer Protocol"
-+ */
-+libssh2pack_t
-+libssh2_packet_read(LIBSSH2_SESSION * session)
-+{
-+    libssh2pack_t rc;
-+    struct transportpacket *p = &session->packet;
-+    int remainbuf;
-+    int remainpack;
-+    int numbytes;
-+    int numdecrypt;
-+    unsigned char block[MAX_BLOCKSIZE];
-+    int blocksize;
-+    int encrypted = 1;
-+
-+    int status;
-+
-+    /*
-+     * All channels, systems, subsystems, etc eventually make it down here
-+     * when looking for more incoming data. If a key exchange is going on
-+     * (LIBSSH2_STATE_EXCHANGING_KEYS bit is set) then the remote end
-+     * will ONLY send key exchange related traffic. In non-blocking mode,
-+     * there is a chance to break out of the kex_exchange function with an
-+     * EAGAIN status, and never come back to it. If LIBSSH2_STATE_EXCHANGING_KEYS
-+     * is active, then we must redirect to the key exchange. However,
-+     * if kex_exchange is active (as in it is the one that calls this execution
-+     * of packet_read, then don't redirect, as that would be an infinite loop!
-+     */
-+
-+    if (session->state & LIBSSH2_STATE_EXCHANGING_KEYS &&
-+        !(session->state & LIBSSH2_STATE_KEX_ACTIVE)) {
-+
-+        /* Whoever wants a packet won't get anything until the key re-exchange
-+         * is done!
-+         */
-+        _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Redirecting into the"
-+            " key re-exchange");
-+        status = libssh2_kex_exchange(session, 1, &session->startup_key_state);
-+        if (status == PACKET_EAGAIN) {
-+            libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
-+                "Would block exchanging encryption keys", 0);
-+            return PACKET_EAGAIN;
-+      } else if (status) {
-+          libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE,
-+                      "Unable to exchange encryption keys",0);
-+          return LIBSSH2_ERROR_KEX_FAILURE;
-+      }
-+    }
-+
-+    /*
-+     * =============================== NOTE ===============================
-+     * I know this is very ugly and not a really good use of "goto", but
-+     * this case statement would be even uglier to do it any other way
-+     */
-+    if (session->readPack_state == libssh2_NB_state_jump1) {
-+        session->readPack_state = libssh2_NB_state_idle;
-+        encrypted = session->readPack_encrypted;
-+        goto libssh2_packet_read_point1;
-+    }
-+
-+    do {
-+        if (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
-+            return PACKET_NONE;
-+        }
-+
-+        if (session->state & LIBSSH2_STATE_NEWKEYS) {
-+            blocksize = session->remote.crypt->blocksize;
-+        } else {
-+            encrypted = 0;      /* not encrypted */
-+            blocksize = 5;      /* not strictly true, but we can use 5 here to
-+                                   make the checks below work fine still */
-+        }
-+
-+        /* read/use a whole big chunk into a temporary area stored in
-+           the LIBSSH2_SESSION struct. We will decrypt data from that
-+           buffer into the packet buffer so this temp one doesn't have
-+           to be able to keep a whole SSH packet, just be large enough
-+           so that we can read big chunks from the network layer. */
-+
-+        /* how much data there is remaining in the buffer to deal with
-+           before we should read more from the network */
-+        remainbuf = p->writeidx - p->readidx;
-+
-+        /* if remainbuf turns negative we have a bad internal error */
-+        assert(remainbuf >= 0);
-+
-+        if (remainbuf < blocksize) {
-+            /* If we have less than a blocksize left, it is too
-+               little data to deal with, read more */
-+            ssize_t nread;
-+
-+            /* move any remainder to the start of the buffer so
-+               that we can do a full refill */
-+            if (remainbuf) {
-+                memmove(p->buf, &p->buf[p->readidx], remainbuf);
-+                p->readidx = 0;
-+                p->writeidx = remainbuf;
-+            } else {
-+                /* nothing to move, just zero the indexes */
-+                p->readidx = p->writeidx = 0;
-+            }
-+
-+            /* now read a big chunk from the network into the temp buffer */
-+            nread =
-+                recv(session->socket_fd, &p->buf[remainbuf],
-+                     PACKETBUFSIZE - remainbuf,
-+                     LIBSSH2_SOCKET_RECV_FLAGS(session));
-+            if (nread <= 0) {
-+                /* check if this is due to EAGAIN and return the special
-+                   return code if so, error out normally otherwise */
-+#ifdef WIN32
-+                switch (WSAGetLastError()) {
-+                case WSAEWOULDBLOCK:
-+                    errno = EAGAIN;
-+                    break;
-+
-+                case WSAENOTSOCK:
-+                    errno = EBADF;
-+                    break;
-+
-+                case WSAENOTCONN:
-+                case WSAECONNABORTED:
-+                    errno = WSAENOTCONN;
-+                    break;
-+
-+                case WSAEINTR:
-+                    errno = EINTR;
-+                    break;
-+                }
-+#endif /* WIN32 */
-+                if ((nread < 0) && (errno == EAGAIN)) {
-+                    session->socket_block_directions =
-+                        LIBSSH2_SESSION_BLOCK_INBOUND;
-+                    return PACKET_EAGAIN;
-+                }
-+                return PACKET_FAIL;
-+            }
-+            debugdump(session, "libssh2_packet_read() raw",
-+                      &p->buf[remainbuf], nread);
-+            /* advance write pointer */
-+            p->writeidx += nread;
-+
-+            /* update remainbuf counter */
-+            remainbuf = p->writeidx - p->readidx;
-+        }
-+
-+        /* how much data to deal with from the buffer */
-+        numbytes = remainbuf;
-+
-+        if (!p->total_num) {
-+            /* No payload package area allocated yet. To know the
-+               size of this payload, we need to decrypt the first
-+               blocksize data. */
-+
-+            if (numbytes < blocksize) {
-+                /* we can't act on anything less than blocksize, but this
-+                   check is only done for the initial block since once we have
-+                   got the start of a block we can in fact deal with fractions
-+                */
-+                return PACKET_EAGAIN;
-+            }
-+
-+            if (encrypted) {
-+                rc = decrypt(session, &p->buf[p->readidx], block, blocksize);
-+                if (rc != PACKET_NONE) {
-+                    return rc;
-+                }
-+                /* save the first 5 bytes of the decrypted package, to be
-+                   used in the hash calculation later down. */
-+                memcpy(p->init, &p->buf[p->readidx], 5);
-+            } else {
-+                /* the data is plain, just copy it verbatim to
-+                   the working block buffer */
-+                memcpy(block, &p->buf[p->readidx], blocksize);
-+            }
-+
-+            /* advance the read pointer */
-+            p->readidx += blocksize;
-+
-+            /* we now have the initial blocksize bytes decrypted,
-+             * and we can extract packet and padding length from it
-+             */
-+            p->packet_length = libssh2_ntohu32(block);
-+            p->padding_length = block[4];
-+
-+            /* total_num is the number of bytes following the initial
-+               (5 bytes) packet length and padding length fields */
-+            p->total_num =
-+                p->packet_length - 1 +
-+                (encrypted ? session->remote.mac->mac_len : 0);
-+
-+            /* RFC4253 section 6.1 Maximum Packet Length says:
-+             *
-+             * "All implementations MUST be able to process
-+             * packets with uncompressed payload length of 32768
-+             * bytes or less and total packet size of 35000 bytes
-+             * or less (including length, padding length, payload,
-+             * padding, and MAC.)."
-+             */
-+            if (p->total_num > LIBSSH2_PACKET_MAXPAYLOAD) {
-+                return PACKET_TOOBIG;
-+            }
-+
-+            /* Get a packet handle put data into. We get one to
-+               hold all data, including padding and MAC. */
-+            p->payload = LIBSSH2_ALLOC(session, p->total_num);
-+            if (!p->payload) {
-+                return PACKET_ENOMEM;
-+            }
-+            /* init write pointer to start of payload buffer */
-+            p->wptr = p->payload;
-+
-+            if (blocksize > 5) {
-+                /* copy the data from index 5 to the end of
-+                   the blocksize from the temporary buffer to
-+                   the start of the decrypted buffer */
-+                memcpy(p->wptr, &block[5], blocksize - 5);
-+                p->wptr += blocksize - 5;       /* advance write pointer */
-+            }
-+
-+            /* init the data_num field to the number of bytes of
-+               the package read so far */
-+            p->data_num = p->wptr - p->payload;
-+
-+            /* we already dealt with a blocksize worth of data */
-+            numbytes -= blocksize;
-+        }
-+
-+        /* how much there is left to add to the current payload
-+           package */
-+        remainpack = p->total_num - p->data_num;
-+
-+        if (numbytes > remainpack) {
-+            /* if we have more data in the buffer than what is going into this
-+               particular packet, we limit this round to this packet only */
-+            numbytes = remainpack;
-+        }
-+
-+        if (encrypted) {
-+            /* At the end of the incoming stream, there is a MAC,
-+               and we don't want to decrypt that since we need it
-+               "raw". We MUST however decrypt the padding data
-+               since it is used for the hash later on. */
-+            int skip = session->remote.mac->mac_len;
-+
-+            /* if what we have plus numbytes is bigger than the
-+               total minus the skip margin, we should lower the
-+               amount to decrypt even more */
-+            if ((p->data_num + numbytes) > (p->total_num - skip)) {
-+                numdecrypt = (p->total_num - skip) - p->data_num;
-+            } else {
-+                int frac;
-+                numdecrypt = numbytes;
-+                frac = numdecrypt % blocksize;
-+                if (frac) {
-+                    /* not an aligned amount of blocks,
-+                       align it */
-+                    numdecrypt -= frac;
-+                    /* and make it no unencrypted data
-+                       after it */
-+                    numbytes = 0;
-+                }
-+            }
-+        } else {
-+            /* unencrypted data should not be decrypted at all */
-+            numdecrypt = 0;
-+        }
-+
-+        /* if there are bytes to decrypt, do that */
-+        if (numdecrypt > 0) {
-+            /* now decrypt the lot */
-+            rc = decrypt(session, &p->buf[p->readidx], p->wptr, numdecrypt);
-+            if (rc != PACKET_NONE) {
-+                return rc;
-+            }
-+
-+            /* advance the read pointer */
-+            p->readidx += numdecrypt;
-+            /* advance write pointer */
-+            p->wptr += numdecrypt;
-+            /* increse data_num */
-+            p->data_num += numdecrypt;
-+
-+            /* bytes left to take care of without decryption */
-+            numbytes -= numdecrypt;
-+        }
-+
-+        /* if there are bytes to copy that aren't decrypted, simply
-+           copy them as-is to the target buffer */
-+        if (numbytes > 0) {
-+            memcpy(p->wptr, &p->buf[p->readidx], numbytes);
-+
-+            /* advance the read pointer */
-+            p->readidx += numbytes;
-+            /* advance write pointer */
-+            p->wptr += numbytes;
-+            /* increse data_num */
-+            p->data_num += numbytes;
-+        }
-+
-+        /* now check how much data there's left to read to finish the
-+           current packet */
-+        remainpack = p->total_num - p->data_num;
-+
-+        if (!remainpack) {
-+            /* we have a full packet */
-+          libssh2_packet_read_point1:
-+            rc = fullpacket(session, encrypted);
-+            if (rc == PACKET_EAGAIN) {
-+
-+                if (session->packAdd_state != libssh2_NB_state_idle)
-+                {
-+                    /* fullpacket only returns PACKET_EAGAIN if
-+                     * libssh2_packet_add returns PACKET_EAGAIN. If that
-+                     * returns PACKET_EAGAIN but the packAdd_state is idle,
-+                     * then the packet has been added to the brigade, but some
-+                     * immediate action that was taken based on the packet
-+                     * type (such as key re-exchange) is not yet complete.
-+                     * Clear the way for a new packet to be read in.
-+                     */
-+                    session->readPack_encrypted = encrypted;
-+                    session->readPack_state = libssh2_NB_state_jump1;
-+                }
-+
-+                return PACKET_EAGAIN;
-+            }
-+
-+            p->total_num = 0;   /* no packet buffer available */
-+
-+            return rc;
-+        }
-+    } while (1);                /* loop */
-+
-+    return PACKET_FAIL;         /* we never reach this point */
-+}
-+
-+/* }}} */
-+
-+static libssh2pack_t
-+send_existing(LIBSSH2_SESSION * session, unsigned char *data,
-+              unsigned long data_len, ssize_t * ret)
-+{
-+    ssize_t rc;
-+    ssize_t length;
-+    struct transportpacket *p = &session->packet;
-+
-+    if (!p->outbuf) {
-+        *ret = 0;
-+        return PACKET_NONE;
-+    }
-+
-+    /* send as much as possible of the existing packet */
-+    if ((data != p->odata) || (data_len != p->olen)) {
-+        /* When we are about to complete the sending of a packet, it is vital
-+           that the caller doesn't try to send a new/different packet since
-+           we don't add this one up until the previous one has been sent. To
-+           make the caller really notice his/hers flaw, we return error for
-+           this case */
-+        return PACKET_BADUSE;
-+    }
-+
-+    *ret = 1;                   /* set to make our parent return */
-+
-+    /* number of bytes left to send */
-+    length = p->ototal_num - p->osent;
-+
-+    rc = send(session->socket_fd, &p->outbuf[p->osent], length,
-+              LIBSSH2_SOCKET_SEND_FLAGS(session));
-+
-+    if (rc == length) {
-+        /* the remainder of the package was sent */
-+        LIBSSH2_FREE(session, p->outbuf);
-+        p->outbuf = NULL;
-+        p->ototal_num = 0;
-+    } else if (rc < 0) {
-+        /* nothing was sent */
-+        if (errno != EAGAIN) {
-+            /* send failure! */
-+            return PACKET_FAIL;
-+        }
-+        session->socket_block_directions = LIBSSH2_SESSION_BLOCK_OUTBOUND;
-+        return PACKET_EAGAIN;
-+    }
-+
-+    debugdump(session, "libssh2_packet_write send()", &p->outbuf[p->osent],
-+              length);
-+    p->osent += length;         /* we sent away this much data */
-+
-+    return PACKET_NONE;
-+}
-+
-+/* {{{ libssh2_packet_write
-+ * Send a packet, encrypting it and adding a MAC code if necessary
-+ * Returns 0 on success, non-zero on failure.
-+ *
-+ * Returns PACKET_EAGAIN if it would block - and if it does so, you should
-+ * call this function again as soon as it is likely that more data can be
-+ * sent, and this function should then be called with the same argument set
-+ * (same data pointer and same data_len) until zero or failure is returned.
-+ *
-+ * NOTE: this function does not verify that 'data_len' is less than ~35000
-+ * which is what all implementations should support at least as packet size.
-+ * (RFC4253 section 6.1)
-+ */
-+int
-+libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
-+                     unsigned long data_len)
-+{
-+    int blocksize =
-+        (session->state & LIBSSH2_STATE_NEWKEYS) ? session->local.crypt->
-+        blocksize : 8;
-+    int padding_length;
-+    int packet_length;
-+    int total_length;
-+    int free_data = 0;
-+#ifdef RANDOM_PADDING
-+    int rand_max;
-+    int seed = data[0];         /* FIXME: make this random */
-+#endif
-+    struct transportpacket *p = &session->packet;
-+    int encrypted;
-+    int i;
-+    ssize_t ret;
-+    libssh2pack_t rc;
-+    unsigned char *orgdata = data;
-+    unsigned long orgdata_len = data_len;
-+
-+    debugdump(session, "libssh2_packet_write plain", data, data_len);
-+
-+    /* FIRST, check if we have a pending write to complete */
-+    rc = send_existing(session, data, data_len, &ret);
-+    if (rc || ret) {
-+        return rc;
-+    }
-+
-+    encrypted = (session->state & LIBSSH2_STATE_NEWKEYS) ? 1 : 0;
-+
-+    /* check if we should compress */
-+    if (encrypted && strcmp(session->local.comp->name, "none")) {
-+        if (session->local.comp->comp(session, 1, &data, &data_len,
-+                                      LIBSSH2_PACKET_MAXCOMP,
-+                                      &free_data, data, data_len,
-+                                      &session->local.comp_abstract)) {
-+            return PACKET_COMPRESS;     /* compression failure */
-+        }
-+    }
-+
-+    /* RFC4253 says: Note that the length of the concatenation of
-+       'packet_length', 'padding_length', 'payload', and 'random padding'
-+       MUST be a multiple of the cipher block size or 8, whichever is
-+       larger. */
-+
-+    /* Plain math: (4 + 1 + packet_length + padding_length) % blocksize == 0 */
-+
-+    packet_length = data_len + 1 + 4;   /* 1 is for padding_length field
-+                                           4 for the packet_length field */
-+
-+    /* at this point we have it all except the padding */
-+
-+    /* first figure out our minimum padding amount to make it an even
-+       block size */
-+    padding_length = blocksize - (packet_length % blocksize);
-+
-+    /* if the padding becomes too small we add another blocksize worth
-+       of it (taken from the original libssh2 where it didn't have any
-+       real explanation) */
-+    if (padding_length < 4) {
-+        padding_length += blocksize;
-+    }
-+#ifdef RANDOM_PADDING
-+    /* FIXME: we can add padding here, but that also makes the packets
-+       bigger etc */
-+
-+    /* now we can add 'blocksize' to the padding_length N number of times
-+       (to "help thwart traffic analysis") but it must be less than 255 in
-+       total */
-+    rand_max = (255 - padding_length) / blocksize + 1;
-+    padding_length += blocksize * (seed % rand_max);
-+#endif
-+
-+    packet_length += padding_length;
-+
-+    /* append the MAC length to the total_length size */
-+    total_length =
-+        packet_length + (encrypted ? session->local.mac->mac_len : 0);
-+
-+    /* allocate memory to store the outgoing packet in, in case we can't
-+       send the whole one and thus need to keep it after this function
-+       returns. */
-+    p->outbuf = LIBSSH2_ALLOC(session, total_length);
-+    if (!p->outbuf) {
-+        return PACKET_ENOMEM;
-+    }
-+
-+    /* store packet_length, which is the size of the whole packet except
-+       the MAC and the packet_length field itself */
-+    libssh2_htonu32(p->outbuf, packet_length - 4);
-+    /* store padding_length */
-+    p->outbuf[4] = padding_length;
-+    /* copy the payload data */
-+    memcpy(p->outbuf + 5, data, data_len);
-+    /* fill the padding area with random junk */
-+    libssh2_random(p->outbuf + 5 + data_len, padding_length);
-+    if (free_data) {
-+        LIBSSH2_FREE(session, data);
-+    }
-+
-+    if (encrypted) {
-+        /* Calculate MAC hash. Put the output at index packet_length,
-+           since that size includes the whole packet. The MAC is
-+           calculated on the entire unencrypted packet, including all
-+           fields except the MAC field itself. */
-+        session->local.mac->hash(session, p->outbuf + packet_length,
-+                                 session->local.seqno, p->outbuf,
-+                                 packet_length, NULL, 0,
-+                                 &session->local.mac_abstract);
-+
-+        /* Encrypt the whole packet data, one block size at a time.
-+           The MAC field is not encrypted. */
-+        for(i = 0; i < packet_length; i += session->local.crypt->blocksize) {
-+            unsigned char *ptr = &p->outbuf[i];
-+            if (session->local.crypt->crypt(session, ptr,
-+                                            &session->local.crypt_abstract))
-+                return PACKET_FAIL;     /* encryption failure */
-+        }
-+    }
-+
-+    session->local.seqno++;
-+
-+    ret = send(session->socket_fd, p->outbuf, total_length,
-+               LIBSSH2_SOCKET_SEND_FLAGS(session));
-+
-+    if (ret != -1) {
-+        debugdump(session, "libssh2_packet_write send()", p->outbuf, ret);
-+    }
-+    if (ret != total_length) {
-+        if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
-+            /* the whole packet could not be sent, save the rest */
-+            session->socket_block_directions = LIBSSH2_SESSION_BLOCK_OUTBOUND;
-+            p->odata = orgdata;
-+            p->olen = orgdata_len;
-+            p->osent = (ret == -1) ? 0 : ret;
-+            p->ototal_num = total_length;
-+            return PACKET_EAGAIN;
-+        }
-+        return PACKET_FAIL;
-+    }
-+
-+    /* the whole thing got sent away */
-+    p->odata = NULL;
-+    p->olen = 0;
-+    LIBSSH2_FREE(session, p->outbuf);
-+    p->outbuf = NULL;
-+
-+    return PACKET_NONE;         /* all is good */
-+}
-+
-+/* }}} */
-+
-
-Property changes on: libssh2/src/transport.c
-___________________________________________________________________
-Added: svn:mime-type
-   + text/x-c
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.1
-Added: svn:eol-style
-   + native
-Added: svn:executable
-   + *
-
-
-Property changes on: libssh2/src
-___________________________________________________________________
-Added: svn:ignore
-   + libssh2_config.h
-
-
-Index: package.xml
-===================================================================
-Cannot display: file marked as a binary type.
-svn:mime-type = application/xml
-
-Property changes on: package.xml
-___________________________________________________________________
-Deleted: svn:mime-type
-   - application/xml
-
-Index: ssh2_fopen_wrappers.c
-===================================================================
---- ssh2_fopen_wrappers.c      (.../tags/RELEASE_0_11_0)
-+++ ssh2_fopen_wrappers.c      (.../trunk)
-@@ -46,7 +46,7 @@
-       libssh2_channel_set_blocking(abstract->channel, abstract->is_blocking);
-               
-       readstate = libssh2_channel_read_ex(abstract->channel, abstract->streamid, buf, count);
--      return (readstate == LIBSSH2_ERROR_EAGAIN ? 0 : readstate);
-+      return (readstate < 0 ? 0 : readstate);
- }
- static int php_ssh2_channel_stream_close(php_stream *stream, int close_handle TSRMLS_DC)
-
-Property changes on: ssh2_fopen_wrappers.c
-___________________________________________________________________
-Modified: cvs2svn:cvs-rev
-   - 1.15
-   + 1.16
-
-Index: php_ssh2.h
-===================================================================
---- php_ssh2.h (.../tags/RELEASE_0_11_0)
-+++ php_ssh2.h (.../trunk)
-@@ -101,6 +101,10 @@
- } php_ssh2_pkey_subsys_data;
- #endif
-+#ifndef PHP_WIN32
-+#define closesocket(s)        close(s)
-+#endif
-+
- #ifdef ZTS
- #define SSH2_TSRMLS_SET(datap)                ((php_ssh2_session_data*)(datap))->tsrm_ls = TSRMLS_C
- #define SSH2_TSRMLS_FETCH(datap)      TSRMLS_D = ((php_ssh2_session_data*)(datap))->tsrm_ls
-@@ -109,6 +113,12 @@
- #define SSH2_TSRMLS_FETCH(datap)
- #endif
-+#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION >= 3)
-+#define ZEND_IS_CALLABLE_TSRMLS_CC            TSRMLS_CC
-+#else
-+#define ZEND_IS_CALLABLE_TSRMLS_CC
-+#endif
-+
- /* < 5.3 compatibility */
- #ifndef Z_REFCOUNT_P
- #define Z_REFCOUNT_P(pz)              (pz)->refcount
-
-Property changes on: php_ssh2.h
-___________________________________________________________________
-Modified: cvs2svn:cvs-rev
-   - 1.12
-   + 1.14
-
-Index: EXPERIMENTAL
-===================================================================
-
-Property changes on: EXPERIMENTAL
-___________________________________________________________________
-Added: svn:eol-style
-   + native
-Added: svn:keywords
-   + Id Rev Revision Date LastChangedDate LastChangedRevision Author LastChangedBy HeadURL URL
-Added: cvs2svn:cvs-rev
-   + 1.1
-
-
-Property changes on: .
-___________________________________________________________________
-Added: svn:ignore
-   + #*#
-*.dsw
-*.la
-*.lo
-*.ncb
-*.opt
-*.plg
-*.tgz
-*~
-.#*
-.deps
-.libs
-Debug
-Debug_TS
-Makefile
-Makefile.fragments
-Makefile.global
-Makefile.objects
-Release
-Release_TS
-Release_TSDbg
-Release_TS_inline
-Release_inline
-acinclude.m4
-aclocal.m4
-autom4te.cache
-build
-config.cache
-config.guess
-config.h
-config.h.in
-config.log
-config.nice
-config.status
-config.sub
-configure
-configure.in
-conftest
-conftest.c
-include
-install-sh
-libs.mk
-libtool
-ltmain.sh
-missing
-mkinstalldirs
-modules
-scan_makefile_in.awk
-*.gcda
-*.gcno
-run-tests.php
-
-
index 56732e833523dc31dbf115b7e53a7813ac5efed5..4996b8c4a9719f102afbaba09e07da4e0849711a 100644 (file)
@@ -1,17 +1,15 @@
 %define                php_name        php%{?php_suffix}
 %define                modname ssh2
-%define                status  beta
 Summary:       %{modname} - bindings for the libssh2 library
 Summary(pl.UTF-8):     %{modname} - dowiązania do biblioteki libssh2
 Name:          %{php_name}-pecl-%{modname}
-Version:       0.12
-Release:       5
+Version:       0.13
+Release:       1
 License:       PHP
 Group:         Development/Languages/PHP
 Source0:       http://pecl.php.net/get/%{modname}-%{version}.tgz
-# Source0-md5: 409b91678a842bb0ff56f2cf018b9160
-Patch0:                branch.diff
-URL:           http://pecl.php.net/package/ssh2/
+# Source0-md5: e35f8438b3f6177066166c8c1916f44e
+URL:           https://pecl.php.net/package/ssh2
 BuildRequires: %{php_name}-devel >= 4:5.0.4
 BuildRequires: libssh2-devel >= 1.2.9
 BuildRequires: openssl-devel >= 0.9.7d
@@ -25,18 +23,13 @@ BuildRoot:  %{tmpdir}/%{name}-%{version}-root-%(id -u -n)
 Provides bindings to the functions of libssh2 which implements the
 SSH2 protocol.
 
-In PECL status of this extension is: %{status}.
-
 %description -l pl.UTF-8
 Dostarcza dowiązań do różnych funkcji biblioteki libssh2
 implementującej protokół SSH2.
 
-To rozszerzenie ma w PECL status: %{status}.
-
 %prep
 %setup -qc
 mv %{modname}-%{version}/* .
-#%patch0 -p0
 
 %build
 phpize
This page took 1.443008 seconds and 4 git commands to generate.