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

3146 lines
69 KiB
C++

// SHCSDK.cpp : DLL 응용 프로그램에 대한 진입점을 정의합니다.
//
#ifdef WIN32
#include <windows.h>
#include <io.h>
#include <math.h>
#include <vector>
#include <iostream>
#include "atlstr.h"
typedef BOOL (WINAPI *API_GET_FILE_SIZE_EX)(HANDLE hFile,PLARGE_INTEGER lpFileSize);
#else
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.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
//#include <sys/param.h> // for HZ
#include <string.h>
#define _NEWAUTH
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
//tael
#define lseek64 lseek
#define stat64 stat
#define open64 open
#endif
//#include <fcntl.h>
#include <time.h>
//#include <sys/types.h>
//#include <sys/stat.h>
//#include <fcntl.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,int nFrom=1);
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,int nFrom = 1);
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,int nFrom =1);
static bool DoDownloadBuffer(PSHCSDK_STRUCT psdk, LPCSTR pszSrcFile,
int (*data_func)(
void* userval,
const char* buf,
size_t len),
void* userval,
int nFrom = 1
);
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);
static int _sh_send(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,int nFlag);
char* get_auth_str2(PSHCSDK_STRUCT psdk, LPCSTR pszPath,int nFlag,char*);
int StrTrim(char* dst, const char* src, int len);
static time_t get_time_from_sntp();
#ifdef WIN32
void WriteLogToFile(char* pdata);
void MyOutputDebugString(char* fmt,...);
#else
#define WriteLogToFile(...)
#define MyOutputDebugString(...)
#endif
static int timeout = 5;
string g_sAuth;
#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, int nFlag)
{
unsigned char pszAuth[4096];
unsigned char *bintoken = NULL;
char szTemp[16];
// string sAuth;
int nRet;
#ifdef WIN32
struct tm tmnow;
#endif
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;
int32_t ltime = 0;
switch(nFlag)
{
case 0: // 서버에서 시간 값을 가져온다.
ltime = get_time_from_sntp();
break;
case 1:
ltime = time(NULL);
break;
}
// struct tm *newtime = localtime(&ltime);
// printf("%d-%d-%d %d:%d:%d",newtime->tm_year,newtime->tm_mon,newtime->tm_mday,newtime->tm_hour,newtime->tm_min,newtime->tm_sec);
// printf("\n");
int32_t kkk = ltime + psdk->nAuthExpire;
memcpy(pszAuth,(unsigned char *)&kkk,sizeof(kkk));
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();
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);
g_sAuth = "Basic ";
g_sAuth += pResult;
// if (pszAuth != NULL) delete [] pszAuth;
return strdup(g_sAuth.c_str());
// strncpy(pret_str , g_sAuth.c_str() , 4096);
// return NULL;
}
#if 0
char* get_auth_str(PSHCSDK_STRUCT psdk, LPCSTR pszPath,int nFlag)
{
unsigned char* pszAuth=NULL;
unsigned char *bintoken = NULL;
char szTemp[16];
string sAuth;
int nRet;
#ifdef WIN32
struct tm tmnow;
#endif
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];
long ltime = 0;
switch(nFlag)
{
case 0: // 서버에서 시간 값을 가져온다.
ltime = get_time_from_sntp();
break;
case 1:
ltime = time(NULL);
break;
}
// struct tm *newtime = localtime(&ltime);
// printf("%d-%d-%d %d:%d:%d",newtime->tm_year,newtime->tm_mon,newtime->tm_mday,newtime->tm_hour,newtime->tm_min,newtime->tm_sec);
// printf("\n");
long kkk = ltime + psdk->nAuthExpire;
memcpy(pszAuth,(unsigned char *)&kkk,sizeof(kkk));
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();
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;
if (pszAuth != NULL) delete [] pszAuth;
return strdup(sAuth.c_str());
}
#endif
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
{
if (psdk->nError == SHCERRNO_AUTHORIZATION)
{
if (DoCommand(psdk, "PROPFIND", sPath.c_str(), sHeaders.c_str(), sBody.c_str(), true,
(LPVOID)FileListSTagParser, (LPVOID)FileListDataParser, (LPVOID)FileListETagParser, &shflp,0))
{
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
{
FreeFileListVector(shflp.pvec);
shflp.pvec = NULL;
}
}
}
else {
psdk->nError = GetLastError();
psdk->sError = GetErrorMessage(psdk->nError);
}
sPath.clear();
sBody.clear();
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;
// char* szPath;
// szPath = (char*)malloc(strlen(directory));
// StrTrim(szPath,directory,strlen(directory));
if (sh_file_exist(hshsdk,directory))
{
psdk->nError = SHCERRNO_ALREADYEXIST;
psdk->sError = GetErrorMessage(psdk->nError);
// free(szPath);
return false;
}
string sDirectory = psdk->sPath;
if (directory[0] != '/')
sDirectory += "/";
sDirectory += directory;
int nRet = DoCommand(psdk, "MKCOL", sDirectory.c_str());
if (!nRet)
{
if (sh_get_error_number(psdk) == SHCERRNO_AUTHORIZATION)
nRet = DoCommand(psdk, "MKCOL", sDirectory.c_str(),"","",false,NULL,NULL,NULL,NULL,0);
}
// free(szPath);
return nRet;
}
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");
int nRet = DoCommand(psdk, "COPY", sSrcPath.c_str(), sHeader.c_str());
if (!nRet)
{
if (sh_get_error_number(psdk) == SHCERRNO_AUTHORIZATION)
nRet = DoCommand(psdk, "COPY", sSrcPath.c_str(), sHeader.c_str(),"",false,NULL,NULL,NULL,NULL,0);
}
return nRet;
}
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");
int nRet = DoCommand(psdk, "MOVE", sSrcPath.c_str(), sHeader.c_str());
if(!nRet)
{
if (sh_get_error_number(psdk) == SHCERRNO_AUTHORIZATION)
nRet = DoCommand(psdk, "MOVE", sSrcPath.c_str(), sHeader.c_str(),"",false,NULL,NULL,NULL,NULL,0);
}
return nRet;
}
WIN32DLL
int sh_delete(HSHSDK hshsdk, const char* path)
{
if (!hshsdk)
return FALSE;
PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk;
psdk->nError = 0;
int ncount=0;
// 경로가 '////////' 형식인경우
for(int i=0;i<strlen(path);i++)
{
if(path[i] == '/')
ncount++;
}
if (path == NULL || strlen(path) == 0 || (strlen(path) == 1 && path[0] == '/') || (ncount == strlen(path))) {
psdk->nError = SHCERRNO_SERVICE;
psdk->sError = "루트는 삭제할 수 없습니다.";
return FALSE;
}
string sPath = psdk->sPath;
if (path[0] != '/')
sPath += "/";
sPath += path;
int nRet = DoCommand(psdk, "DELETE", sPath.c_str());
if (!nRet)
{
if (sh_get_error_number(psdk) == SHCERRNO_AUTHORIZATION)
nRet = DoCommand(psdk, "DELETE", sPath.c_str(),"","",false,NULL,NULL,NULL,NULL,0);
}
return nRet;
}
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;
int nRet = DoUpload(psdk, srcPath, dstPath, writePolicy, availQuota);
if (!nRet)
{
if( sh_get_error_number(psdk) == 401)
{
nRet = DoUpload(psdk, srcPath, dstPath, writePolicy, availQuota,0);
}
}
return nRet;
}
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;
int nRet = DoDownloadBuffer(psdk, srcPath, proc, userval);
if(!nRet)
{
if( sh_get_error_number(psdk) == 401)
nRet = DoDownloadBuffer(psdk, srcPath, proc, userval,0);
}
return nRet;
}
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;
//pizon
int nRet = DoDownload(psdk, srcPath, dstPath, writePolicy, availQuota);
if(!nRet)
{
if( sh_get_error_number(psdk) == 401)
nRet = DoDownload(psdk, srcPath, dstPath, writePolicy, availQuota,0);
}
return nRet;
}
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;
}
#define AUTHPRIME 137897
typedef struct _s_time_sync_t
{
long sync_info;
}time_sync_t;
#define SNTP_DOMAIN "ktsh-tsc.ktsh.co.kr"
#define SNTP_PORT 80
static time_t get_time_from_sntp()
{
char szHost[128];
int nRecv;
time_sync_t tst;
int nWrite;
time_sync_t *pSyncInfo = NULL;
#ifdef WIN32
tm *ttm=NULL;
#endif
int32_t ltime = (int32_t)time(NULL);
if (ne_sock_init() != NE_OK)
{
#ifdef _DEBUG
printf("time sever connect error : sock init fail\n");
#endif
return time(NULL);
}
// Get server time
strcpy(szHost, SNTP_DOMAIN);
if (isalpha(szHost[0]))
{
hostent *phe = gethostbyname(szHost);
if (!phe)
{
#ifdef _DEBUG
printf("time sever connect error : gethostbyname fail\n");
#endif
return time(NULL);
}
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));
}
#ifndef WIN32
#define RETRY 2
int recv_err = 0;
recv_retry:
#endif
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
{
#ifdef WIN32
int nRet = WSAGetLastError();
#endif
#ifdef _DEBUG
printf("time sever connect error : socket create fail\n");
#endif
return time(NULL);
}
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();
#ifdef _DEBUG
printf("time sever connect error : select fail\n");
#endif
return time(NULL);
}
}
else
{
#ifdef _DEBUG
printf("time sever connect error : unknown error code\n");
#endif
return time(NULL);
}
}
#else
__nonblock(sock);
{
int i, nRet;
for (i = 0; i < (timeout * 10); i++) {
//fprintf(stderr, "B_CONN\n");
errno = 0;
if (connect(sock, (SOCKADDR*)&sa, sizeof(sa)) != SOCKET_ERROR) {
//fprintf(stderr, "E_CONN QUIT\n");
//errno = 0;
//break;
;
} else {
nRet = errno;
}
//fprintf(stderr, "A_CONN\n");
if (errno == EISCONN) {
//fprintf(stderr, "E CONN\n");
break;
}
if (((i + 1) % 10) == 0) {
//fprintf(stderr, "RETRY\n");
shutdown(sock, SHUT_RDWR);
close(sock);
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
{
//fprintf(stderr, "RETRY-RET\n");
return time(NULL);
}
__nonblock(sock);
/* Elenoa */
}
usleep(100000);
//fprintf(stderr, "CLI %d\n", i);
}
if (errno != EISCONN && errno != 0)
{
return time(NULL);
}
}
#endif
//fprintf(stderr, "M_CONN\n");
tst.sync_info = ltime + AUTHPRIME - (ltime % AUTHPRIME);
tst.sync_info = htonl(tst.sync_info);
nWrite = _sh_send(sock, (char *)&tst, sizeof(tst));
if(nWrite < 0)
{
//fprintf(stderr, "ME_CONN-1\n");
closesocket(sock);
#ifndef WIN32
if (recv_err <= RETRY) {
recv_err ++;
goto recv_retry;
}
#endif
#ifdef _DEBUG
printf("time sever connect error : send fail\n");
#endif
return time(NULL);
}
nRecv = _sh_recv(sock, szHost, sizeof(szHost));
if (nRecv < 4)
{
//fprintf(stderr, "ME_CONN-2\n");
closesocket(sock);
#ifndef WIN32
if (recv_err <= RETRY) {
recv_err ++;
goto recv_retry;
}
#endif
#ifdef _DEBUG
printf("time sever connect error : recv fail\n");
#endif
return time(NULL);
}
pSyncInfo = (time_sync_t *)&szHost;
pSyncInfo->sync_info = ntohl(pSyncInfo->sync_info);
closesocket(sock);
//fprintf(stderr, "D_CONN\n");
return pSyncInfo->sync_info;
}
#include "mcrypt.h"
#define ENCRYPT_KEY "I'm your father"
#define INIT_VECTOR "1234567890123456"
#define ENCRYPT_BIT 24
WIN32DLL
int sh_encrypt(const char *text, char *encrypted)
{
MCRYPT mcrypt = NULL;
BOOL bResult = FALSE;
struct tm *stm;
char szKey[ENCRYPT_BIT];
char szIV[ENCRYPT_BIT];
char szBuf[1024];
time_t tnow;
tnow = get_time_from_sntp();
if(tnow == 0)
goto EXIT_FUNCTION;
stm = gmtime((time_t*)&tnow);
// ttm = gmtime((time_t*)&pSyncInfo->sync_info);
// 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);
#ifndef WIN32
{
#endif
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,int nFrom)
{
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, nFrom);
//fprintf(stderr , "pszAuth:%s:%p:\n" , pszAuth , pszAuth);
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
//pizon
//fprintf(stderr , "pszAuth:%s:%p:\n" , pszAuth , pszAuth);
if(pszAuth)
free(pszAuth);
#endif
sBody.clear();
return bRet;
}
static bool DoUpload(PSHCSDK_STRUCT psdk, LPCSTR pszSrcFile, LPCSTR pszDstFile, int nWritePolicy, INT64 nAvailQuota,int nFrom)
{
// 현재 URI 보관
bool bFindSource = true;
bool bSessionChange = false;
ne_uri nuri = psdk->nuri;
string strAuth;
// 업로드 코드 시작
string sPath = psdk->sPath + pszDstFile;
string sHeaders;
int nRet;
ne_request *pnreq = NULL;
#ifdef _NEWAUTH
char* pszAuth = get_auth_str(psdk,sPath.c_str(),nFrom);
#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 = open64(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;
DWORD dwSize;
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
bool bIsWindowsXPorLater = ((osvi.dwMajorVersion > 5)|| ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion >= 1)));
if( bIsWindowsXPorLater)
{
HMODULE handle = (HMODULE) LoadLibrary("KERNEL32.DLL");
API_GET_FILE_SIZE_EX api_getsize;
if (handle)
{
api_getsize = (API_GET_FILE_SIZE_EX) GetProcAddress(handle, "GetFileSizeEx");
if(api_getsize)
{
api_getsize(psdk->hFile,&Size);
psdk->nFileSize = Size.QuadPart;
}
FreeLibrary(handle);
}
else
{
psdk->nFileSize = 0;
}
}
else
{
psdk->nFileSize = GetFileSize(psdk->hFile,NULL);
}
#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
strAuth = "Basic ";
strAuth += psdk->sAuth;
ne_add_request_header(pnreq, "Authorization", strAuth.c_str());//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
int nFrom)
{
string sPath = psdk->sPath + pszSrcFile;
string sHeaders;
PSHFILE_STRUCT pshf;
int nRet;
ne_request *pnreq = NULL;
char* pszAuth;
REPEAT_FUNC:
#ifdef _NEWAUTH
pszAuth = get_auth_str(psdk,sPath.c_str(),nFrom);
#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,nFrom);
// 원래 서버로 재접속
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,int nFrom)
{
string sPath = psdk->sPath + pszSrcFile;
string sHeaders;
PSHFILE_STRUCT pshf;
char* pszAuth;
ne_request *pnreq = NULL;
#ifdef _NEWAUTH
pszAuth = get_auth_str(psdk,sPath.c_str(),nFrom);
#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 = open64(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,nFrom);
// 원래 서버로 재접속
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;
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;
if (q > m_dbLimit)
{
DWORD dwret = (DWORD)((((q*t)/m_dbLimit)-t));
#ifdef WIN32
Sleep(dwret);
#else
usleep(dwret);
#endif
}
}
psdk->cOldTick = clock();
}
#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;
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)
{
#ifndef WIN32
if (strlen(pszOld) != strlen(pszNew)) {
#endif
string sOld = pszOld;
string sNew = pszNew;
size_t s;
while ((s = sValue.find(sOld)) != string::npos)
sValue.replace(s, sOld.length(), sNew);
#ifndef WIN32
} else {
char *pszValue, *p, *r;
pszValue = (char *)malloc(sValue.length() + 1);
strcpy(pszValue, sValue.c_str());
r = pszValue;
while ((p = strstr(r, pszOld))) {
memcpy(p, pszNew, strlen(pszNew));
r = p;
}
sValue.clear();
sValue = pszValue;
free(pszValue);
}
#endif
}
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;
}
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 = timeout;
tv.tv_usec = 0;
do {
if (select(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;
}
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(uint32_t *v, uint32_t *k)
{
uint32_t v0 = v[0], v1 = v[1], sum = 0, i; /* set up */
uint32_t delta = 0x9e3779b9; /* a key schedule constant */
uint32_t 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(uint32_t *v, uint32_t *k)
{
uint32_t v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i; /* set up */
uint32_t delta = 0x9e3779b9; /* a key schedule constant */
uint32_t 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((((uint32_t *)buf) + (i << 1)), (uint32_t *)PRIVATE_KEY);
}
}
void tea_decrypt(char *buf, int len)
{
int __len = (len + 7) >> 3;
int i;
for (i = 0; i < __len; i++) {
__tea_decrypt((((uint32_t *)buf) + (i << 1)), (uint32_t *)PRIVATE_KEY);
}
}
int StrTrim(char* dst, const char* src, int len)
{
register int dlen, i;
register char *dp, *sp;
char *buff;
if(!len) return 0;
buff = (char *)calloc(1, len + 1);
strncpy(buff, src, len);
/* R-Trim */
sp = buff + len -1; dlen = len -1;
while(1){
if(dlen <= 0) break;
else if(*sp != ' ' && *sp != 0x00) break;
else *sp = 0x00;
sp --; dlen --;
}
dlen = strlen(buff); sp = buff; i = 0;
/* L-Trim */
while(i < dlen){ if(*sp != ' ' && *sp != 0x00) break; sp ++; i++; }
dlen = strlen(sp);
strcpy(dst, sp);
free(buff);
return dlen;
}