Files
interactive/gms/SKBB/sdkfreebsd64/SHCSDK.cpp.bak
T
2026-08-07 17:38:18 +09:00

2695 lines
60 KiB
Plaintext

// SHCSDK.cpp : DLL 응용 프로그램에 대한 진입점을 정의합니다.
//
#ifdef WIN32
#include <windows.h>
#include <io.h>
#include <math.h>
#include <vector>
#include <iostream>
#include "atlstr.h"
#else
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <netdb.h>
#include <errno.h>
#include <asm/param.h> // for HZ
typedef int BOOL;
typedef void* LPVOID;
typedef char* LPSTR;
typedef const char* LPCSTR;
typedef unsigned int UINT;
typedef unsigned int DWORD;
typedef unsigned int* LPDWORD;
typedef unsigned long long UINT64;
typedef int SOCKET;
typedef int __int32;
typedef long long __int64;
typedef struct sockaddr SOCKADDR;
#define closesocket(a) close(a)
#define FALSE 0
#define TRUE 1
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define _O_CREAT O_CREAT
#define _O_TRUNC O_TRUNC
#define _O_APPEND O_APPEND
#define _O_RDONLY O_RDONLY
#define _O_WRONLY O_WRONLY
#define _O_BINARY 0
#define _O_RANDOM 0
#define _S_IFDIR S_IFDIR
#define _lseeki64 lseek64
#define _stati64 stat64
#endif
#include <fcntl.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string>
#include <vector>
#include <set>
#include "SHCSDK.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_md5.h"
#ifdef WIN32
# pragma comment(lib, "ws2_32.lib")
#endif
#define MAX_TRY 3
#define PRIVATE_KEY "gE\x8bk\xc6\x23{2i\x98<dsH3f"
#define DEFAULT_SESSIONID "ANONYMOUS0123456"
#define DEFAULT_EXPIRE_TIME 75
using namespace std;
typedef vector<PSHFILE_STRUCT> VECTOR_SHFILELIST, *PVECTOR_SHFILELIST;
typedef struct SHCSDK_HANDLE {
ne_session* pnsess;
ne_uri nuri;
string sPath;
string sAuth;
bool bWorking;
sh_callback proc;
void* pParam;
int nError;
string sError;
#ifdef WIN32
HANDLE hFile;
#else
int nFileDesc;
#endif
INT64 iFilePos;
INT64 nFileSize;
clock_t cOldTick;
int nTranStop;
string sRedirect;
long nSpeedLimit;
clock_t starttick;
PVECTOR_SHFILELIST pvecshfl;
set<PVECTOR_SHFILELIST> setFileList;
string sSessionID;
int nAuthExpire;
} SHCSDK_STRUCT, *PSHCSDK_STRUCT;
enum {
SHSTOP_NO = 0,
SHSTOP_BYUSER,
SHSTOP_BYERROR,
};
#ifdef WIN32
static bool DoCommand(PSHCSDK_STRUCT psdk, LPCSTR pszService, int nCommand, LPVOID pSendBody, DWORD dwSendBodyLen, LPVOID* ppRecvBody, LPDWORD pdwRecvBodyLen);
#endif
static bool DoCommand(PSHCSDK_STRUCT psdk, 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 bool DoUpload(PSHCSDK_STRUCT psdk, LPCSTR pszSrcFile, LPCSTR pszDstFile, int nWritePolicy, INT64 nAvailQuota);
static ssize_t UploadProvider(void *userdata, char *buffer, size_t buflen);
static bool DoDownload(PSHCSDK_STRUCT psdk, LPCSTR pszSrcFile, LPCSTR pszDstFile, int nWritePolicy, INT64 nAvailQuota);
static bool DoDownloadBuffer(PSHCSDK_STRUCT psdk, LPCSTR pszSrcFile,
int (*data_func)(
void* userval,
const char* buf,
size_t len),
void* userval
);
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 void FreeFileListVector(PVECTOR_SHFILELIST pvec);
static string GetErrorMessage(int nError);
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 FormatLastModified(LPCSTR pszTime);
static bool ParseSntpString(LPCSTR pszTime, struct tm* ptm);
static void ReplaceAll(string& sValue, LPCSTR pszOld, LPCSTR pszNew);
static int _sh_recv(SOCKET s, char *pszBuf, int nLen);
#ifndef WIN32
int GetLastError();
void SetLastError(int nError);
#endif
static INT64 sh_filelength(int nFd);
static INT64 sh_atoi(LPCSTR pszSize);
static BOOL check_suthstring(const char* pszAuthstring);
static int _sh_recv(SOCKET s, char *pszBuf, int nLen);
void tea_encrypt(char *buf, int len);
void tea_decrypt(char *buf, int len);
char* get_auth_str(PSHCSDK_STRUCT psdk, LPCSTR pszPath);
#ifdef WIN32
void WriteLogToFile(char* pdata);
void MyOutputDebugString(char* fmt,...);
#else
#define WriteLogToFile(...)
#define MyOutputDebugString(...)
#endif
static int timeout = 5;
#ifdef WIN32
static int __nonblock_win32(SOCKET s)
{
int ul = 1;
int result;
result = ioctlsocket( s, FIONBIO, (u_long FAR*)&ul );
return result;
}
#else
static int __nonblock(int fd)
{
int result;
int flags;
flags = fcntl(fd, F_GETFL, 0);
result = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
return result;
}
#endif
typedef struct {
int nTag;
UINT nRootPathLen;
PSHFILE_STRUCT pshf;
PVECTOR_SHFILELIST pvec;
} SHFILELIST_PARSER_STRUCT, *PSHFILELIST_PARSER_STRUCT;
enum {
SHFLTAG_UNKNOWN = 0,
SHFLTAG_PATH,
SHFLTAG_TYPE,
SHFLTAG_SIZE,
SHFLTAG_LASTMODIFIED,
SHFLTAG_SOURCE,
};
#define URL_SIZE 1024
#define PATH_SIZE 2048
DWORD dwTransferd;
#ifdef WIN32
HINSTANCE g_hInst;
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
g_hInst = (HINSTANCE)hModule;
return TRUE;
}
#endif
#ifndef WIN32
#include <sys/time.h>
clock_t GetTickCount(void)
{
struct timeval tv;
if (gettimeofday(&tv, NULL) < 0) return 0;
else {
/* It's micro second. 1/1000000 sec.
* window api's GetTickCount is mili second. 1/1000 sec.
* conv it!
*/
return (clock_t)((clock_t)(tv.tv_sec * 1000) + tv.tv_usec / 1000);
}
}
#endif
char* get_auth_str(PSHCSDK_STRUCT psdk, LPCSTR pszPath)
{
unsigned char* pszAuth=NULL;
unsigned char *bintoken = NULL;
char szTemp[16];
string sAuth;
ne_unbase64(psdk->sAuth.c_str(),&bintoken);
if (bintoken == NULL)
return NULL;
char* pData = strtok((char*)bintoken,":");
if(pData == NULL)
return NULL;
int nAuthSize = 4+16+16+psdk->sAuth.size()+8;
pszAuth = new unsigned char[nAuthSize];
int kkk = time(NULL) + psdk->nAuthExpire;
memcpy(pszAuth,(unsigned char *)&kkk,sizeof(int));
ne_md5_buffer_bin(psdk->sSessionID.c_str(),szTemp);
memcpy(pszAuth+4,szTemp,sizeof(szTemp));
ne_md5_buffer_bin(pszPath,szTemp);
memcpy(pszAuth+4+16,szTemp,sizeof(szTemp));
memcpy(pszAuth+4+16+16,psdk->sAuth.c_str(),psdk->sAuth.size());
int nlength = 4 + 16 + 16 + psdk->sAuth.size();
int nRet = nlength % 8;
if (nRet > 0)
memset((char*)pszAuth + 4 + 16 + 16 + psdk->sAuth.size(),0x20,8-nRet);
else
nRet = 8;
tea_encrypt((char*)pszAuth,nlength + 8 - nRet);
char* pszTemp = new char[nlength + 8 -nRet + strlen(pData) + 1];
memcpy(pszTemp,pData,strlen(pData));
memcpy(pszTemp+strlen(pData),":",1);
memcpy(pszTemp+strlen(pData)+1,pszAuth,nlength + 8 -nRet);
char* pResult = ne_base64((const unsigned char*)pszTemp,nlength + 8 -nRet + strlen(pData) + 1);
sAuth = "Basic ";
sAuth += pResult;
delete []pszAuth;
return strdup(sAuth.c_str());
}
WIN32DLL
HSHSDK sh_init(const char *url, const char *authString, sh_callback proc, void *param)
{
PSHCSDK_STRUCT psdk = new SHCSDK_STRUCT;
if (!psdk)
return NULL;
/*
#ifdef _NEWAUTH
if (!check_suthstring(authString))
return NULL;
#endif
*/
psdk->pnsess = NULL;
psdk->pvecshfl = NULL;
// neon.lib init...
if (ne_sock_init() != NE_OK)
return NULL;
int nNeonRet = ne_uri_parse(url, &psdk->nuri);
if (nNeonRet != NE_OK)
return NULL;
if (!psdk->nuri.scheme)
psdk->nuri.scheme = strdup("http");
if (psdk->nuri.port == 0)
psdk->nuri.port = 80;
psdk->pnsess = ne_session_create(psdk->nuri.scheme, psdk->nuri.host, psdk->nuri.port);
if (!psdk->pnsess)
goto EXIT_FUNCTION;
psdk->sPath = psdk->nuri.path;
#ifdef _NEWAUTH
psdk->sAuth = authString;
#else
psdk->sAuth = "Basic ";
psdk->sAuth += authString;
#endif
psdk->nError = 0;
psdk->sError = "";
psdk->proc = proc;
psdk->pParam = param;
psdk->bWorking = false;
psdk->sSessionID = DEFAULT_SESSIONID;
psdk->nAuthExpire = DEFAULT_EXPIRE_TIME;
#ifdef WIN32
psdk->hFile = NULL;
#else
psdk->nFileDesc = -1;
#endif
psdk->nTranStop = SHSTOP_NO;
psdk->starttick = GetTickCount();
dwTransferd = 0;
return psdk;
EXIT_FUNCTION:
int nError = GetLastError();
ne_uri_free(&psdk->nuri);
if (psdk->pnsess)
ne_session_destroy(psdk->pnsess);
delete psdk;
SetLastError(nError);
return NULL;
}
WIN32DLL int sh_set_sessionID(HSHSDK hshsdk,const char *pszID)
{
if(!hshsdk)
return FALSE;
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
psdk->sSessionID = pszID;
return TRUE;
}
WIN32DLL const char* sh_get_sessionID(HSHSDK hshsdk)
{
if(!hshsdk)
return FALSE;
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
return psdk->sSessionID.c_str();
}
WIN32DLL
void sh_free(HSHSDK hshsdk)
{
if (!hshsdk)
return;
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
for (set<PVECTOR_SHFILELIST>::iterator iter = psdk->setFileList.begin(); iter != psdk->setFileList.end(); iter++)
FreeFileListVector(*iter);
ne_uri_free(&psdk->nuri);
if (psdk->pnsess)
ne_session_destroy(psdk->pnsess);
dwTransferd = 0;
delete psdk;
}
WIN32DLL
int sh_get_error_number(HSHSDK hshsdk)
{
if (!hshsdk)
return SHCERRNO_INVALIDHDL;
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
return psdk->nError;
}
WIN32DLL
const char* sh_get_error_message(HSHSDK hshsdk)
{
if (!hshsdk)
return GetErrorMessage(SHCERRNO_INVALIDHDL).c_str();
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
return psdk->sError.c_str();
}
WIN32DLL
HSHFILELIST sh_get_filelist(HSHSDK hshsdk, const char* path, unsigned int depth)
{
if (!hshsdk)
return NULL;
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
psdk->nError = 0;
string sPath = psdk->sPath;
if (path[0] != '/')
sPath += "/";
sPath += path;
char szDepth[10];
if (depth <= 1)
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>";
SHFILELIST_PARSER_STRUCT shflp;
::memset(&shflp, 0, sizeof(SHFILELIST_PARSER_STRUCT));
shflp.nRootPathLen = (UINT)psdk->sPath.length();
shflp.pvec = new VECTOR_SHFILELIST;
if (shflp.pvec) {
if (DoCommand(psdk, "PROPFIND", sPath.c_str(), sHeaders.c_str(), sBody.c_str(), true,
(LPVOID)FileListSTagParser, (LPVOID)FileListDataParser, (LPVOID)FileListETagParser, &shflp)) {
psdk->setFileList.insert(shflp.pvec);
psdk->pvecshfl = shflp.pvec;
VECTOR_SHFILELIST::iterator iter = shflp.pvec->begin();
if (strcmp((*iter)->path, "*myself*") == 0)
strcpy((*iter)->path, sPath.substr(psdk->sPath.length(), string::npos).c_str());
}
else {
FreeFileListVector(shflp.pvec);
shflp.pvec = NULL;
}
}
else {
psdk->nError = GetLastError();
psdk->sError = GetErrorMessage(psdk->nError);
}
return shflp.pvec;
}
WIN32DLL
long sh_get_filelist_count(HSHSDK hshsdk, 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
PSHFILE_STRUCT sh_get_file(HSHSDK hshsdk, HSHFILELIST hshfl, long index)
{
if (!hshsdk)
return NULL;
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
if (!hshfl) {
psdk->nError = SHCERRNO_INVALIDFLHDL;
psdk->sError = GetErrorMessage(psdk->nError);
return NULL;
}
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 NULL;
}
psdk->pvecshfl = (*iter);
}
return psdk->pvecshfl->at(index);
}
WIN32DLL
void sh_free_filelist(HSHSDK hshsdk, HSHFILELIST hshfl)
{
if (!hshsdk || !hshfl)
return;
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
PVECTOR_SHFILELIST pvec = (PVECTOR_SHFILELIST)hshfl;
set<PVECTOR_SHFILELIST>::iterator iter = psdk->setFileList.find(pvec);
if (iter == psdk->setFileList.end())
return;
FreeFileListVector(pvec);
psdk->setFileList.erase(pvec);
psdk->pvecshfl = NULL;
}
WIN32DLL
int sh_make_directory(HSHSDK hshsdk, const char* directory)
{
if (!hshsdk)
return FALSE;
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
psdk->nError = 0;
if (sh_file_exist(hshsdk,directory))
{
psdk->nError = SHCERRNO_ALREADYEXIST;
psdk->sError = GetErrorMessage(psdk->nError);
return false;
}
string sDirectory = psdk->sPath;
if (directory[0] != '/')
sDirectory += "/";
sDirectory += directory;
return (BOOL)DoCommand(psdk, "MKCOL", sDirectory.c_str());
}
WIN32DLL
int sh_copy(HSHSDK hshsdk, const char* srcPath, const char* dstPath, int overwrite)
{
if (!hshsdk)
return FALSE;
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
psdk->nError = 0;
string sSrcPath = psdk->sPath;
if (srcPath[0] != '/')
sSrcPath += "/";
sSrcPath += srcPath;
string sDstPath = psdk->sPath;
if (dstPath[0] != '/')
sDstPath += "/";
sDstPath += dstPath;
string sHeader = "New-uri|" + PathEncode(sDstPath.c_str()) + ",Overwrite|";
sHeader += (overwrite ? "T" : "F");
return (BOOL)DoCommand(psdk, "COPY", sSrcPath.c_str(), sHeader.c_str());
}
WIN32DLL
int sh_move(HSHSDK hshsdk, const char* srcPath, const char* dstPath, int overwrite)
{
if (!hshsdk)
return FALSE;
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
psdk->nError = 0;
string sSrcPath = psdk->sPath;
if (srcPath[0] != '/')
sSrcPath += "/";
sSrcPath += srcPath;
string sDstPath = psdk->sPath;
if (dstPath[0] != '/')
sDstPath += "/";
sDstPath += dstPath;
string sHeader = "New-uri|" + PathEncode(sDstPath.c_str()) + ",Overwrite|";
sHeader += (overwrite ? "T" : "F");
return (BOOL)DoCommand(psdk, "MOVE", sSrcPath.c_str(), sHeader.c_str());
}
WIN32DLL
int sh_delete(HSHSDK hshsdk, const char* path)
{
if (!hshsdk)
return FALSE;
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
psdk->nError = 0;
if (path == NULL || strlen(path) == 0 || (strlen(path) == 1 && path[0] == '/')) {
psdk->nError = SHCERRNO_SERVICE;
psdk->sError = "루트는 삭제할 수 없습니다.";
return FALSE;
}
string sPath = psdk->sPath;
if (path[0] != '/')
sPath += "/";
sPath += path;
return (BOOL)DoCommand(psdk, "DELETE", sPath.c_str());
}
WIN32DLL
int sh_upload(HSHSDK hshsdk, const char *srcPath, const char *dstPath, int writePolicy, INT64 availQuota)
{
MyOutputDebugString("sh_upload : %s, %s, %d, %I64d",srcPath,dstPath,writePolicy,availQuota);
if (!hshsdk)
{
MyOutputDebugString("ERROR : sh_upload : invalid handle");
return FALSE;
}
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
if (psdk->bWorking) {
psdk->nError = SHCERRNO_ISBUSY;
psdk->sError = GetErrorMessage(psdk->nError);
MyOutputDebugString("ERROR : sh_upload : SHCERRNO_ISBUSY");
return FALSE;
}
#ifdef WIN32
psdk->hFile = NULL;
#else
psdk->nFileDesc = -1;
#endif
psdk->iFilePos = 0;
psdk->cOldTick = clock();
psdk->nTranStop = SHSTOP_NO;
return (BOOL)DoUpload(psdk, srcPath, dstPath, writePolicy, availQuota);
}
WIN32DLL int sh_download_buffer(
HSHSDK hshsdk, // SDK handle
const char *srcPath, // Source file
down_stream proc,
void* userval // User-supplied value for callback
)
{
if (!hshsdk)
return FALSE;
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
if (psdk->bWorking) {
psdk->nError = SHCERRNO_ISBUSY;
psdk->sError = GetErrorMessage(psdk->nError);
return FALSE;
}
psdk->iFilePos = 0;
psdk->cOldTick = clock();
psdk->nTranStop = SHSTOP_NO;
return (BOOL)DoDownloadBuffer(psdk, srcPath, proc, userval);
}
WIN32DLL
int sh_download(HSHSDK hshsdk, const char *srcPath, const char *dstPath, int writePolicy, INT64 availQuota)
{
MyOutputDebugString("sh_download : %s, %s, %d, %I64d",srcPath,dstPath,writePolicy,availQuota);
if (!hshsdk)
{
MyOutputDebugString("ERROR : sh_download : invalid handle");
return FALSE;
}
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
if (psdk->bWorking) {
psdk->nError = SHCERRNO_ISBUSY;
psdk->sError = GetErrorMessage(psdk->nError);
MyOutputDebugString("ERROR : sh_download : SHCERRNO_ISBUSY");
return FALSE;
}
#ifdef WIN32
psdk->hFile = NULL;
#else
psdk->nFileDesc = -1;
#endif
psdk->iFilePos = 0;
psdk->cOldTick = clock();
psdk->nTranStop = SHSTOP_NO;
return (BOOL)DoDownload(psdk, srcPath, dstPath, writePolicy, availQuota);
}
WIN32DLL
int sh_set_limit(HSHSDK hshsdk,int nLimit)
{
if (!hshsdk)
return FALSE;
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
psdk->nSpeedLimit = nLimit;
return TRUE;
}
WIN32DLL
int sh_get_limit(HSHSDK hshsdk)
{
if (!hshsdk)
return FALSE;
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
return psdk->nSpeedLimit;
}
WIN32DLL
INT64 sh_get_filepos(HSHSDK hshsdk)
{
if(!hshsdk)
return FALSE;
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
return psdk->iFilePos;
}
WIN32DLL
bool sh_file_exist(
HSHSDK hshsdk, // SDK Handle
const char *path) // file/folder Path
{
// 파일 목록 가져오기
HSHFILELIST hshfl = sh_get_filelist(hshsdk, path, 0);
if (!hshfl)
return false;
else
return true;
}
#include "mcrypt.h"
#define ENCRYPT_KEY "I'm your father"
#define INIT_VECTOR "1234567890123456"
#define ENCRYPT_BIT 24
#define SNTP_DOMAIN "time.kriss.re.kr"
#define SNTP_PORT 13
WIN32DLL
int sh_encrypt(const char *text, char *encrypted)
{
MCRYPT mcrypt = NULL;
BOOL bResult = FALSE;
if (ne_sock_init() != NE_OK)
return FALSE;
// Get server time
char szHost[128];
strcpy(szHost, SNTP_DOMAIN);
if (isalpha(szHost[0])) {
hostent *phe = gethostbyname(szHost);
if (!phe)
return FALSE;
sprintf(szHost, "%d.%d.%d.%d",
(unsigned char)*(phe->h_addr_list[0]), (unsigned char)*(phe->h_addr_list[0] + 1),
(unsigned char)*(phe->h_addr_list[0] + 2), (unsigned char)*(phe->h_addr_list[0] + 3));
}
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
return FALSE;
sockaddr_in sa;
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr(szHost);
sa.sin_port = htons(SNTP_PORT);
#ifdef WIN32
__nonblock_win32(sock);
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 = timeout;
tv.tv_usec = 0;
int result = select(0, 0, &wfd, &efd,&tv);
if (SOCKET_ERROR == result || 0 == result)
{
int nRet = WSAGetLastError();
goto EXIT_FUNCTION;
}
}
else
goto EXIT_FUNCTION;
}
#else
__nonblock(sock);
{
int i, nRet;
for (i = 0; i < (timeout * 10); i++) {
if (connect(sock, (SOCKADDR*)&sa, sizeof(sa)) != SOCKET_ERROR) {
errno = 0;
break;
} else {
nRet = errno;
}
if (errno == EISCONN)
break;
if (((i + 1) % 10) == 0) {
shutdown(sock, 2);
//close(sock);
//fprintf(stderr, "RETRY ");
}
usleep(100000);
//fprintf(stderr, "CLI %d\n", i);
}
if (errno != EISCONN && errno != 0)
goto EXIT_FUNCTION;
}
#endif
#ifndef WIN32
{
#endif
int nRecv = _sh_recv(sock, szHost, sizeof(szHost));
char szBuf[1024];
struct tm stm;
char szKey[ENCRYPT_BIT];
char szIV[ENCRYPT_BIT];
if (nRecv < 20) {
closesocket(sock);
return FALSE;
}
szHost[nRecv] = (char)NULL;
closesocket(sock);
if (!ParseSntpString(szHost, &stm))
return FALSE;
// encrypt
mcrypt = mcrypt_module_open(MCRYPT_BLOWFISH, NULL, MCRYPT_CBC, NULL);
if (mcrypt == MCRYPT_FAILED)
return FALSE;
::memset(szKey, 0, ENCRYPT_BIT);
strcpy(szKey, ENCRYPT_KEY);
memcpy(szIV, INIT_VECTOR, ENCRYPT_BIT);
if (mcrypt_generic_init(mcrypt, szKey, ENCRYPT_BIT, szIV) < 0)
goto EXIT_FUNCTION;
sprintf(szBuf, "%s%04d%02d%02d%02d%02d%02d", text, stm.tm_year, stm.tm_mon, stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec);
int nBufSize = (int)strlen(szBuf);
mcrypt_generic(mcrypt, szBuf, nBufSize);
mcrypt_generic_deinit(mcrypt);
char szEncrypted[URL_SIZE];
char* pszEncrypted = ne_base64((const unsigned char *)szBuf, nBufSize);
int nEncryptedSize = (int)strlen(pszEncrypted);
memcpy(szEncrypted, pszEncrypted, nEncryptedSize);
free(pszEncrypted);
memcpy(&szEncrypted[nEncryptedSize], szIV, ENCRYPT_BIT);
szEncrypted[nEncryptedSize + ENCRYPT_BIT] = (char)NULL;
strcpy(encrypted, URLEncode(szEncrypted).c_str());
bResult = TRUE;
#ifndef WIN32
}
#endif
EXIT_FUNCTION:
mcrypt_module_close(mcrypt);
return bResult;
}
static bool DoCommand(PSHCSDK_STRUCT psdk, LPCSTR pszMethod, LPCSTR pszPath, LPCSTR pszHeaders, LPCSTR pszBody, bool bParseBody, LPVOID pSTagParser, LPVOID pDataParser, LPVOID pETagParser, LPVOID pParam)
{
bool bRet = false;
int nRet;
string sBody;
ne_status* pnstat;
string sAuth;
char szTemp[16];
#ifdef _NEWAUTH
char* pszAuth = NULL;
#endif
ne_request *pnreq = ne_request_create(psdk->pnsess, pszMethod, PathEncode(pszPath).c_str());
if (!pnreq) {
psdk->nError = SHCERRNO_UNDEFINED;
psdk->sError = ne_get_error(psdk->pnsess);
goto EXIT_FUNCTION;
}
#ifdef _NEWAUTH
pszAuth = get_auth_str(psdk,pszPath);
ne_add_request_header(pnreq, "Authorization",pszAuth);
#else
ne_add_request_header(pnreq, "Authorization", psdk->sAuth.c_str());
#endif
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) {
psdk->nError = nRet;
psdk->sError = ne_get_error(psdk->pnsess);
goto EXIT_FUNCTION;
}
pnstat = (ne_status*)ne_get_status(pnreq);
if (pnstat->code != 0 && (pnstat->code < 200 || pnstat->code >= 300)) {
psdk->nError = pnstat->code;
psdk->sError = ne_get_error(psdk->pnsess);
goto EXIT_FUNCTION;
}
// ne_end_request(pnreq);
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;
EXIT_FUNCTION:
switch (psdk->nError) {
case 400:
psdk->nError = SHCERRNO_SERVICE;
break;
case 401:
psdk->nError = SHCERRNO_AUTHORIZATION;
break;
case 403:
psdk->nError = SHCERRNO_SERVICE;
break;
case 404:
psdk->sRedirect = ne_get_response_header(pnreq, "Redirect") != NULL ? ne_get_response_header(pnreq, "Redirect") : "";
psdk->nError = SHCERRNO_NOEXISTSFILE;
break;
case 500:
psdk->nError = SHCERRNO_SERVICE;
break;
}
if (pnreq)
ne_request_destroy(pnreq);
#ifdef _NEWAUTH
if(pszAuth)
free(pszAuth);
#endif
return bRet;
}
static bool DoUpload(PSHCSDK_STRUCT psdk, LPCSTR pszSrcFile, LPCSTR pszDstFile, int nWritePolicy, INT64 nAvailQuota)
{
// 현재 URI 보관
bool bFindSource = true;
bool bSessionChange = false;
ne_uri nuri = psdk->nuri;
// 업로드 코드 시작
string sPath = psdk->sPath + pszDstFile;
string sHeaders;
int nRet;
ne_request *pnreq = NULL;
#ifdef _NEWAUTH
char* pszAuth = get_auth_str(psdk,sPath.c_str());
#endif
sPath = PathEncode(sPath.c_str());
#ifdef WIN32
psdk->hFile = CreateFile(pszSrcFile,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
#else
psdk->nFileDesc = open(pszSrcFile, _O_RDONLY | _O_BINARY | _O_RANDOM);
#endif
#ifdef WIN32
if (psdk->hFile == INVALID_HANDLE_VALUE){
#else
if (psdk->nFileDesc == -1) {
#endif
psdk->nError = GetLastError();
psdk->sError = GetErrorMessage(psdk->nError);
MyOutputDebugString("ERROR : Upload 1 : %s",psdk->sError.c_str());
return false;
}
bool bResult = false;
#ifdef WIN32
LARGE_INTEGER Size;
GetFileSizeEx(psdk->hFile,&Size);
psdk->nFileSize = Size.QuadPart;
#else
psdk->nFileSize = sh_filelength(psdk->nFileDesc);
#endif
MyOutputDebugString("Upload :File(%s) Size %I64d",pszSrcFile,psdk->nFileSize);
if (psdk->nFileSize == -1L) {
psdk->nError = GetLastError();
psdk->sError = GetErrorMessage(psdk->nError);
MyOutputDebugString("ERROR : Upload 2 : %s",psdk->sError.c_str());
goto EXIT_FUNCTION;
}
if (nWritePolicy == SHWRITEPOLICY_OVERWRITE) {
PVECTOR_SHFILELIST pvec = (PVECTOR_SHFILELIST)sh_get_filelist((HSHSDK)psdk, pszDstFile, 0);
if (pvec && pvec->size() > 0) {
sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec);
if (!sh_delete((HSHSDK)psdk, pszDstFile))
{
MyOutputDebugString("ERROR : Upload 3 : %s",psdk->sError.c_str());
goto EXIT_FUNCTION;
}
}
/* Elenoa ADD START */
if (pvec)
sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec);
/* Elenoa ADD END */
}
else if (nWritePolicy == SHWRITEPOLICY_APPEND)
{
PVECTOR_SHFILELIST pvec = (PVECTOR_SHFILELIST)sh_get_filelist((HSHSDK)psdk, pszDstFile, 0);
if (pvec && pvec->size() > 0)
{
PSHFILE_STRUCT pshf = sh_get_file((HSHSDK)psdk, (HSHFILELIST)pvec, 0);
if (psdk->nFileSize == pshf->size)
{
sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec);
bResult = true;
MyOutputDebugString("ERROR : Upload 4 : sh_get_filelist : %I64d : %I64d",psdk->nFileSize,pshf->size);
goto EXIT_FUNCTION;
}
else if (psdk->nFileSize < pshf->size)
{
sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec);
bResult = false;
MyOutputDebugString("ERROR : Upload 5 : sh_get_filelist");
goto EXIT_FUNCTION;
}
#ifdef WIN32
psdk->iFilePos = SetFilePointer(psdk->hFile,(long)pshf->size, NULL, FILE_BEGIN);
#else
psdk->iFilePos = _lseeki64(psdk->nFileDesc, pshf->size, SEEK_SET);
#endif
if (psdk->iFilePos == -1L) {
sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec);
MyOutputDebugString("ERROR : Upload 6 : SetFilePointer");
goto EXIT_FUNCTION;
}
char szRange[100];
#ifdef WIN32
sprintf(szRange, "bytes %I64d-%I64d/%I64d", psdk->iFilePos, psdk->nFileSize - 1, psdk->nFileSize);
#else
sprintf(szRange, "bytes %lld-%lld/%lld", psdk->iFilePos, psdk->nFileSize - 1, psdk->nFileSize);
#endif
sHeaders = "Content-Range|";
sHeaders += szRange;
MyOutputDebugString("Upload Header : %s",sHeaders.c_str());
if (pshf->source && strlen(pshf->source) > 7) {
bSessionChange = true;
ne_session_destroy(psdk->pnsess);
ne_uri_parse(pshf->source, &psdk->nuri);
if (psdk->nuri.path)
free(psdk->nuri.path);
psdk->nuri.path = strdup("/dav");
if (!psdk->nuri.scheme)
psdk->nuri.scheme = strdup("http");
if (psdk->nuri.port == 0)
psdk->nuri.port = 80;
psdk->pnsess = ne_session_create(psdk->nuri.scheme, psdk->nuri.host, psdk->nuri.port);
psdk->sPath = psdk->nuri.path;
}
bFindSource = false;
}
sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec);
}
else {
PVECTOR_SHFILELIST pvec = (PVECTOR_SHFILELIST)sh_get_filelist((HSHSDK)psdk, pszDstFile, 0);
if (pvec && pvec->size() > 0) {
sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec);
psdk->nError = SHCERRNO_EXISTSFILE;
psdk->sError = GetErrorMessage(psdk->nError);
MyOutputDebugString("ERROR : Upload 7 : SHCERRNO_EXISTSFILE");
goto EXIT_FUNCTION;
}
/* Elenoa ADD START */
if (pvec)
sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec);
/* Elenoa ADD END */
}
if ((UINT64)nAvailQuota < (UINT64)(psdk->nFileSize - psdk->iFilePos)) {
psdk->nError = SHCERRNO_NOAVAILQUOTA;
psdk->sError = GetErrorMessage(psdk->nError);
MyOutputDebugString("ERROR : Upload 8 : SHCERRNO_NOAVAILQUOTA");
goto EXIT_FUNCTION;
}
if (bFindSource) {
for (int i = 0; !bSessionChange && i < MAX_TRY; i++) {
PVECTOR_SHFILELIST pvec = (PVECTOR_SHFILELIST)sh_get_filelist((HSHSDK)psdk, pszDstFile, 0);
if (pvec && pvec->size() > 0) {
sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec);
psdk->nError = SHCERRNO_EXISTSFILE;
psdk->sError = GetErrorMessage(psdk->nError);
MyOutputDebugString("ERROR : Upload 9 : SHCERRNO_EXISTSFILE");
goto EXIT_FUNCTION;
}
/* Elenoa ADD START */
if (pvec)
sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec);
/* Elenoa ADD END */
if (psdk->sRedirect == "")
break;
if (i > 0)
ne_uri_free(&psdk->nuri);
bSessionChange = true;
ne_session_destroy(psdk->pnsess);
ne_uri_parse(psdk->sRedirect.c_str(), &psdk->nuri);
if (!psdk->nuri.scheme)
psdk->nuri.scheme = strdup("http");
if (psdk->nuri.port == 0)
psdk->nuri.port = 80;
psdk->pnsess = ne_session_create(psdk->nuri.scheme, psdk->nuri.host, psdk->nuri.port);
psdk->sPath = psdk->nuri.path;
if (i == (MAX_TRY - 1)) {
sHeaders = "Force|YES";
break;
}
}
}
pnreq = ne_request_create(psdk->pnsess, "PUT", sPath.c_str());
if (!pnreq) {
psdk->nError = SHCERRNO_UNDEFINED;
psdk->sError = ne_get_error(psdk->pnsess);
MyOutputDebugString("ERROR : Upload 10 : SHCERRNO_UNDEFINED");
goto EXIT_FUNCTION;
}
#ifdef _NEWAUTH
ne_add_request_header(pnreq, "Authorization", pszAuth);
#else
ne_add_request_header(pnreq, "Authorization", psdk->sAuth.c_str());
#endif
if (sHeaders.length() > 0) {
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);
}
ne_set_request_body_provider64(pnreq, psdk->nFileSize - psdk->iFilePos, UploadProvider, psdk);
nRet = ne_request_dispatch(pnreq);
if (psdk->nTranStop == SHSTOP_NO) {
if (nRet != NE_OK) {
psdk->nError = nRet;
psdk->sError = ne_get_error(psdk->pnsess);
MyOutputDebugString("ERROR : Upload 11 : %s",psdk->sError.c_str());
goto EXIT_FUNCTION;
}
ne_status* pnstat = (ne_status*)ne_get_status(pnreq);
if (pnstat->code != 0 && (pnstat->code < 200 || pnstat->code >= 300)) {
psdk->nError = pnstat->code;
psdk->sError = ne_get_error(psdk->pnsess);
MyOutputDebugString("ERROR : Upload 12 : %s",psdk->sError.c_str());
goto EXIT_FUNCTION;
}
}
ne_end_request(pnreq);
bResult = true;
EXIT_FUNCTION:
switch (psdk->nError) {
case 404:
psdk->nError = SHCERRNO_NOEXISTSFILE;
break;
}
#ifdef _NEWAUTH
if(pszAuth)
free(pszAuth);
#endif
#ifdef WIN32
if(psdk->hFile != NULL)
{
CloseHandle(psdk->hFile);
psdk->hFile = NULL;
}
#else
if (psdk->nFileDesc != -1)
{
close(psdk->nFileDesc);
psdk->nFileDesc = -1;
}
#endif
if (pnreq)
ne_request_destroy(pnreq);
if (bSessionChange) {
/* Elenoa ADD START */
ne_session_destroy(psdk->pnsess);
/* Elenoa ADD END */
ne_uri_free(&psdk->nuri);
psdk->nuri = nuri;
psdk->pnsess = ne_session_create(psdk->nuri.scheme, psdk->nuri.host, psdk->nuri.port);
psdk->sPath = psdk->nuri.path;
}
#ifdef WIN32
CString strTemp;
strTemp.Format("Upload %s : %s : %d", bResult ? "SUCCESS" : "ERROR", pszDstFile, psdk->nError);
OutputDebugString(strTemp);
#endif
return bResult;
}
static bool DoDownloadBuffer(PSHCSDK_STRUCT psdk, LPCSTR pszSrcFile,
int (*data_func)(
void* userval,
const char* buf,
size_t len), // If len is zero the transfer is restarted from the begining
void* userval // User-supplied value for callback
)
{
string sPath = psdk->sPath + pszSrcFile;
string sHeaders;
PSHFILE_STRUCT pshf;
int nRet;
ne_request *pnreq = NULL;
#ifdef _NEWAUTH
char* pszAuth = get_auth_str(psdk,sPath.c_str());
#endif
sPath = PathEncode(sPath.c_str());
PVECTOR_SHFILELIST pvec = (PVECTOR_SHFILELIST)sh_get_filelist((HSHSDK)psdk, pszSrcFile, 0);
if (!pvec || pvec->size() == 0)
return false;
bool bResult = false;
pshf = sh_get_file((HSHSDK)psdk, (HSHFILELIST)pvec, 0);
pnreq = ne_request_create(psdk->pnsess, "GET", sPath.c_str());
if (!pnreq) {
psdk->nError = SHCERRNO_UNDEFINED;
psdk->sError = ne_get_error(psdk->pnsess);
goto EXIT_FUNCTION;
}
#ifdef _NEWAUTH
ne_add_request_header(pnreq, "Authorization", pszAuth);
#else
ne_add_request_header(pnreq, "Authorization", psdk->sAuth.c_str());
#endif
if (sHeaders.length() > 0) {
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);
}
ne_add_response_body_reader(pnreq, ne_accept_2xx, data_func, userval);
psdk->nFileSize = pshf->size;
nRet = ne_request_dispatch(pnreq);
if (psdk->nTranStop == SHSTOP_NO) {
if (nRet != NE_OK) {
psdk->nError = nRet;
psdk->sError = ne_get_error(psdk->pnsess);
goto EXIT_FUNCTION;
}
ne_status* pnstat = (ne_status*)ne_get_status(pnreq);
if (pnstat->code != 0 && (pnstat->code < 200 || pnstat->code >= 300)) {
psdk->nError = pnstat->code;
psdk->sError = ne_get_error(psdk->pnsess);
goto EXIT_FUNCTION;
}
}
ne_end_request(pnreq);
bResult = true;
EXIT_FUNCTION:
sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec);
#ifdef _NEWAUTH
if(pszAuth)
free(pszAuth);
#endif
string sRedirection;
if (pnreq) {
const char *pszLocation = ne_get_response_header(pnreq, "Location");
if (pszLocation)
sRedirection = pszLocation;
ne_request_destroy(pnreq);
}
// Redirection
if (psdk->nError == 301 && sRedirection != "") {
ne_session_destroy(psdk->pnsess);
// 지정된 곳으로 접속
ne_uri nuri;
ne_uri_parse(sRedirection.c_str(), &nuri);
if (!nuri.scheme)
nuri.scheme = strdup("http");
if (nuri.port == 0)
nuri.port = 80;
psdk->pnsess = ne_session_create(nuri.scheme, nuri.host, nuri.port);
psdk->sPath = nuri.path;
psdk->sPath.erase(psdk->sPath.find('/', 1), string::npos);
ne_uri_free(&nuri);
psdk->iFilePos = 0;
psdk->cOldTick = clock();
psdk->nTranStop = SHSTOP_NO;
bResult = DoDownloadBuffer(psdk, pszSrcFile, data_func, userval);
// 원래 서버로 재접속
ne_session_destroy(psdk->pnsess);
psdk->pnsess = ne_session_create(psdk->nuri.scheme, psdk->nuri.host, psdk->nuri.port);
psdk->sPath = psdk->nuri.path;
}
return bResult;
}
static bool DoDownload(PSHCSDK_STRUCT psdk, LPCSTR pszSrcFile, LPCSTR pszDstFile, int nWritePolicy, INT64 nAvailQuota)
{
string sPath = psdk->sPath + pszSrcFile;
string sHeaders;
PSHFILE_STRUCT pshf;
ne_request *pnreq = NULL;
#ifdef _NEWAUTH
char* pszAuth = get_auth_str(psdk,sPath.c_str());
#endif
sPath = PathEncode(sPath.c_str());
struct _stati64 stDstFile;
int nRet = _stati64(pszDstFile, &stDstFile);
if (nWritePolicy == SHWRITEPOLICY_NONE) {
if (nRet != -1) {
psdk->nError = SHCERRNO_EXISTSFILE;
psdk->sError = GetErrorMessage(psdk->nError);
MyOutputDebugString("ERROR : DoDownload : SHCERRNO_EXISTSFILE");
return false;
}
}
else {
if (nRet != -1 && (stDstFile.st_mode & _S_IFDIR)) {
if (nWritePolicy == SHWRITEPOLICY_OVERWRITE) {
if (!DeleteDirectory(pszDstFile)) {
psdk->nError = GetLastError();
psdk->sError = GetErrorMessage(psdk->nError);
MyOutputDebugString("ERROR : DoDownload : DeleteFile : %d",psdk->nError);
return false;
}
}
else {
psdk->nError = SHCERRNO_EXISTSFILE;
psdk->sError = GetErrorMessage(psdk->nError);
}
}
}
PVECTOR_SHFILELIST pvec = (PVECTOR_SHFILELIST)sh_get_filelist((HSHSDK)psdk, pszSrcFile, 0);
if (!pvec || pvec->size() == 0)
{
MyOutputDebugString("ERROR : DoDownload : sh_get_filelist");
return false;
}
bool bResult = false;
#ifdef WIN32
int nFlag=nWritePolicy;
switch (nWritePolicy)
{
case SHWRITEPOLICY_OVERWRITE:
case SHWRITEPOLICY_NONE :
nFlag = CREATE_ALWAYS;
break;
case SHWRITEPOLICY_APPEND:
nFlag = OPEN_ALWAYS;
break;
}
#else
int nFlag = _O_CREAT | _O_WRONLY | _O_BINARY | _O_RANDOM;
switch (nWritePolicy)
{
case SHWRITEPOLICY_OVERWRITE: nFlag |= _O_TRUNC; break;
case SHWRITEPOLICY_APPEND: nFlag |= _O_APPEND; break;
}
#endif
#ifdef WIN32
psdk->hFile = CreateFile(pszDstFile,GENERIC_WRITE,FILE_SHARE_READ,NULL,nFlag,FILE_ATTRIBUTE_NORMAL,NULL);
if (psdk->hFile == INVALID_HANDLE_VALUE) {
#else
psdk->nFileDesc = open(pszDstFile, nFlag);
if (psdk->nFileDesc == -1L) {
#endif
psdk->nError = GetLastError();
psdk->sError = GetErrorMessage(psdk->nError);
MyOutputDebugString("ERROR : DoDownload : CreateFile : %d",psdk->nError);
goto EXIT_FUNCTION;
}
pshf = sh_get_file((HSHSDK)psdk, (HSHFILELIST)pvec, 0);
#ifdef WIN32
psdk->iFilePos = SetFilePointer(psdk->hFile,0,0,FILE_END);
#else
psdk->iFilePos = _lseeki64(psdk->nFileDesc, 0, SEEK_END);
#endif
if (psdk->iFilePos == -1L)
{
psdk->nError = GetLastError();
psdk->sError = GetErrorMessage(psdk->nError);
MyOutputDebugString("ERROR : DoDownload : SetFilePointer : %d",psdk->nError);
goto EXIT_FUNCTION;
}
if (psdk->iFilePos >= pshf->size)
{
bResult = true;
WriteLogToFile("ERROR : DoDownload : invalid file pos");
goto EXIT_FUNCTION;
}
if (nWritePolicy == SHWRITEPOLICY_APPEND)
{
/*
#ifdef WIN32
psdk->iFilePos = SetFilePointer(psdk->hFile,0,0,FILE_END);
#else
psdk->iFilePos = _lseeki64(psdk->nFileDesc, 0, SEEK_END);
#endif
if (psdk->iFilePos == -1L) {
psdk->nError = GetLastError();
psdk->sError = GetErrorMessage(psdk->nError);
goto EXIT_FUNCTION;
}
if (psdk->iFilePos >= pshf->size) {
bResult = true;
goto EXIT_FUNCTION;
}
*/
char szRange[100];
#ifdef WIN32
sprintf(szRange, "bytes=%I64d-%I64d", psdk->iFilePos, pshf->size);
#else
sprintf(szRange, "bytes=%lld-%lld", psdk->iFilePos, pshf->size);
#endif
sHeaders += "Range|";
sHeaders += szRange;
sHeaders += ",Accept-Ranges|bytes";
}
if ((UINT64)nAvailQuota < (UINT64)(pshf->size - psdk->iFilePos)) {
psdk->nError = SHCERRNO_NOAVAILQUOTA;
psdk->sError = GetErrorMessage(psdk->nError);
MyOutputDebugString("ERROR : DoDownload : SHCERRNO_NOAVAILQUOTA");
goto EXIT_FUNCTION;
}
pnreq = ne_request_create(psdk->pnsess, "GET", sPath.c_str());
if (!pnreq) {
psdk->nError = SHCERRNO_UNDEFINED;
psdk->sError = ne_get_error(psdk->pnsess);
MyOutputDebugString("ERROR : DoDownload : ne_request_create");
goto EXIT_FUNCTION;
}
#ifdef _NEWAUTH
ne_add_request_header(pnreq, "Authorization", pszAuth);
#else
ne_add_request_header(pnreq, "Authorization", psdk->sAuth.c_str());
#endif
if (sHeaders.length() > 0) {
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);
}
ne_add_response_body_reader(pnreq, ne_accept_2xx, DownloadProvider, psdk);
psdk->nFileSize = pshf->size;
nRet = ne_request_dispatch(pnreq);
if (psdk->nTranStop == SHSTOP_NO) {
if (nRet != NE_OK) {
psdk->nError = nRet;
psdk->sError = ne_get_error(psdk->pnsess);
MyOutputDebugString("ERROR : DoDownload : ne_request_dispatch : %d",psdk->nError);
goto EXIT_FUNCTION;
}
ne_status* pnstat = (ne_status*)ne_get_status(pnreq);
if (pnstat->code != 0 && (pnstat->code < 200 || pnstat->code >= 300)) {
psdk->nError = pnstat->code;
psdk->sError = ne_get_error(psdk->pnsess);
goto EXIT_FUNCTION;
}
}
ne_end_request(pnreq);
bResult = true;
EXIT_FUNCTION:
sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec);
#ifdef _NEWAUTH
if(pszAuth)
free(pszAuth);
#endif
#ifdef WIN32
if (psdk->hFile != NULL) {
CloseHandle(psdk->hFile);
psdk->hFile = NULL;
}
#else
if (psdk->nFileDesc) {
close(psdk->nFileDesc);
psdk->nFileDesc = -1;
}
#endif
string sRedirection;
if (pnreq) {
const char *pszLocation = ne_get_response_header(pnreq, "Location");
if (pszLocation)
sRedirection = pszLocation;
ne_request_destroy(pnreq);
}
// Redirection
if (psdk->nError == 301 && sRedirection != "") {
ne_session_destroy(psdk->pnsess);
// 지정된 곳으로 접속
ne_uri nuri;
ne_uri_parse(sRedirection.c_str(), &nuri);
if (!nuri.scheme)
nuri.scheme = strdup("http");
if (nuri.port == 0)
nuri.port = 80;
psdk->pnsess = ne_session_create(nuri.scheme, nuri.host, nuri.port);
psdk->sPath = nuri.path;
psdk->sPath.erase(psdk->sPath.find('/', 1), string::npos);
ne_uri_free(&nuri);
#ifdef WIN32
psdk->hFile = NULL;
#else
psdk->nFileDesc = -1;
#endif
psdk->iFilePos = 0;
psdk->cOldTick = clock();
psdk->nTranStop = SHSTOP_NO;
bResult = DoDownload(psdk, pszSrcFile, pszDstFile, nWritePolicy == SHWRITEPOLICY_NONE ? SHWRITEPOLICY_OVERWRITE : nWritePolicy, nAvailQuota);
// 원래 서버로 재접속
ne_session_destroy(psdk->pnsess);
psdk->pnsess = ne_session_create(psdk->nuri.scheme, psdk->nuri.host, psdk->nuri.port);
psdk->sPath = psdk->nuri.path;
}
return bResult;
}
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] = (char)NULL;
(*psBody) += pszTemp;
delete []pszTemp;
return NE_OK;
}
//#ifdef WIN32
#define TERM_TICKCOUNT (CLOCKS_PER_SEC >> 3)
//#else
//#define TERM_TICKCOUNT (HZ >> 1)
//#endif
inline int WaitForBandCtl(double dWrite, long double ldDesiredBand)
{
struct timeval tv;
int iWaitTimeInt = 0;
double dWaitTime = 0.00;
unsigned long ulWaitTimeDec = 0;
fd_set fakeFD;
FD_ZERO(&fakeFD);
if((dWrite <= 0) || (ldDesiredBand <= 0)) {
return -1;
}
memset((char *)&tv, 0, sizeof(tv));
dWaitTime = (double)( 1 / (double)(ldDesiredBand/dWrite));
iWaitTimeInt = (int)(dWaitTime);
ulWaitTimeDec = (long)((dWaitTime - iWaitTimeInt) * 1000);
fprintf(stderr, "dWaitTime = %f\n", dWaitTime);
tv.tv_sec = iWaitTimeInt;
tv.tv_usec = ulWaitTimeDec;
#ifdef WIN32
Sleep((DWORD)(dWaitTime*1000));
#else
usleep((DWORD)(dWaitTime*1000));
#endif
return 1;
}
static ssize_t UploadProvider(void *userdata, char *buffer, size_t buflen)
{
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)userdata;
if (buflen == 0)
return 0;
#ifdef WIN32
DWORD nRead;
ReadFile(psdk->hFile,buffer,(DWORD)buflen,&nRead,NULL);
#else
int nRead = read(psdk->nFileDesc, buffer, (UINT)buflen);
#endif
if (nRead < 0) {
psdk->nTranStop = SHSTOP_BYERROR;
psdk->nError = GetLastError();
psdk->sError = GetErrorMessage(psdk->nError);
return -1;
}
dwTransferd += nRead;
psdk->iFilePos += nRead;
if (clock() > psdk->cOldTick + TERM_TICKCOUNT || psdk->iFilePos >= psdk->nFileSize)
{
if (psdk->proc)
{
if (!psdk->proc(psdk->pParam, psdk->iFilePos)) {
psdk->nTranStop = SHSTOP_BYUSER;
return -1;
}
}
if(psdk->nSpeedLimit > 0)
{
double t = (double)(GetTickCount() - psdk->starttick);
double q = (double)((double)dwTransferd/ t*1000);
DWORD m_dbLimit = psdk->nSpeedLimit * 1024;
// printf("SPEED : %f\n",q);
if (q > m_dbLimit)
{
DWORD dwret = (DWORD)((((q*t)/m_dbLimit)-t));
#ifdef WIN32
Sleep(dwret);
#else
usleep(dwret);
#endif
}
}
psdk->cOldTick = clock();
}
return nRead;
}
static int DownloadProvider(void* userdata, const char* buf, size_t len)
{
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)userdata;
if (len == 0)
return 0;
DWORD nWritten, nTotal = 0;
do {
#ifdef WIN32
WriteFile(psdk->hFile,buf,(DWORD)len,&nWritten,NULL);
#else
nWritten = write(psdk->nFileDesc, buf + nTotal, (UINT)len - nTotal);
#endif
if (nWritten < 0) {
psdk->nTranStop = SHSTOP_BYERROR;
psdk->nError = GetLastError();
psdk->sError = GetErrorMessage(psdk->nError);
return 1;
}
nTotal += nWritten;
} while (nTotal < (DWORD)len);
dwTransferd += nTotal;
psdk->iFilePos += nTotal;
if (clock() > psdk->cOldTick + TERM_TICKCOUNT || psdk->iFilePos >= psdk->nFileSize)
{
if (psdk->proc)
{
if (!psdk->proc(psdk->pParam, psdk->iFilePos))
{
psdk->nTranStop = SHSTOP_BYUSER;
return 1;
}
}
if(psdk->nSpeedLimit > 0)
{
double t = (double)(GetTickCount() - psdk->starttick);
double q = (double)((double)dwTransferd/ t*1000);
DWORD m_dbLimit = psdk->nSpeedLimit * 1024;
// printf("SPEED : %f\n",q);
if (q > m_dbLimit)
{
DWORD dwret = (DWORD)((((q*t)/m_dbLimit)-t));
#ifdef WIN32
Sleep(dwret);
#else
usleep(dwret);
#endif
}
}
psdk->cOldTick = clock();
}
return NE_OK;
}
static int FileListSTagParser(void *userdata, int parent, const char *nspace, const char *name, const char **atts)
{
PSHFILELIST_PARSER_STRUCT pshflp = (PSHFILELIST_PARSER_STRUCT)userdata;
if (strcmp(name, "response") == 0) {
pshflp->pshf = new SHFILE_STRUCT;
::memset(pshflp->pshf, 0, sizeof(SHFILE_STRUCT));
}
else if (strcmp(name, "href") == 0) {
pshflp->nTag = SHFLTAG_PATH;
}
else if (strcmp(name, "collection") == 0) {
pshflp->pshf->attr = SHFILEATTR_FOLDER;
}
else if (strcmp(name, "getcontentlength") == 0) {
pshflp->nTag = SHFLTAG_SIZE;
}
else if (strcmp(name, "getlastmodified") == 0) {
pshflp->nTag = SHFLTAG_LASTMODIFIED;
}
else if (strcmp(name, "source") == 0) {
pshflp->nTag = SHFLTAG_SOURCE;
}
else {
pshflp->nTag = SHFLTAG_UNKNOWN;
}
return 1;
}
static int FileListDataParser(void *userdata, int state, const char *data, size_t len)
{
PSHFILELIST_PARSER_STRUCT pshflp = (PSHFILELIST_PARSER_STRUCT)userdata;
switch (pshflp->nTag) {
case SHFLTAG_PATH:
if (!pshflp->pshf->path) {
if (len >= pshflp->nRootPathLen) {
int nPathLen = (int)len - pshflp->nRootPathLen;
char szPath[PATH_SIZE];
memcpy(szPath, data + pshflp->nRootPathLen, nPathLen);
szPath[nPathLen - (nPathLen > 1 && szPath[nPathLen - 1] == '/' ? 1 : 0)] = (char)NULL;
string sPath = PathDecode(szPath).c_str();
pshflp->pshf->path = new char[sPath.length() + 1];
strcpy(pshflp->pshf->path, sPath.c_str());
}
else {
pshflp->pshf->path = new char[PATH_SIZE];
strcpy(pshflp->pshf->path, "*myself*");
}
}
break;
case SHFLTAG_TYPE:
break;
case SHFLTAG_SIZE:
if (isdigit(data[0])) {
char szSize[20];
memcpy(szSize, data, len);
szSize[len] = (char)NULL;
pshflp->pshf->size = sh_atoi(szSize);
}
break;
case SHFLTAG_LASTMODIFIED:
if (!pshflp->pshf->lastModified) {
char szTime[30];
memcpy(szTime, data, len);
szTime[len] = (char)NULL;
string sTime = FormatLastModified(szTime);
pshflp->pshf->lastModified = new char[sTime.length() + 1];
pshflp->pshf->lastModified_gmt = new char[sizeof(szTime)];
strcpy(pshflp->pshf->lastModified_gmt,szTime);
strcpy(pshflp->pshf->lastModified, sTime.c_str());
}
break;
case SHFLTAG_SOURCE:
if (!pshflp->pshf->source) {
char szSource[PATH_SIZE];
memcpy(szSource, data, len);
szSource[len] = (char)NULL;
pshflp->pshf->source = new char[strlen(szSource) + 1];
strcpy(pshflp->pshf->source, szSource);
}
break;
default:
break;
}
return 0;
}
static int FileListETagParser(void *userdata, int state, const char *nspace, const char *name)
{
PSHFILELIST_PARSER_STRUCT pshflp = (PSHFILELIST_PARSER_STRUCT)userdata;
if (strcmp(name, "response") == 0) {
if (pshflp->pshf) {
pshflp->pvec->push_back(pshflp->pshf);
}
pshflp->pshf = NULL;
}
return 0;
}
static void FreeFileListVector(PVECTOR_SHFILELIST pvec)
{
for (VECTOR_SHFILELIST::iterator iter = pvec->begin(); iter != pvec->end(); iter++) {
PSHFILE_STRUCT pshf = (*iter);
delete []pshf->path;
delete []pshf->lastModified;
delete []pshf->lastModified_gmt;
delete []pshf->source;
}
delete pvec;
}
static string GetErrorMessage(int nError)
{
string sError;
if (nError >= SHCERRNO_UNDEFINED && nError < SHCERRNO_MAX) {
switch (nError) {
case SHCERRNO_UNDEFINED:
sError = "알 수 없는 오류입니다.";
break;
case SHCERRNO_INVALIDHDL:
sError = "잘못된 SDK 핸들입니다.";
break;
case SHCERRNO_INVALIDFLHDL:
sError = "잘못된 파일리스트 핸들입니다.";
break;
case SHCERRNO_SERVICE:
sError = "서버 응답이 정상적이지 않습니다..";
break;
case SHCERRNO_AUTHORIZATION:
sError = "인증에 실패 했습니다.";
break;
case SHCERRNO_ISBUSY:
sError = "다른 작업을 처리하고 있는 중 입니다.";
break;
case SHCERRNO_EXISTSFILE:
sError = "지정한 이름을 가진 파일 또는 디렉토리가 이미 존재합니다.";
break;
case SHCERRNO_NOEXISTSFILE:
sError = "파일 또는 디렉토리가 존재하지 않습니다.";
break;
case SHCERRNO_NOAVAILQUOTA:
sError = "사용 가능한 용량이 부족합니다.";
break;
case SHCERRNO_ALREADYEXIST:
sError = "폴더가 이미 존재 합니다.";
break;
}
}
else {
#ifdef WIN32
LPVOID lpError;
if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, nError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpError, 0, NULL))
sError = "알 수 없는 오류입니다.";
else
sError = (LPCSTR)lpError;
LocalFree(lpError);
#else
sError = strerror(nError);
#endif
}
return sError;
}
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);
string sPath = sSrcPath.substr(stBegin, stEnd - stBegin);
// if (IsDBCS(sPath.c_str())) {
// sRetPath += "/" + URLEncode(UTF8Encode(sPath.c_str()).c_str());
// }
// else
sRetPath += "/" + URLEncode(sPath.c_str());
stBegin = stEnd + 1;
} while (stEnd != 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);
string sPath = URLDecode(sSrcPath.substr(stBegin, stEnd - stBegin).c_str());
// if (IsDBCS(sPath.c_str())) {
// sRetPath += "/" + UTF8Decode(sPath.c_str());
// }
// else
sRetPath += "/" + sPath;
stBegin = stEnd + 1;
} while (stEnd != string::npos);
ReplaceAll(sRetPath, "*amp;", "&");
return sRetPath;
}
static string URLEncode(LPCSTR pszURL)
{
char szEncoded[URL_SIZE];
char* pszEncoded = szEncoded;
while (*pszURL != (char)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 = (char)NULL;
string sRet = szEncoded;
return sRet;
}
static string URLDecode(LPCSTR pszURL)
{
char szOut[URL_SIZE], szHex[3];
::memset(szOut, 0, 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;
#ifdef WIN32
sscanf((char*)szHex, "%x", &szOut[j]);
#else
szOut[j] = (char)strtol(szHex, NULL, 16);
#endif
} else {
szOut[j] = pszURL[i];
}
}
string sRet = szOut;
return sRet;
}
static BOOL DeleteDirectory(LPCSTR pszDirectory)
{
#ifdef WIN32
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);
#else
#define PATH_MAX 4096
char buf[PATH_MAX + 5];
int ret;
snprintf(buf, PATH_MAX, "/bin/rm -rf %s", pszDirectory);
ret = system(buf);
return (ret == 0);
#endif
}
// format : Thu, 15 Dec 2005 05:22:33 GMT
static string FormatLastModified(LPCSTR pszTime)
{
string sTime = pszTime;
if (sTime == "")
return "";
struct tm stm;
int iString = 0;
string::size_type stBegin = 0, stEnd = 0;
do {
stEnd = sTime.find(' ', stBegin);
string sToken = sTime.substr(stBegin, stEnd - stBegin);
switch (iString) {
case 1:
stm.tm_mday = atoi(sToken.c_str());
break;
case 2:
if (sToken == "Jan") stm.tm_mon = 1;
else if (sToken == "Feb") stm.tm_mon = 2;
else if (sToken == "Mar") stm.tm_mon = 3;
else if (sToken == "Apr") stm.tm_mon = 4;
else if (sToken == "May") stm.tm_mon = 5;
else if (sToken == "Jun") stm.tm_mon = 6;
else if (sToken == "Jul") stm.tm_mon = 7;
else if (sToken == "Aug") stm.tm_mon = 8;
else if (sToken == "Sep") stm.tm_mon = 9;
else if (sToken == "Oct") stm.tm_mon = 10;
else if (sToken == "Nov") stm.tm_mon = 11;
else if (sToken == "Dec") stm.tm_mon = 12;
break;
case 3:
stm.tm_year = atoi(sToken.c_str());
break;
case 4:
stm.tm_hour = atoi(sToken.substr(0, 2).c_str()) + 9;
stm.tm_min = atoi(sToken.substr(3, 5).c_str());
stm.tm_sec = atoi(sToken.substr(6, 8).c_str());
break;
}
if (iString++ >= 4)
break;
stBegin = stEnd + 1;
} while (stEnd != string::npos);
char szTemp[20];
sprintf(szTemp, "%04d-%02d-%02d ", stm.tm_year, stm.tm_mon, stm.tm_mday);
sTime = szTemp;
if (stm.tm_hour < 12) {
sTime += "오전";
}
else {
sTime += "오후";
stm.tm_hour -= 12;
}
if (stm.tm_hour == 0)
stm.tm_hour = 12;
sprintf(szTemp, " %02d:%02d:%02d ", stm.tm_hour, stm.tm_min, stm.tm_sec);
sTime += szTemp;
return sTime;
}
// format : Fri Jan 27 12:12:22 2006 Thu
static bool ParseSntpString(LPCSTR pszTime, struct tm* ptm)
{
string sTime = pszTime;
sTime.erase(sTime.find_last_not_of(" \t\n") + 1);
sTime.erase(0, sTime.find_first_not_of(" \t\n"));
if (sTime == "")
return false;
int iString = 0;
string::size_type stBegin = 0, stEnd = 0;
do {
stEnd = sTime.find(' ', stBegin);
string sToken = sTime.substr(stBegin, stEnd - stBegin);
switch (iString) {
case 1:
if (sToken == "Jan") ptm->tm_mon = 1;
else if (sToken == "Feb") ptm->tm_mon = 2;
else if (sToken == "Mar") ptm->tm_mon = 3;
else if (sToken == "Apr") ptm->tm_mon = 4;
else if (sToken == "May") ptm->tm_mon = 5;
else if (sToken == "Jun") ptm->tm_mon = 6;
else if (sToken == "Jul") ptm->tm_mon = 7;
else if (sToken == "Aug") ptm->tm_mon = 8;
else if (sToken == "Sep") ptm->tm_mon = 9;
else if (sToken == "Oct") ptm->tm_mon = 10;
else if (sToken == "Nov") ptm->tm_mon = 11;
else if (sToken == "Dec") ptm->tm_mon = 12;
break;
case 2:
ptm->tm_mday = atoi(sToken.c_str());
break;
case 3:
ptm->tm_hour = atoi(sToken.substr(0, 2).c_str()) + 9;
ptm->tm_min = atoi(sToken.substr(3, 5).c_str());
ptm->tm_sec = atoi(sToken.substr(6, 8).c_str());
break;
case 4:
ptm->tm_year = atoi(sToken.c_str());
break;
}
if (iString++ >= 4)
break;
stBegin = stEnd + 1;
} while (stEnd != string::npos);
return true;
}
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);
}
static INT64 sh_filelength(int nFd)
{
#ifdef WIN32
return _filelengthi64(nFd);
#else
INT64 nLength = lseek64(nFd, 0, SEEK_END);
lseek64(nFd, 0, SEEK_SET);
return nLength;
#endif
}
static INT64 sh_atoi(LPCSTR pszSize)
{
#ifdef WIN32
return _atoi64(pszSize);
#else
return strtoll(pszSize, NULL, 10);
#endif
}
#ifndef WIN32
int GetLastError()
{
return errno;
}
void SetLastError(int nError)
{
errno = nError;
}
#endif
static int _sh_recv(SOCKET s, char *pszBuf, int nLen)
{
int iRecv = 0, nRecvLen;
fd_set rset;
struct timeval tv;
FD_ZERO(&rset);
FD_SET(s, &rset);
tv.tv_sec = timeout;
tv.tv_usec = 0;
do {
if (select(s + 1, &rset, NULL, NULL, &tv) < 0) break;
if (!FD_ISSET(s, &rset)) break;
nRecvLen = recv(s, pszBuf + iRecv, nLen, 0);
iRecv += nRecvLen;
nLen -= nRecvLen;
} while (nLen > 0 && nRecvLen > 0);
return nLen < 0 ? SOCKET_ERROR : iRecv;
}
void sh_set_C_timeout(int second)
{
timeout = second;
}
int sh_set_auth_expire(HSHSDK hshsdk,int ntime)
{
if(!hshsdk)
return FALSE;
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
psdk->nAuthExpire = ntime;
return TRUE;
}
int sh_get_auth_expire(HSHSDK hshsdk)
{
if(!hshsdk)
return FALSE;
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
return psdk->nAuthExpire;
}
static BOOL check_suthstring(const char* pszAuthstring)
{
char* pAuth;
char* pData;
char* pSrc;
char szDst[128]={0};
BOOL bResult;
pSrc = new char[strlen(pszAuthstring)+1];
memcpy(pSrc,pszAuthstring,strlen(pszAuthstring)+1);
pAuth = strtok((char*)pSrc,":");
if(pAuth == NULL)
bResult = FALSE;
else
{
pData = strtok(NULL,":");
if(pData == NULL)
bResult = FALSE;
else
{
ne_md5_buffer(pAuth,szDst);
#ifdef WIN32
if(stricmp(pData,szDst) == 0)
#else
if(strcasecmp(pData,szDst) == 0)
#endif
{
strcpy((char*)pszAuthstring,pAuth);
bResult = TRUE;
}
else
bResult = FALSE;
}
}
delete []pSrc;
return bResult;
}
#ifdef WIN32
void MyOutputDebugString(char* fmt,...)
{
/*
va_list ap;
CString strTemp;
CString str;
char szTemp1[1000]={0};
char wszPath[MAX_PATH*2]={0};
va_start(ap, fmt);
str.FormatV(fmt,ap);
str += "\n";
SYSTEMTIME SystemTime;
GetLocalTime(&SystemTime);
memset(szTemp1,0,1000);
// 기록할 로그 문자열
sprintf(szTemp1,"%d-%02d-%02d %02d:%02d:%02d : %s",
SystemTime.wYear,
SystemTime.wMonth,
SystemTime.wDay,
SystemTime.wHour,
SystemTime.wMinute,
SystemTime.wSecond,
str);
WriteLogToFile(szTemp1);
va_end(ap);
*/
}
void WriteLogToFile(char* pdata)
{
FILE *file;
long curpos, length;
file = fopen("C:\\CSDK.log","a");
curpos = ftell(file);
fseek(file, 0L, SEEK_END);
length = ftell(file);
fseek(file, curpos, SEEK_SET);
fprintf(file,pdata);
fclose(file);
}
#endif
void __tea_encrypt(unsigned long *v, unsigned long *k)
{
unsigned long v0 = v[0], v1 = v[1], sum = 0, i; /* set up */
unsigned long delta = 0x9e3779b9; /* a key schedule constant */
unsigned long k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; /* cache key */
for (i = 0; i < 32; i++) { /* basic cycle start */
sum += delta;
v0 += (v1 << 4) + (k0 ^ v1) + (sum ^ (v1 >> 5)) + k1;
v1 += (v0 << 4) + (k2 ^ v0) + (sum ^ (v0 >> 5)) + k3; /* end cycle */
}
v[0] = v0; v[1] = v1;
}
void __tea_decrypt(unsigned long *v, unsigned long *k)
{
unsigned long v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i; /* set up */
unsigned long delta = 0x9e3779b9; /* a key schedule constant */
unsigned long k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; /* cache key */
for (i = 0; i < 32; i++) { /* basic cycle start */
v1 -= (v0 << 4) + k2 ^ v0 + sum ^ (v0 >> 5) + k3;
v0 -= (v1 << 4) + k0 ^ v1 + sum ^ (v1 >> 5) + k1;
sum -= delta; /* end cycle */
}
v[0] = v0; v[1] = v1;
}
void tea_encrypt(char *buf, int len)
{
int __len = (len + 7) >> 3;
int i;
//char *key = PRIVATE_KEY;
for (i = 0; i < __len; i++) {
__tea_encrypt((((unsigned long *)buf) + (i << 1)), (unsigned long *)PRIVATE_KEY);
}
}
void tea_decrypt(char *buf, int len)
{
int __len = (len + 7) >> 3;
int i;
for (i = 0; i < __len; i++) {
__tea_decrypt((((unsigned long *)buf) + (i << 1)), (unsigned long *)PRIVATE_KEY);
}
}