summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/libssh/libssh.h2
-rw-r--r--libssh/scp.c36
2 files changed, 38 insertions, 0 deletions
diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h
index 9707ba88..f7896fb2 100644
--- a/include/libssh/libssh.h
+++ b/include/libssh/libssh.h
@@ -486,6 +486,8 @@ LIBSSH_API int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len);
LIBSSH_API int ssh_scp_pull_request(ssh_scp scp);
LIBSSH_API int ssh_scp_deny_request(ssh_scp scp, const char *reason);
LIBSSH_API int ssh_scp_accept_request(ssh_scp scp);
+LIBSSH_API int ssh_scp_read(ssh_scp scp, void *buffer, size_t size);
+
#ifdef __cplusplus
}
diff --git a/libssh/scp.c b/libssh/scp.c
index c3d7e494..2c891472 100644
--- a/libssh/scp.c
+++ b/libssh/scp.c
@@ -423,3 +423,39 @@ int ssh_scp_accept_request(ssh_scp scp){
scp->state=SSH_SCP_READ_INITED;
return SSH_OK;
}
+
+/** @brief Read from a remote scp file
+ * @param buffer Destination buffer
+ * @param size Size of the buffer
+ * @returns Number of bytes read
+ * @returns SSH_ERROR An error happened while reading
+ */
+int ssh_scp_read(ssh_scp scp, void *buffer, size_t size){
+ int r;
+ if(scp->state == SSH_SCP_READ_REQUESTED && scp->request_type == SSH_SCP_REQUEST_NEWFILE){
+ r=ssh_scp_accept_request(scp);
+ if(r==SSH_ERROR)
+ return r;
+ }
+ if(scp->state != SSH_SCP_READ_READING){
+ ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_read called under invalid state");
+ return SSH_ERROR;
+ }
+ if(scp->processed + size > scp->filelen)
+ size = scp->filelen - scp->processed;
+ if(size > 65536)
+ size=65536; /* avoid too large reads */
+ r=channel_read(scp->channel,buffer,size,0);
+ if(r != SSH_ERROR)
+ scp->processed += r;
+ else {
+ scp->state=SSH_SCP_ERROR;
+ return SSH_ERROR;
+ }
+ /* Check if we arrived at end of file */
+ if(scp->processed == scp->filelen) {
+ scp->processed=scp->filelen=0;
+ scp->state=SSH_SCP_READ_INITED;
+ }
+ return r;
+}