Index: src/channel.c
===================================================================
RCS file: /cvsroot/libssh2/libssh2/src/channel.c,v
retrieving revision 1.52
diff -u -r1.52 channel.c
--- src/channel.c	23 Jun 2007 22:20:30 -0000	1.52
+++ src/channel.c	5 Jul 2007 10:14:35 -0000
@@ -1172,7 +1172,7 @@
 /* }}} */
 
 /*
- * {{{ _libssh2_channel_read_ex
+ * {{{ 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
@@ -1329,6 +1329,52 @@
 }
 /* }}} */
 
+/*
+ * {{{ 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
  */
Index: src/libssh2_priv.h
===================================================================
RCS file: /cvsroot/libssh2/libssh2/src/libssh2_priv.h,v
retrieving revision 1.31
diff -u -r1.31 libssh2_priv.h
--- src/libssh2_priv.h	18 Jun 2007 22:39:30 -0000	1.31
+++ src/libssh2_priv.h	5 Jul 2007 10:14:35 -0000
@@ -798,6 +798,8 @@
     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;
 };
 
@@ -1041,6 +1043,7 @@
 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);
Index: src/scp.c
===================================================================
RCS file: /cvsroot/libssh2/libssh2/src/scp.c,v
retrieving revision 1.14
diff -u -r1.14 scp.c
--- src/scp.c	12 Jun 2007 18:27:50 -0000	1.14
+++ src/scp.c	5 Jul 2007 10:14:35 -0000
@@ -419,6 +419,15 @@
     unsigned const char *base;
     int rc;
 
+    /*
+     * =============================== 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->scpSend_state == libssh2_NB_state_jump1) {
+        goto scp_read_ex_point1;
+    }
+    
     if (session->scpSend_state == libssh2_NB_state_idle) {
         session->scpSend_command_len = path_len + sizeof("scp -t ");
         
@@ -577,15 +586,49 @@
         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) || (session->scpSend_response[0] != 0)) {
-        libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
-        goto scp_send_error;
+    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) {
+            session->scpSend_state = libssh2_NB_state_jump1;
+
+            /*
+             * 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 */
+scp_read_ex_point1:
+            rc = libssh2_channel_read_ex(session->scpSend_channel, 0, session->scpSend_err_msg, session->scpSend_err_len);
+            if (rc == PACKET_EAGAIN) {
+                libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response", 0);
+                return NULL;
+            }
+            else if (rc <= 0) {
+                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);
+            goto scp_send_error;
+        }
     }
     
     session->scpSend_state = libssh2_NB_state_idle;
