|
@@ -5,7 +5,6 @@
|
|
|
#include <iosfwd>
|
|
|
|
|
|
#include "fmtlog.h"
|
|
|
-#include "CurlFtpInfo.h"
|
|
|
|
|
|
|
|
|
#if defined(_WIN32)
|
|
@@ -70,6 +69,23 @@ static int writeStringListCallback(void* buffer, size_t size, size_t nmemb, void
|
|
|
return size * nmemb;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ * @brief 写入文件回调函数
|
|
|
+ *
|
|
|
+ * @param contents 下载到的数据内容
|
|
|
+ * @param size 数据大小
|
|
|
+ * @param nmemb 数据单位
|
|
|
+ * @param pFile 文件指针
|
|
|
+ * @return size_t 写入的大小
|
|
|
+ */
|
|
|
+static size_t writeDataCallBack(void* contents, size_t size, size_t nmemb, FILE* pFile)
|
|
|
+{
|
|
|
+ size_t written = fwrite(contents, size, nmemb, pFile);
|
|
|
+ return written;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
#if defined(_WIN32)
|
|
|
static char* GBToUTF8(const char* gb2312)
|
|
@@ -90,8 +106,8 @@ static char* GBToUTF8(const char* gb2312)
|
|
|
|
|
|
* @brief 解析字符串文件信息
|
|
|
*
|
|
|
- * @param strSrc
|
|
|
- * @param fileList
|
|
|
+ * @param strSrc 读取到的字符串
|
|
|
+ * @param fileList 文件信息列表
|
|
|
* @return true
|
|
|
* @return false
|
|
|
*/
|
|
@@ -162,7 +178,6 @@ CurlFtp::CurlFtp()
|
|
|
|
|
|
curl_global_init(CURL_GLOBAL_DEFAULT);
|
|
|
|
|
|
- m_curl = curl_easy_init();
|
|
|
hasInstace = true;
|
|
|
}
|
|
|
|
|
@@ -170,68 +185,10 @@ CurlFtp::CurlFtp()
|
|
|
CurlFtp::~CurlFtp()
|
|
|
{
|
|
|
|
|
|
- curl_easy_cleanup(m_curl);
|
|
|
curl_global_cleanup();
|
|
|
hasInstace = false;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
|
|
|
|
|
|
* @brief 列出FTP文件夹
|
|
@@ -379,13 +336,13 @@ bool CurlFtp::createDir(const std::string &ftpUrl, const std::string &username,
|
|
|
|
|
|
|
|
|
|
|
|
-bool CurlFtp::setFtpIPAndPort(const std::string& IP, const std::string& port)
|
|
|
+bool CurlFtp::setFtpIPAndPort(const std::string& IP, const int port)
|
|
|
{
|
|
|
|
|
|
m_IP = IP;
|
|
|
m_port = port;
|
|
|
- m_ftpUrl = "ftp://" + m_IP + ":" + m_port;
|
|
|
- printf("ftpUrl = %s\n", m_ftpUrl.c_str());
|
|
|
+ m_ftpUrl = "ftp://" + m_IP + ":" + std::to_string(m_port);
|
|
|
+ FMTLOG_INFO("ftpUrl = {}", m_ftpUrl);
|
|
|
|
|
|
return true;
|
|
|
}
|
|
@@ -404,68 +361,240 @@ bool CurlFtp::setFtpUsernameAndPassword(const std::string& username, const std::
|
|
|
|
|
|
bool CurlFtp::getFileList(std::string dir, std::vector<std::string>& fileList)
|
|
|
{
|
|
|
- if(m_IP.empty() || m_port.empty())
|
|
|
+ if(m_IP.empty())
|
|
|
{
|
|
|
FMTLOG_WARN("IP or port is empty");
|
|
|
return false;
|
|
|
}
|
|
|
- if(m_curl == nullptr)
|
|
|
+
|
|
|
+ auto dirTmp = checkDirPath(dir);
|
|
|
+
|
|
|
+ CURL *curl = nullptr;
|
|
|
+ curl = curl_easy_init();
|
|
|
+ if(curl == nullptr)
|
|
|
{
|
|
|
- FMTLOG_WARN("m_curl is nullptr");
|
|
|
+ FMTLOG_ERROR("curl init failed !");
|
|
|
return false;
|
|
|
}
|
|
|
+
|
|
|
std::vector<CF_FileInfo> listInfo;
|
|
|
- listAll(dir, listInfo);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
+ listAll(curl, dirTmp, listInfo);
|
|
|
+ for(const CF_FileInfo& fi : listInfo)
|
|
|
+ {
|
|
|
+
|
|
|
+ if(fi.type == CF_FileType::FILE)
|
|
|
+ {
|
|
|
+ fileList.push_back(fi.name);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ curl_easy_cleanup(curl);
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+bool CurlFtp::getDirList(std::string dir, std::vector<std::string>& dirList)
|
|
|
+{
|
|
|
+ if(m_IP.empty())
|
|
|
+ {
|
|
|
+ FMTLOG_WARN("IP or port is empty");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ auto dirTmp = checkDirPath(dir);
|
|
|
+
|
|
|
+ CURL *curl = nullptr;
|
|
|
+ curl = curl_easy_init();
|
|
|
+ if(curl == nullptr)
|
|
|
+ {
|
|
|
+ FMTLOG_ERROR("curl init failed !");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::vector<CF_FileInfo> listInfo;
|
|
|
+
|
|
|
+ listAll(curl, dirTmp, listInfo);
|
|
|
+ for(const CF_FileInfo& fi : listInfo)
|
|
|
+ {
|
|
|
+
|
|
|
+ if(fi.type == CF_FileType::DIR)
|
|
|
+ {
|
|
|
+ dirList.push_back(fi.name);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ curl_easy_cleanup(curl);
|
|
|
|
|
|
-
|
|
|
-bool CurlFtp::listAll(std::string dir, std::vector<CF_FileInfo>& fileList)
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+bool CurlFtp::isDirExist(const std::string& dir)
|
|
|
{
|
|
|
- if(m_IP.empty() || m_port.empty())
|
|
|
+ if(m_ftpUrl.empty())
|
|
|
{
|
|
|
- printf("IP or port is empty\n");
|
|
|
+ FMTLOG_ERROR("ftpUrl is empty");
|
|
|
return false;
|
|
|
}
|
|
|
- if(m_curl == nullptr)
|
|
|
+
|
|
|
+ auto dirTmp = checkDirPath(dir);
|
|
|
+
|
|
|
+ CURL* curl = nullptr;
|
|
|
+ curl = curl_easy_init();
|
|
|
+ if(curl == nullptr)
|
|
|
{
|
|
|
- printf("m_curl is nullptr\n");
|
|
|
+ FMTLOG_ERROR("curl init failed !");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ std::string ftpUrl = m_ftpUrl + dirTmp;
|
|
|
+ curl_easy_setopt(curl, CURLOPT_URL, ftpUrl.c_str());
|
|
|
+ curl_easy_setopt(curl, CURLOPT_USERNAME, m_username.c_str());
|
|
|
+ curl_easy_setopt(curl, CURLOPT_PASSWORD, m_password.c_str());
|
|
|
+
|
|
|
+ curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
|
|
|
+
|
|
|
+ CURLcode res = curl_easy_perform(curl);
|
|
|
+ bool result = true;
|
|
|
+ if(res != CURLE_OK)
|
|
|
+ {
|
|
|
+ FMTLOG_ERROR("Failed to get file list, error code: {} ,{}", (int)res, curl_easy_strerror(res));
|
|
|
+ result = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+bool CurlFtp::downloadFile(const std::string& remoteFile, const std::string& localFile)
|
|
|
+{
|
|
|
+ if(m_ftpUrl.empty())
|
|
|
+ {
|
|
|
+ FMTLOG_ERROR("ftpUrl is empty");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ CURL* curl = nullptr;
|
|
|
+ curl = curl_easy_init();
|
|
|
+ if(curl == nullptr)
|
|
|
+ {
|
|
|
+ FMTLOG_ERROR("curl init failed !");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::string ftpUrl = m_ftpUrl + remoteFile;
|
|
|
+
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ * @brief 列出文件列表,这个需要的参数很多,无法设置成静态函数
|
|
|
+ *
|
|
|
+ * @param curl CURL句柄
|
|
|
+ * @param dir 文件夹,相对路径,不带有IP和端口号
|
|
|
+ * @param fileList 返回值,文件列表
|
|
|
+ * @return true
|
|
|
+ * @return false
|
|
|
+ */
|
|
|
+bool CurlFtp::listAll(CURL* curl, std::string dir, std::vector<CF_FileInfo>& fileInfoList)
|
|
|
+{
|
|
|
+ if(m_IP.empty())
|
|
|
+ {
|
|
|
+ FMTLOG_ERROR("IP is empty");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if(curl == nullptr)
|
|
|
+ {
|
|
|
+ FMTLOG_ERROR("curl is nullptr");
|
|
|
return false;
|
|
|
}
|
|
|
bool result = false;
|
|
|
std::string strSrc;
|
|
|
|
|
|
std::string ftpUrl = m_ftpUrl + dir;
|
|
|
- curl_easy_setopt(m_curl, CURLOPT_URL, ftpUrl.c_str());
|
|
|
+ curl_easy_setopt(curl, CURLOPT_URL, ftpUrl.c_str());
|
|
|
+ curl_easy_setopt(curl, CURLOPT_PORT, m_port);
|
|
|
|
|
|
- curl_easy_setopt(m_curl, CURLOPT_USERNAME, m_username.c_str());
|
|
|
- curl_easy_setopt(m_curl, CURLOPT_PASSWORD, m_password.c_str());
|
|
|
+ curl_easy_setopt(curl, CURLOPT_USERNAME, m_username.c_str());
|
|
|
+ curl_easy_setopt(curl, CURLOPT_PASSWORD, m_password.c_str());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, writeStringCallback);
|
|
|
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeStringCallback);
|
|
|
|
|
|
- curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &strSrc);
|
|
|
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &strSrc);
|
|
|
+
|
|
|
+
|
|
|
+ curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
|
|
|
+ curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L);
|
|
|
|
|
|
|
|
|
- m_res = curl_easy_perform(m_curl);
|
|
|
- if(m_res != CURLE_OK)
|
|
|
+ CURLcode res = curl_easy_perform(curl);
|
|
|
+ if(res != CURLE_OK)
|
|
|
{
|
|
|
- FMTLOG_ERROR("Failed to get file list, error code: {} ,{}", (int)m_res, curl_easy_strerror(m_res));
|
|
|
+ FMTLOG_ERROR("Failed to get file list, error code: {} ,{}", (int)res, curl_easy_strerror(res));
|
|
|
+ FMTLOG_ERROR("ftpUrl = {}", ftpUrl);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- parseFileInfo(strSrc, fileList);
|
|
|
+ parseFileInfo(strSrc, fileInfoList);
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+std::string CurlFtp::checkDirPath(const std::string& dir)
|
|
|
+{
|
|
|
+ std::string dirTmp = dir;
|
|
|
+
|
|
|
+ std::regex reg(R"(^/[.]*)");
|
|
|
+ if(!std::regex_match(dirTmp, reg))
|
|
|
+ {
|
|
|
+ dirTmp = "/" + dirTmp;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::regex reg1(R"(//)");
|
|
|
+ dirTmp = std::regex_replace(dirTmp, reg1, "/");
|
|
|
+
|
|
|
+ std::regex reg2(R"([.]*/$)");
|
|
|
+ if(!std::regex_match(dirTmp, reg2))
|
|
|
+ {
|
|
|
+ dirTmp = dirTmp + "/";
|
|
|
+ }
|
|
|
+
|
|
|
+ return dirTmp;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+std::string CurlFtp::checkFilePath(const std::string& file)
|
|
|
+{
|
|
|
+ std::string dirTmp = file;
|
|
|
+
|
|
|
+ std::regex reg2(R"([.]*/$)");
|
|
|
+ if(std::regex_match(dirTmp, reg2))
|
|
|
+ {
|
|
|
+ FMTLOG_ERROR("File path is not correct, end with '/'");
|
|
|
+ return std::string();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ std::regex reg(R"(^/[.]*)");
|
|
|
+ if(!std::regex_match(dirTmp, reg))
|
|
|
+ {
|
|
|
+ dirTmp = "/" + dirTmp;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::regex reg1(R"(//)");
|
|
|
+ dirTmp = std::regex_replace(dirTmp, reg1, "/");
|
|
|
+
|
|
|
+
|
|
|
+ return dirTmp;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|