aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2009-09-06 19:35:40 +0300
committerAris Adamantiadis <aris@0xbadc0de.be>2009-09-13 14:03:34 +0300
commit929f5ca25b56ce46bf49e9a44d40bab3ef2d6076 (patch)
tree4641c368f4b655e01c4fd9ee1262f9340419a2a0
parent7ff80a2666fcdd0ee8dc897ce5ea665a4faed681 (diff)
downloadlibssh-929f5ca25b56ce46bf49e9a44d40bab3ef2d6076.tar.gz
libssh-929f5ca25b56ce46bf49e9a44d40bab3ef2d6076.tar.xz
libssh-929f5ca25b56ce46bf49e9a44d40bab3ef2d6076.zip
scp recursive mode
-rw-r--r--examples/scp_download.c5
-rw-r--r--include/libssh/libssh.h9
-rw-r--r--include/libssh/priv.h1
-rw-r--r--libssh/scp.c28
4 files changed, 31 insertions, 12 deletions
diff --git a/examples/scp_download.c b/examples/scp_download.c
index f719515c..9da3aafd 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 99d4a598..ade69d38 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 7645c431..d05f3a60 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 6c9257db..4f74dc10 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;