static int fetch_files(ssh_session session){ int size; char buffer[16384]; int mode; char *filename; int r; 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; } printf("Trying to download 3 files (a,b,d) and 1 directory (c)\n"); do { r=ssh_scp_pull_request(scp); switch(r){ case SSH_SCP_REQUEST_NEWFILE: size=ssh_scp_request_get_size(scp); filename=strdup(ssh_scp_request_get_filename(scp)); mode=ssh_scp_request_get_permissions(scp); printf("downloading file %s, size %d, perms 0%o\n",filename,size,mode); free(filename); ssh_scp_accept_request(scp); r=ssh_scp_read(scp,buffer,sizeof(buffer)); if(r==SSH_ERROR){ fprintf(stderr,"Error reading scp: %s\n",ssh_get_error(session)); return -1; } printf("done\n"); break; case SSH_ERROR: fprintf(stderr,"Error: %s\n",ssh_get_error(session)); return -1; case SSH_SCP_REQUEST_WARNING: fprintf(stderr,"Warning: %s\n",ssh_scp_request_get_warning(scp)); break; case SSH_SCP_REQUEST_NEWDIR: filename=strdup(ssh_scp_request_get_filename(scp)); mode=ssh_scp_request_get_permissions(scp); printf("downloading directory %s, perms 0%o\n",filename,mode); 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; } } while (1); end: return 0; }
static int lscp_pull_request(lua_State *L) { struct scp_ud * scpud = get_scpud(L); int r=ssh_scp_pull_request(scpud->scp); if(r==SSH_ERROR){ scp_error(L,scpud); } switch(r){ case SSH_SCP_REQUEST_NEWFILE:lua_pushstring(L,"SSH_SCP_REQUEST_NEWFILE");break; case SSH_SCP_REQUEST_NEWDIR:lua_pushstring(L,"SSH_SCP_REQUEST_NEWDIR");break; case SSH_SCP_REQUEST_ENDDIR:lua_pushstring(L,"SSH_SCP_REQUEST_ENDDIR");break; case SSH_SCP_REQUEST_EOF:lua_pushstring(L,"SSH_SCP_REQUEST_EOF");break; case SSH_SCP_REQUEST_WARNING:lua_pushstring(L,"SSH_SCP_REQUEST_WARNING");break; } return 1; }
/** @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; int mode; char *filename; /* recursive mode doesn't work yet */ (void)recursive; /* Get the file name and size*/ if(!src->is_ssh){ fd=fileno(src->file); fstat(fd,&s); size=s.st_size; mode = s.st_mode & S_IFMT; filename=ssh_basename(src->path); } else { size=0; 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, mode); // 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 { 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; } if(r==0) break; } 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(total < size); printf("wrote %d bytes\n",total); return 0; }
static int do_scp_read(ssh_scp scp, const char* infile, FILE* fp, getmode_t mode, ftp_transfer_func hookf) { time_t then = time(NULL) - 1; ftp_set_close_handler(); if (hookf) hookf(&ftp->ti); ftp->ti.begin = false; int rc = ssh_scp_pull_request(scp); if (rc != SSH_SCP_REQUEST_NEWFILE) { ftp_err(_("Failed to start scp download: %s\n"), ssh_get_error(ftp->session)); ssh_scp_close(scp); ssh_scp_free(scp); return -1; } size_t size = ssh_scp_request_get_size(scp); ssh_scp_accept_request(scp); /* read file */ char buffer[SSH_BUFSIZ]; int r = 0; while (size && (r = ssh_scp_read(scp, buffer, MIN(SSH_BUFSIZ, size))) != SSH_ERROR) { if (ftp_sigints() > 0) { ftp_trace("break due to sigint\n"); break; } errno = 0; if (fwrite(buffer, r, 1, fp) != 1) { ftp_err(_("Error while writing to file: %s\n"), strerror(errno)); ssh_scp_close(scp); ssh_scp_free(scp); return -1; } ftp->ti.size += r; if (hookf) { time_t now = time(NULL); if (now > then) { hookf(&ftp->ti); then = now; } } size -= r; } if (r == SSH_ERROR) { ftp_err(_("Error while reading from file: %s\n"), ssh_get_error(ftp->session)); r = -1; } else { r = ssh_scp_pull_request(scp); if (r != SSH_SCP_REQUEST_EOF) ftp_err(_("Unexpected request: %s %lu\n"), ssh_get_error(ftp->session), size); else r = 0; } ssh_scp_close(scp); ssh_scp_free(scp); return r; }