|
58 | 58 | # include <curl/curl.h> |
59 | 59 | #endif |
60 | 60 |
|
61 | | -#ifdef EXV_USE_SSH |
62 | | -# include "ssh.hpp" |
63 | | -#else |
64 | | -# define mode_t unsigned short |
65 | | -#endif |
| 61 | +#define mode_t unsigned short |
66 | 62 |
|
67 | 63 | // Platform specific headers for handling extended attributes (xattr) |
68 | 64 | #if defined(__APPLE__) |
@@ -2401,225 +2397,6 @@ namespace Exiv2 { |
2401 | 2397 | } |
2402 | 2398 | #endif |
2403 | 2399 |
|
2404 | | -#endif |
2405 | | - |
2406 | | -#ifdef EXV_USE_SSH |
2407 | | - //! Internal Pimpl structure of class RemoteIo. |
2408 | | - class SshIo::SshImpl : public Impl { |
2409 | | - public: |
2410 | | - //! Constructor |
2411 | | - SshImpl(const std::string& path, size_t blockSize); |
2412 | | -#ifdef EXV_UNICODE_PATH |
2413 | | - //! Constructor accepting a unicode path in an std::wstring |
2414 | | - SshImpl(const std::wstring& wpath, size_t blockSize); |
2415 | | -#endif |
2416 | | - //! Destructor. Closes ssh session and releases all managed memory. |
2417 | | - ~SshImpl(); |
2418 | | - |
2419 | | - Exiv2::Uri hostInfo_; //!< host information extracted from path |
2420 | | - SSH* ssh_; //!< SSH pointer |
2421 | | - sftp_file fileHandler_; //!< sftp file handler |
2422 | | - |
2423 | | - // METHODS |
2424 | | - /*! |
2425 | | - @brief Get the length (in bytes) of the remote file. |
2426 | | - @return Return -1 if the size is unknown. Otherwise it returns the length of remote file (in bytes). |
2427 | | - @throw Error if the server returns the error code. |
2428 | | - */ |
2429 | | - long getFileLength(); |
2430 | | - /*! |
2431 | | - @brief Get the data by range. |
2432 | | - @param lowBlock The start block index. |
2433 | | - @param highBlock The end block index. |
2434 | | - @param response The data from the server. |
2435 | | - @throw Error if the server returns the error code. |
2436 | | - @note Set lowBlock = -1 and highBlock = -1 to get the whole file content. |
2437 | | - */ |
2438 | | - void getDataByRange(long lowBlock, long highBlock, std::string& response); |
2439 | | - /*! |
2440 | | - @brief Submit the data to the remote machine. The data replace a part of the remote file. |
2441 | | - The replaced part of remote file is indicated by from and to parameters. |
2442 | | - @param data The data are submitted to the remote machine. |
2443 | | - @param size The size of data. |
2444 | | - @param from The start position in the remote file where the data replace. |
2445 | | - @param to The end position in the remote file where the data replace. |
2446 | | - @note The write access is only available on the SSH protocol. It requires the write permission |
2447 | | - to edit the remote file. |
2448 | | - @throw Error if it fails. |
2449 | | - */ |
2450 | | - void writeRemote(const byte* data, size_t size, long from, long to); |
2451 | | - |
2452 | | - SshImpl& operator=(const SshImpl& rhs) = delete; |
2453 | | - SshImpl& operator=(const SshImpl&& rhs) = delete; |
2454 | | - SshImpl(const SshImpl& rhs) = delete; |
2455 | | - SshImpl(const SshImpl&& rhs) = delete; |
2456 | | - }; // class RemoteIo::Impl |
2457 | | - |
2458 | | - SshIo::SshImpl::SshImpl(const std::string& url, size_t blockSize):Impl(url, blockSize) |
2459 | | - { |
2460 | | - hostInfo_ = Exiv2::Uri::Parse(url); |
2461 | | - Exiv2::Uri::Decode(hostInfo_); |
2462 | | - |
2463 | | - // remove / at the beginning of the path |
2464 | | - if (hostInfo_.Path[0] == '/') { |
2465 | | - hostInfo_.Path = hostInfo_.Path.substr(1); |
2466 | | - } |
2467 | | - ssh_ = new SSH(hostInfo_.Host, hostInfo_.Username, hostInfo_.Password, hostInfo_.Port); |
2468 | | - |
2469 | | - if (protocol_ == pSftp) { |
2470 | | - ssh_->getFileSftp(hostInfo_.Path, fileHandler_); |
2471 | | - if (fileHandler_ == nullptr) throw Error(kerErrorMessage, "Unable to open the file"); |
2472 | | - } else { |
2473 | | - fileHandler_ = nullptr; |
2474 | | - } |
2475 | | - } |
2476 | | -#ifdef EXV_UNICODE_PATH |
2477 | | - SshIo::SshImpl::SshImpl(const std::wstring& wurl, size_t blockSize):Impl(wurl, blockSize) |
2478 | | - { |
2479 | | - std::string url; |
2480 | | - url.assign(wurl.begin(), wurl.end()); |
2481 | | - path_ = url; |
2482 | | - |
2483 | | - hostInfo_ = Exiv2::Uri::Parse(url); |
2484 | | - Exiv2::Uri::Decode(hostInfo_); |
2485 | | - |
2486 | | - // remove / at the beginning of the path |
2487 | | - if (hostInfo_.Path[0] == '/') { |
2488 | | - hostInfo_.Path = hostInfo_.Path.substr(1); |
2489 | | - } |
2490 | | - ssh_ = new SSH(hostInfo_.Host, hostInfo_.Username, hostInfo_.Password, hostInfo_.Port); |
2491 | | - |
2492 | | - if (protocol_ == pSftp) { |
2493 | | - ssh_->getFileSftp(hostInfo_.Path, fileHandler_); |
2494 | | - if (fileHandler_ == nullptr) throw Error(kerErrorMessage, "Unable to open the file"); |
2495 | | - } else { |
2496 | | - fileHandler_ = nullptr; |
2497 | | - } |
2498 | | - } |
2499 | | -#endif |
2500 | | - |
2501 | | - long SshIo::SshImpl::getFileLength() |
2502 | | - { |
2503 | | - long length = 0; |
2504 | | - if (protocol_ == pSftp) { // sftp |
2505 | | - sftp_attributes attributes = sftp_fstat(fileHandler_); |
2506 | | - length = (long)attributes->size; |
2507 | | - } else { // ssh |
2508 | | - std::string response; |
2509 | | - //std::string cmd = "stat -c %s " + hostInfo_.Path; |
2510 | | - std::string cmd = "declare -a x=($(ls -alt " + hostInfo_.Path + ")); echo ${x[4]}"; |
2511 | | - if (ssh_->runCommand(cmd, &response) != 0) { |
2512 | | - throw Error(kerErrorMessage, "Unable to get file length."); |
2513 | | - } else { |
2514 | | - length = atol(response.c_str()); |
2515 | | - if (length == 0) { |
2516 | | - throw Error(kerErrorMessage, "File is empty or not found."); |
2517 | | - } |
2518 | | - } |
2519 | | - } |
2520 | | - return length; |
2521 | | - } |
2522 | | - |
2523 | | - void SshIo::SshImpl::getDataByRange(long lowBlock, long highBlock, std::string& response) |
2524 | | - { |
2525 | | - if (protocol_ == pSftp) { |
2526 | | - if (sftp_seek(fileHandler_, (uint32_t) (lowBlock * blockSize_)) < 0) throw Error(kerErrorMessage, "SFTP: unable to sftp_seek"); |
2527 | | - size_t buffSize = (highBlock - lowBlock + 1) * blockSize_; |
2528 | | - std::vector<char> buffer(buffSize); |
2529 | | - long nBytes = static_cast<long>(sftp_read(fileHandler_, &buffer.at(0), buffSize)); |
2530 | | - if (nBytes < 0) { |
2531 | | - throw Error(kerErrorMessage, "SFTP: unable to sftp_read"); |
2532 | | - } |
2533 | | - response.assign(&buffer.at(0), buffSize); |
2534 | | - } else { |
2535 | | - std::stringstream ss; |
2536 | | - if (lowBlock > -1 && highBlock > -1) { |
2537 | | - ss << "dd if=" << hostInfo_.Path |
2538 | | - << " ibs=" << blockSize_ |
2539 | | - << " skip=" << lowBlock |
2540 | | - << " count=" << (highBlock - lowBlock) + 1<< " 2>/dev/null"; |
2541 | | - } else { |
2542 | | - ss << "dd if=" << hostInfo_.Path |
2543 | | - << " ibs=" << blockSize_ |
2544 | | - << " 2>/dev/null"; |
2545 | | - } |
2546 | | - std::string cmd = ss.str(); |
2547 | | - if (ssh_->runCommand(cmd, &response) != 0) { |
2548 | | - throw Error(kerErrorMessage, "Unable to get data by range."); |
2549 | | - } |
2550 | | - } |
2551 | | - } |
2552 | | - |
2553 | | - void SshIo::SshImpl::writeRemote(const byte* data, size_t size, long from, long to) |
2554 | | - { |
2555 | | - if (protocol_ == pSftp) throw Error(kerErrorMessage, "not support SFTP write access."); |
2556 | | - |
2557 | | - //printf("ssh update size=%ld from=%ld to=%ld\n", (long)size, from, to); |
2558 | | - assert(isMalloced_); |
2559 | | - |
2560 | | - std::string tempFile = hostInfo_.Path + ".exiv2tmp"; |
2561 | | - std::string response; |
2562 | | - std::stringstream ss; |
2563 | | - // copy the head (byte 0 to byte fromByte) of original file to filepath.exiv2tmp |
2564 | | - ss << "head -c " << from |
2565 | | - << " " << hostInfo_.Path |
2566 | | - << " > " << tempFile; |
2567 | | - std::string cmd = ss.str(); |
2568 | | - if (ssh_->runCommand(cmd, &response) != 0) { |
2569 | | - throw Error(kerErrorMessage, "SSH: Unable to cope the head of file to temp"); |
2570 | | - } |
2571 | | - |
2572 | | - // upload the data (the byte ranges which are different between the original |
2573 | | - // file and the new file) to filepath.exiv2datatemp |
2574 | | - if (ssh_->scp(hostInfo_.Path + ".exiv2datatemp", data, size) != 0) { |
2575 | | - throw Error(kerErrorMessage, "SSH: Unable to copy file"); |
2576 | | - } |
2577 | | - |
2578 | | - // concatenate the filepath.exiv2datatemp to filepath.exiv2tmp |
2579 | | - cmd = "cat " + hostInfo_.Path + ".exiv2datatemp >> " + tempFile; |
2580 | | - if (ssh_->runCommand(cmd, &response) != 0) { |
2581 | | - throw Error(kerErrorMessage, "SSH: Unable to copy the rest"); |
2582 | | - } |
2583 | | - |
2584 | | - // copy the tail (from byte toByte to the end of file) of original file to filepath.exiv2tmp |
2585 | | - ss.str(""); |
2586 | | - ss << "tail -c+" << (to + 1) |
2587 | | - << " " << hostInfo_.Path |
2588 | | - << " >> " << tempFile; |
2589 | | - cmd = ss.str(); |
2590 | | - if (ssh_->runCommand(cmd, &response) != 0) { |
2591 | | - throw Error(kerErrorMessage, "SSH: Unable to copy the rest"); |
2592 | | - } |
2593 | | - |
2594 | | - // replace the original file with filepath.exiv2tmp |
2595 | | - cmd = "mv " + tempFile + " " + hostInfo_.Path; |
2596 | | - if (ssh_->runCommand(cmd, &response) != 0) { |
2597 | | - throw Error(kerErrorMessage, "SSH: Unable to copy the rest"); |
2598 | | - } |
2599 | | - |
2600 | | - // remove filepath.exiv2datatemp |
2601 | | - cmd = "rm " + hostInfo_.Path + ".exiv2datatemp"; |
2602 | | - if (ssh_->runCommand(cmd, &response) != 0) { |
2603 | | - throw Error(kerErrorMessage, "SSH: Unable to copy the rest"); |
2604 | | - } |
2605 | | - } |
2606 | | - |
2607 | | - SshIo::SshImpl::~SshImpl() { |
2608 | | - if (fileHandler_) sftp_close(fileHandler_); |
2609 | | - if (ssh_) delete ssh_; |
2610 | | - } |
2611 | | - |
2612 | | - SshIo::SshIo(const std::string& url, size_t blockSize) |
2613 | | - { |
2614 | | - p_ = new SshImpl(url, blockSize); |
2615 | | - } |
2616 | | -#ifdef EXV_UNICODE_PATH |
2617 | | - SshIo::SshIo(const std::wstring& wurl, size_t blockSize) |
2618 | | - { |
2619 | | - p_ = new SshImpl(wurl, blockSize); |
2620 | | - } |
2621 | | -#endif |
2622 | | - |
2623 | 2400 | #endif |
2624 | 2401 |
|
2625 | 2402 | // ************************************************************************* |
|
0 commit comments