static void torture_basename(void **state) { char *path; (void) state; path=ssh_basename(TORTURE_TEST_DIR "/test"); assert_true(path != NULL); assert_string_equal(path, "test"); SAFE_FREE(path); path=ssh_basename(TORTURE_TEST_DIR "/test/"); assert_true(path != NULL); assert_string_equal(path, "test"); SAFE_FREE(path); }
/** * @brief Create a directory in a scp in sink mode. * * @param[in] scp The scp handle. * * @param[in] dirname The name of the directory being created. * * @param[in] mode The UNIX permissions for the new directory, e.g. 0755. * * @returns SSH_OK if the directory has been created, SSH_ERROR if * an error occured. * * @see ssh_scp_leave_directory() */ int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode){ char buffer[1024]; int r; uint8_t code; char *dir; char *perms; if(scp==NULL) return SSH_ERROR; if(scp->state != SSH_SCP_WRITE_INITED){ ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_push_directory called under invalid state"); return SSH_ERROR; } dir=ssh_basename(dirname); perms=ssh_scp_string_mode(mode); snprintf(buffer, sizeof(buffer), "D%s 0 %s\n", perms, dir); SAFE_FREE(dir); SAFE_FREE(perms); r=ssh_channel_write(scp->channel,buffer,strlen(buffer)); if(r==SSH_ERROR){ scp->state=SSH_SCP_ERROR; return SSH_ERROR; } r=ssh_channel_read(scp->channel,&code,1,0); if(r<=0){ ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session)); scp->state=SSH_SCP_ERROR; return SSH_ERROR; } if(code != 0){ ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code); scp->state=SSH_SCP_ERROR; return SSH_ERROR; } return SSH_OK; }
/** @brief initializes the sending of a file to a scp in sink mode * @param scp the scp handle. * @param filename Name of the file being sent. It should not contain any path indicator * @param size Exact size in bytes of the file being sent. * @param mode Unix permissions for the new file, e.g. 0644 * @returns SSH_OK if the file is ready to be sent. * @returns SSH_ERROR if an error happened. */ int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int mode){ char buffer[1024]; int r; uint8_t code; char *file; char *perms; if(scp->state != SSH_SCP_WRITE_INITED){ ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_push_file called under invalid state"); return SSH_ERROR; } file=ssh_basename(filename); perms=ssh_scp_string_mode(mode); ssh_log(scp->session,SSH_LOG_PROTOCOL,"SCP pushing file %s, size %" PRIdS " with permissions '%s'",file,size,perms); snprintf(buffer, sizeof(buffer), "C%s %" PRIdS " %s\n", perms, size, file); SAFE_FREE(file); SAFE_FREE(perms); r=channel_write(scp->channel,buffer,strlen(buffer)); if(r==SSH_ERROR){ scp->state=SSH_SCP_ERROR; return SSH_ERROR; } r=channel_read(scp->channel,&code,1,0); if(code != 0){ ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code); scp->state=SSH_SCP_ERROR; return SSH_ERROR; } scp->filelen = size; scp->processed = 0; scp->state=SSH_SCP_WRITE_WRITING; return SSH_OK; }
int sftp_file_open(const char *username, const char *longname) { int fp = -1; char *filename = ssh_basename(longname); fp = api_sftpfile_open(username, filename); SAFE_FREE(filename); return fp; }
/** @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; }