void clSSH::DoOpenChannel() throw(clException) { if(m_channel) return; m_channel = ssh_channel_new(m_session); if(!m_channel) { throw clException(ssh_get_error(m_session)); } int rc = ssh_channel_open_session(m_channel); if(rc != SSH_OK) { throw clException(ssh_get_error(m_session)); } rc = ssh_channel_request_pty(m_channel); if(rc != SSH_OK) { throw clException(ssh_get_error(m_session)); } rc = ssh_channel_change_pty_size(m_channel, 80, 24); if(rc != SSH_OK) { throw clException(ssh_get_error(m_session)); } rc = ssh_channel_request_shell(m_channel); if(rc != SSH_OK) { throw clException(ssh_get_error(m_session)); } }
void clPatch::Patch(const wxFileName& patchFile, const wxString& workingDirectory, const wxString& args) { // Sanity if(!m_patch.FileExists()) { throw clException("Could not locate patch executable"); } if(!patchFile.FileExists()) { throw clException("Patch failed. File: '" + patchFile.GetFullPath() + "' does not exist"); } // Prepare the command wxString command; command << m_patch.GetFullPath(); ::WrapWithQuotes(command); if(!args.IsEmpty()) { command << " " << args; } // Change directory to the working directory requested by the user DirSaver ds; wxSetWorkingDirectory(workingDirectory.IsEmpty() ? ::wxGetCwd() : workingDirectory); wxString patch = patchFile.GetFullPath(); command << " " << ::WrapWithQuotes(patch); ::WrapInShell(command); ProcUtils::SafeExecuteCommand(command); }
void clSFTP::Mkpath(const wxString& remoteDirFullpath) throw(clException) { if(!m_sftp) { throw clException("SFTP is not initialized"); } wxString tmpPath = remoteDirFullpath; tmpPath.Replace("\\", "/"); if(!tmpPath.StartsWith("/")) { throw clException("Mkpath: path must be absolute"); } wxFileName fn(remoteDirFullpath, ""); const wxArrayString& dirs = fn.GetDirs(); wxString curdir; curdir << "/"; for(size_t i = 0; i < dirs.GetCount(); ++i) { curdir << dirs.Item(i); sftp_attributes attr = sftp_stat(m_sftp, curdir.mb_str(wxConvISO8859_1).data()); if(!attr) { // directory does not exists CreateDir(curdir); } else { // directory already exists sftp_attributes_free(attr); } curdir << "/"; } }
wxString clSFTP::Read(const wxString& remotePath) throw (clException) { if ( !m_sftp ) { throw clException("SFTP is not initialized"); } sftp_file file = sftp_open(m_sftp, remotePath.mb_str(wxConvISO8859_1).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)); } wxString content; char buffer[1024]; int nbytes = 0; memset(buffer, 0, sizeof(buffer)); nbytes = sftp_read(file, buffer, sizeof(buffer)); while (nbytes > 0) { content << wxString(buffer, nbytes); memset(buffer, 0, sizeof(buffer)); nbytes = sftp_read(file, buffer, sizeof(buffer)); } if ( nbytes < 0 ) { sftp_close(file); throw clException(wxString() << _("Failed to read remote file: ") << remotePath << ". " << ssh_get_error(m_ssh->GetSession()), sftp_get_error(m_sftp)); } sftp_close( file ); return content; }
void clSFTP::Write(const wxFileName& localFile, const wxString& remotePath) throw(clException) { if(!m_connected) { throw clException("scp is not initialized!"); } if(!localFile.Exists()) { throw clException(wxString() << "scp::Write file '" << localFile.GetFullPath() << "' does not exist!"); } wxFFile fp(localFile.GetFullPath(), "rb"); if(!fp.IsOpened()) { throw clException(wxString() << "scp::Write could not open file '" << localFile.GetFullPath() << "'. " << ::strerror(errno)); } char buffer[4096]; wxMemoryBuffer memBuffer; size_t nbytes(0); while(!fp.Eof()) { nbytes = fp.Read(buffer, sizeof(buffer)); if(nbytes == 0) break; memBuffer.AppendData(buffer, nbytes); } fp.Close(); Write(memBuffer, remotePath); }
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)); } }
bool clSSH::AuthenticateServer(wxString& message) { int state; unsigned char* hash = NULL; char* hexa = NULL; message.Clear(); state = ssh_is_server_known(m_session); #if LIBSSH_VERSION_INT < SSH_VERSION_INT(0, 6, 1) int hlen = 0; hlen = ssh_get_pubkey_hash(m_session, &hash); if(hlen < 0) { throw clException("Unable to obtain server public key!"); } #else size_t hlen = 0; ssh_key key = NULL; ssh_get_publickey(m_session, &key); ssh_get_publickey_hash(key, SSH_PUBLICKEY_HASH_SHA1, &hash, &hlen); if(hlen == 0) { throw clException("Unable to obtain server public key!"); } #endif switch(state) { case SSH_SERVER_KNOWN_OK: free(hash); return true; case SSH_SERVER_KNOWN_CHANGED: hexa = ssh_get_hexa(hash, hlen); message << _("Host key for server changed: it is now:\n") << hexa << "\n" << _("Accept server authentication?"); free(hexa); free(hash); return false; case SSH_SERVER_FOUND_OTHER: message << _("The host key for this server was not found but another type of key exists.\n") << _("An attacker might change the default server key to confuse your client into thinking the key " "does not exist\n") << _("Accept server authentication?"); free(hash); return false; case SSH_SERVER_FILE_NOT_FOUND: message << _("Could not find known host file.\n") << _("If you accept the host key here, the file will be automatically created.\n"); /* fallback to SSH_SERVER_NOT_KNOWN behavior */ case SSH_SERVER_NOT_KNOWN: hexa = ssh_get_hexa(hash, hlen); message << _("The server is unknown. Do you trust the host key?\n") << _("Public key hash: ") << hexa << "\n" << _("Accept server authentication?"); free(hexa); free(hash); return false; default: case SSH_SERVER_ERROR: throw clException(wxString() << "An error occurred: " << ssh_get_error(m_session)); } return false; }
dMatrix clSpline::GetCoordinates(const dMatrix &uSpec) { dMatrix coord; if(uSpec.GetNumberColumns() != 1 || uSpec.GetNumberRows() == 0) { throw clException("clSpline", "GetCoordinates", "Invalid dimensions of matrix uSpec."); } else { coord.SetNumberRows(uSpec.GetNumberRows()); coord.SetNumberColumns(3); if(!initialised) { Initialise(); } // Do for all specified u's for(int i=1; i<=uSpec.GetNumberRows(); i++) { if(uSpec(i, 1) < 0 || uSpec(i, 1) > 1) { throw clException("clSpline", "GetCoordinates", "Invalid value for uSpec."); } else { // Now find the position of uSpec double uu = uSpec(i, 1)*GetSplineLength(); int j = 1; while((uu - u(j+1, 1) > 0) && (j<u.GetNumberRows()-1)) { j++; } // Now calculate the coefficients double A = (u(j+1, 1)-uu)/(u(j+1, 1)-u(j,1)); double B = 1-A; double C = (A*A*A-A)/6 * (u(j+1, 1)-u(j, 1))*(u(j+1, 1)-u(j, 1)); double D = (B*B*B-B)/6 * (u(j+1, 1)-u(j, 1))*(u(j+1, 1)-u(j, 1)); // Finally calculate the coordinates coord.SetElement(i, 1, A*X(j, 1) + B*X(j+1, 1) + C*X2(j, 1) + D*X2(j+1, 1)); coord.SetElement(i, 2, A*Y(j, 1) + B*Y(j+1, 1) + C*Y2(j, 1) + D*Y2(j+1, 1)); coord.SetElement(i, 3, A*Z(j, 1) + B*Z(j+1, 1) + C*Z2(j, 1) + D*Z2(j+1, 1)); } } } return (coord); }
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::CreateDir(const wxString& dirname) throw (clException) { if ( !m_sftp ) { throw clException("SFTP is not initialized"); } int rc; rc = sftp_mkdir(m_sftp, dirname.mb_str(wxConvISO8859_1).data(), S_IRWXU); if ( rc != SSH_OK ) { throw clException(wxString() << _("Failed to create directory: ") << dirname << ". " << ssh_get_error(m_ssh->GetSession()), sftp_get_error(m_sftp)); } }
void clSSHChannel::Execute(const wxString& command, wxEvtHandler* sink) { // Sanity if(m_readerThread) { throw clException("Channel is busy"); } if(!IsOpen()) { throw clException("Channel is not opened"); } int rc = ssh_channel_request_exec(m_channel, command.mb_str(wxConvUTF8).data()); if(rc != SSH_OK) { Close(); throw clException(BuildError("Execute failed")); } m_readerThread = new clSSHChannelReader(sink, m_channel); m_readerThread->Start(); }
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 clSSHChannel::Open() { if(IsOpen()) { return; } if(!m_ssh) { throw clException("ssh session is not opened"); } m_channel = ssh_channel_new(m_ssh->GetSession()); if(!m_channel) { throw clException(BuildError("Failed to allocte ssh channel")); } int rc = ssh_channel_open_session(m_channel); if(rc != SSH_OK) { ssh_channel_free(m_channel); m_channel = NULL; throw clException(BuildError("Failed to open ssh channel")); } }
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)); } }
void clSSH::ExecuteShellCommand(wxEvtHandler* owner, const wxString& command) { DoOpenChannel(); m_owner = owner; if(!m_owner) { throw clException(wxString() << "No owner specified for output"); } wxCharBuffer buffer = command.mb_str(wxConvUTF8); int rc = ssh_channel_write(m_channel, buffer.data(), buffer.length()); if(rc != (int)buffer.length()) { throw clException("SSH Socket error"); } // Start a timer to check for the output on 10ms intervals if(!m_timer->IsRunning()) { m_timer->Start(50); } }
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::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; }
void clSSH::AcceptServerAuthentication() throw(clException) { if(!m_session) { throw clException("NULL SSH session"); } ssh_write_knownhost(m_session); }
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); }
void clSSH::DoConnectWithRetries(int retries) { while(retries) { int rc = ssh_connect(m_session); if(rc == SSH_AGAIN) { if(wxThread::IsMain()) { ::wxSafeYield(); } wxThread::Sleep(10); --retries; continue; } if(rc == SSH_OK) { m_connected = true; return; } else { throw clException(ssh_get_error(m_session)); } } throw clException("Connect timeout"); }
void clSFTP::Write(const wxFileName& localFile, const wxString& remotePath) throw (clException) { if ( !m_connected ) { throw clException("scp is not initialized!"); } if ( !localFile.Exists() ) { throw clException(wxString() << "scp::Write file '" << localFile.GetFullPath() << "' does not exist!"); } wxFFile fp(localFile.GetFullPath(), "rb"); if ( !fp.IsOpened() ) { throw clException(wxString() << "scp::Write could not open file '" << localFile.GetFullPath() << "'. " << ::strerror(errno) ); } wxString fileContent; fp.ReadAll(&fileContent); Write(fileContent, remotePath); }
void clSFTP::Write(const wxString& 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; std::string str = fileContent.mb_str(wxConvUTF8).data(); file = sftp_open(m_sftp, remotePath.mb_str(wxConvUTF8).data(), access_type, 0644); if (file == NULL) { throw clException(wxString() << _("Can't open file: ") << remotePath << ". " << ssh_get_error(m_ssh->GetSession()), sftp_get_error(m_sftp)); } size_t nbytes = sftp_write(file, str.c_str(), str.length()); if (nbytes != str.length()) { sftp_close(file); throw clException(wxString() << _("Can't write data to file: ") << remotePath << ". " << ssh_get_error(m_ssh->GetSession()), sftp_get_error(m_sftp)); } sftp_close(file); }
void clSpline::SetControlPoints(const dMatrix &cPointsX, const dMatrix &cPointsY, const dMatrix &cPointsZ) { // Check if dimensions are correct if((cPointsX.GetNumberColumns() != 1 || cPointsY.GetNumberColumns() != 1 || cPointsZ.GetNumberColumns() != 1) || (cPointsX.GetNumberRows() != cPointsY.GetNumberRows()) || (cPointsX.GetNumberRows() != cPointsZ.GetNumberRows())) { throw clException("clSpline", "SetControlPoints", "Dimensions of matrices do not match."); } else { X = cPointsX; Y = cPointsY; Z = cPointsZ; } }
void clSSH::Connect(int seconds) { m_session = ssh_new(); if(!m_session) { throw clException("ssh_new failed!"); } ssh_set_blocking(m_session, 0); int verbosity = SSH_LOG_NOLOG; ssh_options_set(m_session, SSH_OPTIONS_HOST, m_host.mb_str(wxConvUTF8).data()); ssh_options_set(m_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); ssh_options_set(m_session, SSH_OPTIONS_PORT, &m_port); ssh_options_set(m_session, SSH_OPTIONS_USER, GetUsername().mb_str().data()); // Connect the session int retries = seconds * 100; if(retries < 0) { retries = 1; } DoConnectWithRetries(retries); ssh_set_blocking(m_session, 1); }
void clSpline::SetControlPoints(const dMatrix &cPoints) { // Check if matrix is in correct format. // 3 columns; 1 = x; 2 = y; 3 = z // Number of rows is number of control points if(cPoints.GetNumberColumns() != 3) { throw clException("clSpline", "SetControlPoints", "Incorrect number of columns."); } else { int rmax = cPoints.GetNumberColumns(); X.SetNumberRows(rmax); X.SetNumberColumns(1); Y.SetNumberRows(rmax); Y.SetNumberColumns(1); Z.SetNumberRows(rmax); Z.SetNumberColumns(1); for(int i=1; i<=rmax; i++) { X.SetElement(i, 1, cPoints(i, 1)); Y.SetElement(i, 1, cPoints(i, 2)); Z.SetElement(i, 1, cPoints(i, 3)); } } }
void clSpline::SecondDerivatives(void) { // Get maximum number of rows int rmax = u.GetNumberRows(); // Check for minimum size matrix if(rmax<3) { throw clException("clSpline", "SecondDerivatives", "Need at least 3 points to create spline."); } // Set up matrices dMatrix tri(rmax-2, 3); dMatrix SX(rmax-2, 1); dMatrix SY(rmax-2, 1); dMatrix SZ(rmax-2, 1); // Set up all coefficients for(int i=2; i<rmax; i++) { double alpha = u(i, 1)-u(i-1, 1) + PRECISION; double beta = 2*(u(i+1, 1)-u(i-1, 1)) + PRECISION; double gamma = u(i+1, 1)-u(i, 1) + PRECISION; int j=i-1; tri.SetElement(j, 1, alpha); tri.SetElement(j, 2, beta); tri.SetElement(j, 3, gamma); SX.SetElement(j, 1, 6*((X(i+1, 1) - X(i , 1))/gamma - (X(i , 1) - X(i-1, 1))/alpha) + PRECISION); SY.SetElement(j, 1, 6*((Y(i+1, 1) - Y(i , 1))/gamma - (Y(i , 1) - Y(i-1, 1))/alpha) + PRECISION); SZ.SetElement(j, 1, 6*((Z(i+1, 1) - Z(i , 1))/gamma - (Z(i , 1) - Z(i-1, 1))/alpha) + PRECISION); } // Calculate the second derivatives tri.SolveTri(SX); tri.SolveTri(SY); tri.SolveTri(SZ); // Substitute in appropiate vectors X2.SetNumberRows(rmax); X2.SetNumberColumns(1); Y2.SetNumberRows(rmax); Y2.SetNumberColumns(1); Z2.SetNumberRows(rmax); Z2.SetNumberColumns(1); { for(int i=1; i<=rmax; i++) { if(i==1 || i==rmax) { X2.SetElement(i, 1, (double)(0)); Y2.SetElement(i, 1, (double)(0)); Z2.SetElement(i, 1, (double)(0)); } else { X2.SetElement(i, 1, SX(i-1, 1)); Y2.SetElement(i, 1, SY(i-1, 1)); Z2.SetElement(i, 1, SZ(i-1, 1)); } } } }