aboutsummaryrefslogtreecommitdiff
path: root/examples/libssh_scp.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/libssh_scp.c')
-rw-r--r--examples/libssh_scp.c144
1 files changed, 109 insertions, 35 deletions
diff --git a/examples/libssh_scp.c b/examples/libssh_scp.c
index 25d95ad6..26e2fd41 100644
--- a/examples/libssh_scp.c
+++ b/examples/libssh_scp.c
@@ -8,7 +8,7 @@ Copyright 2009 Aris Adamantiadis
This file is part of the SSH Library
You are free to copy this file, modify it in any way, consider it being public
-domain. This does not apply to the rest of the library though, but it is
+domain. This does not apply to the rest of the library though, but it is
allowed to cut-and-paste working code from this file to any license of
program.
*/
@@ -187,58 +187,132 @@ static int open_location(struct location *loc, int flag){
} else {
loc->file=fopen(loc->path,flag==READ ? "r":"w");
if(!loc->file){
- fprintf(stderr,"Error opening %s : %s\n",loc->path,strerror(errno));
- return -1;
- }
+ if(errno==EISDIR){
+ if(chdir(loc->path)){
+ fprintf(stderr,"Error changing directory to %s: %s\n",loc->path,strerror(errno));
+ return -1;
+ }
+ return 0;
+ }
+ fprintf(stderr,"Error opening %s: %s\n",loc->path,strerror(errno));
+ return -1;
+ }
return 0;
}
return -1;
}
-static int do_copy(struct location *src, struct location *dest){
+/** @brief copies files from source location to destination
+ * @param src source location
+ * @param dest destination location
+ * @param recursive Copy also directories
+ */
+static int do_copy(struct location *src, struct location *dest, int recursive){
int size;
socket_t fd;
struct stat s;
int w,r;
char buffer[16384];
int total=0;
- /*FIXME*/
- if(dest->is_ssh && !src->is_ssh){
+ int mode;
+ char *filename;
+ /* Get the file name and size*/
+ if(!src->is_ssh){
fd=fileno(src->file);
fstat(fd,&s);
size=s.st_size;
- } else
+ mode=s.st_mode;
+ filename=ssh_basename(src->path);
+ } else {
size=0;
- r=ssh_scp_push_file(dest->scp,src->path,size,"0644");
-// snprintf(buffer,sizeof(buffer),"C0644 %d %s\n",size,src->path);
- if(r==SSH_ERROR){
- fprintf(stderr,"error: %s\n",ssh_get_error(dest->session));
- ssh_scp_free(dest->scp);
- return -1;
+ do {
+ r=ssh_scp_pull_request(src->scp);
+ if(r==SSH_SCP_REQUEST_NEWDIR){
+ ssh_scp_deny_request(src->scp,"Not in recursive mode");
+ continue;
+ }
+ if(r==SSH_SCP_REQUEST_NEWFILE){
+ size=ssh_scp_request_get_size(src->scp);
+ filename=strdup(ssh_scp_request_get_filename(src->scp));
+ mode=ssh_scp_request_get_permissions(src->scp);
+ //ssh_scp_accept_request(src->scp);
+ break;
+ }
+ if(r==SSH_ERROR){
+ fprintf(stderr,"Error: %s\n",ssh_get_error(src->session));
+ return -1;
+ }
+ } while(r != SSH_SCP_REQUEST_NEWFILE);
+ }
+
+ if(dest->is_ssh){
+ r=ssh_scp_push_file(dest->scp,src->path,size,0644);
+ // snprintf(buffer,sizeof(buffer),"C0644 %d %s\n",size,src->path);
+ if(r==SSH_ERROR){
+ fprintf(stderr,"error: %s\n",ssh_get_error(dest->session));
+ ssh_scp_free(dest->scp);
+ return -1;
+ }
+ } else {
+ if(!dest->file){
+ dest->file=fopen(filename,"w");
+ if(!dest->file){
+ fprintf(stderr,"Cannot open %s for writing: %s\n",filename,strerror(errno));
+ if(src->is_ssh)
+ ssh_scp_deny_request(src->scp,"Cannot open local file");
+ return -1;
+ }
+ }
+ if(src->is_ssh){
+ ssh_scp_accept_request(src->scp);
+ }
}
do {
- r=fread(buffer,1,sizeof(buffer),src->file);
- if(r==0)
- break;
- if(r<0){
- fprintf(stderr,"Error reading file: %s\n",strerror(errno));
- return -1;
- }
- w=ssh_scp_write(dest->scp,buffer,r);
- if(w == SSH_ERROR){
- fprintf(stderr,"error writing in scp: %s\n",ssh_get_error(dest->session));
- ssh_scp_free(dest->scp);
- return -1;
- }
- total+=r;
+ if(src->is_ssh){
+ r=ssh_scp_read(src->scp,buffer,sizeof(buffer));
+ if(r==SSH_ERROR){
+ fprintf(stderr,"Error reading scp: %s\n",ssh_get_error(src->session));
+ return -1;
+ }
+ } else {
+ r=fread(buffer,1,sizeof(buffer),src->file);
+ if(r==0)
+ break;
+ if(r<0){
+ fprintf(stderr,"Error reading file: %s\n",strerror(errno));
+ return -1;
+ }
+ }
+ if(dest->is_ssh){
+ w=ssh_scp_write(dest->scp,buffer,r);
+ if(w == SSH_ERROR){
+ fprintf(stderr,"Error writing in scp: %s\n",ssh_get_error(dest->session));
+ ssh_scp_free(dest->scp);
+ dest->scp=NULL;
+ return -1;
+ }
+ } else {
+ w=fwrite(buffer,r,1,dest->file);
+ if(w<=0){
+ fprintf(stderr,"Error writing in local file: %s\n",strerror(errno));
+ return -1;
+ }
+ }
+ total+=r;
- } while(1);
+ } while(total < size);
printf("wrote %d bytes\n",total);
- r=ssh_scp_close(dest->scp);
- if(r == SSH_ERROR){
- fprintf(stderr,"Error closing scp: %s\n",ssh_get_error(dest->session));
- ssh_scp_free(dest->scp);
- return -1;
+ if(dest->is_ssh){
+ r=ssh_scp_close(dest->scp);
+ if(r == SSH_ERROR){
+ fprintf(stderr,"Error closing scp: %s\n",ssh_get_error(dest->session));
+ ssh_scp_free(dest->scp);
+ dest->scp=NULL;
+ return -1;
+ }
+ } else {
+ fclose(dest->file);
+ dest->file=NULL;
}
return 0;
}
@@ -257,7 +331,7 @@ int main(int argc, char **argv){
if(open_location(src,READ)<0){
return EXIT_FAILURE;
}
- if(do_copy(src,dest) < 0)
+ if(do_copy(src,dest,0) < 0)
return EXIT_FAILURE;
}
ssh_disconnect(dest->session);