Remove deprecated SSH support
This commit is contained in:
@@ -29,7 +29,6 @@ option( EXIV2_ENABLE_DYNAMIC_RUNTIME "Use dynamic runtime (used for static libs
|
||||
option( EXIV2_ENABLE_WIN_UNICODE "Use Unicode paths (wstring) on Windows" OFF )
|
||||
option( EXIV2_ENABLE_WEBREADY "Build webready support into library" OFF )
|
||||
option( EXIV2_ENABLE_CURL "USE Libcurl for HttpIo (WEBREADY)" OFF )
|
||||
option( EXIV2_ENABLE_SSH "USE Libssh for SshIo (WEBREADY)" OFF )
|
||||
option( EXIV2_ENABLE_BMFF "Build with BMFF support" ON )
|
||||
|
||||
option( EXIV2_BUILD_SAMPLES "Build sample applications" ON )
|
||||
|
||||
+2
-2
@@ -564,11 +564,11 @@ $ cmake --build . --config Release
|
||||
|
||||
Exiv2 can perform I/O using internet protocols such as http, https and ftp.
|
||||
|
||||
The feature is disabled by default. You will need to instruct conan to build/download necessary libraries (curl, openssl and libssh) and tell CMake to link to the libraries.
|
||||
The feature is disabled by default. You will need to instruct conan to build/download necessary libraries (curl and openssl) and tell CMake to link to the libraries.
|
||||
|
||||
```bash
|
||||
$ conan install .. --options webready=True
|
||||
$ cmake -DEXIV2_ENABLE_WEBREADY=ON -DEXIV2_ENABLE_CURL=ON -DEXIV2_ENABLE_SSH=ON ..
|
||||
$ cmake -DEXIV2_ENABLE_WEBREADY=ON -DEXIV2_ENABLE_CURL=ON ..
|
||||
```
|
||||
|
||||
[TOC](#TOC)
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
#ifndef _EXV_CONF_H_
|
||||
#define _EXV_CONF_H_
|
||||
|
||||
// Defined if you want to use libssh for SshIO.
|
||||
#cmakedefine EXV_USE_SSH
|
||||
|
||||
// Define to 1 if you want to use libcurl in httpIO.
|
||||
#cmakedefine EXV_USE_CURL
|
||||
|
||||
|
||||
@@ -23,19 +23,6 @@ if( EXIV2_ENABLE_WEBREADY )
|
||||
if( EXIV2_ENABLE_CURL )
|
||||
find_package(CURL REQUIRED)
|
||||
endif()
|
||||
|
||||
if( EXIV2_ENABLE_SSH )
|
||||
find_package(libssh CONFIG REQUIRED)
|
||||
# Define an imported target to have compatibility with <=libssh-0.9.0
|
||||
# libssh-0.9.1 is broken regardless.
|
||||
if(NOT TARGET ssh)
|
||||
add_library(ssh SHARED IMPORTED)
|
||||
set_target_properties(ssh PROPERTIES
|
||||
IMPORTED_LOCATION "${LIBSSH_LIBRARIES}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${LIBSSH_INCLUDE_DIR}"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (EXIV2_ENABLE_XMP AND EXIV2_ENABLE_EXTERNAL_XMP)
|
||||
|
||||
@@ -4,7 +4,6 @@ include(CheckCXXSymbolExists)
|
||||
|
||||
# Note that the scope of the EXV_ variables in local
|
||||
if (${EXIV2_ENABLE_WEBREADY})
|
||||
set(EXV_USE_SSH ${EXIV2_ENABLE_SSH})
|
||||
set(EXV_USE_CURL ${EXIV2_ENABLE_CURL})
|
||||
endif()
|
||||
set(EXV_ENABLE_BMFF ${EXIV2_ENABLE_BMFF})
|
||||
|
||||
@@ -58,7 +58,6 @@ OptionOutput( "Building video support: " EXIV2_ENABLE_VIDEO
|
||||
OptionOutput( "Building webready support: " EXIV2_ENABLE_WEBREADY )
|
||||
if ( EXIV2_ENABLE_WEBREADY )
|
||||
OptionOutput( "USE Libcurl for HttpIo: " EXIV2_ENABLE_CURL )
|
||||
OptionOutput( "USE Libssh for SshIo: " EXIV2_ENABLE_SSH )
|
||||
endif ( EXIV2_ENABLE_WEBREADY )
|
||||
|
||||
if (WIN32)
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
#ifndef _EXV_CONF_H_
|
||||
#define _EXV_CONF_H_
|
||||
|
||||
// Defined if you want to use libssh for SshIO.
|
||||
#define EXV_USE_SSH
|
||||
|
||||
// Define to 1 if you want to use libcurl in httpIO.
|
||||
#define EXV_USE_CURL
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ install(FILES
|
||||
rw2image.hpp
|
||||
rwlock.hpp
|
||||
slice.hpp
|
||||
ssh.hpp
|
||||
tags.hpp
|
||||
tgaimage.hpp
|
||||
tiffimage.hpp
|
||||
|
||||
@@ -1107,51 +1107,6 @@ namespace Exiv2 {
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef EXV_USE_SSH
|
||||
/*!
|
||||
@brief Provides the ssh read/write access and sftp read access for the RemoteIo.
|
||||
This class is based on libssh.
|
||||
*/
|
||||
class EXIV2LIB_DEPRECATED_EXPORT SshIo : public RemoteIo {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor that accepts the URL on which IO will be
|
||||
performed.
|
||||
@param url The full path of url
|
||||
@param blockSize the size of the memory block. The file content is
|
||||
divided into the memory blocks. These blocks are populated
|
||||
on demand from the server, so it avoids copying the complete file.
|
||||
@throw Error if it is unable to init ssh session.
|
||||
*/
|
||||
SshIo(const std::string& url, size_t blockSize = 1024);
|
||||
#ifdef EXV_UNICODE_PATH
|
||||
/*!
|
||||
@brief Like SshIo(const std::string& url, size_t blockSize = 1024) but accepts a
|
||||
unicode url in an std::wstring.
|
||||
@note This constructor is only available on Windows.
|
||||
*/
|
||||
SshIo(const std::wstring& wurl, size_t blockSize = 1024);
|
||||
#endif
|
||||
//@}
|
||||
protected:
|
||||
// NOT IMPLEMENTED
|
||||
//! Copy constructor
|
||||
SshIo(SshIo& rhs);
|
||||
//! Assignment operator
|
||||
SshIo& operator=(const SshIo& rhs);
|
||||
// Pimpl idiom
|
||||
class SshImpl;
|
||||
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default Destructor
|
||||
virtual ~SshIo(){}
|
||||
//@}
|
||||
};
|
||||
#endif
|
||||
|
||||
// *****************************************************************************
|
||||
// template, inline and free functions
|
||||
|
||||
|
||||
@@ -56,10 +56,6 @@
|
||||
#include "exiv2/rafimage.hpp"
|
||||
#include "exiv2/rw2image.hpp"
|
||||
|
||||
#ifdef EXV_USE_SSH
|
||||
#include "exiv2/ssh.hpp"
|
||||
#endif
|
||||
|
||||
#include "exiv2/tags.hpp"
|
||||
#include "exiv2/tgaimage.hpp"
|
||||
#include "exiv2/tiffimage.hpp"
|
||||
|
||||
@@ -42,7 +42,6 @@ namespace Exiv2
|
||||
pFtp,
|
||||
pHttps,
|
||||
pSftp,
|
||||
pSsh,
|
||||
pFileUri,
|
||||
pDataUri,
|
||||
pStdin
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2004-2021 Exiv2 authors
|
||||
* This program is part of the Exiv2 distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef SSH_HPP_
|
||||
#define SSH_HPP_
|
||||
|
||||
// included header files
|
||||
#include "config.h"
|
||||
|
||||
#ifdef EXV_USE_SSH
|
||||
#include <libssh/libssh.h>
|
||||
#include <libssh/sftp.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string>
|
||||
|
||||
#include "error.hpp"
|
||||
#include "types.hpp"
|
||||
#include "futils.hpp"
|
||||
|
||||
namespace Exiv2 {
|
||||
/*!
|
||||
@brief The class provides the high-level functions related to libssh.
|
||||
It makes the libssh transparent. The functions in this class can
|
||||
be used without the requirement of understanding libssh.
|
||||
*/
|
||||
class EXIV2LIB_DEPRECATED_EXPORT SSH {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor to set up the connection to ssh server.
|
||||
@param host The host name of ssh server.
|
||||
@param user The username used to connect to ssh server.
|
||||
@param pass The password used to connect to ssh server.
|
||||
@param port The port to connect to ssh server. Set empty string to use the default port.
|
||||
@throw Error if it fails to connect the server.
|
||||
*/
|
||||
SSH (const std::string& host, const std::string& user, const std::string& pass, const std::string port = "");
|
||||
//! Destructor
|
||||
~SSH();
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Run the command on the remote machine.
|
||||
@param cmd The command
|
||||
@param output The container for the command's output
|
||||
@return 0 (SSH_OK) if there is no error.
|
||||
*/
|
||||
int runCommand(const std::string& cmd, std::string* output);
|
||||
/*!
|
||||
@brief SCP data to the remote machine.
|
||||
@param filePath The path of the new file on the remote machine where the data is saved.
|
||||
@param data The data copied to the remote machine.
|
||||
@param size The size of the data.
|
||||
@return 0 (SSH_OK) if there is no error.
|
||||
@throw Error if it is unable to copy the data.
|
||||
*/
|
||||
int scp(const std::string& filePath, const byte* data, size_t size);
|
||||
/*!
|
||||
@brief Return the sftp file handle of the file on the remote machine to read the data.
|
||||
@param filePath The path of the file on the remote machine.
|
||||
@param handle The container for the file handle.
|
||||
@throw Error if it is unable to get the sftp file handle.
|
||||
|
||||
@note Be sure to close() the file handle after use.
|
||||
*/
|
||||
void getFileSftp(const std::string& filePath, sftp_file& handle);
|
||||
//@}
|
||||
private:
|
||||
/*!
|
||||
@brief Open the sftp session.
|
||||
*/
|
||||
void openSftp();
|
||||
// DATA
|
||||
//! The number of seconds to wait while trying to connect.
|
||||
long timeout_;
|
||||
//! the ssh server host
|
||||
std::string host_;
|
||||
//! the username
|
||||
std::string user_;
|
||||
//! the password
|
||||
std::string pass_;
|
||||
//! the ssh session
|
||||
ssh_session session_;
|
||||
//! the sftp session
|
||||
sftp_session sftp_;
|
||||
}; // class SSH
|
||||
} // namespace Exiv2
|
||||
#endif
|
||||
|
||||
#endif // #ifdef EXIV2_HPP_
|
||||
@@ -88,46 +88,6 @@ void curlcon(const std::string& url, bool useHttp1_0 = false) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef EXV_USE_SSH
|
||||
void sshcon(const std::string& url) {
|
||||
Exiv2::Uri uri = Exiv2::Uri::Parse(url);
|
||||
Exiv2::Uri::Decode(uri);
|
||||
|
||||
std::string page = uri.Path;
|
||||
// remove / at the beginning of the path
|
||||
if (page[0] == '/') {
|
||||
page = page.substr(1);
|
||||
}
|
||||
Exiv2::SSH ssh(uri.Host, uri.Username, uri.Password, uri.Port);
|
||||
std::string response = "";
|
||||
std::string cmd = "declare -a x=($(ls -alt " + page + ")); echo ${x[4]}";
|
||||
if (ssh.runCommand(cmd, &response) != 0) {
|
||||
throw Exiv2::Error(Exiv2::kerErrorMessage, "Unable to get file length.");
|
||||
} else {
|
||||
long length = atol(response.c_str());
|
||||
if (length == 0) {
|
||||
throw Exiv2::Error(Exiv2::kerErrorMessage, "File is empty or not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sftpcon(const std::string& url) {
|
||||
Exiv2::Uri uri = Exiv2::Uri::Parse(url);
|
||||
Exiv2::Uri::Decode(uri);
|
||||
|
||||
std::string page = uri.Path;
|
||||
// remove / at the beginning of the path
|
||||
if (page[0] == '/') {
|
||||
page = page.substr(1);
|
||||
}
|
||||
Exiv2::SSH ssh(uri.Host, uri.Username, uri.Password, uri.Port);
|
||||
sftp_file handle;
|
||||
ssh.getFileSftp(page, handle);
|
||||
if (handle == NULL) throw Exiv2::Error(Exiv2::kerErrorMessage, "Unable to open the file");
|
||||
else sftp_close(handle);
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc,const char** argv)
|
||||
{
|
||||
Exiv2::XmpParser::initialize();
|
||||
@@ -151,15 +111,6 @@ int main(int argc,const char** argv)
|
||||
|
||||
bool isOk = false;
|
||||
try {
|
||||
#ifdef EXV_USE_SSH
|
||||
if (prot == Exiv2::pSsh) {
|
||||
sshcon(url);
|
||||
isOk = true;
|
||||
} else if (prot == Exiv2::pSftp){
|
||||
sftpcon(url);
|
||||
isOk = true;
|
||||
}
|
||||
#endif
|
||||
#ifdef EXV_USE_CURL
|
||||
if (prot == Exiv2::pHttp || prot == Exiv2::pHttps || prot == Exiv2::pFtp) {
|
||||
curlcon(url, useHttp1_0);
|
||||
|
||||
@@ -96,10 +96,6 @@ if( EXIV2_ENABLE_WEBREADY )
|
||||
if( EXIV2_ENABLE_CURL)
|
||||
target_sources(exiv2lib PRIVATE easyaccess.cpp ../include/exiv2/easyaccess.hpp)
|
||||
endif()
|
||||
|
||||
if( EXIV2_ENABLE_SSH )
|
||||
target_sources(exiv2lib PRIVATE ssh.cpp ../include/exiv2/ssh.hpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if( EXIV2_ENABLE_PNG )
|
||||
@@ -172,10 +168,6 @@ target_include_directories(exiv2lib_int PUBLIC
|
||||
|
||||
if (EXIV2_ENABLE_WEBREADY)
|
||||
|
||||
if( EXIV2_ENABLE_SSH )
|
||||
target_link_libraries(exiv2lib PUBLIC ssh)
|
||||
endif()
|
||||
|
||||
if( EXIV2_ENABLE_CURL )
|
||||
target_include_directories(exiv2lib SYSTEM PRIVATE ${CURL_INCLUDE_DIR} )
|
||||
target_link_libraries(exiv2lib PRIVATE ${CURL_LIBRARIES})
|
||||
|
||||
+1
-224
@@ -60,11 +60,7 @@
|
||||
# include <curl/curl.h>
|
||||
#endif
|
||||
|
||||
#ifdef EXV_USE_SSH
|
||||
# include "ssh.hpp"
|
||||
#else
|
||||
# define mode_t unsigned short
|
||||
#endif
|
||||
#define mode_t unsigned short
|
||||
|
||||
// Platform specific headers for handling extended attributes (xattr)
|
||||
#if defined(__APPLE__)
|
||||
@@ -2437,225 +2433,6 @@ namespace Exiv2 {
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef EXV_USE_SSH
|
||||
//! Internal Pimpl structure of class RemoteIo.
|
||||
class SshIo::SshImpl : public Impl {
|
||||
public:
|
||||
//! Constructor
|
||||
SshImpl(const std::string& path, size_t blockSize);
|
||||
#ifdef EXV_UNICODE_PATH
|
||||
//! Constructor accepting a unicode path in an std::wstring
|
||||
SshImpl(const std::wstring& wpath, size_t blockSize);
|
||||
#endif
|
||||
//! Destructor. Closes ssh session and releases all managed memory.
|
||||
~SshImpl();
|
||||
|
||||
Exiv2::Uri hostInfo_; //!< host information extracted from path
|
||||
SSH* ssh_; //!< SSH pointer
|
||||
sftp_file fileHandler_; //!< sftp file handler
|
||||
|
||||
// METHODS
|
||||
/*!
|
||||
@brief Get the length (in bytes) of the remote file.
|
||||
@return Return -1 if the size is unknown. Otherwise it returns the length of remote file (in bytes).
|
||||
@throw Error if the server returns the error code.
|
||||
*/
|
||||
long getFileLength();
|
||||
/*!
|
||||
@brief Get the data by range.
|
||||
@param lowBlock The start block index.
|
||||
@param highBlock The end block index.
|
||||
@param response The data from the server.
|
||||
@throw Error if the server returns the error code.
|
||||
@note Set lowBlock = -1 and highBlock = -1 to get the whole file content.
|
||||
*/
|
||||
void getDataByRange(long lowBlock, long highBlock, std::string& response);
|
||||
/*!
|
||||
@brief Submit the data to the remote machine. The data replace a part of the remote file.
|
||||
The replaced part of remote file is indicated by from and to parameters.
|
||||
@param data The data are submitted to the remote machine.
|
||||
@param size The size of data.
|
||||
@param from The start position in the remote file where the data replace.
|
||||
@param to The end position in the remote file where the data replace.
|
||||
@note The write access is only available on the SSH protocol. It requires the write permission
|
||||
to edit the remote file.
|
||||
@throw Error if it fails.
|
||||
*/
|
||||
void writeRemote(const byte* data, size_t size, long from, long to);
|
||||
|
||||
protected:
|
||||
// NOT IMPLEMENTED
|
||||
SshImpl(const SshImpl& rhs); //!< Copy constructor
|
||||
SshImpl& operator=(const SshImpl& rhs); //!< Assignment
|
||||
}; // class RemoteIo::Impl
|
||||
|
||||
SshIo::SshImpl::SshImpl(const std::string& url, size_t blockSize):Impl(url, blockSize)
|
||||
{
|
||||
hostInfo_ = Exiv2::Uri::Parse(url);
|
||||
Exiv2::Uri::Decode(hostInfo_);
|
||||
|
||||
// remove / at the beginning of the path
|
||||
if (hostInfo_.Path[0] == '/') {
|
||||
hostInfo_.Path = hostInfo_.Path.substr(1);
|
||||
}
|
||||
ssh_ = new SSH(hostInfo_.Host, hostInfo_.Username, hostInfo_.Password, hostInfo_.Port);
|
||||
|
||||
if (protocol_ == pSftp) {
|
||||
ssh_->getFileSftp(hostInfo_.Path, fileHandler_);
|
||||
if (fileHandler_ == NULL) throw Error(kerErrorMessage, "Unable to open the file");
|
||||
} else {
|
||||
fileHandler_ = NULL;
|
||||
}
|
||||
}
|
||||
#ifdef EXV_UNICODE_PATH
|
||||
SshIo::SshImpl::SshImpl(const std::wstring& wurl, size_t blockSize):Impl(wurl, blockSize)
|
||||
{
|
||||
std::string url;
|
||||
url.assign(wurl.begin(), wurl.end());
|
||||
path_ = url;
|
||||
|
||||
hostInfo_ = Exiv2::Uri::Parse(url);
|
||||
Exiv2::Uri::Decode(hostInfo_);
|
||||
|
||||
// remove / at the beginning of the path
|
||||
if (hostInfo_.Path[0] == '/') {
|
||||
hostInfo_.Path = hostInfo_.Path.substr(1);
|
||||
}
|
||||
ssh_ = new SSH(hostInfo_.Host, hostInfo_.Username, hostInfo_.Password, hostInfo_.Port);
|
||||
|
||||
if (protocol_ == pSftp) {
|
||||
ssh_->getFileSftp(hostInfo_.Path, fileHandler_);
|
||||
if (fileHandler_ == NULL) throw Error(kerErrorMessage, "Unable to open the file");
|
||||
} else {
|
||||
fileHandler_ = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
long SshIo::SshImpl::getFileLength()
|
||||
{
|
||||
long length = 0;
|
||||
if (protocol_ == pSftp) { // sftp
|
||||
sftp_attributes attributes = sftp_fstat(fileHandler_);
|
||||
length = (long)attributes->size;
|
||||
} else { // ssh
|
||||
std::string response;
|
||||
//std::string cmd = "stat -c %s " + hostInfo_.Path;
|
||||
std::string cmd = "declare -a x=($(ls -alt " + hostInfo_.Path + ")); echo ${x[4]}";
|
||||
if (ssh_->runCommand(cmd, &response) != 0) {
|
||||
throw Error(kerErrorMessage, "Unable to get file length.");
|
||||
} else {
|
||||
length = atol(response.c_str());
|
||||
if (length == 0) {
|
||||
throw Error(kerErrorMessage, "File is empty or not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
void SshIo::SshImpl::getDataByRange(long lowBlock, long highBlock, std::string& response)
|
||||
{
|
||||
if (protocol_ == pSftp) {
|
||||
if (sftp_seek(fileHandler_, (uint32_t) (lowBlock * blockSize_)) < 0) throw Error(kerErrorMessage, "SFTP: unable to sftp_seek");
|
||||
size_t buffSize = (highBlock - lowBlock + 1) * blockSize_;
|
||||
std::vector<char> buffer(buffSize);
|
||||
long nBytes = static_cast<long>(sftp_read(fileHandler_, &buffer.at(0), buffSize));
|
||||
if (nBytes < 0) {
|
||||
throw Error(kerErrorMessage, "SFTP: unable to sftp_read");
|
||||
}
|
||||
response.assign(&buffer.at(0), buffSize);
|
||||
} else {
|
||||
std::stringstream ss;
|
||||
if (lowBlock > -1 && highBlock > -1) {
|
||||
ss << "dd if=" << hostInfo_.Path
|
||||
<< " ibs=" << blockSize_
|
||||
<< " skip=" << lowBlock
|
||||
<< " count=" << (highBlock - lowBlock) + 1<< " 2>/dev/null";
|
||||
} else {
|
||||
ss << "dd if=" << hostInfo_.Path
|
||||
<< " ibs=" << blockSize_
|
||||
<< " 2>/dev/null";
|
||||
}
|
||||
std::string cmd = ss.str();
|
||||
if (ssh_->runCommand(cmd, &response) != 0) {
|
||||
throw Error(kerErrorMessage, "Unable to get data by range.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SshIo::SshImpl::writeRemote(const byte* data, size_t size, long from, long to)
|
||||
{
|
||||
if (protocol_ == pSftp) throw Error(kerErrorMessage, "not support SFTP write access.");
|
||||
|
||||
//printf("ssh update size=%ld from=%ld to=%ld\n", (long)size, from, to);
|
||||
assert(isMalloced_);
|
||||
|
||||
std::string tempFile = hostInfo_.Path + ".exiv2tmp";
|
||||
std::string response;
|
||||
std::stringstream ss;
|
||||
// copy the head (byte 0 to byte fromByte) of original file to filepath.exiv2tmp
|
||||
ss << "head -c " << from
|
||||
<< " " << hostInfo_.Path
|
||||
<< " > " << tempFile;
|
||||
std::string cmd = ss.str();
|
||||
if (ssh_->runCommand(cmd, &response) != 0) {
|
||||
throw Error(kerErrorMessage, "SSH: Unable to cope the head of file to temp");
|
||||
}
|
||||
|
||||
// upload the data (the byte ranges which are different between the original
|
||||
// file and the new file) to filepath.exiv2datatemp
|
||||
if (ssh_->scp(hostInfo_.Path + ".exiv2datatemp", data, size) != 0) {
|
||||
throw Error(kerErrorMessage, "SSH: Unable to copy file");
|
||||
}
|
||||
|
||||
// concatenate the filepath.exiv2datatemp to filepath.exiv2tmp
|
||||
cmd = "cat " + hostInfo_.Path + ".exiv2datatemp >> " + tempFile;
|
||||
if (ssh_->runCommand(cmd, &response) != 0) {
|
||||
throw Error(kerErrorMessage, "SSH: Unable to copy the rest");
|
||||
}
|
||||
|
||||
// copy the tail (from byte toByte to the end of file) of original file to filepath.exiv2tmp
|
||||
ss.str("");
|
||||
ss << "tail -c+" << (to + 1)
|
||||
<< " " << hostInfo_.Path
|
||||
<< " >> " << tempFile;
|
||||
cmd = ss.str();
|
||||
if (ssh_->runCommand(cmd, &response) != 0) {
|
||||
throw Error(kerErrorMessage, "SSH: Unable to copy the rest");
|
||||
}
|
||||
|
||||
// replace the original file with filepath.exiv2tmp
|
||||
cmd = "mv " + tempFile + " " + hostInfo_.Path;
|
||||
if (ssh_->runCommand(cmd, &response) != 0) {
|
||||
throw Error(kerErrorMessage, "SSH: Unable to copy the rest");
|
||||
}
|
||||
|
||||
// remove filepath.exiv2datatemp
|
||||
cmd = "rm " + hostInfo_.Path + ".exiv2datatemp";
|
||||
if (ssh_->runCommand(cmd, &response) != 0) {
|
||||
throw Error(kerErrorMessage, "SSH: Unable to copy the rest");
|
||||
}
|
||||
}
|
||||
|
||||
SshIo::SshImpl::~SshImpl() {
|
||||
if (fileHandler_) sftp_close(fileHandler_);
|
||||
if (ssh_) delete ssh_;
|
||||
}
|
||||
|
||||
SshIo::SshIo(const std::string& url, size_t blockSize)
|
||||
{
|
||||
p_ = new SshImpl(url, blockSize);
|
||||
}
|
||||
#ifdef EXV_UNICODE_PATH
|
||||
SshIo::SshIo(const std::wstring& wurl, size_t blockSize)
|
||||
{
|
||||
p_ = new SshImpl(wurl, blockSize);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
@@ -229,7 +229,6 @@ namespace Exiv2 {
|
||||
, { "https://" ,pHttps , true }
|
||||
, { "ftp://" ,pFtp , true }
|
||||
, { "sftp://" ,pSftp , true }
|
||||
, { "ssh://" ,pSsh , true }
|
||||
, { "file://" ,pFileUri , true }
|
||||
, { "data://" ,pDataUri , true }
|
||||
, { "-" ,pStdin , false }
|
||||
@@ -254,7 +253,6 @@ namespace Exiv2 {
|
||||
, { L"https://" ,pHttps , true }
|
||||
, { L"ftp://" ,pFtp , true }
|
||||
, { L"sftp://" ,pSftp , true }
|
||||
, { L"ssh://" ,pSsh , true }
|
||||
, { L"file://" ,pFileUri , true }
|
||||
, { L"data://" ,pDataUri , true }
|
||||
, { L"-" ,pStdin , false }
|
||||
|
||||
@@ -850,12 +850,6 @@ namespace Exiv2 {
|
||||
{
|
||||
Protocol fProt = fileProtocol(path);
|
||||
|
||||
#ifdef EXV_USE_SSH
|
||||
if (fProt == pSsh || fProt == pSftp) {
|
||||
return BasicIo::UniquePtr(new SshIo(path)); // may throw
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef EXV_USE_CURL
|
||||
if (useCurl && (fProt == pHttp || fProt == pHttps || fProt == pFtp)) {
|
||||
return BasicIo::UniquePtr(new CurlIo(path)); // may throw
|
||||
@@ -878,11 +872,6 @@ namespace Exiv2 {
|
||||
BasicIo::UniquePtr ImageFactory::createIo(const std::wstring& wpath, bool useCurl)
|
||||
{
|
||||
Protocol fProt = fileProtocol(wpath);
|
||||
#ifdef EXV_USE_SSH
|
||||
if (fProt == pSsh || fProt == pSftp) {
|
||||
return BasicIo::UniquePtr(new SshIo(wpath));
|
||||
}
|
||||
#endif
|
||||
#ifdef EXV_USE_CURL
|
||||
if (useCurl && (fProt == pHttp || fProt == pHttps || fProt == pFtp)) {
|
||||
return BasicIo::UniquePtr(new CurlIo(wpath));
|
||||
|
||||
-147
@@ -1,147 +0,0 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2004-2021 Exiv2 authors
|
||||
* This program is part of the Exiv2 distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "config.h"
|
||||
#include "ssh.hpp"
|
||||
|
||||
#ifdef EXV_USE_SSH
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
SSH::SSH(const std::string& host, const std::string& user, const std::string& pass, const std::string port):
|
||||
host_(host),user_(user),pass_(pass),sftp_(0) {
|
||||
|
||||
std::string timeout = getEnv(envTIMEOUT);
|
||||
timeout_ = atol(timeout.c_str());
|
||||
if (timeout_ == 0) {
|
||||
throw Error(kerErrorMessage, "Timeout Environmental Variable must be a positive integer.");
|
||||
}
|
||||
|
||||
session_ = ssh_new();
|
||||
if (session_ == NULL) {
|
||||
throw Error(kerErrorMessage, "Unable to create the the ssh session");
|
||||
}
|
||||
|
||||
// try to connect
|
||||
ssh_options_set(session_, SSH_OPTIONS_HOST, host_.c_str());
|
||||
ssh_options_set(session_, SSH_OPTIONS_USER, user_.c_str());
|
||||
ssh_options_set(session_, SSH_OPTIONS_TIMEOUT, &timeout_);
|
||||
if (port != "") ssh_options_set(session_, SSH_OPTIONS_PORT_STR, port.c_str());
|
||||
|
||||
if (ssh_connect(session_) != SSH_OK) {
|
||||
throw Error(kerErrorMessage, ssh_get_error(session_));
|
||||
}
|
||||
// Authentication
|
||||
if (ssh_userauth_password(session_, NULL, pass_.c_str()) != SSH_AUTH_SUCCESS) {
|
||||
throw Error(kerErrorMessage, ssh_get_error(session_));
|
||||
}
|
||||
}
|
||||
|
||||
int SSH::runCommand(const std::string& cmd, std::string* output) {
|
||||
int rc;
|
||||
ssh_channel channel;
|
||||
channel = ssh_channel_new(session_);
|
||||
if (channel == NULL) {
|
||||
rc = SSH_ERROR;
|
||||
} else {
|
||||
rc = ssh_channel_open_session(channel);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_channel_free(channel);
|
||||
} else {
|
||||
char buffer[256];
|
||||
rc = ssh_channel_request_exec(channel, cmd.c_str());
|
||||
if (rc == SSH_OK) {
|
||||
while ((rc = ssh_channel_read(channel, buffer, sizeof(buffer), 0)) > 0) {
|
||||
output->append(buffer, rc);
|
||||
}
|
||||
}
|
||||
ssh_channel_send_eof(channel);
|
||||
ssh_channel_close(channel);
|
||||
ssh_channel_free(channel);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int SSH::scp(const std::string& filePath, const byte* data, size_t size) {
|
||||
ssh_scp scp;
|
||||
int rc;
|
||||
|
||||
size_t found = filePath.find_last_of("/\\");
|
||||
std::string filename = filePath.substr(found+1);
|
||||
std::string path = filePath.substr(0, found+1);
|
||||
|
||||
scp = ssh_scp_new(session_, SSH_SCP_WRITE, path.c_str());
|
||||
if (scp == NULL) {
|
||||
rc = SSH_ERROR;
|
||||
throw Error(kerErrorMessage, ssh_get_error(session_));
|
||||
} else {
|
||||
rc = ssh_scp_init(scp);
|
||||
if (rc != SSH_OK) {
|
||||
throw Error(kerErrorMessage, ssh_get_error(session_));
|
||||
} else {
|
||||
#ifdef _MSC_VER
|
||||
// S_IRUSR & S_IWUSR not in MSVC (0000400 & 0000200 in /usr/include/sys/stat.h on MacOS-X 10.8)
|
||||
#define S_IRUSR S_IREAD
|
||||
#define S_IWUSR S_IWRITE
|
||||
#endif
|
||||
rc = ssh_scp_push_file (scp, filename.c_str(), size, S_IRUSR | S_IWUSR);
|
||||
if (rc != SSH_OK) {
|
||||
throw Error(kerErrorMessage, ssh_get_error(session_));
|
||||
} else {
|
||||
rc = ssh_scp_write(scp, data, size);
|
||||
if (rc != SSH_OK) {
|
||||
throw Error(kerErrorMessage, ssh_get_error(session_));
|
||||
}
|
||||
}
|
||||
ssh_scp_close(scp);
|
||||
}
|
||||
ssh_scp_free(scp);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void SSH::openSftp() {
|
||||
if (sftp_) return;
|
||||
|
||||
sftp_ = sftp_new(session_);
|
||||
if (sftp_ == NULL) {
|
||||
throw Error(kerErrorMessage, "Unable to create the the sftp session");
|
||||
}
|
||||
if (sftp_init(sftp_) != SSH_OK) {
|
||||
sftp_free(sftp_);
|
||||
throw Error(kerErrorMessage, "Error initializing SFTP session");
|
||||
}
|
||||
}
|
||||
|
||||
void SSH::getFileSftp(const std::string& filePath, sftp_file& handle) {
|
||||
if (!sftp_) openSftp();
|
||||
handle = sftp_open(sftp_, ("/"+filePath).c_str(), 0x0000, 0); // read only
|
||||
}
|
||||
|
||||
SSH::~SSH() {
|
||||
if (sftp_) sftp_free(sftp_);
|
||||
ssh_disconnect(session_);
|
||||
ssh_free(session_);
|
||||
}
|
||||
}
|
||||
#endif // EXV_USE_SSH == 1
|
||||
@@ -350,7 +350,6 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys)
|
||||
int enable_webready =0;
|
||||
int enable_nls =0;
|
||||
int use_curl =0;
|
||||
int use_ssh =0;
|
||||
|
||||
#ifdef EXV_HAVE_INTTYPES_H
|
||||
have_inttypes=1;
|
||||
@@ -482,10 +481,6 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys)
|
||||
use_curl=1;
|
||||
#endif
|
||||
|
||||
#ifdef EXV_USE_SSH
|
||||
use_ssh=1;
|
||||
#endif
|
||||
|
||||
Exiv2::StringVector libs =getLoadedLibraries();
|
||||
|
||||
output(os,keys,"exiv2",Exiv2::versionString());
|
||||
@@ -553,7 +548,6 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys)
|
||||
output(os,keys,"enable_webready" ,enable_webready );
|
||||
output(os,keys,"enable_nls" ,enable_nls );
|
||||
output(os,keys,"use_curl" ,use_curl );
|
||||
output(os,keys,"use_ssh" ,use_ssh );
|
||||
|
||||
output(os,keys,"config_path" ,Exiv2::Internal::getExiv2ConfigPath());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user