diff options
-rw-r--r-- | examples/scp_download.c | 5 | ||||
-rw-r--r-- | include/libssh/libssh.h | 9 | ||||
-rw-r--r-- | include/libssh/priv.h | 1 | ||||
-rw-r--r-- | libssh/scp.c | 28 |
4 files changed, 31 insertions, 12 deletions
diff --git a/examples/scp_download.c b/examples/scp_download.c index f719515..9da3aaf 100644 --- a/examples/scp_download.c +++ b/examples/scp_download.c @@ -85,7 +85,7 @@ static int fetch_files(ssh_session session){ int mode; char *filename; int r; - ssh_scp scp=ssh_scp_new(session, SSH_SCP_READ, "/tmp/libssh_tests/*"); + ssh_scp scp=ssh_scp_new(session, SSH_SCP_READ | SSH_SCP_RECURSIVE, "/tmp/libssh_tests/*"); if(ssh_scp_init(scp) != SSH_OK){ fprintf(stderr,"error initializing scp: %s\n",ssh_get_error(session)); return -1; @@ -121,6 +121,9 @@ static int fetch_files(ssh_session session){ free(filename); ssh_scp_accept_request(scp); break; + case SSH_SCP_REQUEST_ENDDIR: + printf("End of directory\n"); + break; case SSH_SCP_REQUEST_EOF: printf("End of requests\n"); goto end; diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index 99d4a59..ade69d3 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -467,7 +467,8 @@ enum { /** Code is going to write/create remote files */ SSH_SCP_WRITE, /** Code is going to read remote files */ - SSH_SCP_READ + SSH_SCP_READ, + SSH_SCP_RECURSIVE=0x10 }; enum ssh_scp_request_types { @@ -476,7 +477,11 @@ enum ssh_scp_request_types { /** A new file is going to be pulled */ SSH_SCP_REQUEST_NEWFILE, /** End of requests */ - SSH_SCP_REQUEST_EOF + SSH_SCP_REQUEST_EOF, + /** End of directory */ + SSH_SCP_REQUEST_ENDDIR, + /** Warning received */ + SSH_SCP_REQUEST_WARNING }; LIBSSH_API ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location); diff --git a/include/libssh/priv.h b/include/libssh/priv.h index 7645c43..d05f3a6 100644 --- a/include/libssh/priv.h +++ b/include/libssh/priv.h @@ -365,6 +365,7 @@ enum ssh_scp_states { struct ssh_scp_struct { ssh_session session; int mode; + int recursive; ssh_channel channel; char *location; enum ssh_scp_states state; diff --git a/libssh/scp.c b/libssh/scp.c index 6c9257d..4f74dc1 100644 --- a/libssh/scp.c +++ b/libssh/scp.c @@ -40,7 +40,7 @@ ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location){ return NULL; } ZERO_STRUCTP(scp); - if(mode != SSH_SCP_WRITE && mode != SSH_SCP_READ){ + if((mode&~SSH_SCP_RECURSIVE) != SSH_SCP_WRITE && (mode &~SSH_SCP_RECURSIVE) != SSH_SCP_READ){ ssh_set_error(session,SSH_FATAL,"Invalid mode %d for ssh_scp_new()",mode); ssh_scp_free(scp); return NULL; @@ -52,7 +52,8 @@ ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location){ return NULL; } scp->session=session; - scp->mode=mode; + scp->mode=mode & ~SSH_SCP_RECURSIVE; + scp->recursive = (mode & SSH_SCP_RECURSIVE) != 0; scp->channel=NULL; scp->state=SSH_SCP_NEW; return scp; @@ -66,7 +67,10 @@ int ssh_scp_init(ssh_scp scp){ ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_init called under invalid state"); return SSH_ERROR; } - ssh_log(scp->session,SSH_LOG_PROTOCOL,"Initializing scp session %s on location '%s'",scp->mode==SSH_SCP_WRITE?"write":"read",scp->location); + ssh_log(scp->session,SSH_LOG_PROTOCOL,"Initializing scp session %s %son location '%s'", + scp->mode==SSH_SCP_WRITE?"write":"read", + scp->recursive?"recursive ":"", + scp->location); scp->channel=channel_new(scp->session); if(scp->channel == NULL){ scp->state=SSH_SCP_ERROR; @@ -78,9 +82,11 @@ int ssh_scp_init(ssh_scp scp){ return SSH_ERROR; } if(scp->mode == SSH_SCP_WRITE) - snprintf(execbuffer,sizeof(execbuffer),"scp -t %s",scp->location); + snprintf(execbuffer,sizeof(execbuffer),"scp -t %s %s", + scp->recursive ? "-r":"", scp->location); else - snprintf(execbuffer,sizeof(execbuffer),"scp -f %s",scp->location); + snprintf(execbuffer,sizeof(execbuffer),"scp -f %s %s", + scp->recursive ? "-r":"", scp->location); if(channel_request_exec(scp->channel,execbuffer) == SSH_ERROR){ scp->state=SSH_SCP_ERROR; return SSH_ERROR; @@ -416,15 +422,19 @@ int ssh_scp_pull_request(ssh_scp scp){ scp->processed = 0; return scp->request_type; break; - case 'T': - /* Timestamp */ - break; + case 'E': + scp->request_type=SSH_SCP_REQUEST_ENDDIR; + channel_write(scp->channel,"",1); + return scp->request_type; case 0x1: ssh_set_error(scp->session,SSH_REQUEST_DENIED,"SCP: Warning: %s",&buffer[1]); - return SSH_ERROR; + scp->request_type=SSH_SCP_REQUEST_WARNING; + return scp->request_type; case 0x2: ssh_set_error(scp->session,SSH_FATAL,"SCP: Error: %s",&buffer[1]); return SSH_ERROR; + case 'T': + /* Timestamp */ default: ssh_set_error(scp->session,SSH_FATAL,"Unhandled message: (%d)%s",buffer[0],buffer); return SSH_ERROR; |