Files
interactive/application/sp-console(down)/CommLib/CommLib.cpp
2026-08-07 17:38:18 +09:00

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;", "*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;
}