///////////////////////////////////////////////////////
| 530 | |
| 531 | //////////////////////////////////////////////////////////// |
| 532 | Ftp::Response Ftp::DataChannel::open(Ftp::TransferMode mode) |
| 533 | { |
| 534 | // Open a data connection in active mode (we connect to the server) |
| 535 | Ftp::Response response = m_ftp.sendCommand("PASV"); |
| 536 | if (response.isOk()) |
| 537 | { |
| 538 | // Extract the connection address and port from the response |
| 539 | const std::string::size_type begin = response.getMessage().find_first_of("0123456789"); |
| 540 | if (begin != std::string::npos) |
| 541 | { |
| 542 | std::array<std::uint8_t, 6> data{}; |
| 543 | std::string str = response.getMessage().substr(begin); |
| 544 | std::size_t index = 0; |
| 545 | for (unsigned char& datum : data) |
| 546 | { |
| 547 | // Extract the current number |
| 548 | while (std::isdigit(str[index])) |
| 549 | { |
| 550 | datum = static_cast<std::uint8_t>( |
| 551 | static_cast<std::uint8_t>(datum * 10) + static_cast<std::uint8_t>(str[index] - '0')); |
| 552 | ++index; |
| 553 | } |
| 554 | |
| 555 | // Skip separator |
| 556 | ++index; |
| 557 | } |
| 558 | |
| 559 | // Reconstruct connection port and address |
| 560 | const auto port = static_cast<std::uint16_t>(data[4] * 256 + data[5]); |
| 561 | const IpAddress address(data[0], data[1], data[2], data[3]); |
| 562 | |
| 563 | // Connect the data channel to the server |
| 564 | if (m_dataSocket.connect(address, port) == Socket::Status::Done) |
| 565 | { |
| 566 | // Translate the transfer mode to the corresponding FTP parameter |
| 567 | std::string modeStr; |
| 568 | switch (mode) |
| 569 | { |
| 570 | case Ftp::TransferMode::Binary: |
| 571 | modeStr = "I"; |
| 572 | break; |
| 573 | case Ftp::TransferMode::Ascii: |
| 574 | modeStr = "A"; |
| 575 | break; |
| 576 | case Ftp::TransferMode::Ebcdic: |
| 577 | modeStr = "E"; |
| 578 | break; |
| 579 | } |
| 580 | |
| 581 | // Set the transfer mode |
| 582 | response = m_ftp.sendCommand("TYPE", modeStr); |
| 583 | } |
| 584 | else |
| 585 | { |
| 586 | // Failed to connect to the server |
| 587 | response = Ftp::Response(Ftp::Response::Status::ConnectionFailed); |
| 588 | } |
| 589 | } |
no test coverage detected