void clSFTP::Write(const wxMemoryBuffer& fileContent, const wxString& remotePath) throw(clException) { if(!m_sftp) { throw clException("SFTP is not initialized"); } int access_type = O_WRONLY | O_CREAT | O_TRUNC; sftp_file file; wxString tmpRemoteFile = remotePath; tmpRemoteFile << ".codelitesftp"; file = sftp_open(m_sftp, tmpRemoteFile.mb_str(wxConvUTF8).data(), access_type, 0644); if(file == NULL) { throw clException(wxString() << _("Can't open file: ") << tmpRemoteFile << ". " << ssh_get_error(m_ssh->GetSession()), sftp_get_error(m_sftp)); } char* p = (char*)fileContent.GetData(); const int maxChunkSize = 65536; wxInt64 bytesLeft = fileContent.GetDataLen(); while(bytesLeft > 0) { wxInt64 chunkSize = bytesLeft > maxChunkSize ? maxChunkSize : bytesLeft; wxInt64 bytesWritten = sftp_write(file, p, chunkSize); if(bytesWritten < 0) { sftp_close(file); throw clException(wxString() << _("Can't write data to file: ") << tmpRemoteFile << ". " << ssh_get_error(m_ssh->GetSession()), sftp_get_error(m_sftp)); } bytesLeft -= bytesWritten; p += bytesWritten; } sftp_close(file); // Unlink the original file if it exists bool needUnlink = false; { // Check if the file exists sftp_attributes attr = sftp_stat(m_sftp, remotePath.mb_str(wxConvISO8859_1).data()); if(attr) { needUnlink = true; sftp_attributes_free(attr); } } if(needUnlink && sftp_unlink(m_sftp, remotePath.mb_str(wxConvUTF8).data()) < 0) { throw clException(wxString() << _("Failed to unlink file: ") << remotePath << ". " << ssh_get_error(m_ssh->GetSession()), sftp_get_error(m_sftp)); } // Rename the file if(sftp_rename(m_sftp, tmpRemoteFile.mb_str(wxConvUTF8).data(), remotePath.mb_str(wxConvUTF8).data()) < 0) { throw clException(wxString() << _("Failed to rename file: ") << tmpRemoteFile << " -> " << remotePath << ". " << ssh_get_error(m_ssh->GetSession()), sftp_get_error(m_sftp)); } }
int FSSftp::Stat ( FSPath& path, FSStat* st, int* err, FSCInfo* info ) { MutexLock lock( &mutex ); int ret = CheckSession( err, info ); if ( ret ) { return ret; } char* fullPath = ( char* ) path.GetString( _operParam.charset ); sftp_attributes la = sftp_lstat( sftpSession, fullPath ); if ( !la ) { if ( err ) { *err = sftp_get_error( sftpSession ); } return -1; } if ( la->type == SSH_FILEXFER_TYPE_SYMLINK ) { char* s = sftp_readlink( sftpSession, fullPath ); if ( s ) { st->link.Set( _operParam.charset, s ); } sftp_attributes_free( la ); //!!! } else { st->mode = la->permissions; st->size = la->size; st->uid = la->uid; st->gid = la->gid; st->mtime = la->mtime; sftp_attributes_free( la ); //!!! return 0; } sftp_attributes a = sftp_stat( sftpSession, fullPath ); if ( !a ) { if ( err ) { *err = sftp_get_error( sftpSession ); } return -1; } st->mode = la->permissions; st->size = la->size; st->uid = la->uid; st->gid = la->gid; st->mtime = la->mtime; sftp_attributes_free( a ); //!!! return 0; }
static int _sftp_rename(const char *olduri, const char *newuri) { char *oldpath = NULL; char *newpath = NULL; int rc = -1; if (_sftp_connect(olduri) < 0) { return -1; } if (c_parse_uri(olduri, NULL, NULL, NULL, NULL, NULL, &oldpath) < 0) { rc = -1; goto out; } if (c_parse_uri(newuri, NULL, NULL, NULL, NULL, NULL, &newpath) < 0) { rc = -1; goto out; } /* FIXME: workaround cause, sftp_rename can't overwrite */ sftp_unlink(_sftp_session, newpath); rc = sftp_rename(_sftp_session, oldpath, newpath); if (rc < 0) { errno = _sftp_portable_to_errno(sftp_get_error(_sftp_session)); } out: SAFE_FREE(oldpath); SAFE_FREE(newpath); return rc; }
static int _sftp_chmod(const char *uri, mode_t mode) { struct sftp_attributes_struct attrs; char *path = NULL; int rc = -1; if (_sftp_connect(uri) < 0) { return -1; } if (c_parse_uri(uri, NULL, NULL, NULL, NULL, NULL, &path) < 0) { return -1; } ZERO_STRUCT(attrs); attrs.permissions = mode; attrs.flags |= SSH_FILEXFER_ATTR_PERMISSIONS; rc = sftp_setstat(_sftp_session, path, &attrs); if (rc < 0) { errno = _sftp_portable_to_errno(sftp_get_error(_sftp_session)); } SAFE_FREE(path); return rc; }
static int _sftp_chown(const char *uri, uid_t owner, gid_t group) { struct sftp_attributes_struct attrs; char *path = NULL; int rc = -1; if (_sftp_connect(uri) < 0) { return -1; } if (c_parse_uri(uri, NULL, NULL, NULL, NULL, NULL, &path) < 0) { return -1; } ZERO_STRUCT(attrs); attrs.uid = owner; attrs.gid = group; attrs.flags |= SSH_FILEXFER_ATTR_OWNERGROUP; rc = sftp_setstat(_sftp_session, path, &attrs); if (rc < 0) { errno = _sftp_portable_to_errno(sftp_get_error(_sftp_session)); } SAFE_FREE(path); return rc; }
static int _sftp_utimes(const char *uri, const struct timeval *times) { struct sftp_attributes_struct attrs; char *path = NULL; int rc = -1; if (_sftp_connect(uri) < 0) { return -1; } if (c_parse_uri(uri, NULL, NULL, NULL, NULL, NULL, &path) < 0) { return -1; } ZERO_STRUCT(attrs); attrs.atime = times[0].tv_sec; attrs.atime_nseconds = times[0].tv_usec; attrs.mtime = times[1].tv_sec; attrs.mtime_nseconds = times[1].tv_usec; attrs.flags |= SSH_FILEXFER_ATTR_ACCESSTIME | SSH_FILEXFER_ATTR_MODIFYTIME; rc = sftp_setstat(_sftp_session, path, &attrs); if (rc < 0) { errno = _sftp_portable_to_errno(sftp_get_error(_sftp_session)); } SAFE_FREE(path); return rc; }
int FSSftp::SetFileTime ( FSPath& path, FSTime aTime, FSTime mTime, int* err, FSCInfo* info ) { MutexLock lock( &mutex ); int ret = CheckSession( err, info ); if ( ret ) { return ret; } struct timeval tv[2]; tv[0].tv_sec = aTime; tv[0].tv_usec = 0; tv[1].tv_sec = mTime; tv[1].tv_usec = 0; if ( sftp_utimes( sftpSession, ( char* )path.GetString( _operParam.charset ), tv ) ) { if ( err ) { *err = sftp_get_error( sftpSession ); } return -1; } return 0; }
int FSSftp::Close ( int fd, int* err, FSCInfo* info ) { MutexLock lock( &mutex ); int ret = CheckSession( err, info ); if ( ret ) { return ret; } if ( fd < 0 || fd >= MAX_FILES || !fileTable[fd] ) { if ( err ) { *err = EINVAL; } return -1; } ret = sftp_close( fileTable[fd] ); fileTable[fd] = 0; if ( ret != SSH_NO_ERROR ) { if ( err ) { *err = sftp_get_error( sftpSession ); } return -1; } return 0; }
int FSSftp::OpenRead ( FSPath& path, int* err, FSCInfo* info ) { MutexLock lock( &mutex ); int ret = CheckSession( err, info ); if ( ret ) { return ret; } int n = 0; for ( ; n < MAX_FILES; n++ ) if ( !fileTable[n] ) { break; } if ( n >= MAX_FILES ) { if ( err ) { *err = SSH_INTERROR_OUTOF; } return -1; } sftp_file f = sftp_open( sftpSession, ( char* ) path.GetString( _operParam.charset, '/' ), O_RDONLY, 0 ); if ( !f ) { if ( err ) { *err = sftp_get_error( sftpSession ); } return -1; } fileTable[n] = f; return n; }
void clSFTP::Read(const wxString& remotePath, wxMemoryBuffer& buffer) throw(clException) { if(!m_sftp) { throw clException("SFTP is not initialized"); } sftp_file file = sftp_open(m_sftp, remotePath.mb_str(wxConvUTF8).data(), O_RDONLY, 0); if(file == NULL) { throw clException(wxString() << _("Failed to open remote file: ") << remotePath << ". " << ssh_get_error(m_ssh->GetSession()), sftp_get_error(m_sftp)); } SFTPAttribute::Ptr_t fileAttr = Stat(remotePath); if(!fileAttr) { throw clException(wxString() << _("Could not stat file:") << remotePath << ". " << ssh_get_error(m_ssh->GetSession()), sftp_get_error(m_sftp)); } wxInt64 fileSize = fileAttr->GetSize(); if(fileSize == 0) return; // Allocate buffer for the file content char pBuffer[65536]; // buffer // Read the entire file content wxInt64 bytesLeft = fileSize; wxInt64 bytesRead = 0; while(bytesLeft > 0) { wxInt64 nbytes = sftp_read(file, pBuffer, sizeof(pBuffer)); bytesRead += nbytes; bytesLeft -= nbytes; buffer.AppendData(pBuffer, nbytes); } if(bytesRead != fileSize) { sftp_close(file); buffer.Clear(); throw clException(wxString() << _("Could not read file:") << remotePath << ". " << ssh_get_error(m_ssh->GetSession()), sftp_get_error(m_sftp)); } sftp_close(file); }
int FSSftp::Write ( int fd, void* buf, int size, int* err, FSCInfo* info ) { MutexLock lock( &mutex ); int ret = CheckSession( err, info ); //??? if ( ret ) { return ret; } if ( fd < 0 || fd >= MAX_FILES || !fileTable[fd] ) { if ( err ) { *err = EINVAL; } return -1; } /* Бля, libssh похоже какие-то уроды пишут при size 65536 портит данные, если 16к то нормально, пришлось уменьшить, а вот читать такие блоки - читает. хотя надо и там уменьшить, кто этих пидоров знает а было - так int bytes = sftp_write(fileTable[fd], buf, size); */ int bytes = 0; char* s = ( char* )buf; while ( size > 0 ) { int n = size; if ( n > 0x4000 ) { n = 0x4000; } int ret = sftp_write( fileTable[fd], s, n ); if ( ret < 0 ) { if ( err ) { *err = sftp_get_error( sftpSession ); } return -1; } if ( !ret ) { break; } s += ret; size -= ret; bytes += ret; } return bytes; }
SshFsModel::SshFsModel(QSharedPointer<ssh_session_struct> ssh, QObject *parent) : QAbstractItemModel(parent), _ssh(ssh) { _sftp = QSharedPointer<sftp_session_struct>(sftp_new(ssh.data()), sftp_free); if (sftp_init(_sftp.data()) != SSH_OK) { fprintf(stderr, "Error initializing SFTP session: %s.\n", sftp_get_error(_sftp.data())); } }
static ssize_t _sftp_write(csync_vio_method_handle_t *fhandle, const void *buf, size_t count) { int rc = -1; rc = sftp_write(fhandle, (void *) buf, count); if (rc < 0) { errno = _sftp_portable_to_errno(sftp_get_error(_sftp_session)); } return rc; }
static int _sftp_closedir(csync_vio_method_handle_t *dhandle) { int rc = -1; rc = sftp_closedir(dhandle); if (rc < 0) { errno = _sftp_portable_to_errno(sftp_get_error(_sftp_session)); } return rc; }
int FSSftp::OpenCreate ( FSPath& path, bool overwrite, int mode, int* err, FSCInfo* info ) { MutexLock lock( &mutex ); int ret = CheckSession( err, info ); if ( ret ) { return ret; } if ( !overwrite ) { /* заебался выяснять почему sftp_open с O_EXCL выдает "generc error" при наличии файла, а не EEXIST какой нибудь поэтому встанил эту дурацкую проверку на наличие */ sftp_attributes a = sftp_lstat( sftpSession, ( char* ) path.GetString( _operParam.charset, '/' ) ); if ( a ) { sftp_attributes_free( a ); //!!! if ( err ) { *err = SSH_FX_FILE_ALREADY_EXISTS; } return -1; } } int n = 0; for ( ; n < MAX_FILES; n++ ) if ( !fileTable[n] ) { break; } if ( n >= MAX_FILES ) { if ( err ) { *err = SSH_INTERROR_OUTOF; } return -1; } sftp_file f = sftp_open( sftpSession, ( char* ) path.GetString( _operParam.charset, '/' ), O_CREAT | O_WRONLY | ( overwrite ? O_TRUNC : O_EXCL ), mode ); if ( !f ) { //printf("ssh-err:'%s'\n",ssh_get_error(sshSession)); if ( err ) { *err = sftp_get_error( sftpSession ); } return -1; } fileTable[n] = f; return n; }
SFTPAttribute::Ptr_t clSFTP::Stat(const wxString& path) throw(clException) { if(!m_sftp) { throw clException("SFTP is not initialized"); } sftp_attributes attr = sftp_stat(m_sftp, path.mb_str(wxConvISO8859_1).data()); if(!attr) { throw clException(wxString() << _("Could not stat: ") << path << ". " << ssh_get_error(m_ssh->GetSession()), sftp_get_error(m_sftp)); } SFTPAttribute::Ptr_t pattr(new SFTPAttribute(attr)); return pattr; }
void clSFTP::Rename(const wxString& oldpath, const wxString& newpath) throw(clException) { if(!m_sftp) { throw clException("SFTP is not initialized"); } int rc; rc = sftp_rename(m_sftp, oldpath.mb_str(wxConvISO8859_1).data(), newpath.mb_str(wxConvISO8859_1).data()); if(rc != SSH_OK) { throw clException(wxString() << _("Failed to rename path. ") << ssh_get_error(m_ssh->GetSession()), sftp_get_error(m_sftp)); } }
SFTPAttribute::List_t clSFTP::List(const wxString& folder, size_t flags, const wxString& filter) throw(clException) { sftp_dir dir; sftp_attributes attributes; if(!m_sftp) { throw clException("SFTP is not initialized"); } dir = sftp_opendir(m_sftp, folder.mb_str(wxConvUTF8).data()); if(!dir) { throw clException(wxString() << _("Failed to list directory: ") << folder << ". " << ssh_get_error(m_ssh->GetSession()), sftp_get_error(m_sftp)); } // Keep the current folder name m_currentFolder = dir->name; // Ensure the directory is closed SFTPDirCloser dc(dir); SFTPAttribute::List_t files; attributes = sftp_readdir(m_sftp, dir); while(attributes) { SFTPAttribute::Ptr_t attr(new SFTPAttribute(attributes)); attributes = sftp_readdir(m_sftp, dir); // Don't show files ? if(!(flags & SFTP_BROWSE_FILES) && !attr->IsFolder()) { continue; } else if((flags & SFTP_BROWSE_FILES) && !attr->IsFolder() // show files && filter.IsEmpty()) { // no filter is given files.push_back(attr); } else if((flags & SFTP_BROWSE_FILES) && !attr->IsFolder() // show files && !::wxMatchWild(filter, attr->GetName())) { // but the file does not match the filter continue; } else { files.push_back(attr); } } files.sort(SFTPAttribute::Compare); return files; }
void clSFTP::UnlinkFile(const wxString& path) throw(clException) { if(!m_sftp) { throw clException("SFTP is not initialized"); } int rc; rc = sftp_unlink(m_sftp, path.mb_str(wxConvISO8859_1).data()); if(rc != SSH_OK) { throw clException(wxString() << _("Failed to unlink path: ") << path << ". " << ssh_get_error(m_ssh->GetSession()), sftp_get_error(m_sftp)); } }
void clSFTP::RemoveDir(const wxString& dirname) throw(clException) { if(!m_sftp) { throw clException("SFTP is not initialized"); } int rc; rc = sftp_rmdir(m_sftp, dirname.mb_str(wxConvISO8859_1).data()); if(rc != SSH_OK) { throw clException(wxString() << _("Failed to remove directory: ") << dirname << ". " << ssh_get_error(m_ssh->GetSession()), sftp_get_error(m_sftp)); } }
int ssh_unlink(const char *path) { int rc = sftp_unlink(ftp->sftp_session, path); if (rc != SSH_OK && sftp_get_error(ftp->sftp_session) != SSH_FX_NO_SUCH_FILE) { ftp_err(_("Couldn't delete file: %s\n"), ssh_get_error(ftp->session)); ftp->code = ctError; ftp->fullcode = 500; return -1; } else ftp_cache_flush_mark_for(path); return 0; }
void clSFTP::Initialize() throw(clException) { if(m_sftp) return; m_sftp = sftp_new(m_ssh->GetSession()); if(m_sftp == NULL) { throw clException(wxString() << "Error allocating SFTP session: " << ssh_get_error(m_ssh->GetSession())); } int rc = sftp_init(m_sftp); if(rc != SSH_OK) { throw clException(wxString() << "Error initializing SFTP session: " << ssh_get_error(m_ssh->GetSession()), sftp_get_error(m_sftp)); } m_connected = true; }
int FSSftp::MkDir ( FSPath& path, int mode, int* err, FSCInfo* info ) { MutexLock lock( &mutex ); int ret = CheckSession( err, info ); if ( ret ) { return ret; } if ( sftp_mkdir( sftpSession, ( char* )path.GetString( _operParam.charset ), mode ) ) { if ( err ) { *err = sftp_get_error( sftpSession ); } return -1; } return 0; }
int FSSftp::Symlink ( FSPath& path, FSString& str, int* err, FSCInfo* info ) { MutexLock lock( &mutex ); int ret = CheckSession( err, info ); if ( ret ) { return ret; } if ( sftp_symlink( sftpSession, ( char* )str.Get( _operParam.charset ), ( char* )path.GetString( _operParam.charset ) ) ) { if ( err ) { *err = sftp_get_error( sftpSession ); } return -1; } return 0; }
int ssh_mkdir_verb(const char *path, verbose_t verb) { char* abspath = ftp_path_absolute(path); stripslash(abspath); int rc = sftp_mkdir(ftp->sftp_session, abspath, S_IRWXU); if (rc != SSH_OK && sftp_get_error(ftp->sftp_session) != SSH_FX_FILE_ALREADY_EXISTS) { ftp_err(_("Couldn't create directory: %s\n"), ssh_get_error(ftp->session)); free(abspath); return rc; } ftp_cache_flush_mark_for(abspath); free(abspath); return 0; }
sftp_session sn_sftp_get_session(ssh_session session) { sftp_session s = sftp_new(session); if (!s) { std::cerr << "[sftp\tfail] Error allocating SFTP session: " << ssh_get_error(session) << std::endl; exit(ERR_SFTP_ALLOC_SESSION); } int rc = sftp_init(s); if (rc != SSH_OK) { std::cerr << "Error initializing SFTP session: " << sftp_get_error(s) << std::endl; sftp_free(s); exit(ERR_SFTP_INIT_SESSION); } return s; }
int FSSftp::Rename ( FSPath& oldpath, FSPath& newpath, int* err, FSCInfo* info ) { MutexLock lock( &mutex ); int ret = CheckSession( err, info ); if ( ret ) { return ret; } if ( sftp_rename( sftpSession, ( char* ) oldpath.GetString( _operParam.charset, '/' ), ( char* ) newpath.GetString( _operParam.charset, '/' ) ) ) { if ( err ) { *err = sftp_get_error( sftpSession ); } return -1; } return 0; }
int ssh_rmdir(const char *path) { char* abspath = ftp_path_absolute(path); stripslash(abspath); int rc = sftp_rmdir(ftp->sftp_session, abspath); if (rc != SSH_OK && sftp_get_error(ftp->sftp_session) != SSH_FX_NO_SUCH_FILE) { ftp_err(_("Couldn't remove directory: %s\n"), ssh_get_error(ftp->session)); free(abspath); return rc; } ftp_cache_flush_mark(abspath); ftp_cache_flush_mark_for(abspath); free(abspath); return 0; }
static int _sftp_unlink(const char *uri) { char *path = NULL; int rc = -1; if (_sftp_connect(uri) < 0) { return -1; } if (c_parse_uri(uri, NULL, NULL, NULL, NULL, NULL, &path) < 0) { return -1; } rc = sftp_unlink(_sftp_session, path); if (rc < 0) { errno = _sftp_portable_to_errno(sftp_get_error(_sftp_session)); } SAFE_FREE(path); return rc; }
static csync_vio_method_handle_t *_sftp_opendir(const char *uri) { csync_vio_method_handle_t *mh = NULL; char *path = NULL; if (_sftp_connect(uri) < 0) { return NULL; } if (c_parse_uri(uri, NULL, NULL, NULL, NULL, NULL, &path) < 0) { return NULL; } mh = (csync_vio_method_handle_t *) sftp_opendir(_sftp_session, path); if (mh == NULL) { errno = _sftp_portable_to_errno(sftp_get_error(_sftp_session)); } SAFE_FREE(path); return mh; }