From d5840aa1f0ec98937d3d977851637c45a86d6a54 Mon Sep 17 00:00:00 2001 From: Aris Adamantiadis Date: Fri, 4 Sep 2009 18:26:57 +0300 Subject: add support for local output, scp input Still needs to be debugged and improved but the idea it there --- examples/libssh_scp.c | 144 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 109 insertions(+), 35 deletions(-) (limited to 'examples') 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); -- cgit v1.2.3