2638 lines
64 KiB
C++
2638 lines
64 KiB
C++
// SHCSDK.cpp : DLL 응용 프로그램에 대한 진입점을 정의합니다.
|
|
//
|
|
|
|
#include <windows.h>
|
|
#include <atlenc.h>
|
|
|
|
#include <time.h>
|
|
#include <io.h>
|
|
#include <fcntl.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <set>
|
|
|
|
#include "CommLib.h"
|
|
|
|
#ifndef off64_t
|
|
#define off64_t __int64
|
|
#endif
|
|
|
|
#include "ne_socket.h"
|
|
#include "ne_uri.h"
|
|
#include "ne_request.h"
|
|
#include "ne_xml.h"
|
|
#include "ne_string.h"
|
|
#include "ne_dates.h"
|
|
|
|
|
|
#define G_CENTERADDR "gts01.ktsystemhosting.com"
|
|
#define G_CENTERADDR_PORT "gts01.ktsystemhosting.com:80"
|
|
|
|
//#include "../Common/SBUtil.h"
|
|
#include <atlstr.h>
|
|
#include <atltime.h>
|
|
|
|
#pragma comment(lib, "ws2_32.lib")
|
|
//#pragma comment(lib, "libexpat.lib")
|
|
|
|
#include <direct.h>
|
|
|
|
using namespace std;
|
|
|
|
#define CENTER_ADDR G_CENTERADDR_PORT
|
|
#define DELIMITER 0x1b
|
|
|
|
#define MAX_TRY 3
|
|
#define COUNT_SIZE 4
|
|
#define PATH_SIZE 2048
|
|
#define SOCK_TIMEOUT 5
|
|
|
|
typedef struct COMMLIB_HANDLE {
|
|
ne_session* pnsess;
|
|
ne_uri nuri;
|
|
string sUserId;
|
|
string sPassword;
|
|
string sDavAuth;
|
|
DWORD dwError;
|
|
string sError;
|
|
|
|
// 업/다운 관련
|
|
HANDLE hThread;
|
|
HANDLE hWaitEvent;
|
|
UINT32 uJob;
|
|
string sJobParam;
|
|
cl_callback proc;
|
|
void* pParam;
|
|
HANDLE hTranFile;
|
|
__int64 nExFileSize;
|
|
__int64 iTranPos;
|
|
__int64 nFileSize;
|
|
DWORD dwOldTick;
|
|
int nTranStop;
|
|
string sRedirect;
|
|
string sDomain2;
|
|
|
|
set<PCLSERVICE_STRUCT> setServiceList;
|
|
set<PCLPATHINFO_STRUCT> setPathInfoList;
|
|
set<PCLFILE_STRUCT> setFileList;
|
|
} COMMLIB_STRUCT, *PCOMMLIB_STRUCT;
|
|
|
|
static enum {
|
|
CLJOB_PUT = 0,
|
|
CLJOB_GET,
|
|
};
|
|
|
|
static enum {
|
|
CLSTOP_NO = 0,
|
|
CLSTOP_BYUSER,
|
|
CLSTOP_BYERROR,
|
|
};
|
|
|
|
|
|
BOOL StartTransfer(PCOMMLIB_STRUCT pcl);
|
|
static DWORD WINAPI ThreadProc(LPVOID lpParam);
|
|
|
|
// Socket command
|
|
static bool DoCommand(PCOMMLIB_STRUCT pcl, LPCSTR pszService, int nCommand, LPVOID pSendBody, DWORD dwSendBodyLen, LPVOID* ppRecvBody, LPDWORD pdwRecvBodyLen);
|
|
|
|
#define COUNT_SIZE 4
|
|
#define PATH_SIZE 2048
|
|
|
|
// Webdav command
|
|
static bool DoCommand(PCOMMLIB_STRUCT pcl, LPCSTR pszMethod, LPCSTR pszPath, LPCSTR pszHeaders = NULL, LPCSTR pszBody = NULL,
|
|
bool bParseBody = false, LPVOID pSTagParser = NULL, LPVOID pDataParser = NULL, LPVOID pETagParser = NULL, LPVOID pParam = NULL);
|
|
static int ResponseBodyReader(void* userdata, const char* buf, size_t len);
|
|
|
|
static void DoUpload(PCOMMLIB_STRUCT pcl);
|
|
static ssize_t UploadProvider(void *userdata, char *buffer, size_t buflen);
|
|
|
|
static void DoDownload(PCOMMLIB_STRUCT pcl);
|
|
static int DownloadProvider(void* userdata, const char* buf, size_t len);
|
|
|
|
static int FileListSTagParser(void *userdata, int parent, const char *nspace, const char *name, const char **atts);
|
|
static int FileListDataParser(void *userdata, int state, const char *data, size_t len);
|
|
static int FileListETagParser(void *userdata, int state, const char *nspace, const char *name);
|
|
|
|
static string GetErrorMessage(DWORD dwError);
|
|
|
|
static string PathEncode(LPCSTR pszPath);
|
|
static string PathDecode(LPCSTR pszPath);
|
|
static string URLEncode(LPCSTR pszURL);
|
|
static string URLDecode(LPCSTR pszURL);
|
|
|
|
static BOOL DeleteDirectory(LPCSTR pszDirectory);
|
|
static string ConvertTimeFormat(LPCSTR pszTime);
|
|
static void ReplaceAll(string& sValue, LPCSTR pszOld, LPCSTR pszNew);
|
|
static int _sh_send(SOCKET s, char *buf, int len);
|
|
static int _sh_recv(SOCKET s, char *buf, int len);
|
|
|
|
int GetCurrentPath(char* pszPath);
|
|
|
|
typedef struct {
|
|
int nTag;
|
|
UINT nRootPathLen;
|
|
PCLFILE_STRUCT pclf;
|
|
vector<PCLFILE_STRUCT> vec;
|
|
} CLFILELIST_PARSER_STRUCT, *PCLFILELIST_PARSER_STRUCT;
|
|
|
|
static enum {
|
|
CLFLTAG_UNKNOWN = 0,
|
|
CLFLTAG_PATH,
|
|
CLFLTAG_TYPE,
|
|
CLFLTAG_SIZE,
|
|
CLFLTAG_LASTMODIFIED,
|
|
CLFLTAG_SOURCE,
|
|
};
|
|
|
|
|
|
static HINSTANCE g_hInst = NULL;
|
|
static HANDLE g_hFile = NULL;
|
|
|
|
static HANDLE g_hLogFile = NULL;
|
|
static bool g_bWriteDirLog = true;
|
|
static bool g_bWriteUploadLog = true;
|
|
|
|
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
|
|
{
|
|
g_hInst = (HINSTANCE)hModule;
|
|
|
|
if (dwReason == DLL_PROCESS_ATTACH)
|
|
g_hFile = CreateFile("C:\\CommLib.log", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
|
|
else if (dwReason == DLL_PROCESS_DETACH)
|
|
CloseHandle(g_hFile);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#ifdef _OLD
|
|
WIN32DLL
|
|
HCOMMLIB cl_init(const char *url, const char *userId, const char *password, const char *proxyAddr, unsigned int proxyPort)
|
|
#else
|
|
WIN32DLL
|
|
HCOMMLIB cl_init(const char *url, const char *D2, const char *userId, const char *password, const char *proxyAddr, unsigned int proxyPort)
|
|
#endif
|
|
{
|
|
PCOMMLIB_STRUCT pcl = new COMMLIB_STRUCT;
|
|
CString strTemp;
|
|
|
|
// strTemp.Format("cl_init : %s - %s - %s\n",url,userId,password);
|
|
// OutputDebugString(strTemp);
|
|
|
|
if (!pcl)
|
|
return NULL;
|
|
|
|
pcl->pnsess = NULL;
|
|
|
|
CString sUrl = CENTER_ADDR;
|
|
|
|
if (url && strlen(url) > 0)
|
|
{
|
|
sUrl = url;
|
|
}
|
|
|
|
if(strlen(D2) == 0)
|
|
{
|
|
if (ne_sock_init() != NE_OK)
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
int nRet = ne_uri_parse(sUrl.GetBuffer()/*c_str()*/, &pcl->nuri);
|
|
// strTemp.Format("%x : %s\n",pcl->nuri.host,pcl->nuri.host);
|
|
// OutputDebugString(strTemp);
|
|
|
|
if (nRet != NE_OK)
|
|
goto EXIT_FUNCTION;
|
|
|
|
if (!pcl->nuri.scheme)
|
|
pcl->nuri.scheme = strdup("http");
|
|
|
|
if (pcl->nuri.port == 0)
|
|
pcl->nuri.port = 80;
|
|
|
|
pcl->sUserId = userId;
|
|
pcl->sPassword = password;
|
|
|
|
char szMD5[1024];
|
|
ne_md5_buffer(password, szMD5);
|
|
|
|
pcl->sDavAuth = pcl->sUserId + ":";
|
|
pcl->sDavAuth += szMD5;
|
|
|
|
char* pszBase64 = (char*)ne_base64((const unsigned char*)pcl->sDavAuth.c_str(), pcl->sDavAuth.length());
|
|
|
|
pcl->sDavAuth = "Basic ";
|
|
pcl->sDavAuth += pszBase64;
|
|
pcl->sDomain2 = D2;
|
|
|
|
free(pszBase64);
|
|
|
|
pcl->pnsess = ne_session_create(pcl->nuri.scheme, pcl->nuri.host, pcl->nuri.port);
|
|
if (!pcl->pnsess)
|
|
goto EXIT_FUNCTION;
|
|
|
|
if (proxyAddr != NULL && strlen(proxyAddr) > 0 && strlen(proxyAddr) > 0)
|
|
ne_session_proxy(pcl->pnsess, proxyAddr, proxyPort);
|
|
|
|
pcl->dwError = 0;
|
|
pcl->sError = "";
|
|
|
|
// 업/다운 관련
|
|
pcl->hThread = NULL;
|
|
pcl->hWaitEvent = NULL;
|
|
|
|
return pcl;
|
|
|
|
EXIT_FUNCTION:
|
|
DWORD dwError = GetLastError();
|
|
|
|
if (pcl->nuri.scheme)
|
|
ne_uri_free(&pcl->nuri);
|
|
|
|
if (pcl->pnsess)
|
|
ne_session_destroy(pcl->pnsess);
|
|
|
|
delete pcl;
|
|
|
|
SetLastError(dwError);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
WIN32DLL
|
|
void cl_free(HCOMMLIB hcl)
|
|
{
|
|
if (!hcl)
|
|
return;
|
|
|
|
cl_stop_transfer(hcl);
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
|
|
for (set<PCLSERVICE_STRUCT>::iterator iter = pcl->setServiceList.begin(); iter != pcl->setServiceList.end(); iter++)
|
|
delete [](*iter);
|
|
|
|
for (set<PCLPATHINFO_STRUCT>::iterator iter = pcl->setPathInfoList.begin(); iter != pcl->setPathInfoList.end(); iter++)
|
|
delete [](*iter);
|
|
|
|
for (set<PCLFILE_STRUCT>::iterator iter = pcl->setFileList.begin(); iter != pcl->setFileList.end(); iter++)
|
|
delete [](*iter);
|
|
|
|
if (pcl->hWaitEvent)
|
|
CloseHandle(pcl->hWaitEvent);
|
|
|
|
if (pcl->pnsess)
|
|
ne_session_destroy(pcl->pnsess);
|
|
|
|
// CString strTemp;
|
|
// strTemp.Format("Delete : %x : %s",pcl->nuri.host,pcl->nuri.host);
|
|
// OutputDebugString(strTemp);
|
|
|
|
if (pcl->nuri.scheme)
|
|
ne_uri_free(&pcl->nuri);
|
|
|
|
// OutputDebugString("... Complete...\n");
|
|
delete pcl;
|
|
}
|
|
|
|
|
|
WIN32DLL
|
|
int cl_get_error_number(HCOMMLIB hcl)
|
|
{
|
|
if (!hcl)
|
|
return CLERRNO_INVALID_HANDLE;
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
|
|
return (int)pcl->dwError;
|
|
}
|
|
|
|
WIN32DLL
|
|
const char* cl_get_error_message(HCOMMLIB hcl)
|
|
{
|
|
if (!hcl)
|
|
return GetErrorMessage(CLERRNO_INVALID_HANDLE).c_str();
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
|
|
return pcl->sError.c_str();
|
|
}
|
|
|
|
|
|
WIN32DLL
|
|
PCLSERVICE_STRUCT cl_get_service_list(HCOMMLIB hcl, unsigned int *count)
|
|
{
|
|
if (!hcl)
|
|
return NULL;
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
pcl->dwError = 0;
|
|
pcl->sError = "";
|
|
|
|
PBYTE pbyBody = NULL;
|
|
DWORD dwBodyLen = 0;
|
|
|
|
#ifdef _OLD
|
|
if (!DoCommand(pcl, NULL, 0x0010, NULL, 0, (LPVOID*)&pbyBody, &dwBodyLen))
|
|
return NULL;
|
|
#else
|
|
if (!DoCommand(pcl, NULL, 0x0080, NULL, 0, (LPVOID*)&pbyBody, &dwBodyLen))
|
|
return NULL;
|
|
#endif
|
|
|
|
if (dwBodyLen == 0) {
|
|
pcl->dwError = CLERRNO_ABNORMAL_RESPONSE;
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
return NULL;
|
|
}
|
|
|
|
memcpy(count, pbyBody, COUNT_SIZE);
|
|
*count = ntohl(*count);
|
|
|
|
PCLSERVICE_STRUCT pclsl = NULL;
|
|
if (*count == 0) {
|
|
pcl->dwError = CLERRNO_NOSERVICE_LIST;
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
pclsl = new CLSERVICE_STRUCT[*count];
|
|
if (!pclsl) {
|
|
pcl->dwError = GetLastError();
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
for (UINT i = 0; i < *count; i++)
|
|
memcpy(&pclsl[i], pbyBody + COUNT_SIZE + (sizeof(CLSERVICE_STRUCT) * i), sizeof(CLSERVICE_STRUCT));
|
|
|
|
pcl->setServiceList.insert(pclsl);
|
|
|
|
EXIT_FUNCTION:
|
|
if (pbyBody)
|
|
delete []pbyBody;
|
|
|
|
return pclsl;
|
|
}
|
|
|
|
WIN32DLL
|
|
void cl_free_service_list(HCOMMLIB hcl, PCLSERVICE_STRUCT pclsl)
|
|
{
|
|
if (!hcl || !pclsl)
|
|
return;
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
|
|
set<PCLSERVICE_STRUCT>::iterator iter = pcl->setServiceList.find(pclsl);
|
|
if (iter == pcl->setServiceList.end())
|
|
return;
|
|
|
|
delete []pclsl;
|
|
|
|
pcl->setServiceList.erase(pclsl);
|
|
}
|
|
|
|
WIN32DLL
|
|
BOOL cl_get_service_info(HCOMMLIB hcl, const char *serviceId, __int64 *totalBytes, __int64 *usedBytes)
|
|
{
|
|
if (!hcl)
|
|
return FALSE;
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
pcl->dwError = 0;
|
|
pcl->sError = "";
|
|
|
|
PBYTE pbyBody = NULL;
|
|
DWORD dwBodyLen = 0;
|
|
|
|
for (int i = 0; i < MAX_TRY; i++) {
|
|
if (DoCommand(pcl, serviceId, 0x0012, NULL, 0, (LPVOID*)&pbyBody, &dwBodyLen))
|
|
break;
|
|
|
|
if (pcl->dwError != WSAETIMEDOUT || i == (MAX_TRY - 1))
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
if (!DoCommand(pcl, serviceId, 0x0012, NULL, 0, (LPVOID*)&pbyBody, &dwBodyLen))
|
|
return FALSE;
|
|
*/
|
|
|
|
BOOL bRet = FALSE;
|
|
|
|
char szTotal[MAX_PATH];
|
|
memcpy(szTotal, pbyBody, dwBodyLen);
|
|
szTotal[dwBodyLen] = NULL;
|
|
|
|
char* pszFree = strchr(szTotal, DELIMITER);
|
|
*(pszFree++) = NULL;
|
|
|
|
*totalBytes = _atoi64(szTotal);
|
|
*usedBytes = _atoi64(pszFree);
|
|
|
|
bRet = TRUE;
|
|
|
|
//EXIT_FUNCTION:
|
|
if (pbyBody)
|
|
delete []pbyBody;
|
|
|
|
return bRet;
|
|
}
|
|
WIN32DLL
|
|
PCLFILE_STRUCT cl_get_file_list(HCOMMLIB hcl, const char* path, unsigned int depth, unsigned int *count)
|
|
{
|
|
if (!hcl)
|
|
return NULL;
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
|
|
// CString strTemp;
|
|
// strTemp.Format("DDD : cl_get_file_list : %s, %s\n",pcl->nuri.host,path);
|
|
// OutputDebugString(strTemp);
|
|
|
|
pcl->dwError = 0;
|
|
pcl->sError = "";
|
|
|
|
char szDepth[10];
|
|
if (depth < 2)
|
|
sprintf(szDepth, "%d", depth);
|
|
else
|
|
strcpy(szDepth, "infinity");
|
|
|
|
string sHeaders = "Depth|";
|
|
sHeaders += szDepth;
|
|
|
|
string sBody = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
|
|
sBody += "<D:propfind xmlns:D=\"DAV:\">";
|
|
sBody += "<D:prop>";
|
|
sBody += "<D:resourcetype/>";
|
|
sBody += "<D:getcontentlength/>";
|
|
sBody += "<D:getlastmodified/>";
|
|
sBody += "<D:source/>";
|
|
sBody += "</D:prop>";
|
|
sBody += "</D:propfind>";
|
|
|
|
CLFILELIST_PARSER_STRUCT clflp;
|
|
clflp.pclf = NULL;
|
|
clflp.nRootPathLen = (UINT)strlen(pcl->nuri.path);
|
|
|
|
PCLFILE_STRUCT pclf = NULL;
|
|
for (int i = 0; i < MAX_TRY; i++) {
|
|
if (DoCommand(pcl, "PROPFIND", path, sHeaders.c_str(), sBody.c_str(), true, FileListSTagParser, FileListDataParser, FileListETagParser, &clflp))
|
|
break;
|
|
/*
|
|
if (!DoCommand(pcl, "PROPFIND", path, sHeaders.c_str(), sBody.c_str(), true, FileListSTagParser, FileListDataParser, FileListETagParser, &clflp))
|
|
goto EXIT_FUNCTION;
|
|
*/
|
|
if (pcl->dwError != WSAETIMEDOUT || i == (MAX_TRY - 1))
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
unsigned int nFileCount = (unsigned int)clflp.vec.size();
|
|
if (nFileCount > 0) {
|
|
pclf = new CLFILE_STRUCT[nFileCount];
|
|
for (unsigned int i = 0; i < nFileCount; i++) {
|
|
memcpy(&pclf[i], clflp.vec.at(i), sizeof(CLFILE_STRUCT));
|
|
if (strcmp(pclf[i].path, "*myself*") == 0) {
|
|
string sPath = path;
|
|
if (sPath[0] != '/')
|
|
sPath = '/' + sPath;
|
|
strcpy(pclf[i].path, sPath.c_str());
|
|
}
|
|
}
|
|
|
|
pcl->setFileList.insert(pclf);
|
|
}
|
|
|
|
if (count)
|
|
*count = nFileCount;
|
|
|
|
EXIT_FUNCTION:
|
|
for (vector<PCLFILE_STRUCT>::iterator iter = clflp.vec.begin(); iter != clflp.vec.end(); iter++)
|
|
delete (*iter);
|
|
|
|
return pclf;
|
|
}
|
|
|
|
/*
|
|
WIN32DLL
|
|
long cl_get_filelist_count(HCOMMLIB hcl, HSHFILELIST hshfl)
|
|
{
|
|
if (!hshsdk)
|
|
return -1;
|
|
|
|
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
|
|
|
|
if (!hshfl) {
|
|
psdk->nError = SHCERRNO_INVALIDFLHDL;
|
|
psdk->sError = GetErrorMessage(psdk->nError);
|
|
return -1;
|
|
}
|
|
|
|
if (psdk->pvecshfl != hshfl) {
|
|
set<PVECTOR_SHFILELIST>::iterator iter = psdk->setFileList.find((PVECTOR_SHFILELIST)hshfl);
|
|
if (iter == psdk->setFileList.end()) {
|
|
psdk->nError = SHCERRNO_INVALIDFLHDL;
|
|
psdk->sError = GetErrorMessage(psdk->nError);
|
|
return -1;
|
|
}
|
|
|
|
psdk->pvecshfl = (*iter);
|
|
}
|
|
|
|
return (long)psdk->pvecshfl->size();
|
|
}
|
|
*/
|
|
|
|
WIN32DLL
|
|
void cl_free_file_list(HCOMMLIB hcl, PCLFILE_STRUCT pclf)
|
|
{
|
|
if (!hcl || !pclf)
|
|
return;
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
|
|
set<PCLFILE_STRUCT>::iterator iter = pcl->setFileList.find(pclf);
|
|
if (iter == pcl->setFileList.end())
|
|
return;
|
|
|
|
delete []pclf;
|
|
|
|
pcl->setFileList.erase(pclf);
|
|
}
|
|
|
|
WIN32DLL
|
|
PCLPATHINFO_STRUCT cl_get_path_auth(HCOMMLIB hcl, const char *serviceId, unsigned int *count)
|
|
{
|
|
if (!hcl)
|
|
return NULL;
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
pcl->dwError = 0;
|
|
pcl->sError = "";
|
|
|
|
PBYTE pbyBody = NULL;
|
|
DWORD dwBodyLen = 0;
|
|
/*
|
|
if (!DoCommand(pcl, serviceId, 0x0030, NULL, 0, (LPVOID*)&pbyBody, &dwBodyLen))
|
|
return NULL;
|
|
*/
|
|
for (int i = 0; i < MAX_TRY; i++) {
|
|
if (DoCommand(pcl, serviceId, 0x0030, NULL, 0, (LPVOID*)&pbyBody, &dwBodyLen))
|
|
break;
|
|
|
|
if (pcl->dwError != WSAETIMEDOUT || i == (MAX_TRY - 1))
|
|
return NULL;
|
|
}
|
|
|
|
|
|
if (dwBodyLen == 0) {
|
|
pcl->dwError = CLERRNO_ABNORMAL_RESPONSE;
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
return NULL;
|
|
}
|
|
|
|
memcpy(count, pbyBody, COUNT_SIZE);
|
|
*count = ntohl(*count);
|
|
|
|
PCLPATHINFO_STRUCT pclpi = NULL;
|
|
if (*count == 0) {
|
|
pcl->dwError = CLERRNO_NOAVAILPATH_LIST;
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
pclpi = new CLPATHINFO_STRUCT[*count];
|
|
if (!pclpi) {
|
|
pcl->dwError = GetLastError();
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
for (UINT i = 0; i < *count; i++)
|
|
memcpy(pclpi[i].path, pbyBody + COUNT_SIZE + (PATH_SIZE * i), PATH_SIZE);
|
|
|
|
pcl->setPathInfoList.insert(pclpi);
|
|
|
|
EXIT_FUNCTION:
|
|
if (pbyBody)
|
|
delete []pbyBody;
|
|
|
|
return pclpi;
|
|
}
|
|
|
|
WIN32DLL
|
|
void cl_free_path_auth(HCOMMLIB hcl, PCLPATHINFO_STRUCT pclpi)
|
|
{
|
|
if (!hcl || !pclpi)
|
|
return;
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
|
|
set<PCLPATHINFO_STRUCT>::iterator iter = pcl->setPathInfoList.find(pclpi);
|
|
if (iter == pcl->setPathInfoList.end())
|
|
return;
|
|
|
|
delete []pclpi;
|
|
|
|
pcl->setPathInfoList.erase(pclpi);
|
|
}
|
|
|
|
WIN32DLL
|
|
BOOL cl_set_anonyauth(HCOMMLIB hcl, const char *serviceName, BOOL set, const char *path)
|
|
{
|
|
if (!hcl)
|
|
return FALSE;
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
pcl->dwError = 0;
|
|
pcl->sError = "";
|
|
|
|
BOOL bRet = FALSE;
|
|
|
|
string sPath = path;
|
|
vector<string> vecPath;
|
|
|
|
int iString = 0;
|
|
string::size_type stBegin = 0, stEnd = 0;
|
|
do {
|
|
stEnd = sPath.find(',', stBegin);
|
|
vecPath.push_back(sPath.substr(stBegin, stEnd - stBegin));
|
|
stBegin = stEnd + 1;
|
|
} while (stEnd != string::npos);
|
|
|
|
int nBodyLen = ((int)vecPath.size() * PATH_SIZE) + COUNT_SIZE;
|
|
char* pszBody = new char[nBodyLen];
|
|
if (!pszBody) {
|
|
pcl->dwError = GetLastError();
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
memset(pszBody, NULL, nBodyLen);
|
|
|
|
int nPathCount = htonl((u_long)vecPath.size());
|
|
memcpy(pszBody, &nPathCount, COUNT_SIZE);
|
|
|
|
for (UINT i = 0; i < vecPath.size(); i++)
|
|
strcpy(pszBody + COUNT_SIZE + (PATH_SIZE * i), vecPath[i].c_str());
|
|
|
|
/*
|
|
if (!DoCommand(pcl, serviceName, set ? 0x0014 : 0x0018, pszBody, nBodyLen, NULL, NULL))
|
|
goto EXIT_FUNCTION;
|
|
*/
|
|
for (int i = 0; i < MAX_TRY; i++) {
|
|
if (DoCommand(pcl, serviceName, set ? 0x0014 : 0x0018, pszBody, nBodyLen, NULL, NULL))
|
|
break;
|
|
|
|
if (pcl->dwError != WSAETIMEDOUT || i == (MAX_TRY - 1))
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
bRet = TRUE;
|
|
|
|
EXIT_FUNCTION:
|
|
if (pszBody)
|
|
delete []pszBody;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
WIN32DLL
|
|
BOOL cl_set_bandwidth(HCOMMLIB hcl, const char *serviceName, const char *levelnpath)
|
|
{
|
|
if (!hcl)
|
|
return FALSE;
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
pcl->dwError = 0;
|
|
pcl->sError = "";
|
|
|
|
BOOL bRet = FALSE;
|
|
|
|
string sLevelnPath = levelnpath;
|
|
vector<string> vecLevel;
|
|
vector<string> vecPath;
|
|
|
|
int iString = 0;
|
|
string::size_type stBegin = 0, stEnd = 0;
|
|
do {
|
|
stEnd = sLevelnPath.find('|', stBegin);
|
|
vecLevel.push_back(sLevelnPath.substr(stBegin, stEnd - stBegin));
|
|
stBegin = stEnd + 1;
|
|
|
|
stEnd = sLevelnPath.find(',', stBegin);
|
|
vecPath.push_back(sLevelnPath.substr(stBegin, stEnd - stBegin));
|
|
stBegin = stEnd + 1;
|
|
} while (stEnd != string::npos);
|
|
|
|
int nPackedSize = COUNT_SIZE + PATH_SIZE;
|
|
|
|
int nBodyLen = COUNT_SIZE + ((int)vecPath.size() * nPackedSize);
|
|
char* pszBody = new char[nBodyLen];
|
|
if (!pszBody) {
|
|
pcl->dwError = GetLastError();
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
memset(pszBody, NULL, nBodyLen);
|
|
|
|
int nPathCount = htonl((u_long)vecPath.size());
|
|
memcpy(pszBody, &nPathCount, COUNT_SIZE);
|
|
|
|
for (UINT i = 0; i < vecPath.size(); i++) {
|
|
int nLevel = htonl(atoi(vecLevel[i].c_str()));
|
|
memcpy(pszBody + COUNT_SIZE + (nPackedSize * i), &nLevel, COUNT_SIZE);
|
|
strcpy(pszBody + COUNT_SIZE + (nPackedSize * i) + COUNT_SIZE, vecPath[i].c_str());
|
|
}
|
|
|
|
/*
|
|
if (!DoCommand(pcl, serviceName, 0x001C, pszBody, nBodyLen, NULL, NULL))
|
|
goto EXIT_FUNCTION;
|
|
*/
|
|
for (int i = 0; i < MAX_TRY; i++) {
|
|
if (DoCommand(pcl, serviceName, 0x001C, pszBody, nBodyLen, NULL, NULL))
|
|
break;
|
|
|
|
if (pcl->dwError != WSAETIMEDOUT || i == (MAX_TRY - 1))
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
bRet = TRUE;
|
|
|
|
EXIT_FUNCTION:
|
|
if (pszBody)
|
|
delete []pszBody;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
WIN32DLL
|
|
BOOL cl_make_directory(HCOMMLIB hcl, const char* directory)
|
|
{
|
|
if (!hcl)
|
|
return FALSE;
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
pcl->dwError = 0;
|
|
pcl->sError = "";
|
|
|
|
/*
|
|
return (BOOL)DoCommand(pcl, "MKCOL", directory);
|
|
*/
|
|
for (int i = 0; i < MAX_TRY; i++) {
|
|
if (DoCommand(pcl, "MKCOL", directory))
|
|
break;
|
|
|
|
if (pcl->dwError != WSAETIMEDOUT || i == (MAX_TRY - 1))
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
WIN32DLL
|
|
BOOL cl_copy(HCOMMLIB hcl, const char* srcPath, const char* dstPath, BOOL overwrite)
|
|
{
|
|
if (!hcl)
|
|
return FALSE;
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
pcl->dwError = 0;
|
|
pcl->sError = "";
|
|
|
|
string sDstPath = pcl->nuri.path;
|
|
if (dstPath[0] != '/')
|
|
sDstPath += "/";
|
|
sDstPath += dstPath;
|
|
|
|
string sHeaders = "New-uri|";
|
|
/*
|
|
sHeaders += sDstPath + ",Overwrite|";
|
|
*/
|
|
sHeaders += PathEncode(sDstPath.c_str()) + ",Overwrite|";
|
|
sHeaders += overwrite ? "T" : "F";
|
|
|
|
/*
|
|
return (BOOL)DoCommand(pcl, "COPY", srcPath, sHeaders.c_str());
|
|
*/
|
|
// CString strTemp;
|
|
|
|
// strTemp.Format("XXX COPY : %s - %s\n",srcPath,sHeaders.c_str());
|
|
// OutputDebugString(strTemp);
|
|
for (int i = 0; i < MAX_TRY; i++) {
|
|
if (DoCommand(pcl, "COPY", srcPath, sHeaders.c_str()))
|
|
break;
|
|
|
|
if (pcl->dwError != WSAETIMEDOUT || i == (MAX_TRY - 1))
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
WIN32DLL
|
|
BOOL cl_move(HCOMMLIB hcl, const char* srcPath, const char* dstPath, BOOL overwrite)
|
|
{
|
|
if (!hcl)
|
|
return FALSE;
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
pcl->dwError = 0;
|
|
pcl->sError = "";
|
|
|
|
string sDstPath = pcl->nuri.path;
|
|
if (dstPath[0] != '/')
|
|
sDstPath += "/";
|
|
sDstPath += dstPath;
|
|
|
|
string sHeaders = "New-uri|";
|
|
//sHeaders += sDstPath + ",Overwrite|";
|
|
sHeaders += PathEncode(sDstPath.c_str()) + ",Overwrite|";
|
|
sHeaders += overwrite ? "T" : "F";
|
|
|
|
// CString strTemp;
|
|
|
|
// strTemp.Format("XXX cl_move : %s\n",srcPath);
|
|
// OutputDebugString(strTemp);
|
|
|
|
for (int i = 0; i < MAX_TRY; i++) {
|
|
if (DoCommand(pcl, "MOVE", srcPath, sHeaders.c_str()))
|
|
break;
|
|
|
|
if (pcl->dwError != WSAETIMEDOUT || i == (MAX_TRY - 1))
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
WIN32DLL
|
|
BOOL cl_delete(HCOMMLIB hcl, const char* path)
|
|
{
|
|
if (!hcl)
|
|
return FALSE;
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
pcl->dwError = 0;
|
|
pcl->sError = "";
|
|
|
|
/*
|
|
return (BOOL)DoCommand(pcl, "DELETE", path);
|
|
*/
|
|
for (int i = 0; i < MAX_TRY; i++) {
|
|
if (DoCommand(pcl, "DELETE", path))
|
|
break;
|
|
|
|
if (pcl->dwError != WSAETIMEDOUT || i == (MAX_TRY - 1))
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
WIN32DLL
|
|
BOOL cl_upload(HCOMMLIB hcl, const char *srcPath, const char *dstPath, int writePolicy, __int64 availQuota, cl_callback callbackProc, void *pParam)
|
|
{
|
|
if (!hcl)
|
|
return FALSE;
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
|
|
// CString strTemp;
|
|
// OutputDebugString(strTemp);
|
|
|
|
if (pcl->hThread) {
|
|
pcl->dwError = CLERRNO_BUSY;
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
return FALSE;
|
|
}
|
|
|
|
pcl->dwError = 0;
|
|
pcl->sError = "";
|
|
|
|
pcl->hTranFile = INVALID_HANDLE_VALUE;
|
|
pcl->iTranPos = 0;
|
|
pcl->dwOldTick = 0;
|
|
pcl->nTranStop = CLSTOP_NO;
|
|
|
|
pcl->sJobParam = srcPath;
|
|
pcl->sJobParam += "|";
|
|
|
|
if (dstPath[0] != '/')
|
|
pcl->sJobParam += "/";
|
|
pcl->sJobParam += dstPath;
|
|
pcl->sJobParam += "|";
|
|
|
|
char szTemp[100];
|
|
|
|
sprintf(szTemp, "%d", writePolicy);
|
|
pcl->sJobParam += szTemp;
|
|
pcl->sJobParam += "|";
|
|
|
|
sprintf(szTemp, "%I64d", availQuota);
|
|
pcl->sJobParam += szTemp;
|
|
|
|
pcl->uJob = CLJOB_PUT;
|
|
pcl->proc = callbackProc;
|
|
pcl->pParam = pParam;
|
|
|
|
pcl->dwOldTick = GetTickCount();
|
|
|
|
return StartTransfer(pcl);
|
|
}
|
|
|
|
WIN32DLL
|
|
BOOL cl_download(HCOMMLIB hcl, const char *srcPath, const char *dstPath, int writePolicy, __int64 availQuota, cl_callback callbackProc, void *pParam)
|
|
{
|
|
if (!hcl)
|
|
return FALSE;
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
if (pcl->hThread) {
|
|
pcl->dwError = CLERRNO_BUSY;
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
return FALSE;
|
|
}
|
|
|
|
pcl->dwError = 0;
|
|
pcl->sError = "";
|
|
|
|
pcl->hTranFile = INVALID_HANDLE_VALUE;
|
|
pcl->iTranPos = 0;
|
|
pcl->dwOldTick = 0;
|
|
pcl->nTranStop = CLSTOP_NO;
|
|
|
|
pcl->sJobParam = srcPath[0] != '/' ? "/" : "";
|
|
pcl->sJobParam += srcPath;
|
|
pcl->sJobParam += "|";
|
|
|
|
pcl->sJobParam += dstPath;
|
|
pcl->sJobParam += "|";
|
|
|
|
char szTemp[100];
|
|
|
|
sprintf(szTemp, "%d", writePolicy);
|
|
pcl->sJobParam += szTemp;
|
|
pcl->sJobParam += "|";
|
|
|
|
sprintf(szTemp, "%I64d", availQuota);
|
|
pcl->sJobParam += szTemp;
|
|
|
|
pcl->uJob = CLJOB_GET;
|
|
pcl->proc = callbackProc;
|
|
pcl->pParam = pParam;
|
|
|
|
pcl->dwOldTick = GetTickCount();
|
|
|
|
return StartTransfer(pcl);
|
|
}
|
|
|
|
WIN32DLL
|
|
void cl_stop_transfer(HCOMMLIB hcl)
|
|
{
|
|
if (!hcl)
|
|
return;
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)hcl;
|
|
if (!pcl->hThread)
|
|
return;
|
|
|
|
pcl->nTranStop = CLSTOP_BYUSER;
|
|
WaitForSingleObject(pcl->hWaitEvent, 10);
|
|
}
|
|
|
|
WIN32DLL
|
|
void cl_set_write_log_dir(bool bLog)
|
|
{
|
|
g_bWriteDirLog = bLog;
|
|
}
|
|
|
|
WIN32DLL
|
|
void cl_set_write_log_upload(bool bLog)
|
|
{
|
|
g_bWriteUploadLog = bLog;
|
|
}
|
|
|
|
WIN32DLL
|
|
bool cl_create_log_file()
|
|
{
|
|
if(g_hLogFile != INVALID_HANDLE_VALUE)
|
|
CloseHandle(g_hLogFile);
|
|
|
|
mkdir("c:\\TEMP\\");
|
|
mkdir("c:\\TEMP\\SP-CONSOLE");
|
|
|
|
g_hLogFile = CreateFile("C:\\TEMP\\SP-CONSOLE\\upload.log", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
|
|
|
|
return g_hLogFile == INVALID_HANDLE_VALUE ? false : true;
|
|
}
|
|
|
|
WIN32DLL
|
|
void cl_destroy_log_file()
|
|
{
|
|
if(g_hLogFile != INVALID_HANDLE_VALUE)
|
|
CloseHandle(g_hLogFile);
|
|
|
|
g_hLogFile = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
WIN32DLL void cl_write_log(char* pszLog, DWORD dwSize, bool bWriteTime)
|
|
{
|
|
if(g_hLogFile == INVALID_HANDLE_VALUE)
|
|
return;
|
|
|
|
if(bWriteTime)
|
|
{
|
|
CTime time = CTime::GetCurrentTime();
|
|
CString strTime = time.Format("[%Y-%m-%d %H:%M:%S] ");
|
|
|
|
cl_write_log((LPTSTR)(LPCTSTR)strTime, strTime.GetLength(), false);
|
|
}
|
|
|
|
DWORD dwWritten = 0;
|
|
bool bWritten = false;
|
|
|
|
bWritten = WriteFile(g_hLogFile, pszLog, dwSize, &dwWritten, NULL) ? true : false;
|
|
if(bWritten)
|
|
FlushFileBuffers(g_hLogFile);
|
|
}
|
|
|
|
bool send(SOCKET s, LPCSTR pszBuf, int nLen);
|
|
bool recv(SOCKET s, LPSTR pszBuf, int nLen);
|
|
|
|
#pragma pack(1)
|
|
typedef struct {
|
|
char szTranId[52];
|
|
__int32 nMode;
|
|
char szIssuer[128];
|
|
char szServiceId[128];
|
|
__int32 nResult;
|
|
__int32 nLength;
|
|
} COMMAND_STRUCT, PCOMMAND_STRUCT;
|
|
#pragma pack()
|
|
|
|
#define PRIVATE_KEY "I'm your father"
|
|
#define SERVER_NAME "SP-Console"
|
|
|
|
#define TRANSACTION_PORT 13104
|
|
|
|
unsigned long conv_addr(const char *name)
|
|
{
|
|
struct hostent *he;
|
|
int max;
|
|
unsigned long retval;
|
|
|
|
if ((retval = inet_addr(name)) != INADDR_NONE)
|
|
return retval;
|
|
|
|
he = gethostbyname(name);
|
|
if (he == NULL)
|
|
return INADDR_NONE;
|
|
|
|
for (max = 0; he->h_addr_list[max]; max++) ;
|
|
if (max == 1) return *((unsigned long *)(he->h_addr_list[0]));
|
|
else return *((unsigned long *)(he->h_addr_list[rand() % max]));
|
|
}
|
|
|
|
static bool DoCommand(PCOMMLIB_STRUCT pcl, LPCSTR pszServiceId, int nCommand,
|
|
LPVOID pSendBody, DWORD dwSendBodyLen, LPVOID* ppRecvBody, LPDWORD pdwRecvBodyLen)
|
|
{
|
|
CString strTemp;
|
|
__time64_t time = _time64(NULL);
|
|
|
|
srand((unsigned int)time);
|
|
__int64 nRandom = rand() * rand();
|
|
|
|
struct tm *tmNow = _localtime64(&time);
|
|
|
|
time %= 10000000000; // MAX 10
|
|
nRandom %= 10000000000; // MAX 10
|
|
|
|
char szMD5[256], szVerifyKey[256];
|
|
sprintf(szMD5, "%010I64d%010I64d%s%s", time, nRandom, PRIVATE_KEY, SERVER_NAME);
|
|
ne_md5_buffer(szMD5, szVerifyKey);
|
|
|
|
char szPassword[128];
|
|
strcpy(szMD5, pcl->sPassword.c_str());
|
|
ne_md5_buffer(szMD5, szPassword);
|
|
|
|
sprintf(szMD5, "%s%s%I64d", pcl->sUserId.c_str(), szPassword, time);
|
|
ne_md5_buffer(szMD5, szPassword);
|
|
|
|
char szAuth[256];
|
|
sprintf(szAuth, "%s%c%s%c%I64d", pcl->sUserId.c_str(), DELIMITER, szPassword, DELIMITER, time);
|
|
|
|
// Make header
|
|
COMMAND_STRUCT cmd;
|
|
memset(&cmd, NULL, sizeof(cmd));
|
|
|
|
sprintf(cmd.szTranId, "%04d%02d%02d-%.10s-%010I64d-%010I64d",
|
|
tmNow->tm_year, tmNow->tm_mon, tmNow->tm_wday, szVerifyKey, time, nRandom);
|
|
cmd.nMode = htonl(nCommand);
|
|
strcpy(cmd.szIssuer, SERVER_NAME);
|
|
if (pszServiceId)
|
|
strcpy(cmd.szServiceId, pszServiceId);
|
|
cmd.nLength = htonl((u_long)strlen(szAuth) + dwSendBodyLen);
|
|
|
|
|
|
#ifdef _OLD
|
|
#else
|
|
if (nCommand == 0x30 || nCommand == 0x12)
|
|
{
|
|
sprintf(pcl->nuri.host,"%s",pcl->sDomain2.c_str());
|
|
}
|
|
#endif
|
|
|
|
// char szPort[MAX_PATH]={0};
|
|
// char szPath[MAX_PATH]={0};
|
|
// GetCurrentPath(szPath);
|
|
// strcat(szPath,"\\");
|
|
//
|
|
// #ifdef _OPENDISK
|
|
// strcat(szPath,"OD-Console.ini");
|
|
// #else
|
|
// strcat(szPath,"KPClient.ini");
|
|
// #endif
|
|
//
|
|
// GetPrivateProfileString("CONNECT", "TRCPORT", "", szPort, MAX_PATH, szPath);
|
|
|
|
// #ifdef _OLD
|
|
// if (pcl->nuri.port == 80)
|
|
// {
|
|
// if (strlen(szPort) > 0)
|
|
// pcl->nuri.port = atol(szPort);
|
|
// else
|
|
// pcl->nuri.port = TRANSACTION_PORT;
|
|
// }
|
|
// #else
|
|
if ( nCommand == 0x12)
|
|
{
|
|
// if (strlen(szPort) > 0)
|
|
// pcl->nuri.port = atol(szPort);
|
|
// else
|
|
pcl->nuri.port = TRANSACTION_PORT;
|
|
}
|
|
// #endif
|
|
|
|
// Send packet
|
|
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
if (sock == INVALID_SOCKET) {
|
|
pcl->dwError = WSAGetLastError();
|
|
return false;
|
|
}
|
|
|
|
bool bRet = false;
|
|
|
|
DWORD dwWritten;
|
|
|
|
/* Elenoa: nonblock start */
|
|
// struct fd_set fs;
|
|
// struct timeval tv = { 3, 0 };
|
|
|
|
// memset(&fs, NULL, sizeof(fs));
|
|
|
|
// int nNonBlocking = 1;
|
|
// ioctlsocket(sock, FIONBIO, (u_long FAR*)&nNonBlocking);
|
|
/* Elenoa: nonblock end */
|
|
//#endif
|
|
|
|
char s[1024];
|
|
|
|
sockaddr_in sa;
|
|
sa.sin_family = AF_INET;
|
|
sa.sin_addr.s_addr = conv_addr(pcl->nuri.host);
|
|
sa.sin_port = htons(pcl->nuri.port);
|
|
|
|
// strTemp.Format("XXX CommLib : connect : %s, port= %d\n",inet_ntoa(sa.sin_addr),ntohs(sa.sin_port));
|
|
|
|
// OutputDebugString(strTemp);
|
|
|
|
int nNonBlocking = 1;
|
|
ioctlsocket(sock, FIONBIO, (u_long FAR*)&nNonBlocking);
|
|
|
|
if (connect(sock, (SOCKADDR*)&sa, sizeof(sa)) == SOCKET_ERROR)
|
|
{
|
|
if (WSAEWOULDBLOCK == WSAGetLastError())
|
|
{
|
|
fd_set wfd, efd;
|
|
struct timeval tv;
|
|
FD_ZERO(&wfd);
|
|
FD_ZERO(&efd);
|
|
FD_SET(sock, &wfd);
|
|
FD_SET(sock, &efd);
|
|
tv.tv_sec = SOCK_TIMEOUT;
|
|
tv.tv_usec = 0;
|
|
int nRecv = select(0, 0, &wfd, &efd,&tv);
|
|
if (SOCKET_ERROR == nRecv || 0 == nRecv)
|
|
{
|
|
pcl->dwError = WSAGetLastError();
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sprintf(s, "[%08d] %09d> connect() failed!!!(ERROR:%d) EXIT!!!!!\n", GetCurrentThreadId(), GetTickCount(), WSAGetLastError());
|
|
WriteFile(g_hFile, s, (DWORD)strlen(s), &dwWritten, NULL);
|
|
|
|
pcl->dwError = WSAGetLastError();
|
|
OutputDebugString("XXX CommLib : connect fail\n");
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
}
|
|
// OutputDebugString("XXX CommLib : connect complete\n");
|
|
|
|
// strTemp.Format("XXX CommLib : send : %s\n",inet_ntoa(sa.sin_addr));
|
|
// OutputDebugString(strTemp);
|
|
if (!_sh_send(sock, (char*)&cmd, sizeof(cmd))) {
|
|
sprintf(s, "[%08d] %09d> send1() failed!!!(ERROR:%d) EXIT!!!!!\n", GetCurrentThreadId(), GetTickCount(), WSAGetLastError());
|
|
WriteFile(g_hFile, s, (DWORD)strlen(s), &dwWritten, NULL);
|
|
|
|
pcl->dwError = WSAGetLastError();
|
|
OutputDebugString("XXX CommLib : send fail\n");
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
// OutputDebugString("XXX CommLib : send complete\n");
|
|
|
|
if (dwSendBodyLen > 0) {
|
|
DWORD dwAuthLen = (DWORD)strlen(szAuth);
|
|
|
|
char* pszBody = new char[dwAuthLen + dwSendBodyLen];
|
|
memcpy(pszBody, szAuth, dwAuthLen);
|
|
memcpy(pszBody + dwAuthLen, pSendBody, dwSendBodyLen);
|
|
|
|
// strTemp.Format("XXX CommLib : send : %s : %s\n",inet_ntoa(sa.sin_addr),pszBody);
|
|
// OutputDebugString(strTemp);
|
|
|
|
if (!_sh_send(sock, pszBody, dwAuthLen + dwSendBodyLen)) {
|
|
sprintf(s, "[%08d] %09d> send2() failed!!!(ERROR:%d) EXIT!!!!!\n", GetCurrentThreadId(), GetTickCount(), WSAGetLastError());
|
|
WriteFile(g_hFile, s, (DWORD)strlen(s), &dwWritten, NULL);
|
|
|
|
delete []pszBody;
|
|
|
|
pcl->dwError = WSAGetLastError();
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
delete []pszBody;
|
|
}
|
|
else if (!_sh_send(sock, szAuth, (int)strlen(szAuth))) {
|
|
sprintf(s, "[%08d] %09d> send2() failed!!!(ERROR:%d) EXIT!!!!!\n", GetCurrentThreadId(), GetTickCount(), WSAGetLastError());
|
|
WriteFile(g_hFile, s, (DWORD)strlen(s), &dwWritten, NULL);
|
|
|
|
pcl->dwError = WSAGetLastError();
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
strTemp.Format("XXX CommLib : recv : %s\n",inet_ntoa(sa.sin_addr));
|
|
OutputDebugString(strTemp);
|
|
if (!_sh_recv(sock, (char*)&cmd, sizeof(cmd))) {
|
|
sprintf(s, "[%08d] %09d> recv1() failed!!!(ERROR:%d) EXIT!!!!!\n", GetCurrentThreadId(), GetTickCount(), WSAGetLastError());
|
|
WriteFile(g_hFile, s, (DWORD)strlen(s), &dwWritten, NULL);
|
|
|
|
pcl->dwError = WSAGetLastError();
|
|
|
|
if (pcl->dwError == 0)
|
|
{
|
|
pcl->sError = "Recv 1 Fail : " + string((char*)&cmd);
|
|
}
|
|
|
|
OutputDebugString("XXXx CommLib : recv fail 1\n");
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
strTemp.Format("XXX CommLib : recv header...",inet_ntoa(sa.sin_addr));
|
|
OutputDebugString(strTemp);
|
|
// OutputDebugString("XXX CommLib : recv complete\n");
|
|
|
|
cmd.nResult = ntohl(cmd.nResult);
|
|
if (cmd.nResult != 0x1000)
|
|
{
|
|
OutputDebugString("XXX CommLib : Invalid cmd.Result\n");
|
|
if(cmd.nResult == 0)
|
|
pcl->dwError = WSAGetLastError();
|
|
else
|
|
pcl->dwError = cmd.nResult;
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
|
|
|
|
cmd.nLength = ntohl(cmd.nLength);
|
|
|
|
strTemp.Format(("ok11? BodyLen : %d "), cmd.nLength);
|
|
OutputDebugString(strTemp);
|
|
|
|
cmd.nLength;
|
|
if (ppRecvBody && cmd.nLength > 0) {
|
|
*pdwRecvBodyLen = cmd.nLength;
|
|
*ppRecvBody = new char[*pdwRecvBodyLen];
|
|
if (!(*ppRecvBody))
|
|
{
|
|
OutputDebugString("XXX CommLib : Mem Alloc Fail\n");
|
|
pcl->dwError = GetLastError();
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
strTemp.Format(("ok11? size : %d "), *pdwRecvBodyLen);
|
|
OutputDebugString(strTemp);
|
|
|
|
if (!_sh_recv(sock, (char*)*ppRecvBody, *pdwRecvBodyLen)) {
|
|
delete [](*ppRecvBody);
|
|
|
|
sprintf(s, "[%08d] %09d> recv2() failed!!!(ERROR:%d) EXIT!!!!!\n", GetCurrentThreadId(), GetTickCount(), WSAGetLastError());
|
|
WriteFile(g_hFile, s, (DWORD)strlen(s), &dwWritten, NULL);
|
|
|
|
OutputDebugString("XXX CommLib : recv fail 2\n");
|
|
pcl->dwError = WSAGetLastError();
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
strTemp.Format(("ok11? pdwRecvBodyLen : %s "), *ppRecvBody);
|
|
OutputDebugString(strTemp);
|
|
|
|
}
|
|
|
|
bRet = true;
|
|
|
|
EXIT_FUNCTION:
|
|
if (pcl->dwError > 0)
|
|
{
|
|
switch (pcl->dwError)
|
|
{
|
|
case 0x3000:
|
|
pcl->dwError = CLERRNO_ABNORMAL_RESPONSE;
|
|
break;
|
|
case 0x3001:
|
|
pcl->dwError = CLERRNO_AUTHORIZATION;
|
|
break;
|
|
case 0x9000:
|
|
pcl->dwError = CLERRNO_SERVICE;
|
|
break;
|
|
}
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
}
|
|
|
|
if (sock != INVALID_SOCKET)
|
|
closesocket(sock);
|
|
|
|
return bRet;
|
|
}
|
|
|
|
bool send(SOCKET s, LPCSTR pszBuf, int nLen)
|
|
{
|
|
int iSent = 0, nSentLen;
|
|
do {
|
|
nSentLen = send(s, pszBuf + iSent, nLen, 0);
|
|
|
|
iSent += nSentLen;
|
|
nLen -= nSentLen;
|
|
} while (nLen > 0 && nSentLen > 0);
|
|
|
|
return (nLen == 0);
|
|
}
|
|
|
|
bool recv(SOCKET s, LPSTR pszBuf, int nLen)
|
|
{
|
|
int iRecv = 0, nRecvLen;
|
|
do {
|
|
nRecvLen = recv(s, pszBuf + iRecv, nLen, 0);
|
|
|
|
iRecv += nRecvLen;
|
|
nLen -= nRecvLen;
|
|
} while (nLen > 0 && nRecvLen > 0);
|
|
|
|
return (nLen == 0);
|
|
}
|
|
|
|
static bool DoCommand(PCOMMLIB_STRUCT pcl, LPCSTR pszMethod, LPCSTR pszPath, LPCSTR pszHeaders, LPCSTR pszBody,
|
|
bool bParseBody, LPVOID pSTagParser, LPVOID pDataParser, LPVOID pETagParser, LPVOID pParam)
|
|
{
|
|
string sPath = pcl->nuri.path;
|
|
if (pszPath[0] != '/')
|
|
sPath += "/";
|
|
sPath += pszPath;
|
|
|
|
CString strMethod = pszMethod;
|
|
if(g_bWriteDirLog && strMethod == "MKCOL")
|
|
{
|
|
CString strLog;
|
|
strLog.Format(_T("Request creation directory : Host(\"%s\"), Method(\"%s\"), Path(\"%s\")\r\n"), pcl->nuri.host, strMethod, sPath.c_str());
|
|
cl_write_log((LPTSTR)(LPCTSTR)strLog, strLog.GetLength(), true);
|
|
}
|
|
|
|
bool bRet = false;
|
|
int nRet;
|
|
string sBody;
|
|
// CString strTemp;
|
|
|
|
// strTemp.Format("XXX CommLib : DoCommand %s - %s - %s - %s\n",pcl->nuri.host,pszMethod,pcl->nuri.path,pszPath);
|
|
// OutputDebugString(strTemp);
|
|
|
|
ne_request *pnreq = ne_request_create(pcl->pnsess, pszMethod, PathEncode(sPath.c_str()).c_str());
|
|
if (!pnreq) {
|
|
pcl->dwError = GetLastError();
|
|
pcl->sError = ne_get_error(pcl->pnsess);
|
|
OutputDebugString("XXX CommLib : Error : ne_request_create\n");
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
ne_add_request_header(pnreq, "Authorization", pcl->sDavAuth.c_str());
|
|
ne_add_request_header(pnreq, "Cache-Control", "no-cache");
|
|
if (pszHeaders && strlen(pszHeaders) > 0) {
|
|
string sHeaders = pszHeaders;
|
|
|
|
string::size_type stBegin = 0, stEnd = 0;
|
|
do {
|
|
stEnd = sHeaders.find(',', stBegin);
|
|
|
|
string sHeader = sHeaders.substr(stBegin, stEnd - stBegin);
|
|
|
|
string::size_type stDivider = sHeader.find('|');
|
|
ne_add_request_header(pnreq, sHeader.substr(0, stDivider).c_str(), sHeader.substr(stDivider + 1, sHeader.length()).c_str());
|
|
|
|
stBegin = stEnd + 1;
|
|
} while (stEnd != string::npos);
|
|
}
|
|
|
|
if (pszBody && strlen(pszBody) > 0)
|
|
ne_set_request_body_buffer(pnreq, pszBody, strlen(pszBody));
|
|
|
|
if (bParseBody)
|
|
ne_add_response_body_reader(pnreq, ne_accept_2xx, ResponseBodyReader, &sBody);
|
|
|
|
nRet = ne_request_dispatch(pnreq);
|
|
if (nRet != NE_OK)
|
|
{
|
|
pcl->dwError = nRet;
|
|
pcl->sError = ne_get_error(pcl->pnsess);
|
|
CString strTemp;
|
|
strTemp.Format("XXX CommLib : Error : ne_request_dispatch, Message : %s\r\n", pcl->sError.c_str());
|
|
OutputDebugString(strTemp);
|
|
|
|
if(g_bWriteDirLog && strMethod == "MKCOL")
|
|
cl_write_log((LPTSTR)(LPCTSTR)strTemp, strTemp.GetLength(), true);
|
|
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
ne_status* pnstat = (ne_status*)ne_get_status(pnreq);
|
|
if (pnstat->code != 0 && (pnstat->code < 200 || pnstat->code >= 300)) {
|
|
pcl->dwError = pnstat->code;
|
|
pcl->sError = ne_get_error(pcl->pnsess);
|
|
CString strTemp;
|
|
strTemp.Format("XXX CommLib : ne_get_status, Error : ne_get_status : %s\n",pcl->sError.c_str());
|
|
OutputDebugString(strTemp);
|
|
|
|
if(g_bWriteDirLog && strMethod == "MKCOL")
|
|
cl_write_log((LPTSTR)(LPCTSTR)strTemp, strTemp.GetLength(), true);
|
|
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
if (bParseBody) {
|
|
ReplaceAll(sBody, "&", "*amp;");
|
|
|
|
ne_xml_parser* pnxparser = ne_xml_create();
|
|
ne_xml_push_handler(pnxparser, (ne_xml_startelm_cb*)pSTagParser, (ne_xml_cdata_cb*)pDataParser, (ne_xml_endelm_cb*)pETagParser, pParam);
|
|
ne_xml_parse(pnxparser, sBody.c_str(), sBody.length());
|
|
ne_xml_destroy(pnxparser);
|
|
}
|
|
|
|
bRet = true;
|
|
|
|
if(g_bWriteDirLog && strMethod == "MKCOL")
|
|
{
|
|
CString strLog;
|
|
strLog.Format(_T("Response creation directory : Path(\"%s\"), Return code(%ld)\r\n"), sPath.c_str(), pcl->dwError);
|
|
cl_write_log((LPTSTR)(LPCTSTR)strLog, strLog.GetLength(), true);
|
|
}
|
|
|
|
EXIT_FUNCTION:
|
|
bool bError = false;
|
|
CString strErrorCode;
|
|
|
|
switch (pcl->dwError)
|
|
{
|
|
case 400:
|
|
bError = true;
|
|
strErrorCode = "CLERRNO_ABNORMAL_RESPONSE";
|
|
pcl->dwError = CLERRNO_ABNORMAL_RESPONSE;
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
break;
|
|
case 401:
|
|
bError = true;
|
|
strErrorCode = "CLERRNO_AUTHORIZATION";
|
|
pcl->dwError = CLERRNO_AUTHORIZATION;
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
break;
|
|
case 403:
|
|
bError = true;
|
|
strErrorCode = "CLERRNO_FORBIDDEN";
|
|
pcl->dwError = CLERRNO_FORBIDDEN;
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
break;
|
|
case 404:
|
|
bError = true;
|
|
strErrorCode = "CLERRNO_NOEXISTSFILE";
|
|
|
|
pcl->sRedirect = ne_get_response_header(pnreq, "Redirect") != NULL ? ne_get_response_header(pnreq, "Redirect") : "";
|
|
pcl->dwError = CLERRNO_NOEXISTSFILE;
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
break;
|
|
case 500:
|
|
bError = true;
|
|
strErrorCode = "CLERRNO_SERVICE";
|
|
pcl->dwError = CLERRNO_SERVICE;
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
break;
|
|
}
|
|
|
|
if(bError && g_bWriteDirLog && strMethod == "MKCOL")
|
|
{
|
|
CString strLog;
|
|
strLog.Format(_T("Error : %s(%ld), %s\r\n"), strErrorCode, pcl->dwError, pcl->sError.c_str());
|
|
cl_write_log((LPTSTR)(LPCTSTR)strLog, strLog.GetLength(), true);
|
|
}
|
|
|
|
if (pnreq)
|
|
ne_request_destroy(pnreq);
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL StartTransfer(PCOMMLIB_STRUCT pcl)
|
|
{
|
|
if (!pcl->hWaitEvent) {
|
|
pcl->hWaitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
if (!pcl->hWaitEvent) {
|
|
pcl->dwError = GetLastError();
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
pcl->hThread = CreateThread(NULL, 0, ThreadProc, pcl, 0, NULL);
|
|
if (!pcl->hThread) {
|
|
pcl->dwError = GetLastError();
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static DWORD WINAPI ThreadProc(LPVOID lpParam)
|
|
{
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)lpParam;
|
|
|
|
switch (pcl->uJob) {
|
|
case CLJOB_PUT:
|
|
/*
|
|
DoUpload(pcl);
|
|
*/
|
|
for (int i = 0; i < MAX_TRY; i++) {
|
|
pcl->hTranFile = NULL;
|
|
DoUpload(pcl);
|
|
if (pcl->hTranFile)
|
|
CloseHandle(pcl->hTranFile);
|
|
|
|
if (pcl->dwError != WSAETIMEDOUT || i == (MAX_TRY - 1))
|
|
break;
|
|
}
|
|
break;
|
|
case CLJOB_GET:
|
|
/*
|
|
DoDownload(pcl);
|
|
*/
|
|
for (int i = 0; i < MAX_TRY; i++) {
|
|
pcl->hTranFile = NULL;
|
|
DoDownload(pcl);
|
|
|
|
if (pcl->hTranFile)
|
|
{
|
|
SetFilePointerEx(pcl->hTranFile, (LARGE_INTEGER&)pcl->iTranPos, NULL, FILE_BEGIN);
|
|
SetEndOfFile(pcl->hTranFile);
|
|
CloseHandle(pcl->hTranFile);
|
|
}
|
|
|
|
if (pcl->dwError != WSAETIMEDOUT || i == (MAX_TRY - 1))
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (pcl->nTranStop == CLSTOP_BYUSER)
|
|
SetEvent(pcl->hWaitEvent);
|
|
|
|
pcl->proc(pcl->pParam, pcl->dwError != 0 ? -1 : 0);
|
|
|
|
CloseHandle(pcl->hThread);
|
|
pcl->hThread = NULL;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void DoUpload(PCOMMLIB_STRUCT pcl)
|
|
{
|
|
// 현재 URI 보관
|
|
bool bFindSource = true;
|
|
bool bSessionChange = false;
|
|
ne_uri nuri = pcl->nuri;
|
|
|
|
// 업로드 코드 시작
|
|
string sSrcObj, sDstObj;
|
|
int nRet, nWritePolicy;
|
|
__int64 nAvailQuota;
|
|
|
|
int iString = 0;
|
|
string::size_type stBegin = 0, stEnd = 0;
|
|
do {
|
|
stEnd = pcl->sJobParam.find('|', stBegin);
|
|
|
|
switch (iString++) {
|
|
case 0:
|
|
sSrcObj = pcl->sJobParam.substr(stBegin, stEnd - stBegin);
|
|
break;
|
|
case 1:
|
|
sDstObj = pcl->sJobParam.substr(stBegin, stEnd - stBegin);
|
|
break;
|
|
case 2:
|
|
nWritePolicy = atoi(pcl->sJobParam.substr(stBegin, stEnd - stBegin).c_str());
|
|
break;
|
|
case 3:
|
|
nAvailQuota = _atoi64(pcl->sJobParam.substr(stBegin, stEnd - stBegin).c_str());
|
|
break;
|
|
}
|
|
|
|
stBegin = stEnd + 1;
|
|
} while (stEnd != string::npos);
|
|
|
|
string sPath = pcl->nuri.path + sDstObj;
|
|
string sHeaders;
|
|
|
|
CString strPath = sPath.c_str();
|
|
|
|
ne_request *pnreq = NULL;
|
|
|
|
sPath = PathEncode(sPath.c_str());
|
|
|
|
pcl->hTranFile = CreateFile(sSrcObj.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
if (pcl->hTranFile == INVALID_HANDLE_VALUE) {
|
|
pcl->dwError = GetLastError();
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
return;
|
|
}
|
|
|
|
LARGE_INTEGER liFileSize, liFilePos = {0, 0};
|
|
if (!GetFileSizeEx(pcl->hTranFile, &liFileSize)) {
|
|
pcl->dwError = GetLastError();
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
if(g_bWriteUploadLog)
|
|
{
|
|
CString strLog;
|
|
strLog.Format(_T("Request Upload : Host(\"%s\"), Source(\"%s\" - %ld bytes), "), pcl->nuri.path, sSrcObj.c_str(), liFileSize);
|
|
cl_write_log((LPTSTR)(LPCTSTR)strLog, strLog.GetLength(), true);
|
|
|
|
strLog.Format(_T("Target(\"%s\")\r\n"), strPath);
|
|
cl_write_log((LPTSTR)(LPCTSTR)strLog, strLog.GetLength(), false);
|
|
|
|
}
|
|
|
|
if (nWritePolicy == CLWRITEPOLICY_OVERWRITE)
|
|
{
|
|
/*
|
|
sHeaders = "Overwrite|T";
|
|
*/
|
|
PCLFILE_STRUCT pclf = cl_get_file_list((HCOMMLIB)pcl, sDstObj.c_str(), 0, NULL);
|
|
if (pclf) {
|
|
cl_free_file_list((HCOMMLIB)pcl, pclf);
|
|
|
|
if (!cl_delete((HCOMMLIB)pcl, sDstObj.c_str()))
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
}
|
|
else if (nWritePolicy == CLWRITEPOLICY_APPEND) {
|
|
PCLFILE_STRUCT pclf = cl_get_file_list((HCOMMLIB)pcl, sDstObj.c_str(), 0, NULL);
|
|
if (pclf) {
|
|
if (liFileSize.QuadPart <= pclf->size) {
|
|
cl_free_file_list((HCOMMLIB)pcl, pclf);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
LARGE_INTEGER liNewPos;
|
|
liNewPos.QuadPart = pclf->size;
|
|
if (!SetFilePointerEx(pcl->hTranFile, liNewPos, &liFilePos, FILE_BEGIN)) {
|
|
cl_free_file_list((HCOMMLIB)pcl, pclf);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
/*
|
|
}
|
|
cl_free_file_list((HCOMMLIB)pcl, pclf);
|
|
|
|
if (liFilePos.QuadPart > 0) {
|
|
*/
|
|
char szRange[100];
|
|
sprintf(szRange, "bytes %I64d-%I64d/%I64d", liFilePos.QuadPart, liFileSize.QuadPart - 1, liFileSize.QuadPart);
|
|
|
|
sHeaders = "Content-Range|";
|
|
sHeaders += szRange;
|
|
|
|
if (strlen(pclf->source) > 7) {
|
|
bSessionChange = true;
|
|
ne_session_destroy(pcl->pnsess);
|
|
|
|
ne_uri_parse(pclf->source, &pcl->nuri);
|
|
|
|
if (pcl->nuri.path)
|
|
free(pcl->nuri.path);
|
|
pcl->nuri.path = strdup("/dav");
|
|
|
|
if (!pcl->nuri.scheme)
|
|
pcl->nuri.scheme = strdup("http");
|
|
|
|
if (pcl->nuri.port == 0)
|
|
pcl->nuri.port = 80;
|
|
|
|
pcl->pnsess = ne_session_create(pcl->nuri.scheme, pcl->nuri.host, pcl->nuri.port);
|
|
}
|
|
|
|
cl_free_file_list((HCOMMLIB)pcl, pclf);
|
|
|
|
bFindSource = false;
|
|
}
|
|
}
|
|
else {
|
|
PCLFILE_STRUCT pclf = cl_get_file_list((HCOMMLIB)pcl, sDstObj.c_str(), 0, NULL);
|
|
if (pclf) {
|
|
cl_free_file_list((HCOMMLIB)pcl, pclf);
|
|
|
|
pcl->dwError = CLERRNO_EXISTSFILE;
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
//cl_free_file_list((HCOMMLIB)pcl, pclf);
|
|
}
|
|
|
|
if ((UINT64)nAvailQuota < (UINT64)(liFileSize.QuadPart - liFilePos.QuadPart))
|
|
{
|
|
pcl->dwError = CLERRNO_NOAVAILQUOTA;
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
|
|
if(g_bWriteUploadLog)
|
|
{
|
|
CString strLog;
|
|
strLog.Format(_T("Error : %s(CLERRNO_NOAVAILQUOTA)\r\n"), pcl->sError.c_str());
|
|
cl_write_log((LPTSTR)(LPCTSTR)strLog, strLog.GetLength(), true);
|
|
}
|
|
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
if (bFindSource)
|
|
{
|
|
for (int i = 0; !bSessionChange && i < MAX_TRY; i++)
|
|
{
|
|
PCLFILE_STRUCT pclf = cl_get_file_list((HCOMMLIB)pcl, sDstObj.c_str(), 0, NULL);
|
|
if (pclf)
|
|
{
|
|
cl_free_file_list((HCOMMLIB)pcl, pclf);
|
|
pcl->dwError = CLERRNO_ABNORMAL_RESPONSE;
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
|
|
if(g_bWriteUploadLog)
|
|
{
|
|
CString strLog;
|
|
strLog.Format(_T("Error : %s(CLERRNO_ABNORMAL_RESPONSE)\r\n"), pcl->sError.c_str());
|
|
cl_write_log((LPTSTR)(LPCTSTR)strLog, strLog.GetLength(), true);
|
|
}
|
|
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
if (pcl->sRedirect == "")
|
|
break;
|
|
|
|
if (i > 0)
|
|
ne_uri_free(&pcl->nuri);
|
|
bSessionChange = true;
|
|
ne_session_destroy(pcl->pnsess);
|
|
|
|
ne_uri_parse(pcl->sRedirect.c_str(), &pcl->nuri);
|
|
|
|
if (!pcl->nuri.scheme)
|
|
pcl->nuri.scheme = strdup("http");
|
|
if (pcl->nuri.port == 0)
|
|
pcl->nuri.port = 80;
|
|
pcl->pnsess = ne_session_create(pcl->nuri.scheme, pcl->nuri.host, pcl->nuri.port);
|
|
if (i == (MAX_TRY - 1)) {
|
|
sHeaders = "Force|YES";
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
pnreq = ne_request_create(pcl->pnsess, "PUT", sPath.c_str());
|
|
if (!pnreq)
|
|
{
|
|
pcl->dwError = CLERRNO_UNDEFINED;
|
|
pcl->sError = ne_get_error(pcl->pnsess);
|
|
|
|
if(g_bWriteUploadLog)
|
|
{
|
|
CString strLog;
|
|
strLog.Format(_T("Error : %s(CLERRNO_UNDEFINED)\r\n"), pcl->sError.c_str());
|
|
cl_write_log((LPTSTR)(LPCTSTR)strLog, strLog.GetLength(), true);
|
|
}
|
|
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
ne_add_request_header(pnreq, "Authorization", pcl->sDavAuth.c_str());
|
|
if (sHeaders.length() > 0) {
|
|
stBegin = 0, stEnd = 0;
|
|
do {
|
|
stEnd = sHeaders.find(',', stBegin);
|
|
|
|
string sHeader = sHeaders.substr(stBegin, stEnd - stBegin);
|
|
|
|
string::size_type stDivider = sHeader.find('|');
|
|
ne_add_request_header(pnreq, sHeader.substr(0, stDivider).c_str(), sHeader.substr(stDivider + 1, sHeader.length()).c_str());
|
|
|
|
stBegin = stEnd + 1;
|
|
} while (stEnd != string::npos);
|
|
}
|
|
|
|
ne_set_request_body_provider64(pnreq, liFileSize.QuadPart - liFilePos.QuadPart, UploadProvider, pcl);
|
|
pcl->iTranPos = liFilePos.QuadPart;
|
|
pcl->nFileSize = liFileSize.QuadPart;
|
|
|
|
pcl->dwError = 0;
|
|
pcl->sError = "";
|
|
nRet = ne_request_dispatch(pnreq);
|
|
|
|
if (pcl->nTranStop == CLSTOP_NO)
|
|
{
|
|
if (nRet != NE_OK)
|
|
{
|
|
pcl->dwError = nRet;
|
|
pcl->sError = ne_get_error(pcl->pnsess);
|
|
|
|
if(g_bWriteUploadLog)
|
|
{
|
|
CString strLog;
|
|
strLog.Format(_T("Stop : %s(CLSTOP_NO)\r\n"), pcl->sError.c_str());
|
|
cl_write_log((LPTSTR)(LPCTSTR)strLog, strLog.GetLength(), true);
|
|
}
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
ne_status* pnstat = (ne_status*)ne_get_status(pnreq);
|
|
if (pnstat->code != 0 && (pnstat->code < 200 || pnstat->code >= 300))
|
|
{
|
|
pcl->dwError = pnstat->code;
|
|
pcl->sError = ne_get_error(pcl->pnsess);
|
|
|
|
if(g_bWriteUploadLog)
|
|
{
|
|
CString strLog;
|
|
strLog.Format(_T("Response Error : Code(%ld), Message(\"%s\")\r\n"), pcl->dwError, pcl->sError.c_str());
|
|
cl_write_log((LPTSTR)(LPCTSTR)strLog, strLog.GetLength(), true);
|
|
}
|
|
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
else
|
|
{
|
|
if(g_bWriteUploadLog)
|
|
{
|
|
CString strLog;
|
|
strLog.Format(_T("Response Success : Code(%ld)\r\n"), pnstat->code);
|
|
cl_write_log((LPTSTR)(LPCTSTR)strLog, strLog.GetLength(), true);
|
|
}
|
|
}
|
|
}
|
|
ne_end_request(pnreq);
|
|
|
|
EXIT_FUNCTION:
|
|
if (pcl->hTranFile) {
|
|
CloseHandle(pcl->hTranFile);
|
|
pcl->hTranFile = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
if (pnreq)
|
|
ne_request_destroy(pnreq);
|
|
|
|
if (bSessionChange) {
|
|
ne_uri_free(&pcl->nuri);
|
|
|
|
pcl->nuri = nuri;
|
|
pcl->pnsess = ne_session_create(pcl->nuri.scheme, pcl->nuri.host, pcl->nuri.port);
|
|
}
|
|
}
|
|
|
|
static void DoDownload(PCOMMLIB_STRUCT pcl)
|
|
{
|
|
string sSrcObj, sDstObj;
|
|
int nRet, nWritePolicy;
|
|
__int64 nAvailQuota;
|
|
|
|
int iString = 0;
|
|
string::size_type stBegin = 0, stEnd = 0;
|
|
do {
|
|
stEnd = pcl->sJobParam.find('|', stBegin);
|
|
|
|
switch (iString++) {
|
|
case 0:
|
|
sSrcObj = pcl->sJobParam.substr(stBegin, stEnd - stBegin);
|
|
break;
|
|
case 1:
|
|
sDstObj = pcl->sJobParam.substr(stBegin, stEnd - stBegin);
|
|
break;
|
|
case 2:
|
|
nWritePolicy = atoi(pcl->sJobParam.substr(stBegin, stEnd - stBegin).c_str());
|
|
break;
|
|
case 3:
|
|
nAvailQuota = _atoi64(pcl->sJobParam.substr(stBegin, stEnd - stBegin).c_str());
|
|
break;
|
|
}
|
|
|
|
stBegin = stEnd + 1;
|
|
} while (stEnd != string::npos);
|
|
|
|
string sPath = pcl->nuri.path + sSrcObj;
|
|
string sHeaders;
|
|
|
|
ne_request *pnreq = NULL;
|
|
|
|
sPath = PathEncode(sPath.c_str());
|
|
|
|
DWORD dwCreationDisposition = OPEN_ALWAYS;
|
|
DWORD dwAttr = GetFileAttributes(sDstObj.c_str());
|
|
if (nWritePolicy == CLWRITEPOLICY_NONE) {
|
|
if (dwAttr != INVALID_FILE_ATTRIBUTES || GetLastError() != ERROR_FILE_NOT_FOUND) {
|
|
pcl->dwError = CLERRNO_EXISTSFILE;
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
return;
|
|
}
|
|
dwCreationDisposition = CREATE_NEW;
|
|
}
|
|
else {
|
|
if (dwAttr != INVALID_FILE_ATTRIBUTES) {
|
|
if (dwAttr & FILE_ATTRIBUTE_DIRECTORY) {
|
|
if (nWritePolicy == CLWRITEPOLICY_OVERWRITE) {
|
|
if (!DeleteDirectory(sDstObj.c_str())) {
|
|
pcl->dwError = GetLastError();
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
return;
|
|
}
|
|
}
|
|
else {
|
|
pcl->dwError = CLERRNO_EXISTSFILE;
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
}
|
|
}
|
|
else {
|
|
if (nWritePolicy == CLWRITEPOLICY_OVERWRITE)
|
|
dwCreationDisposition = TRUNCATE_EXISTING;
|
|
}
|
|
}
|
|
}
|
|
|
|
PCLFILE_STRUCT pclf = cl_get_file_list((HCOMMLIB)pcl, sSrcObj.c_str(), 0, NULL);
|
|
if (!pclf) {
|
|
cl_free_file_list((HCOMMLIB)pcl, pclf);
|
|
return;
|
|
}
|
|
|
|
LARGE_INTEGER liFilePos = {0, 0};
|
|
|
|
if (pcl->hTranFile == NULL)
|
|
{
|
|
pcl->hTranFile = CreateFile(sDstObj.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
if (pcl->hTranFile == INVALID_HANDLE_VALUE) {
|
|
pcl->dwError = GetLastError();
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
pcl->nExFileSize=0;
|
|
GetFileSizeEx(pcl->hTranFile,(LARGE_INTEGER*)&pcl->nExFileSize);
|
|
|
|
if (pcl->nExFileSize >= pclf->size) {
|
|
pcl->dwError = 0;
|
|
pcl->sError = "";
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
LARGE_INTEGER new_size;
|
|
new_size.QuadPart=pclf->size;
|
|
SetFilePointerEx(pcl->hTranFile,new_size,NULL, FILE_BEGIN);
|
|
SetEndOfFile(pcl->hTranFile);
|
|
new_size.QuadPart=0;
|
|
SetFilePointerEx(pcl->hTranFile,new_size,NULL, FILE_BEGIN);
|
|
}
|
|
|
|
if (nWritePolicy == CLWRITEPOLICY_APPEND) {
|
|
LARGE_INTEGER liNewPos;
|
|
liNewPos.QuadPart = 0;
|
|
|
|
if (!SetFilePointerEx(pcl->hTranFile, (LARGE_INTEGER&)pcl->nExFileSize, &liFilePos, FILE_BEGIN)) {
|
|
pcl->dwError = GetLastError();
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
char szRange[100];
|
|
|
|
sprintf(szRange, "bytes=%I64d-%I64d", liFilePos.QuadPart, pclf->size);
|
|
sHeaders += "Range|";
|
|
sHeaders += szRange;
|
|
sHeaders += ",Accept-Ranges|bytes";
|
|
}
|
|
|
|
if ((UINT64)nAvailQuota < (UINT64)(pclf->size - liFilePos.QuadPart)) {
|
|
pcl->dwError = CLERRNO_NOAVAILQUOTA;
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
pnreq = ne_request_create(pcl->pnsess, "GET", sPath.c_str());
|
|
if (!pnreq) {
|
|
pcl->dwError = CLERRNO_UNDEFINED;
|
|
pcl->sError = ne_get_error(pcl->pnsess);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
ne_add_request_header(pnreq, "Authorization", pcl->sDavAuth.c_str());
|
|
if (sHeaders.length() > 0) {
|
|
stBegin = 0, stEnd = 0;
|
|
do {
|
|
stEnd = sHeaders.find(',', stBegin);
|
|
|
|
string sHeader = sHeaders.substr(stBegin, stEnd - stBegin);
|
|
|
|
string::size_type stDivider = sHeader.find('|');
|
|
ne_add_request_header(pnreq, sHeader.substr(0, stDivider).c_str(), sHeader.substr(stDivider + 1, sHeader.length()).c_str());
|
|
|
|
stBegin = stEnd + 1;
|
|
} while (stEnd != string::npos);
|
|
}
|
|
|
|
ne_add_response_body_reader(pnreq, ne_accept_2xx, DownloadProvider, pcl);
|
|
pcl->iTranPos = liFilePos.QuadPart;
|
|
pcl->nFileSize = pclf->size;
|
|
|
|
pcl->dwError = 0;
|
|
pcl->sError = "";
|
|
|
|
nRet = ne_request_dispatch(pnreq);
|
|
if (pcl->nTranStop == CLSTOP_NO) {
|
|
if (nRet != NE_OK) {
|
|
pcl->dwError = nRet;
|
|
pcl->sError = ne_get_error(pcl->pnsess);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
ne_status* pnstat = (ne_status*)ne_get_status(pnreq);
|
|
if (pnstat->code != 0 && (pnstat->code < 200 || pnstat->code >= 300)) {
|
|
pcl->dwError = pnstat->code;
|
|
pcl->sError = ne_get_error(pcl->pnsess);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
}
|
|
ne_end_request(pnreq);
|
|
|
|
EXIT_FUNCTION:
|
|
cl_free_file_list((HCOMMLIB)pcl, pclf);
|
|
/*
|
|
if (pcl->hTranFile) {
|
|
CloseHandle(pcl->hTranFile);
|
|
pcl->hTranFile = INVALID_HANDLE_VALUE;
|
|
}
|
|
*/
|
|
string sRedirection;
|
|
if (pnreq) {
|
|
const char *pszLocation = ne_get_response_header(pnreq, "Location");
|
|
if (pszLocation)
|
|
sRedirection = pszLocation;
|
|
ne_request_destroy(pnreq);
|
|
}
|
|
|
|
// Redirection
|
|
if (pcl->dwError == 301 && sRedirection != "") {
|
|
if (nWritePolicy == CLWRITEPOLICY_NONE) {
|
|
pcl->sJobParam = sSrcObj;
|
|
pcl->sJobParam += "|";
|
|
|
|
pcl->sJobParam += sDstObj;
|
|
pcl->sJobParam += "|";
|
|
|
|
char szTemp[100];
|
|
sprintf(szTemp, "%d", CLWRITEPOLICY_OVERWRITE);
|
|
pcl->sJobParam += szTemp;
|
|
pcl->sJobParam += "|";
|
|
|
|
sprintf(szTemp, "%I64d", nAvailQuota);
|
|
pcl->sJobParam += szTemp;
|
|
}
|
|
|
|
ne_session_destroy(pcl->pnsess);
|
|
ne_uri nuri = pcl->nuri;
|
|
|
|
// 지정된 곳으로 접속
|
|
ne_uri_parse(sRedirection.c_str(), &pcl->nuri);
|
|
|
|
if (!pcl->nuri.scheme)
|
|
pcl->nuri.scheme = strdup("http");
|
|
|
|
if (pcl->nuri.port == 0)
|
|
pcl->nuri.port = 80;
|
|
|
|
strcpy(pcl->nuri.path, nuri.path);
|
|
|
|
pcl->pnsess = ne_session_create(pcl->nuri.scheme, pcl->nuri.host, pcl->nuri.port);
|
|
|
|
DoDownload(pcl);
|
|
|
|
// 원래 서버로 재접속
|
|
ne_uri_free(&pcl->nuri);
|
|
ne_session_destroy(pcl->pnsess);
|
|
|
|
pcl->nuri = nuri;
|
|
pcl->pnsess = ne_session_create(pcl->nuri.scheme, pcl->nuri.host, pcl->nuri.port);
|
|
}
|
|
}
|
|
|
|
static int ResponseBodyReader(void* userdata, const char* buf, size_t len)
|
|
{
|
|
if (len == 0)
|
|
return 0;
|
|
|
|
string* psBody = (string*)userdata;
|
|
|
|
char* pszTemp = new char[len + 1];
|
|
memcpy(pszTemp, buf, len);
|
|
pszTemp[len] = NULL;
|
|
|
|
(*psBody) += pszTemp;
|
|
|
|
delete []pszTemp;
|
|
|
|
return NE_OK;
|
|
}
|
|
|
|
|
|
#define TERM_TICKCOUNT 500
|
|
|
|
static ssize_t UploadProvider(void *userdata, char *buffer, size_t buflen)
|
|
{
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)userdata;
|
|
|
|
if (buflen == 0)
|
|
return 0;
|
|
|
|
if (pcl->nTranStop == CLSTOP_BYUSER) {
|
|
pcl->proc(pcl->pParam, pcl->iTranPos);
|
|
return -1;
|
|
}
|
|
|
|
DWORD dwRead;
|
|
|
|
if (!ReadFile(pcl->hTranFile, buffer, (DWORD)buflen, &dwRead, NULL)) {
|
|
pcl->nTranStop = CLSTOP_BYERROR;
|
|
|
|
pcl->dwError = GetLastError();
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
return -1;
|
|
}
|
|
|
|
pcl->iTranPos += dwRead;
|
|
|
|
if (GetTickCount() > pcl->dwOldTick + TERM_TICKCOUNT || pcl->iTranPos >= pcl->nFileSize) {
|
|
pcl->proc(pcl->pParam, pcl->iTranPos);
|
|
pcl->dwOldTick = GetTickCount();
|
|
}
|
|
return dwRead;
|
|
}
|
|
|
|
static int DownloadProvider(void* userdata, const char* buf, size_t len)
|
|
{
|
|
/*
|
|
if (rand()%2)
|
|
Sleep(50);
|
|
return 0;*/
|
|
|
|
PCOMMLIB_STRUCT pcl = (PCOMMLIB_STRUCT)userdata;
|
|
|
|
if (len == 0)
|
|
return 0;
|
|
|
|
if (pcl->nTranStop == CLSTOP_BYUSER) {
|
|
pcl->proc(pcl->pParam, pcl->iTranPos);
|
|
return 1;
|
|
}
|
|
|
|
DWORD dwWritten, dwTotal = 0;
|
|
do {
|
|
if (!WriteFile(pcl->hTranFile, buf + dwTotal, (DWORD)len - dwTotal, &dwWritten, NULL)) {
|
|
pcl->nTranStop = CLSTOP_BYERROR;
|
|
|
|
pcl->dwError = GetLastError();
|
|
pcl->sError = GetErrorMessage(pcl->dwError);
|
|
return 1;
|
|
}
|
|
|
|
dwTotal += dwWritten;
|
|
} while (dwTotal < len);
|
|
|
|
pcl->iTranPos += dwTotal;
|
|
|
|
if (GetTickCount() > pcl->dwOldTick + TERM_TICKCOUNT || pcl->iTranPos >= pcl->nFileSize) {
|
|
pcl->proc(pcl->pParam, pcl->iTranPos);
|
|
pcl->dwOldTick = GetTickCount();
|
|
}
|
|
|
|
return NE_OK;
|
|
}
|
|
|
|
|
|
static int FileListSTagParser(void *userdata, int parent, const char *nspace, const char *name, const char **atts)
|
|
{
|
|
PCLFILELIST_PARSER_STRUCT pclflp = (PCLFILELIST_PARSER_STRUCT)userdata;
|
|
|
|
if (strcmp(name, "response") == 0) {
|
|
pclflp->pclf = new CLFILE_STRUCT;
|
|
memset(pclflp->pclf, NULL, sizeof(CLFILE_STRUCT));
|
|
}
|
|
else if (strcmp(name, "href") == 0) {
|
|
pclflp->nTag = CLFLTAG_PATH;
|
|
}
|
|
else if (strcmp(name, "collection") == 0) {
|
|
pclflp->pclf->attr = CLFILEATTR_FOLDER;
|
|
}
|
|
else if (strcmp(name, "getcontentlength") == 0) {
|
|
pclflp->nTag = CLFLTAG_SIZE;
|
|
}
|
|
else if (strcmp(name, "getlastmodified") == 0) {
|
|
pclflp->nTag = CLFLTAG_LASTMODIFIED;
|
|
}
|
|
// else if (strcmp(name, "xxx") == 0) {
|
|
// pclflp->nTag = CLFLTAG_MIMETYPE;
|
|
// }
|
|
else if (strcmp(name, "source") == 0) {
|
|
pclflp->nTag = CLFLTAG_SOURCE;
|
|
}
|
|
else {
|
|
pclflp->nTag = CLFLTAG_UNKNOWN;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int FileListDataParser(void *userdata, int state, const char *data, size_t len)
|
|
{
|
|
PCLFILELIST_PARSER_STRUCT pclflp = (PCLFILELIST_PARSER_STRUCT)userdata;
|
|
|
|
switch (pclflp->nTag) {
|
|
case CLFLTAG_PATH:
|
|
if (!pclflp->pclf->path[0]) {
|
|
if (len >= pclflp->nRootPathLen) {
|
|
int nPathLen = (int)len - pclflp->nRootPathLen;
|
|
char szPath[PATH_SIZE];
|
|
memcpy(szPath, data + pclflp->nRootPathLen, nPathLen);
|
|
szPath[nPathLen - (nPathLen > 1 && szPath[nPathLen - 1] == '/' ? 1 : 0)] = NULL;
|
|
|
|
string sPath = PathDecode(szPath).c_str();
|
|
strcpy(pclflp->pclf->path, sPath.c_str());
|
|
}
|
|
else {
|
|
strcpy(pclflp->pclf->path, "*myself*");
|
|
}
|
|
}
|
|
break;
|
|
case CLFLTAG_TYPE:
|
|
break;
|
|
case CLFLTAG_SIZE:
|
|
if (isdigit(data[0])) {
|
|
char szSize[20];
|
|
memcpy(szSize, data, len);
|
|
szSize[len] = NULL;
|
|
|
|
pclflp->pclf->size = _atoi64(szSize);
|
|
}
|
|
break;
|
|
case CLFLTAG_LASTMODIFIED:
|
|
if (!pclflp->pclf->lastModified[0]) {
|
|
char szTime[30];
|
|
memcpy(szTime, data, len);
|
|
szTime[len] = NULL;
|
|
|
|
string sTime = ConvertTimeFormat(szTime);
|
|
strcpy(pclflp->pclf->lastModified, sTime.c_str());
|
|
}
|
|
break;
|
|
// case CLFLTAG_MIMETYPE:
|
|
// if (!pclflp->pclf->mimeType) {
|
|
// pclflp->pclf->mimeType = new char[len + 1];
|
|
// memcpy(pclflp->pclf->mimeType, data, len);
|
|
// pclflp->pclf->mimeType[len] = NULL;
|
|
// }
|
|
// break;
|
|
case CLFLTAG_SOURCE:
|
|
if (!pclflp->pclf->source[0]) {
|
|
char szSource[PATH_SIZE];
|
|
memcpy(szSource, data, len);
|
|
szSource[len] = NULL;
|
|
|
|
strcpy(pclflp->pclf->source, szSource);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int FileListETagParser(void *userdata, int state, const char *nspace, const char *name)
|
|
{
|
|
PCLFILELIST_PARSER_STRUCT pclflp = (PCLFILELIST_PARSER_STRUCT)userdata;
|
|
|
|
if (strcmp(name, "response") == 0) {
|
|
if (pclflp->pclf)
|
|
pclflp->vec.push_back(pclflp->pclf);
|
|
|
|
pclflp->pclf = NULL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static string GetErrorMessage(DWORD dwError)
|
|
{
|
|
string sError;
|
|
|
|
if (dwError >= CLERRNO_UNDEFINED && dwError <= CLERRNO_MAX) {
|
|
char szError[1000];
|
|
::LoadString(g_hInst, dwError, szError, sizeof(szError));
|
|
|
|
sError = szError;
|
|
}
|
|
else {
|
|
LPVOID lpError;
|
|
|
|
if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpError, 0, NULL))
|
|
sError = "알 수 없는 오류입니다.";
|
|
else
|
|
sError = (LPCSTR)lpError;
|
|
|
|
LocalFree(lpError);
|
|
}
|
|
|
|
return sError;
|
|
}
|
|
|
|
#define BUFFER_SIZE 1024
|
|
|
|
static string PathEncode(LPCSTR pszPath)
|
|
{
|
|
if (pszPath[0] == '/')
|
|
pszPath += 1;
|
|
|
|
string sRetPath = "";
|
|
string sSrcPath = pszPath;
|
|
|
|
string::size_type stBegin = 0, stEnd = 0;
|
|
do {
|
|
stEnd = sSrcPath.find('/', stBegin);
|
|
|
|
sRetPath += "/" + URLEncode(sSrcPath.substr(stBegin, stEnd - stBegin).c_str());
|
|
|
|
stBegin = stEnd + 1;
|
|
} while (stEnd != std::string::npos);
|
|
|
|
return sRetPath;
|
|
}
|
|
|
|
static string PathDecode(LPCSTR pszPath)
|
|
{
|
|
if (pszPath[0] == '/')
|
|
pszPath += 1;
|
|
|
|
string sRetPath = "";
|
|
string sSrcPath = pszPath;
|
|
|
|
string::size_type stBegin = 0, stEnd = 0;
|
|
do {
|
|
stEnd = sSrcPath.find('/', stBegin);
|
|
|
|
sRetPath += "/" + URLDecode(sSrcPath.substr(stBegin, stEnd - stBegin).c_str());
|
|
|
|
stBegin = stEnd + 1;
|
|
} while (stEnd != std::string::npos);
|
|
|
|
ReplaceAll(sRetPath, "*amp;", "&");
|
|
|
|
return sRetPath;
|
|
}
|
|
|
|
static string URLEncode(LPCSTR pszURL)
|
|
{
|
|
char szEncoded[MAX_PATH << 1];
|
|
char* pszEncoded = szEncoded;
|
|
|
|
while (*pszURL != NULL) {
|
|
if ((*pszURL >= 'a' && *pszURL <= 'z') || (*pszURL >= 'A' && *pszURL <= 'Z')
|
|
|| (*pszURL >= '0' && *pszURL <= '9') || *pszURL == '/')
|
|
*pszEncoded = (char)*pszURL;
|
|
else {
|
|
*pszEncoded++ = '%';
|
|
|
|
char szBuf[10];
|
|
sprintf(szBuf, "%02X", *pszURL);
|
|
int nBufLen = (int)strlen(szBuf);
|
|
*pszEncoded++ = szBuf[nBufLen - 2];
|
|
*pszEncoded = szBuf[nBufLen - 1];
|
|
}
|
|
|
|
pszEncoded++;
|
|
pszURL++;
|
|
}
|
|
*pszEncoded = NULL;
|
|
|
|
string sRet = szEncoded;
|
|
|
|
return sRet;
|
|
}
|
|
|
|
static string URLDecode(LPCSTR pszURL)
|
|
{
|
|
char szOut[BUFFER_SIZE], szHex[3];
|
|
|
|
ZeroMemory(szOut, sizeof(szOut));
|
|
|
|
for (int i = 0, j = 0; pszURL[i]; i++, j++) {
|
|
// if (pszURL[i] == '+')
|
|
// szOut[j] = ' ';
|
|
// else if (pszURL[i] == '%') {
|
|
if (pszURL[i] == '%') {
|
|
szHex[0] = pszURL[++i];
|
|
szHex[1] = pszURL[++i];
|
|
szHex[2] = 0;
|
|
sscanf((char *)szHex, "%x", &szOut[j]);
|
|
} else {
|
|
szOut[j] = pszURL[i];
|
|
}
|
|
}
|
|
|
|
string sRet = szOut;
|
|
|
|
return sRet;
|
|
}
|
|
|
|
|
|
static BOOL DeleteDirectory(LPCSTR pszDirectory)
|
|
{
|
|
string sDirectory = pszDirectory;
|
|
sDirectory += "\\*";
|
|
|
|
WIN32_FIND_DATA w32fd;
|
|
|
|
HANDLE hFindFile = FindFirstFile(sDirectory.c_str(), &w32fd);
|
|
while (hFindFile != INVALID_HANDLE_VALUE) {
|
|
if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
|
if (w32fd.cFileName[0] != '.') {
|
|
if (!DeleteDirectory(w32fd.cFileName))
|
|
return false;
|
|
}
|
|
}
|
|
else {
|
|
if (!DeleteFile(w32fd.cFileName))
|
|
return false;
|
|
}
|
|
|
|
if (!FindNextFile(hFindFile, &w32fd))
|
|
break;
|
|
}
|
|
|
|
FindClose(hFindFile);
|
|
|
|
return RemoveDirectory(pszDirectory);
|
|
}
|
|
|
|
|
|
// format : Thu, 15 Dec 2005 05:22:33 GMT
|
|
static string ConvertTimeFormat(LPCSTR pszTime)
|
|
{
|
|
string sTime;
|
|
|
|
// RFC1123_FORMAT to time_t format & GMT+9(32400 sec)
|
|
// "Thu, 15 Dec 2005 05:22:33 GMT" 이런 형태를 RFC1122_FORMAT 이라한다.
|
|
// RFC1122_FORMAT 포맷을 인자로 넘겨서 time_t를 얻을 수 있었고,
|
|
// 얻은 값에다가 9시간에 해당하는 sec를 더해서 GMT+9를 구한다.
|
|
time_t t = ne_rfc1123_parse(pszTime) + 32400;
|
|
|
|
// time_t to struct tm
|
|
// 위 과정에서 이미 GMT+9가 처리되었으므로,
|
|
// 기존 소스처럼 복잡한 과정을 거치지 않아도 된다.
|
|
// 단지 time_t 값을 속성을 알고 year에 1900을 mon1을 더해준다.
|
|
struct tm stm;
|
|
stm = *gmtime(&t);
|
|
stm.tm_year = stm.tm_year + 1900;
|
|
stm.tm_mon = stm.tm_mon + 1;
|
|
|
|
// 최종적으로 표현하고자 하는 날짜 포맷으로 변경처리한다.
|
|
char szTemp[20];
|
|
sprintf(szTemp, "%04d-%02d-%02d ", stm.tm_year, stm.tm_mon, stm.tm_mday);
|
|
sTime = szTemp;
|
|
sprintf(szTemp, " %02d:%02d:%02d", stm.tm_hour, stm.tm_min, stm.tm_sec);
|
|
sTime += szTemp;
|
|
|
|
return sTime;
|
|
}
|
|
|
|
static void ReplaceAll(string& sValue, LPCSTR pszOld, LPCSTR pszNew)
|
|
{
|
|
string sOld = pszOld;
|
|
string sNew = pszNew;
|
|
|
|
size_t s;
|
|
while ((s = sValue.find(sOld)) != string::npos)
|
|
sValue.replace(s, sOld.length(), sNew);
|
|
}
|
|
|
|
int GetCurrentPath(char* pszPath)
|
|
{
|
|
char szPath[MAX_PATH*2]={0};
|
|
char* pData;
|
|
|
|
GetModuleFileName(NULL,szPath,MAX_PATH);
|
|
|
|
pData = strrchr(szPath,'\\');
|
|
|
|
__w64 int len = pData-szPath;
|
|
strncpy(pszPath,szPath,len);
|
|
pszPath[len] = 0; //cause wcsncpy does not appent null character
|
|
return (int)len;
|
|
}
|
|
|
|
static int _sh_send(SOCKET s, char *pszBuf, int nLen)
|
|
{
|
|
int iSent = 0, nSentLen;
|
|
fd_set wset;
|
|
struct timeval tv;
|
|
|
|
FD_ZERO(&wset);
|
|
FD_SET(s, &wset);
|
|
tv.tv_sec = SOCK_TIMEOUT;
|
|
tv.tv_usec = 0;
|
|
do {
|
|
if (select(static_cast<int>(s + 1), NULL, &wset, NULL, &tv) < 0) break;
|
|
if (!FD_ISSET(s, &wset)) break;
|
|
|
|
nSentLen = send(s, pszBuf + iSent, nLen, 0);
|
|
|
|
iSent += nSentLen;
|
|
nLen -= nSentLen;
|
|
} while (nLen > 0 && nSentLen > 0);
|
|
|
|
return nLen > 0 ? SOCKET_ERROR : iSent;
|
|
}
|
|
|
|
static int _sh_recv(SOCKET s, char *pszBuf, int nLen)
|
|
{
|
|
int iRecv = 0, nRecvLen;
|
|
fd_set rset;
|
|
struct timeval tv;
|
|
int nRet;
|
|
|
|
FD_ZERO(&rset);
|
|
FD_SET(s, &rset);
|
|
tv.tv_sec = SOCK_TIMEOUT;
|
|
tv.tv_usec = 0;
|
|
do {
|
|
nRet = select(static_cast<int>(s + 1), &rset, NULL, NULL, &tv);
|
|
|
|
if (nRet <= 0)
|
|
{
|
|
break;
|
|
}
|
|
if (!FD_ISSET(s, &rset)) break;
|
|
|
|
nRecvLen = recv(s, pszBuf + iRecv, nLen, 0);
|
|
|
|
iRecv += nRecvLen;
|
|
nLen -= nRecvLen;
|
|
} while (nLen > 0 && nRecvLen > 0);
|
|
|
|
CString strTemp;
|
|
strTemp.Format(_T("received : %d"),iRecv);
|
|
OutputDebugString(strTemp);
|
|
|
|
return nLen < 0 ? SOCKET_ERROR : iRecv;
|
|
}
|
|
|