// SHCSDK.cpp : DLL ÀÀ¿ë ÇÁ·Î±×·¥¿¡ ´ëÇÑ ÁøÀÔÁ¡À» Á¤ÀÇÇÕ´Ï´Ù. // #ifdef WIN32 #include #include #include #include #include #include #include #include #include #include typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef BOOL (WINAPI *API_GET_FILE_SIZE_EX)(HANDLE hFile,PLARGE_INTEGER lpFileSize); #else #include // for HZ #include #include #include #include #include #include #include #include #include #include #include #include #include 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 #include #include #include #include "solbox_util.h" // dadamin : Implement a function that does not exist. #include "SHCSDK.h" #include "GTS_INFO.h" #include "ne_request.h" #include "ne_session.h" #include "ne_xml.h" #include "ne_dates.h" #ifndef off64_t #define off64_t INT64 #endif #ifdef WIN32 # pragma comment(lib, "ws2_32.lib") #endif #define MAX_TRY 3 #define PRIVATE_KEY "gE\x8bk\xc6\x23{2i\x98 VECTOR_SHFILELIST, *PVECTOR_SHFILELIST; typedef struct SHCSDK_HANDLE { ne_session* pnsess; ne_inet_addr** hostlist; int nhostcnt; 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 setFileList; string sSessionID; int nAuthExpire; } SHCSDK_STRUCT, *PSHCSDK_STRUCT; enum { SHSTOP_NO = 0, SHSTOP_BYUSER, SHSTOP_BYERROR, }; 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 #define TERM_TICKCOUNT (CLOCKS_PER_SEC >> 3) DWORD dwTransferd; static int timeout = 5; static int _connect_time_out = 5; static int _read_time_out = 120; // neon library ±âº» ¼³Á¤°ªÀº 120ÃÊ // #ifdef WIN32 HINSTANCE g_hInst; #ifdef _DEBUG #define _CRTDBG_MAP_ALLOC #include #define SET_CRT_DEBUG_FIELD(a) _CrtSetDbgFlag((a) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)) #define CLEAR_CRT_DEBUG_FIELD(a) _CrtSetDbgFlag(~(a) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)) #else #define SET_CRT_DEBUG_FIELD(a) ((void) 0) #define CLEAR_CRT_DEBUG_FIELD(a) ((void) 0) #endif BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved) { #ifdef DEBUG SET_CRT_DEBUG_FIELD( _CRTDBG_LEAK_CHECK_DF | _CRTDBG_DELAY_FREE_MEM_DF ); //_CrtSetBreakAlloc(76); #endif g_hInst = (HINSTANCE)hModule; return TRUE; } static int __nonblock_win32(SOCKET s) { int ul = 1; int result; result = ioctlsocket( s, FIONBIO, (u_long FAR*)&ul ); return result; } #else int GetLastError() { return errno; } void SetLastError(int nError) { errno = nError; } #include 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); } } 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 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); tv.tv_sec = iWaitTimeInt; tv.tv_usec = ulWaitTimeDec; #ifdef WIN32 Sleep((DWORD)(dWaitTime*1000)); #else usleep((DWORD)(dWaitTime*1000)); #endif return 1; } 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 void status_cb(void *userdata, ne_session_status status, const ne_session_status_info *info) { switch (status) { case ne_status_connected: { ne_socket *sock = get_session_socket((ne_session *)userdata); // ŸÀÓ ¾Æ¿ô °ª ÁöÁ¤ÇÔ(30ÃÊ) // ¸¶Áö¸· µ¥ÀÌÅÍ Àü¼Û ¿Ï·á(½ÇÁ¦ Àü¼Û ¿Ï·áµÇÁö ¾Ê°í Ä¿³Î ÀÀ´ä) ÈÄ // close È£Ãâ µÈ °æ¿ì ÇØ´ç ¿É¼Ç ¹ÌÁöÁ¤µÈ °æ¿ì ³×Æ®¿öÅ© »ó Àü¼ÛÇÒ µ¥ÀÌÅÍ ³²¾Æ // ÀÖ´õ¶óµµ ÇØ´ç µ¥ÀÌÅÍ ¸ðµÎ »èÁ¦µÊ struct linger l = {1, 30}; #ifdef WIN32 setsockopt(ne_sock_fd(sock), SOL_SOCKET, SO_LINGER,(char*) &l, sizeof l); #else // WIN32 setsockopt(ne_sock_fd(sock), SOL_SOCKET, SO_LINGER, &l, sizeof l); #endif // WIN32 } break; } } // ¼¼¼Ç »ý¼º ¹× Ãß°¡ ¼³Á¤ static bool solbox_session_create(PSHCSDK_STRUCT psdk) { psdk->pnsess = ne_session_create(psdk->nuri.scheme, psdk->nuri.host, psdk->nuri.port); // ¼¼¼ÇÀÇ »óÅ notifier ÇÔ¼ö µî·Ï ne_set_notifier(psdk->pnsess, status_cb, psdk->pnsess); return true; } //¼¼¼ÇÀÇ ÆÄ±« ¹× Ãß°¡ ÀÛ¾÷ static void solbox_session_destroy(PSHCSDK_STRUCT psdk) { ne_session_destroy(psdk->pnsess); } // dns cache ±â´ÉÀ» »ç¿ëÇϱâ À§ÇÑ ÇÔ¼öÀÌ´Ù. // //static bool solbox_session_create(PSHCSDK_STRUCT psdk) //{ // const ne_inet_addr** result; // int nResultCnt; // // result = solbox_resolve(psdk->nuri.host, &nResultCnt); // ne_free(result); // result = solbox_resolve("bd-04-fhs001.ktsh.co.kr", &nResultCnt); // ne_free(result); // result = solbox_resolve("bd-04-fhs001.ktsh.co.kr", &nResultCnt); // ne_free(result); // result = solbox_resolve("bd-04-fhs001.ktsh.co.kr", &nResultCnt); // ne_free(result); // result = solbox_resolve(psdk->nuri.host, &nResultCnt); // if( result == NULL ) // { // // host ¿¡·¯ÀÔ´Ï´Ù. // return false; // } // // psdk->pnsess = ne_session_create(psdk->nuri.scheme, psdk->nuri.host, psdk->nuri.port); // // ne_set_addrlist(psdk->pnsess, result, nResultCnt); // ne_free(result); // return true; //} 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; case SHCERRNO_RESP_TIMEOUT: sError = "¼ÒÄÏ ÀÐ±â ½ÇÆÐÀÔ´Ï´Ù."; break; case SHCERRNO_NE_LOOKUP: sError = "È£½ºÆ® Á¤º¸¿¡´ëÇØ ·è¾÷¿¡ ½ÇÆÐÇß½À´Ï´Ù."; break; case SHCERRNO_NE_CONNECT: sError = "¼­¹ö¿¡ ¿¬°áÀ» ÇÏÁö ¸øÇß½À´Ï´Ù."; break; case SHCERRNO_TRAGETBIGGER: sError = "´ë»ó µ¥ÀÌÅÍÀÇ Å©±â°¡ Àü¼ÛÇÒ µ¥ÀÌÅÍ Å©±â¿Í µ¿ÀÏÇϰųª Å®´Ï´Ù."; break; case SHCERRNO_DNS_TIMEOUT: sError = "DNS Äõ¸® ½Ã°£ÃʰúÀÔ´Ï´Ù."; break; case SHCERRNO_EXT_OVERFLOW: sError = "download ½Ã È®Àå °ªÀÌ 512Bytes¸¦ ÃʰúÇÏ¿´½À´Ï´Ù."; 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; } int StrTrim(char* dst, const char* src, int len) { register int dlen, i; register char *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; } static INT64 sh_atoi(LPCSTR pszSize) { #ifdef WIN32 return _atoi64(pszSize); #else return strtoll(pszSize, NULL, 10); #endif } 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 } 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; } // format : Thu, 15 Dec 2005 05:22:33 GMT static string FormatLastModified(LPCSTR pszTime) { string sTime; // RFC1123_FORMAT to time_t format & GMT+9(32400 sec) // "Thu, 15 Dec 2005 05:22:33 GMT" ÀÌ·± ÇüŸ¦ RFC1122_FORMAT À̶óÇÑ´Ù. // RFC1122_FORMAT Æ÷¸ËÀ» ÀÎÀÚ·Î ³Ñ°Ü¼­ time_t¸¦ ¾òÀ» ¼ö ÀÖ¾ú°í, // ¾òÀº °ª¿¡´Ù°¡ 9½Ã°£¿¡ ÇØ´çÇÏ´Â sec¸¦ ´õÇØ¼­ GMT+9¸¦ ±¸ÇÑ´Ù. time_t t = ne_rfc1123_parse(pszTime) + 32400; // time_t to struct tm // À§ °úÁ¤¿¡¼­ ÀÌ¹Ì GMT+9°¡ 󸮵ǾúÀ¸¹Ç·Î, // ±âÁ¸ ¼Ò½ºÃ³·³ º¹ÀâÇÑ °úÁ¤À» °ÅÄ¡Áö ¾Ê¾Æµµ µÈ´Ù. // ´ÜÁö time_t °ªÀ» ¼Ó¼ºÀ» ¾Ë°í year¿¡ 1900À» mon1À» ´õÇØÁØ´Ù. struct tm stm; stm = *gmtime(&t); stm.tm_year = stm.tm_year + 1900; stm.tm_mon = stm.tm_mon + 1; // ÃÖÁ¾ÀûÀ¸·Î Ç¥ÇöÇϰíÀÚ ÇÏ´Â ³¯Â¥ Æ÷¸ËÀ¸·Î º¯°æÃ³¸®ÇÑ´Ù. char szTemp[20]; sprintf(szTemp, "%04d-%02d-%02d ", stm.tm_year, stm.tm_mon, stm.tm_mday); sTime = szTemp; sprintf(szTemp, " %02d:%02d:%02d", stm.tm_hour, stm.tm_min, stm.tm_sec); sTime += szTemp; return sTime; } // 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 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 BOOL check_suthstring(const char* pszAuthstring) { char* pAuth; char* pData; char* pSrc; char* context = NULL; char szDst[128]={0}; BOOL bResult; pSrc = new char[strlen(pszAuthstring)+1]; memcpy(pSrc,pszAuthstring,strlen(pszAuthstring)+1); #ifdef WIN32 pAuth = strtok_s((char*)pSrc,":", &context); #else // WIN32 pAuth = strtok_r((char*)pSrc,":",&context); #endif // WIN32 if(pAuth == NULL) bResult = FALSE; else { #ifdef WIN32 pData = strtok_s(NULL,":", &context); #else // WIN32 pAuth = strtok_r(NULL,":",&context); #endif // WIN32 if(pData == NULL) bResult = FALSE; else { 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; } 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; } typedef struct _s_time_sync_t { int32_t sync_info; }time_sync_t; #define AUTHPRIME 137897 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 struct addrinfo *result; strcpy(szHost, SNTP_DOMAIN); if (isalpha(szHost[0])) { struct addrinfo hints = {0}; hints.ai_socktype = SOCK_STREAM; hints.ai_family = PF_UNSPEC; if( getaddrinfo( szHost, NULL, &hints, &result ) != 0 ) { #ifdef _DEBUG printf("time sever connect error : getaddrinfo fail\n"); #endif return time(NULL); } struct sockaddr_in * addr = (struct sockaddr_in *)result->ai_addr; sprintf(szHost, "%s", inet_ntoa(addr->sin_addr)); freeaddrinfo(result); } #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 // WIN32 __nonblock(sock); { int i, nRet; for (i = 0; i < (timeout * 10); i++) { errno = 0; if (connect(sock, (SOCKADDR*)&sa, sizeof(sa)) != SOCKET_ERROR) { ; } else { nRet = errno; } if (errno == EISCONN) { break; } if (((i + 1) % 10) == 0) { shutdown(sock, SHUT_RDWR); close(sock); sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == INVALID_SOCKET) { return time(NULL); } __nonblock(sock); /* Elenoa */ } usleep(100000); } if (errno != EISCONN && errno != 0) { return time(NULL); } } #endif // WIN32 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) { 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) { 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); return pSyncInfo->sync_info; } 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] == '%') { 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 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); sRetPath += "/" + URLEncode(sPath.c_str()); stBegin = stEnd + 1; } while (stEnd != string::npos); return sRetPath; } 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); } } 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; } 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; ne_unbase64(psdk->sAuth.c_str(),&bintoken); if (bintoken == NULL) return NULL; char* context = NULL; char* pData = NULL; #ifdef WIN32 pData = strtok_s((char*)bintoken,":", &context); #else // WIN32 pData = strtok_r((char*)bintoken,":", &context); #endif // WIN32 if(pData == NULL) { if(bintoken) ne_free(bintoken); 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; } int32_t kkk = ltime + psdk->nAuthExpire; memcpy(pszAuth,(unsigned char *)&kkk,sizeof(kkk)); md5_buffer_bin(psdk->sSessionID.c_str(),szTemp); memcpy(pszAuth+4,szTemp,sizeof(szTemp)); 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); string sAuth; sAuth = "Basic "; sAuth += pResult; if(bintoken) ne_free(bintoken); if(pResult) ne_free(pResult); if(pszTemp) delete [] pszTemp; return strdup(sAuth.c_str()); } 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; 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 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()); sRetPath += "/" + sPath; stBegin = stEnd + 1; } while (stEnd != string::npos); ReplaceAll(sRetPath, "*amp;", "&"); return sRetPath; } 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 pshf; } pvec->clear(); delete pvec; } 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; #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_DOCOMMAND; } #ifdef _NEWAUTH pszAuth = get_auth_str(psdk,pszPath, nFrom); ne_add_request_header(pnreq, "Authorization",pszAuth); #else // _SP_SDK_ 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_DOCOMMAND; } 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_DOCOMMAND; } if (bParseBody) { ReplaceAll(sBody, "&", "*amp;"); ne_xml_parser* pnxparser = ne_xml_create(); ne_xml_push_handler(pnxparser, (ne_xml_startelm_cb*)pSTagParser, (ne_xml_cdata_cb*)pDataParser, (ne_xml_endelm_cb*)pETagParser, pParam); ne_xml_parse(pnxparser, sBody.c_str(), sBody.length()); ne_xml_destroy(pnxparser); } bRet = true; EXIT_DOCOMMAND: 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; case NE_TIMEOUT: psdk->nError = SHCERRNO_RESP_TIMEOUT; break; case NE_LOOKUP: psdk->nError = SHCERRNO_NE_LOOKUP; break; case NE_CONNECT: psdk->nError = SHCERRNO_NE_CONNECT; 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 DoUploaduffer(PSHCSDK_STRUCT psdk, LPCSTR dstPath, int nWritePolicy, //up_stream data_func, ssize_t (*data_func)( void* userval, char* buf, size_t len ), INT64 beginset, // point to write INT64 nbytes, // amount to write void* userval, // User-supplied value for callback int nFrom) { bool ret = false; // ÇöÀç URI º¸°ü bool bFindSource = true; bool bSessionChange = false; ne_uri nuri = psdk->nuri; string strAuth; // ¾÷·Îµå ÄÚµå ½ÃÀÛ string sPath = psdk->sPath + dstPath; string sHeaders; int nRet; ne_request *pnreq = NULL; psdk->nError = 0; //setting NOERROR #ifdef _NEWAUTH char* pszAuth = get_auth_str(psdk,sPath.c_str(),nFrom); #endif sPath = PathEncode(sPath.c_str()); if(data_func == NULL) { goto EXIT_DOUPLOADUFFER; } // write total size psdk->nFileSize = nbytes; // check policy if (nWritePolicy == SHWRITEPOLICY_OVERWRITE) { PVECTOR_SHFILELIST pvec = (PVECTOR_SHFILELIST)sh_get_filelist((HSHSDK)psdk, dstPath, 0); if (pvec && pvec->size() > 0) { sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec); if (!sh_delete((HSHSDK)psdk, dstPath)) { // delete fail goto EXIT_DOUPLOADUFFER; } } else { if(psdk->nError != 0 && psdk->nError != SHCERRNO_NOEXISTSFILE) goto EXIT_DOUPLOADUFFER; } if (pvec) sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec); } else if (nWritePolicy == SHWRITEPOLICY_APPEND) { PVECTOR_SHFILELIST pvec = (PVECTOR_SHFILELIST)sh_get_filelist((HSHSDK)psdk, dstPath, 0); if (pvec && pvec->size() > 0) { PSHFILE_STRUCT pshf = sh_get_file((HSHSDK)psdk, (HSHFILELIST)pvec, 0); char szRange[100]; INT64 startpos, endpos; startpos = (beginset >= 0 ? beginset : pshf->size); endpos = startpos + psdk->nFileSize; #ifdef WIN32 sprintf(szRange, "bytes %I64d-%I64d/%I64d", startpos, endpos - 1, endpos); #else // !WIN32 sprintf(szRange, "bytes %lld-%lld/%lld", startpos, endpos - 1, endpos); #endif // WIN32 sHeaders = "Content-Range|"; sHeaders += szRange; if (pshf->source && strlen(pshf->source) > 7) { bSessionChange = true; solbox_session_destroy(psdk); solbox_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; if( solbox_session_create(psdk) == false ) { psdk->nError = SHCERRNO_DNS_TIMEOUT; psdk->sError = GetErrorMessage(psdk->nError); goto EXIT_DOUPLOADUFFER; } psdk->sPath = psdk->nuri.path; } bFindSource = false; } if (pvec) sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec); } else { PVECTOR_SHFILELIST pvec = (PVECTOR_SHFILELIST)sh_get_filelist((HSHSDK)psdk, dstPath, 0); if (pvec && pvec->size() > 0) { sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec); psdk->nError = SHCERRNO_EXISTSFILE; psdk->sError = GetErrorMessage(psdk->nError); goto EXIT_DOUPLOADUFFER; } if (pvec) sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec); } // change session if (bFindSource) { for (int i = 0; !bSessionChange && i < MAX_TRY; i++) { PVECTOR_SHFILELIST pvec = (PVECTOR_SHFILELIST)sh_get_filelist((HSHSDK)psdk, dstPath, 0); if (pvec && pvec->size() > 0) { sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec); psdk->nError = SHCERRNO_EXISTSFILE; psdk->sError = GetErrorMessage(psdk->nError); goto EXIT_DOUPLOADUFFER; } if (pvec) sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec); if (psdk->sRedirect == "") break; if (i > 0) ne_uri_free(&psdk->nuri); bSessionChange = true; solbox_session_destroy(psdk); solbox_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; if( solbox_session_create(psdk) == false ) { psdk->nError = SHCERRNO_DNS_TIMEOUT; psdk->sError = GetErrorMessage(psdk->nError); goto EXIT_DOUPLOADUFFER; } psdk->sPath = psdk->nuri.path; if (i == (MAX_TRY - 1)) { sHeaders = "Force|YES"; break; } } } // put request pnreq = ne_request_create(psdk->pnsess, "PUT", sPath.c_str()); if (!pnreq) { psdk->nError = SHCERRNO_UNDEFINED; psdk->sError = ne_get_error(psdk->pnsess); goto EXIT_DOUPLOADUFFER; } #ifdef _NEWAUTH strAuth = "Basic "; strAuth += psdk->sAuth; ne_add_request_header(pnreq, "Authorization", strAuth.c_str()); #else // _SP_SDK_ 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); } INT64 body_size; if (beginset > 0) { body_size = psdk->nFileSize - beginset; } else { body_size = psdk->nFileSize; } ne_set_request_body_provider(pnreq, psdk->nFileSize - psdk->iFilePos, data_func, userval); 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_DOUPLOADUFFER; } 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_DOUPLOADUFFER; } } ne_end_request(pnreq); ret = true; EXIT_DOUPLOADUFFER: switch (psdk->nError) { case 404: psdk->nError = SHCERRNO_NOEXISTSFILE; break; } #ifdef _NEWAUTH if(pszAuth) { free(pszAuth); pszAuth =NULL; } #endif // _NEWAUTH if (pnreq) ne_request_destroy(pnreq); if (bSessionChange) { // CHG : dadamin / 2010.12.16 - Redirection ½ÇÆÐ ½Ã ÃÖÃÊ¿¡ ¹ÞÀº uri Á¤º¸·Î ȯ¿øÇÔ. // ÀÌó·³ º¯°æÇÏ´Â ÀÌÀ¯´Â ½Å±Ô(2010.12.16) °³¹ßµÉ SDK¿¡¼­´Â ´ëÇ¥ URI¸¦ »ç¿ëÇÏÁö ¾Ê°í // dns resolveÇØ¼­ ³ª¿Â IP Çϳª¸¸ »ç¿ëÇϱ⠶§¹®¿¡ 301·Î ¿¬°á ¼º°øÇÑ Á¤º¸¸¦ ±×´ë·Î »ç¿ëÇÔ. if( ret == false ) { solbox_session_destroy(psdk); ne_uri_free(&psdk->nuri); psdk->nuri = nuri; if( solbox_session_create(psdk) == false ) { // ¹Ù·Î ¸®ÅÏÇϱ⶧¹®¿¡ ÈÄ󸮴 ÇÏÁö ¾Ê¾Æµµ µÈ´Ù. psdk->nError = SHCERRNO_DNS_TIMEOUT; psdk->sError = GetErrorMessage(psdk->nError); } psdk->sPath = "/dav"; } else { psdk->sPath = "/dav"; ne_uri_free(&nuri); } } #ifdef WIN32 CString strTemp; strTemp.Format("UploadBuffer %s : %s : %d", ret ? "SUCCESS" : "ERROR", dstPath, psdk->nError); OutputDebugString(strTemp); #endif // WIN32 return ret; } static bool DoUpload(PSHCSDK_STRUCT psdk, LPCSTR pszSrcFile, LPCSTR pszDstFile, int nWritePolicy, INT64 nAvailQuota,int nFrom, LPCSTR extSession) { // ÇöÀç 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; bool bResult = false; psdk->nError = 0; // setting NOERROR #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); goto EXIT_DOUPLOAD; } #ifdef WIN32 LARGE_INTEGER filesize; filesize.QuadPart = 0; filesize.LowPart = SetFilePointer(psdk->hFile, filesize.LowPart, &filesize.HighPart, FILE_END); psdk->nFileSize = filesize.QuadPart; SetFilePointer(psdk->hFile,0, 0, FILE_BEGIN); #else psdk->nFileSize = sh_filelength(psdk->nFileDesc); #endif if (psdk->nFileSize == -1L) { psdk->nError = GetLastError(); psdk->sError = GetErrorMessage(psdk->nError); goto EXIT_DOUPLOAD; } 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)) { goto EXIT_DOUPLOAD; } } else { if( psdk->nError != 0 && psdk->nError != SHCERRNO_NOEXISTSFILE ) goto EXIT_DOUPLOAD; } /* 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); // CHG : dadamin / 2011.01.05 - ´ë»ó ÆÄÀÏÀÌ µ¿ÀÏÇϰųª ´õ Å« °æ¿ì ¿¡·¯ ó¸®ÇÔ if (psdk->nFileSize <= pshf->size) { sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec); bResult = false; psdk->nError = SHCERRNO_TRAGETBIGGER; psdk->sError = GetErrorMessage(psdk->nError); goto EXIT_DOUPLOAD; } #ifdef WIN32 // Windows Large file LARGE_INTEGER li; li.QuadPart = pshf->size; li.LowPart = SetFilePointer(psdk->hFile,li.LowPart, &li.HighPart, FILE_BEGIN); psdk->iFilePos = li.QuadPart; #else psdk->iFilePos = _lseeki64(psdk->nFileDesc, pshf->size, SEEK_SET); #endif if (psdk->iFilePos == -1L) { sh_free_filelist((HSHSDK)psdk, (HSHFILELIST)pvec); goto EXIT_DOUPLOAD; } 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; if (pshf->source && strlen(pshf->source) > 7) { bSessionChange = true; solbox_session_destroy(psdk); // CHG : dadamin / 2010.12.15 ¹öÀüUP(0.29.5)¿¡ µû¸¥ ne_uri_parse ÇÏÀ§ ȣȯ¼º °á·Î ¹ß»ýÇÑ ¹®Á¦ ¼öÁ¤ solbox_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; if( solbox_session_create(psdk) == false ) { psdk->nError = SHCERRNO_DNS_TIMEOUT; psdk->sError = GetErrorMessage(psdk->nError); goto EXIT_DOUPLOAD; } 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); goto EXIT_DOUPLOAD; } /* 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); goto EXIT_DOUPLOAD; } 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); goto EXIT_DOUPLOAD; } /* 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; solbox_session_destroy(psdk); // CHG : dadamin / 2010.12.15 ¹öÀüUP(0.29.5)¿¡ µû¸¥ ne_uri_parse ÇÏÀ§ ȣȯ¼º °á¿©·Î ¹ß»ýÇÑ ¹®Á¦ ¼öÁ¤ solbox_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; if( solbox_session_create(psdk) == false ) { psdk->nError = SHCERRNO_DNS_TIMEOUT; psdk->sError = GetErrorMessage(psdk->nError); goto EXIT_DOUPLOAD; } 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); goto EXIT_DOUPLOAD; } #ifdef _NEWAUTH // 2011.06.02 : ¾÷·Îµå ½Ã ½ÅÀÎÁõ(auth timeout üũ) ü°è·Î ¼öÇàÇÒ °æ¿ì // body±îÁö Àü¼Û ÈÄ¿¡ °ü·Ã ¿¡·¯ ¹ÞÀ» ¼ö ÀÖÀ¸¹Ç·Î // °ü·Ã ¿¡·¯(401) ¹Þ±â±îÁö ½Ã°£ ¼Ò¿ä°¡ ±ä´Ù. // ¶ÇÇÑ, Àç½Ãµµ ·ÎÁ÷À¸·Î ÀÎÇØ¼­ ¾÷·Îµå¸¦ ÀÌÁßÀ¸µÇ¾îÁö´Â ¹®Á¦µµ ÀÖ´Ù. // ±×·¯¹Ç·Î, ¾÷·Îµå °ü·Ã ÀÎÁõÀ» ¼öÇàÇÏÁö ¾Ê°Ô ÀÌÀü ÀÎÁõüÁ¦¸¦ »ç¿ëÇÑ´Ù. strAuth = "Basic "; strAuth += psdk->sAuth; ne_add_request_header(pnreq, "Authorization", strAuth.c_str()); #else // _SP_SDK_ ne_add_request_header(pnreq, "Authorization", psdk->sAuth.c_str()); #endif // toto if ( extSession != NULL ) { if ( strlen( extSession ) > 512) { psdk->nError = SHCERRNO_EXT_OVERFLOW; psdk->sError = GetErrorMessage(psdk->nError); goto EXIT_DOUPLOAD; } ne_add_request_header(pnreq, "SB_ExtSession", extSession); } 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); } //dadamin : 32bit Large File Support / Simplify LFS support, drop *64 transition functions ne_set_request_body_provider(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); goto EXIT_DOUPLOAD; } 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_DOUPLOAD; } } ne_end_request(pnreq); bResult = true; EXIT_DOUPLOAD: 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) { // CHG : dadamin / 2010.12.16 - Redirection ½ÇÆÐ ½Ã ÃÖÃÊ¿¡ ¹ÞÀº uri Á¤º¸·Î ȯ¿øÇÔ. // ÀÌó·³ º¯°æÇÏ´Â ÀÌÀ¯´Â ½Å±Ô(2010.12.16) °³¹ßµÉ SDK¿¡¼­´Â ´ëÇ¥ URI¸¦ »ç¿ëÇÏÁö ¾Ê°í // dns resolveÇØ¼­ ³ª¿Â IP Çϳª¸¸ »ç¿ëÇϱ⠶§¹®¿¡ 301·Î ¿¬°á ¼º°øÇÑ Á¤º¸¸¦ ±×´ë·Î »ç¿ëÇÔ. if( bResult == false ) { solbox_session_destroy(psdk); ne_uri_free(&psdk->nuri); psdk->nuri = nuri; if( solbox_session_create(psdk) == false ) { // ¹Ù·Î ¸®ÅÏÇϱ⶧¹®¿¡ ÈÄ󸮴 ÇÏÁö ¾Ê¾Æµµ µÈ´Ù. psdk->nError = SHCERRNO_DNS_TIMEOUT; psdk->sError = GetErrorMessage(psdk->nError); } psdk->sPath = "/dav"; } else { psdk->sPath = "/dav"; ne_uri_free(&nuri); } } #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 INT64 beginset, // point to read INT64 nbytes, // amount to read 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; bool bResult = false; ne_uri prvenuri = psdk->nuri; char szrange[100] = {0}; 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) goto EXIT_DODOWNLOADBUFFER; if(data_func == NULL) goto EXIT_DODOWNLOADBUFFER; 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_DODOWNLOADBUFFER; } #ifdef _NEWAUTH ne_add_request_header(pnreq, "Authorization", pszAuth); #else // _SP_SDK_ ne_add_request_header(pnreq, "Authorization", psdk->sAuth.c_str()); #endif // make range get header if(beginset > 0) { if(nbytes > 0) { sprintf(szrange, #ifdef WIN32 "bytes=%I64d-%I64d", #else "bytes=%lld-%lld", #endif beginset, beginset + nbytes - 1); } else { sprintf(szrange, #ifdef WIN32 "bytes=%I64d-%I64d", #else "bytes=%lld-%lld", #endif beginset, pshf->size); } } else { sprintf(szrange, #ifdef WIN32 "bytes=%I64d-%I64d", #else "bytes=%lld-%lld", #endif psdk->iFilePos, pshf->size); } if (szrange[0] != '\0') { sHeaders += "Range|"; sHeaders += szrange; sHeaders += ",Accept-Ranges|bytes"; } 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_DODOWNLOADBUFFER; } 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_DODOWNLOADBUFFER; } } ne_end_request(pnreq); bResult = true; EXIT_DODOWNLOADBUFFER: 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 != "") { solbox_session_destroy(psdk); // ÁöÁ¤µÈ °÷À¸·Î Á¢¼Ó ne_uri nuri; // CHG : dadamin / 2010.12.15 ¹öÀüUP(0.29.5)¿¡ µû¸¥ ne_uri_parse ÇÏÀ§ ȣȯ¼º °á¿©·Î ¹ß»ýÇÑ ¹®Á¦ ¼öÁ¤ solbox_uri_parse(sRedirection.c_str(), &nuri); if (!nuri.scheme) nuri.scheme = strdup("http"); if (nuri.port == 0) nuri.port = 80; psdk->sPath = nuri.path; psdk->sPath.erase(psdk->sPath.find('/', 1), string::npos); psdk->nuri = nuri; if( solbox_session_create(psdk) == false ) { ne_uri_free(&prvenuri); psdk->nError = SHCERRNO_DNS_TIMEOUT; psdk->sError = GetErrorMessage(psdk->nError); return false; } psdk->iFilePos = 0; psdk->cOldTick = clock(); psdk->nTranStop = SHSTOP_NO; bResult = DoDownloadBuffer(psdk, pszSrcFile, data_func, beginset, nbytes, userval, nFrom); // CHG : dadamin / 2010.12.16 - Redirection ½ÇÆÐ ½Ã ÃÖÃÊ¿¡ ¹ÞÀº uri Á¤º¸·Î ȯ¿øÇÔ. // ÀÌó·³ º¯°æÇÏ´Â ÀÌÀ¯´Â ½Å±Ô(2010.12.16) °³¹ßµÉ SDK¿¡¼­´Â ´ëÇ¥ URI¸¦ »ç¿ëÇÏÁö ¾Ê°í // dns resolveÇØ¼­ ³ª¿Â IP Çϳª¸¸ »ç¿ëÇϱ⠶§¹®¿¡ 301·Î ¿¬°á ¼º°øÇÑ Á¤º¸¸¦ ±×´ë·Î »ç¿ëÇÔ. if(!bResult) { // ¿ø·¡ ¼­¹ö·Î ÀçÁ¢¼Ó solbox_session_destroy(psdk); ne_uri_free(&psdk->nuri); psdk->nuri = prvenuri; if( solbox_session_create(psdk) == false ) { psdk->nError = SHCERRNO_DNS_TIMEOUT; psdk->sError = GetErrorMessage(psdk->nError); } psdk->sPath = "/dav"; } else { psdk->sPath = "/dav"; ne_uri_free(&prvenuri); } } return bResult; } static bool DoDownload(PSHCSDK_STRUCT psdk, LPCSTR pszSrcFile, LPCSTR pszDstFile, int nWritePolicy, INT64 nAvailQuota,int nFrom, LPCSTR extSession) { string sPath = psdk->sPath + pszSrcFile; string sHeaders; PSHFILE_STRUCT pshf; char* pszAuth; ne_request *pnreq = NULL; bool bResult = false; int nFlag = 0; #ifndef WIN32 mode_t mode; #endif // !WIN32 #ifdef _NEWAUTH pszAuth = get_auth_str(psdk,sPath.c_str(),nFrom); #endif sPath = PathEncode(sPath.c_str()); PVECTOR_SHFILELIST pvec = NULL; struct _stati64 stDstFile; int nRet = _stati64(pszDstFile, &stDstFile); if (nWritePolicy == SHWRITEPOLICY_NONE) { if (nRet != -1) { psdk->nError = SHCERRNO_EXISTSFILE; psdk->sError = GetErrorMessage(psdk->nError); goto EXIT_DODOWNLOAD; } } else { if (nRet != -1 && (stDstFile.st_mode & _S_IFDIR)) { if (nWritePolicy == SHWRITEPOLICY_OVERWRITE) { if (!DeleteDirectory(pszDstFile)) { psdk->nError = GetLastError(); psdk->sError = GetErrorMessage(psdk->nError); goto EXIT_DODOWNLOAD; } } else { psdk->nError = SHCERRNO_EXISTSFILE; psdk->sError = GetErrorMessage(psdk->nError); } } } pvec = (PVECTOR_SHFILELIST)sh_get_filelist((HSHSDK)psdk, pszSrcFile, 0); if (!pvec || pvec->size() == 0) { goto EXIT_DODOWNLOAD; } #ifdef WIN32 nFlag=nWritePolicy; switch (nWritePolicy) { case SHWRITEPOLICY_OVERWRITE: case SHWRITEPOLICY_NONE : nFlag = CREATE_ALWAYS; break; case SHWRITEPOLICY_APPEND: nFlag = OPEN_ALWAYS; break; } #else 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 // ÀϺΠlinux °è¿­(Ubuntu) mode ÀÎÀÚ¸¦ ³ÖÁö ¾Ê°í O_CREAT¸¦ ¼öÇàÇÒ ¼ö ¾ø°Ô µÇ¾î ÀÖÀ½. mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // ÆÄÀÏÀÇ ±ÇÇÑ 0644 psdk->nFileDesc = open64(pszDstFile, nFlag, mode); if (psdk->nFileDesc == -1L) { #endif psdk->nError = GetLastError(); psdk->sError = GetErrorMessage(psdk->nError); goto EXIT_DODOWNLOAD; } pshf = sh_get_file((HSHSDK)psdk, (HSHFILELIST)pvec, 0); #ifdef WIN32 LARGE_INTEGER li; li.QuadPart = 0; li.LowPart = SetFilePointer(psdk->hFile, li.LowPart, &li.HighPart, FILE_END); psdk->iFilePos = li.QuadPart; #else psdk->iFilePos = _lseeki64(psdk->nFileDesc, 0, SEEK_END); #endif if (psdk->iFilePos == -1L) { psdk->nError = GetLastError(); psdk->sError = GetErrorMessage(psdk->nError); goto EXIT_DODOWNLOAD; } if (pshf->size > 0 && psdk->iFilePos >= pshf->size) { bResult = false; psdk->nError = SHCERRNO_TRAGETBIGGER; psdk->sError = GetErrorMessage(psdk->nError); goto EXIT_DODOWNLOAD; } if (nWritePolicy == SHWRITEPOLICY_APPEND) { 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); goto EXIT_DODOWNLOAD; } 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_DODOWNLOAD; } #ifdef _NEWAUTH ne_add_request_header(pnreq, "Authorization", pszAuth); #else // _SP_SDK_ ne_add_request_header(pnreq, "Authorization", psdk->sAuth.c_str()); #endif // toto if ( extSession != NULL ) { if ( strlen( extSession ) > 512) { psdk->nError = SHCERRNO_EXT_OVERFLOW; psdk->sError = GetErrorMessage(psdk->nError); goto EXIT_DODOWNLOAD; } ne_add_request_header(pnreq, "SB_ExtSession", extSession); } 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); goto EXIT_DODOWNLOAD; } 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_DODOWNLOAD; } } ne_end_request(pnreq); bResult = true; EXIT_DODOWNLOAD: 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); } ne_uri prvenuri; // Redirection if (psdk->nError == 301 && sRedirection != "") { solbox_session_destroy(psdk); // ÁöÁ¤µÈ °÷À¸·Î Á¢¼Ó ne_uri nuri; // CHG : dadamin / 2010.12.15 ¹öÀüUP(0.29.5)¿¡ µû¸¥ ne_uri_parse ÇÏÀ§ ȣȯ¼º °á·Î ¹ß»ýÇÑ ¹®Á¦ ¼öÁ¤ solbox_uri_parse(sRedirection.c_str(), &nuri); if (!nuri.scheme) nuri.scheme = strdup("http"); if (nuri.port == 0) nuri.port = 80; prvenuri = psdk->nuri; psdk->sPath = nuri.path; psdk->sPath.erase(psdk->sPath.find('/', 1), string::npos); psdk->nuri = nuri; if( solbox_session_create(psdk) == false ) { ne_uri_free(&prvenuri); psdk->nError = SHCERRNO_DNS_TIMEOUT; psdk->sError = GetErrorMessage(psdk->nError); return false; } #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, extSession); // ¿ø·¡ ¼­¹ö·Î ÀçÁ¢¼Ó // CHG : dadamin / 2010.12.16 - Redirection ½ÇÆÐ ½Ã ÃÖÃÊ¿¡ ¹ÞÀº uri Á¤º¸·Î ȯ¿øÇÔ. // ÀÌó·³ º¯°æÇÏ´Â ÀÌÀ¯´Â ½Å±Ô(2010.12.16) °³¹ßµÉ SDK¿¡¼­´Â ´ëÇ¥ URI¸¦ »ç¿ëÇÏÁö ¾Ê°í // dns resolveÇØ¼­ ³ª¿Â IP Çϳª¸¸ »ç¿ëÇϱ⠶§¹®¿¡ 301·Î ¿¬°á ¼º°øÇÑ Á¤º¸¸¦ ±×´ë·Î »ç¿ëÇÔ. if( bResult == false ) { solbox_session_destroy(psdk); ne_uri_free(&psdk->nuri); psdk->nuri = prvenuri; if( solbox_session_create(psdk) == false ) { psdk->nError = SHCERRNO_DNS_TIMEOUT; psdk->sError = GetErrorMessage(psdk->nError); } psdk->sPath = "/dav"; } else { psdk->sPath = "/dav"; ne_uri_free(&prvenuri); } } return bResult; } // interfal function // output interface WIN32DLL HSHSDK sh_init(const char *url, const char *authString, sh_callback proc, void *param) { PSHCSDK_STRUCT psdk = new SHCSDK_STRUCT; const ne_inet_addr** result; int nResultCnt; if (!psdk) return NULL; psdk->pnsess = NULL; psdk->pvecshfl = NULL; // neon.lib init... if (ne_sock_init() != NE_OK) return NULL; // CHG : dadamin / 2010.12.15 ¹öÀüUP(0.29.5)¿¡ µû¸¥ ne_uri_parse ÇÏÀ§ ȣȯ¼º °á·Î ¹ß»ýÇÑ ¹®Á¦ ¼öÁ¤ int nNeonRet = solbox_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; if( solbox_session_create(psdk) == false ) { psdk->nError = SHCERRNO_DNS_TIMEOUT; psdk->sError = GetErrorMessage(psdk->nError); goto EXIT_SH_INIT; } if (!psdk->pnsess) goto EXIT_SH_INIT; // time out setting ne_set_read_timeout(psdk->pnsess, _read_time_out); ne_set_connect_timeout(psdk->pnsess, _connect_time_out); // time out setting psdk->sPath = psdk->nuri.path; #ifdef _NEWAUTH psdk->sAuth = authString; #else // _SP_SDK_ 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(); psdk->nSpeedLimit = 0; dwTransferd = 0; return psdk; EXIT_SH_INIT: int nError = GetLastError(); ne_uri_free(&psdk->nuri); if (psdk->pnsess) solbox_session_destroy(psdk); 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::iterator iter = psdk->setFileList.begin(); iter != psdk->setFileList.end(); iter++) FreeFileListVector(*iter); ne_uri_free(&psdk->nuri); if (psdk->pnsess) solbox_session_destroy(psdk); 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 = SHCERRNO_NOERROR; 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 = ""; sBody += ""; sBody += ""; sBody += ""; sBody += ""; sBody += ""; sBody += ""; sBody += ""; sBody += ""; 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,1)) { 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; psdk->nError = SHCERRNO_NOERROR; if (!hshfl) { psdk->nError = SHCERRNO_INVALIDFLHDL; psdk->sError = GetErrorMessage(psdk->nError); return -1; } if (psdk->pvecshfl != hshfl) { set::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; psdk->nError = SHCERRNO_NOERROR; if (!hshfl) { psdk->nError = SHCERRNO_INVALIDFLHDL; psdk->sError = GetErrorMessage(psdk->nError); return NULL; } if (psdk->pvecshfl != hshfl) { set::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::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; int nRet = DoCommand(psdk, "MKCOL", sDirectory.c_str(), "", "", false, NULL, NULL, NULL, NULL, 1); if (!nRet) { if (sh_get_error_number(psdk) == SHCERRNO_AUTHORIZATION) nRet = DoCommand(psdk, "MKCOL", sDirectory.c_str(),"","",false,NULL,NULL,NULL,NULL,0); } 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 = SHCERRNO_NOERROR; 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(),"", false, NULL, NULL, NULL, NULL, 1); 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 = SHCERRNO_NOERROR; 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(), "", false, NULL, NULL, NULL, NULL, 1); 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 = SHCERRNO_NOERROR; int ncount=0; // °æ·Î°¡ '////////' Çü½ÄÀΰæ¿ì for(int i=0;inError = SHCERRNO_SERVICE; psdk->sError = "·çÆ®´Â »èÁ¦ÇÒ ¼ö ¾ø½À´Ï´Ù."; return FALSE; } string sPath = psdk->sPath; if (path[0] != '/') sPath += "/"; sPath += path; int nRet = DoCommand(psdk, "DELETE", sPath.c_str(), "", "" , false, NULL, NULL, NULL, NULL, 1); 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_buffer( HSHSDK hshsdk, // SDK handle const char *dstPath, // Destination file int writePolicy, // Write policy flag up_stream proc, // user defined function INT64 nbytes, // write size void* userval // User-supplied value for callback ) { int ret = 0; if (!hshsdk) { return ret; } PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk; psdk->nError = SHCERRNO_NOERROR; if (psdk->bWorking) { psdk->nError = SHCERRNO_ISBUSY; psdk->sError = GetErrorMessage(psdk->nError); return ret; } #ifdef WIN32 psdk->hFile = NULL; #else psdk->nFileDesc = -1; #endif psdk->iFilePos = 0; psdk->cOldTick = clock(); psdk->nTranStop = SHSTOP_NO; ret = DoUploaduffer(psdk, dstPath, writePolicy, proc, 0, nbytes, userval, 1); if (!ret) { switch( sh_get_error_number(psdk) ) { case 401: DoUploaduffer(psdk, dstPath, writePolicy, proc, 0, nbytes, userval, 0); break; case NE_LOOKUP: // 2011.06.20 : DNS lookup ½ÇÆÐ ½Ã 1ȸ Àç½Ãµµ DoUploaduffer(psdk, dstPath, writePolicy, proc, 0, nbytes, userval, 1); break; } } return ret; } WIN32DLL int sh_upload_buffer_r( HSHSDK hshsdk, // SDK handle const char *dstPath, // Destination file int writePolicy, // Write policy flag up_stream proc, // user defined function INT64 beginpos, // write start position INT64 nbytes, // write size void* userval // User-supplied value for callback ) { int ret = 0; if (!hshsdk) { return ret; } PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk; psdk->nError = SHCERRNO_NOERROR; if (psdk->bWorking) { psdk->nError = SHCERRNO_ISBUSY; psdk->sError = GetErrorMessage(psdk->nError); return ret; } #ifdef WIN32 psdk->hFile = NULL; #else psdk->nFileDesc = -1; #endif psdk->iFilePos = 0; psdk->cOldTick = clock(); psdk->nTranStop = SHSTOP_NO; ret = DoUploaduffer(psdk, dstPath, writePolicy, proc, beginpos, nbytes, userval, 1); if (!ret) { switch( sh_get_error_number(psdk) ) { case 401: DoUploaduffer(psdk, dstPath, writePolicy, proc, beginpos, nbytes, userval, 0); break; case NE_LOOKUP: // 2011.06.20 : DNS lookup ½ÇÆÐ ½Ã 1ȸ Àç½Ãµµ DoUploaduffer(psdk, dstPath, writePolicy, proc, beginpos, nbytes, userval, 1); break; } } return ret; } WIN32DLL int sh_upload(HSHSDK hshsdk, const char *srcPath, const char *dstPath, int writePolicy, INT64 availQuota, const char *extSession) { if (!hshsdk) { return FALSE; } PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk; psdk->nError = SHCERRNO_NOERROR; if (psdk->bWorking) { psdk->nError = SHCERRNO_ISBUSY; psdk->sError = GetErrorMessage(psdk->nError); 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,1, extSession); if (!nRet) { switch( sh_get_error_number(psdk) ) { case 401: // 2011.06.02 : 401 ¿¡·¯ ¹ß»ý °æ¿ì body¸¦ ¸ðµÎ Àü¼Û ÈÄ ¸®ÅÏ µÇ±â ¶§¹®¿¡ iFilePos¸¦ ÃʱâÈ­ÇÏ¿© ½ÃµµÇÏ¿©ÇÔ. psdk->iFilePos = 0; nRet = DoUpload(psdk, srcPath, dstPath, writePolicy, availQuota,0, extSession); break; case NE_LOOKUP: // 2011.06.20 : DNS lookup ½ÇÆÐ ½Ã 1ȸ Àç½Ãµµ psdk->iFilePos = 0; nRet = DoUpload(psdk, srcPath, dstPath, writePolicy, availQuota,1, extSession); break; } } return nRet; } WIN32DLL int sh_download_buffer( HSHSDK hshsdk, // SDK handle const char *srcPath, // Source file down_stream proc, INT64 beginpos, void* userval // User-supplied value for callback ) { if (!hshsdk) return FALSE; PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk; psdk->nError = SHCERRNO_NOERROR; 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, beginpos, -1, userval, 1); if(!nRet) { switch( sh_get_error_number(psdk) ) { case 401: nRet = DoDownloadBuffer(psdk, srcPath, proc, beginpos, -1, userval,0); break; case NE_LOOKUP: // 2011.06.20 : DNS lookup ½ÇÆÐ ½Ã 1ȸ Àç½Ãµµ nRet = DoDownloadBuffer(psdk, srcPath, proc, beginpos, -1, userval,1); break; } } return nRet; } // sh_download_buffer range version for GAMPLE // WIN32DLL int sh_download_buffer_r( HSHSDK hshsdk, // SDK handle const char *srcPath, // Source file down_stream proc, // user defined function INT64 beginpos, // point to read INT64 nbytes, // amount to read void* userval // User-supplied value for callback ) { if (!hshsdk) return FALSE; PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk; psdk->nError = SHCERRNO_NOERROR; 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, beginpos, nbytes, userval, 1); if(!nRet) { switch ( sh_get_error_number(psdk) ) { case 401: nRet = DoDownloadBuffer(psdk, srcPath, proc, beginpos, nbytes, userval,0); break; case NE_LOOKUP: // 2011.06.20 : DNS lookup ½ÇÆÐ ½Ã 1ȸ Àç½Ãµµ nRet = DoDownloadBuffer(psdk, srcPath, proc, beginpos, nbytes, userval, 1); break; } } return nRet; } WIN32DLL int sh_download(HSHSDK hshsdk, const char *srcPath, const char *dstPath, int writePolicy, INT64 availQuota, const char *extSession) { if (!hshsdk) { return FALSE; } PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk; psdk->nError = SHCERRNO_NOERROR; if (psdk->bWorking) { psdk->nError = SHCERRNO_ISBUSY; psdk->sError = GetErrorMessage(psdk->nError); 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, 1, extSession); if(!nRet) { switch( sh_get_error_number(psdk) ) { case 401: nRet = DoDownload(psdk, srcPath, dstPath, writePolicy, availQuota,0, extSession); break; case NE_LOOKUP: // 2011.06.20 : DNS lookup ½ÇÆÐ ½Ã 1ȸ Àç½Ãµµ nRet = DoDownload(psdk, srcPath, dstPath, writePolicy, availQuota, 1, extSession); break; } } 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 { // ¸Þ¸ð¸® Á¤¸® PVECTOR_SHFILELIST pvec = (PVECTOR_SHFILELIST)hshfl; if (pvec && pvec->size() > 0) { sh_free_filelist(hshsdk, (HSHFILELIST)pvec); } return true; } } #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_SH_ENCRYPT; stm = gmtime((time_t*)&tnow); // 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_SH_ENCRYPT; 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_SH_ENCRYPT: mcrypt_module_close(mcrypt); return bResult; } void sh_set_sntp_timeout(int second) { timeout = second; } void sh_set_C_timeout(int second) { sh_set_sntp_timeout(second); sh_set_connect_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; } void sh_set_connect_timeout(int second) { if( 0 < second ) second = 0; _connect_time_out = second; } void sh_set_response_timeout(int second) { if( 0 < second ) second = 0; _read_time_out = second; } // NEW 2010-03-29 // ƯÁ¤ ½Ã°£(tStart) ÀÌÈÄ¿¡ ¾÷·ÎµåµÈ ¸®½ºÆ®¸¦ ¾ò¾î¿Â´Ù. // °í°´ÀÇ ¿äû¿¡ ÀÇÇØ ÇØ´ç ÀÎÅÍÆäÀ̽º Ãß°¡. WIN32DLL HSHFILELIST sh_get_filelist_certain_time(HSHSDK hshsdk, const char* path, time_t tStart, 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; // sh_get_filelist_certain_time() ÇÔ¼ö¸¦ Ãß°¡·Î ¸¸µé°Ô µÈ ÄÚµå´Ù. char szTime[20]; memset(szTime, 0x00, 20); if (tStart > 0 ) { // time * 1000000 À» ÇÏ´Â ÀÌÀ¯´Â // ¾ÆÆÄÄ¡¿¡¼­ filetimeÀ» ±¸ÇÏ´Â ½ÄÀÌ ÀÌ¹Ì Á¤ÇØÁ® À־. // ¾ÆÆÄÄ¡ÀÇ ·ê¿¡ ¸ÂÃß±â À§Çؼ­ Àû¿ëÇÑ´Ù. sprintf(szTime, "%lld", tStart * 1000000); sHeaders += ","; sHeaders += "StartTime|"; sHeaders += szTime; } string sBody = ""; sBody += ""; sBody += ""; sBody += ""; sBody += ""; sBody += ""; sBody += ""; sBody += ""; sBody += ""; 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, 1)) { 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; } // Àü¼Û °ü·Ã callback ÇÔ¼ö µî·Ï WIN32DLL int sh_set_transfer_callback (HSHSDK hshsdk, sh_callback proc, void *param) { if (!hshsdk) return 1; PSHCSDK_STRUCT psdk = (PSHCSDK_STRUCT)hshsdk; psdk->proc = proc; psdk->pParam = param; return 0; } WIN32DLL int sh_open ( HSHSDK hshsdk, // SDK handle const char *path // Path ) { char ppath[2048] = {0}; char *find = strrchr((char*)path, '/'); strncpy(ppath, path, strlen(path) - strlen(find)); int r = sh_make_directory(hshsdk, ppath) ; if (r == 0) { if ( sh_get_error_number(hshsdk) == SHCERRNO_ALREADYEXIST ) return true; } return r; } WIN32DLL int sh_send_append ( HSHSDK hshsdk, // SDK handle const char *dstPath, // Destination file up_stream proc, // user defined function INT64 nbytes, // write size void* userval // User-supplied value for callback ) { return sh_upload_buffer_r(hshsdk, dstPath, SHWRITEPOLICY_APPEND, proc, -1, nbytes, userval); } WIN32DLL int sh_send_block ( HSHSDK hshsdk, // SDK handle const char *dstPath, // Destination file up_stream proc, // user defined function INT64 beingpos, // write start position INT64 nbytes, // write size void* userval // User-supplied value for callback ) { return sh_upload_buffer_r(hshsdk, dstPath, SHWRITEPOLICY_APPEND, proc, beingpos, nbytes, userval); }