// test_agent.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#ifdef WIN32
#include <windows.h>
#include <atlstr.h>
#else
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#define GetLastError() errno
#endif //WIN32

#include "../../SHCSDK.h"
#include "../../SHSSDK.h"

#if 0 //토토디스크 & QC망 테스트
#define SERVICE "totodisk05"
#define ID "totodisk05"
#define PWD "toto379"
#define AUTHSTR	"icstoto05"
//#define AUTHSTR	"totodisk05"
#define FILE_PATH "D:/cert/totodisk05238.cert"
#endif

#if 0 //SBFS 04 
#define ID "sbfstest"
#define PWD "sbfstest"
#define FILE_PATH "D:/cert/sbfstest260.cert"
#define AUTHSTR	"sbfstest001"
#define SERVICE "sbfstest001"
#endif

#if 0 //SBFS 04 - solboxsvc1
#define ID "solboxsvc1"
#define PWD "5emffld)"
#define FILE_PATH "D:/cert/solboxsvc1298.cert"
#define AUTHSTR	"svc1bd04"
#define SERVICE "svc1bd04"
#endif

#if 0 //SBFS 04 - svc1test05
#define ID "solboxsvc1"
#define PWD "5emffld)"
#define FILE_PATH "D:/cert/solboxsvc1326.cert"
#define AUTHSTR	"svc1test05"
#define SERVICE "svc1test05"
#endif

#if 1 //BD-16 - nctest
#define SERVICE "nctest2"
#define ID "nctest"
#define PWD "nctest123"
#define AUTHSTR	"icstmxmflald"
#define FILE_PATH "D:/cert/nctest348.cert"
#endif

#if 0 //토토디스크 & QC망 테스트
#define SERVICE "softline2009"
#define ID "totodisk05"
#define PWD "toto379"
#define AUTHSTR	"icssoftline09"
#define FILE_PATH "D:/cert/totodisk05240.cert"
#endif

#if 0 //BD-04 - nctest
#define SERVICE "nctest"
#define ID "nctest"
#define PWD "nctest123"
#define AUTHSTR	"icstmxmflald"
#define FILE_PATH "D:/cert/nctest347.cert"
#endif

#if 0 //SBFS 03 & X-CDN
#define ID "solboxtest"
#define PWD "solboxtest"
#define FILE_PATH "D:/cert/solboxtest186.cert"
#define AUTHSTR	"solboxtest"
#define SERVICE "solboxtest"
#endif


HSHSDK g_hshsdk;
bool g_bUp = false;
size_t g_total = 0;
size_t g_buffertotal = 0;

#ifdef WIN32
int __stdcall CallbackProc(void *param, INT64 result)
#else // WIN32
int  CallbackProc(void *param, INT64 result)
#endif // WIN32
{

	static time_t start_time = time(0);
	time_t gap, current_time = time(0);

	gap = current_time - start_time;

	printf("CallbackProc elapsed[%ld] sec\n", gap);
	// 파일 업로드 중…
#ifdef WIN32
	printf("%s loading : %I64d\n", g_bUp ? "Up" : "Down", result);
#else // WIN32
	printf("%s loading : %lld\n", g_bUp ? "Up" : "Down", result);
#endif // WIN32


	//Sleep(10000);
	// 1 : 계속 진행
	// 0 : 멈춤


	return 1;
}

int Download_Func(void* userdata, const char* buf, size_t len)
{
	printf("downloading : %d\n", len);
	// 1 : 멈춤 // 0 : 계속진행
	g_total += len;
	
	if(g_total >= (1024*1024)) 
		return 1;
	
	return 0;
}

ssize_t Upload_Func(void *userval, char *buf, size_t len)
{
	if(buf == 0x00)
		return 0; // 버퍼 할당이 되있지 않다.

	if (g_total > g_buffertotal)
		return 0; // 설정한 용량이다. 종료

	strncpy(buf, "1234567890", 10);	
	//strncpy(buf, "0000000000", 10);

	g_total += 10; // 전송된 용량증가
	
	printf("uploading : %d\n", g_total);

	return 10; // 전송된 용량 리턴
}



int InitSDK()
{
	int r = 0;
	//sh_set_cache_file("C:/test.log");

	char* astring = NULL;
	char *host = (char*)sh_get_service_host(ID, PWD, SERVICE);
	
	if(!host) 
	{
		printf("sh_get_service_host ERROR : %d\n", GetLastError());
		r = 1;
		goto ERR_EXIT;
	}
printf("host: %s\n", host);
	static bool first_time = true;

	if(first_time == true)
	{
#ifndef _SP_SDK_
		astring = (char*)sh_get_auth_string(ID, PWD, SERVICE, AUTHSTR, FILE_PATH, time(NULL) + 86400);
#else // _SP_SDK_
		char userid[256] = {0};
		sprintf(userid,"%s@%s", SERVICE, ID);
		astring = (char*)sh_get_auth_sp_string(userid, PWD);
#endif // _SP_SDK_

		if (!astring)
		{
			printf("sh_get_auth_string ERROR : %d\n", GetLastError());
			r = 1;
			goto ERR_EXIT;
		}

		g_hshsdk =NULL;

		sh_set_response_timeout(3);
		
		g_hshsdk = sh_init(host, astring, CallbackProc, NULL);
		if (!g_hshsdk)
		{
			printf("sh_init ERROR : %d\n", GetLastError());
			r = 1;
			goto ERR_EXIT;
		}

		sh_set_sntp_timeout(3);
		sh_set_limit(g_hshsdk,10240);
		sh_set_sessionID(g_hshsdk,"testID");
	}
	else
	{

		g_hshsdk = sh_init(host, astring, CallbackProc, NULL);
		if (!g_hshsdk)
		{
			printf("sh_init ERROR : %d\n", GetLastError());
			r = 1;
			goto ERR_EXIT;
		}
	}

ERR_EXIT:
	if(host)
		sh_mem_free(host);

	if(astring)
		sh_mem_free(astring);

	return r;
}

void FreeSDK()
{
	sh_free(g_hshsdk);
}

bool makedir()
{
	if (sh_make_directory(g_hshsdk, "/SVC1_TEST") == 0)
	{
		if ( sh_get_error_number(g_hshsdk) == SHCERRNO_ALREADYEXIST )
			return true;
		printf("sh_make_directory ERROR : %d, %s\n", sh_get_error_number(g_hshsdk), sh_get_error_message(g_hshsdk));
		return false;
	}
	else
	{
		printf("sh_make_directory SUCCESS\n");
		return true;
	}
}

bool makedirex(char * path)
{
	if (sh_make_directory(g_hshsdk, path) == 0)
	{
		if ( sh_get_error_number(g_hshsdk) == SHCERRNO_ALREADYEXIST )
			return true;
		printf("sh_make_directory ERROR : %d, %s\n", sh_get_error_number(g_hshsdk), sh_get_error_message(g_hshsdk));
		return false;
	}
	else
	{
		printf("sh_make_directory SUCCESS\n");
		return true;
	}
}

void upload_buffer(int mode, int c) 
{
	g_bUp = true;

	char szFilename[256];

	if ( makedir() == false )
		return;

	for( int i = 0; i < c; i++ ) {
		sprintf(szFilename, "/SVC1_TEST/test_buffer%d%c", i, '\0');
		g_total = 0; g_buffertotal = 2000;
		if(!sh_upload_buffer(g_hshsdk, szFilename, mode, Upload_Func, g_buffertotal, NULL)) {
			printf("upload_buffer : %d, %s\n", sh_get_error_number(g_hshsdk), sh_get_error_message(g_hshsdk));
			return;
		}
		else 
			printf("sh_upload SUCCESS\n");
	}
}

// 업로드
void upload(int mode, int c)
{
	g_bUp = true;
	char szFilename[256];

	// -- 2013-03-25
	char extQuery[600] = {0};
	//strcpy(extQuery, "&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10");
	strcpy(extQuery, "a=10&werfgwerf=123!@#$%^&*()테스트");

	if ( makedir() == false )
		return;

	for( int i = 0; i < c; i++ ) {		
		sprintf(szFilename, "/SVC1_TEST/test_%d%c", i, '\0');
		//sprintf(szFilename, "/k/kji777/( 完結 _ 2007 ) _ 수신연무.Jyushinenbu 03.avi", i, '\0');
		if (!sh_upload(g_hshsdk, "D:/test_10k.txt", szFilename, mode, -1, extQuery))
		{
			printf("sh_upload ERROR 1: %d, %s\n", sh_get_error_number(g_hshsdk), sh_get_error_message(g_hshsdk));
			return;
		}
		else
			printf("sh_upload SUCCESS\n");
	}
}

void uploadex(int mode, char *path, int c)
{
	g_bUp = true;
	char szFilename[256];

	// -- 2013-03-25
	char extQuery[600] = {0};
	//strcpy(extQuery, "&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10");
	strcpy(extQuery, "a=10&werfgwerf=123!@#$%^&*()테스트");

	if ( makedirex(path) == false )
		return;

	for( int i = 0; i < c; i++ ) {		
		sprintf(szFilename, "%s/test_%d%c", path, i, '\0');
		//sprintf(szFilename, "/k/kji777/( 完結 _ 2007 ) _ 수신연무.Jyushinenbu 03.avi", i, '\0');
		
		//if (!sh_upload(g_hshsdk, "D:/output.html", szFilename, mode, -1, extQuery))
		if (!sh_upload(g_hshsdk, "D:/fhs.data.check", szFilename, mode, -1, extQuery))
		{
			printf("sh_upload ERROR 1: %d, %s\n", sh_get_error_number(g_hshsdk), sh_get_error_message(g_hshsdk));
			return;
		}
		else
			printf("sh_upload SUCCESS\n");
	}
}

void download_buffer(int c)
{
	g_bUp = false;
	char szFilename[1024];
	for( int i = 0; i < c; i++ ) {
		sprintf(szFilename, "/SVC1_TEST/test_%d%c", i, '\0');
		if (!sh_download_buffer(g_hshsdk, szFilename, Download_Func, 0, NULL)) {
			printf("download_buffer : %d, %s\n", sh_get_error_number(g_hshsdk), sh_get_error_message(g_hshsdk));
			return;
		} else {
			printf("download_buffer SUCCESS\n");
		}
	}
}

void download_buffer_r(int c)
{
	g_bUp = false;
	char szFilename[1024];
	for( int i = 0; i < c; i++ ) {
		sprintf(szFilename, "/SVC1_TEST/test_%d%c", i, '\0');
		INT64 nBytes = 1024, offset = 1;
		if (!sh_download_buffer_r(g_hshsdk, szFilename, Download_Func, offset, nBytes, NULL)) {
			printf("download_buffer_r : %d, %s\n", sh_get_error_number(g_hshsdk), sh_get_error_message(g_hshsdk));
			return;
		} else {
			printf("download_buffer_r SUCCESS\n");
		}
	}
}
/*
void download(char * filename, int mode, int c)
{
	g_bUp = false;
	char local_location[1024];
	char dav_location[1024];
	for( int i = 0; i < c; i++ ) {
		sprintf(dav_location, "%s/test_%d%c", filename, i, '\0');
		sprintf(local_location, "D:/temp/down_%d.xml%c", i, '\0');

		if (!sh_download(g_hshsdk, dav_location, local_location,  mode, -1))
		{
			printf("sh_download ERROR : %d, %s\n", sh_get_error_number(g_hshsdk), sh_get_error_message(g_hshsdk));
			return;
		}
		else{
			printf("sh_download SUCCESS\n");
		}
	}
	return;
} */

void download(char * filename, int mode, int c)
{
	g_bUp = false;
	char local_location[1024];
	char dav_location[1024];

	// -- 2013-03-25
	char extQuery[600] = {0};
	//strcpy(extQuery, "&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10&a=10");
	strcpy(extQuery, "a=10&werfgwerf=123!@#$%^&*()테스트");

	sprintf(dav_location, "%s", filename,  '\0');
	sprintf(local_location, "D:/cert/aa.txt",  '\0');

	if (!sh_download(g_hshsdk, dav_location, local_location,  mode, -1, extQuery))
	{
		printf("sh_download ERROR : %d, %s\n", sh_get_error_number(g_hshsdk), sh_get_error_message(g_hshsdk));
		return;
	}
	else{
	printf("sh_download SUCCESS\n");
	}

	return;
} 

void getdirex(char * path) 
{
	HSHFILELIST h = sh_get_filelist(g_hshsdk, path, 1);
	if (h == 0 )
	{
		printf("sh_get_filelist ERROR : %d, %s\n", sh_get_error_number(g_hshsdk), sh_get_error_message(g_hshsdk));
	}
	else 
	{
		int n = sh_get_filelist_count(g_hshsdk, h);
		printf("sh_get_filelist CNT = %d SUCCESS\n", n);
		sh_free_filelist(g_hshsdk, h);
	}
}

void getdir() 
{
	HSHFILELIST h = sh_get_filelist(g_hshsdk, "/SVC1_TEST/", 1);
	if (h == 0 )
	{
		printf("sh_get_filelist ERROR : %d, %s\n", sh_get_error_number(g_hshsdk), sh_get_error_message(g_hshsdk));
	}
	else 
	{
		int n = sh_get_filelist_count(g_hshsdk, h);
		printf("sh_get_filelist CNT = %d SUCCESS\n", n);
		sh_free_filelist(g_hshsdk, h);
	}
}

void deldirex(char * path)
{
	if (sh_delete(g_hshsdk, path) == 0)
	{
		printf("sh_delete ERROR : %d, %s\n", sh_get_error_number(g_hshsdk), sh_get_error_message(g_hshsdk));
		return;
	}
	else
		printf("sh_delete SUCCESS\n");
}

void deldir()
{
	if (sh_delete(g_hshsdk, "/SVC1_TEST/") == 0)
	{
		printf("sh_delete ERROR : %d, %s\n", sh_get_error_number(g_hshsdk), sh_get_error_message(g_hshsdk));
		return;
	}
	else
		printf("sh_delete SUCCESS\n");
}

#if defined(WIN32) && defined( _DEBUG)  
#define _CRTDBG_MAP_ALLOC
#include <malloc.h>
#include <crtdbg.h>

#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

#define  _ONCE_INIT_	
//#define _MULT_THRAD_	

#ifndef _MULT_THRAD_
int main(int argc, char* argv[])
{
	time_t time_start, time_end;
	time_start = time(0);
#ifdef WIN32
	//SET_CRT_DEBUG_FIELD( _CRTDBG_LEAK_CHECK_DF | _CRTDBG_DELAY_FREE_MEM_DF );
	SET_CRT_DEBUG_FIELD( _CRTDBG_LEAK_CHECK_DF );
	//_CrtSetBreakAlloc(75);
#endif // _WIN32
	int i = 0, maxc = 1, nc = 1;
#ifdef _ONCE_INIT_
	if(InitSDK()) return -1;	
#endif // _ONCE_INIT_

	char path[256] = {0};

	if(argc > 1 && argv[1]) 
		strcpy(path, argv[1]);
	else 
		strcpy(path, "/SVC1_TEST");
		//strcpy(path, "/u/u9912168/2011091017553163316_MisfitsS01E05WSPDTVXviDBiA_IPHONE.mp4");
		//strcpy(path, "/test/install.ini");
		//strcpy(path, "/msvcr71.dll");
		//strcpy(path, "D:\\x_interactive\\trunk\\SDK\\version_3\\WIN_SDK\\test_agent\\ReadMe.txt");
	
		
	
	
	if(argc > 2 && argv[2] &&  atoi(argv[2]) > 0 ) 
		maxc = atoi(argv[2]);

	if(argc > 3 && argv[3] &&  atoi(argv[3]) > 0 ) 
		nc = atoi(argv[3]);
	
	srand ( time(NULL) );
	while(1)
	{

#ifndef _ONCE_INIT_
		if(InitSDK()) break;
#endif //!_ONCE_INIT_
		time_end = time(0);
		
		if(nc < 0)
			nc = (rand() % 1000) + 1;
			
//		uploadex(SHWRITEPOLICY_OVERWRITE, path , nc);
		upload(SHWRITEPOLICY_OVERWRITE, nc);
//		download(path, SHWRITEPOLICY_OVERWRITE, nc);
//		deldirex(path);

		printf("소요된 시간 [%d]초\n, %s" ,(time(0) - time_end) , path);		

#ifndef _ONCE_INIT_
		FreeSDK();				
#endif //!_ONCE_INIT_
		
		if(++i >= maxc) 
			break;
	}

	printf("총 소요된 시간 [%d]초\n" ,(time(0) - time_start) );
	
#ifdef _ONCE_INIT_
	FreeSDK();
#endif // _ONCE_INIT_
#ifdef WIN32
	_CrtDumpMemoryLeaks();
#endif // WIN32

	return 0;
}
#else // _MULT_THRAD_
char g_szServiceHost[1024];

#ifdef WIN32
#define NUM_OF_THREADS        MAXIMUM_WAIT_OBJECTS
HANDLE  g_hStart = NULL;

DWORD WINAPI TestThread(LPVOID lpParam)
{

	char szAuthString[1024], szRemotePath[1024], szLocalPath[1024];
	::WaitForSingleObject(g_hStart, INFINITE);


#ifndef _SP_SDK_
	const char* pAuthString = sh_get_auth_string(ID, PWD, SERVICE, AUTHSTR, FILE_PATH, time(NULL) + 86400);
	strcpy_s(szAuthString, sizeof(szAuthString), pAuthString);
	sh_mem_free((void *)pAuthString);
#else // _SP_SDK_
	char userid[256] = {0};
	sprintf(userid,"%s@%s", SERVICE, ID);
	const char* pAuthString = (char*)sh_get_auth_sp_string(userid, PWD);
	strcpy_s(szAuthString, sizeof(szAuthString), pAuthString);
	sh_mem_free((void *)pAuthString);
#endif // _SP_SDK_
	
	g_bUp = true;
	HSHSDK hSDK = sh_init(g_szServiceHost, szAuthString, 0, 0);

	// upload
	sprintf_s(szRemotePath, sizeof(szRemotePath), "/testx/test%d", (int)lpParam);
	if(!sh_upload(hSDK, "D:/test_10k.txt", szRemotePath, SHWRITEPOLICY_OVERWRITE, -1))
		printf("sh_upload ERROR 1: %d, %s\n", sh_get_error_number(hSDK), sh_get_error_message(hSDK));
	else
		printf("sh_upload SUCCESS\n");	

	// download 
	sprintf_s(szLocalPath, sizeof(szLocalPath), "D:/temp/test%d", (int)lpParam);
	if (!sh_download(hSDK, szRemotePath, szLocalPath,  SHWRITEPOLICY_OVERWRITE, -1))
	{
		printf("sh_download ERROR : %d, %s\n", sh_get_error_number(g_hshsdk), sh_get_error_message(g_hshsdk));
	}
	else{
		printf("sh_download SUCCESS\n");
	}

	sh_free(hSDK);
	
	return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
	const char *pServiceHost = sh_get_service_host(ID, PWD, SERVICE);

	if(!pServiceHost)
	{
		fprintf(stderr, "Error : get service host.\n");
		return 1;
	}

	strcpy_s(g_szServiceHost, sizeof(g_szServiceHost), pServiceHost);
	sh_mem_free((void *)pServiceHost);

	puts(g_szServiceHost);
	
	g_hStart = ::CreateEvent(NULL, TRUE, FALSE, NULL);

	HANDLE hThread[NUM_OF_THREADS];
	DWORD dwThreadId[NUM_OF_THREADS];
		
	for (int i = 0; i < NUM_OF_THREADS; ++i)
	{
		hThread[i] = CreateThread(NULL, 0, TestThread, (PVOID)i, 0, &dwThreadId[i]);
	}

	puts("Ready. press enter key to start.");
	getchar();

	DWORD dwStart = ::GetTickCount();
	::SetEvent(g_hStart);
	::WaitForMultipleObjects(NUM_OF_THREADS, hThread, TRUE, INFINITE);
	printf("Done : %dms elapsed.\n", ::GetTickCount() - dwStart);

	getchar();
	return 0;
}
#else // WIN32
#include <pthread.h>
#include <unistd.h>

#define NUM_OF_THREADS        100 // file open count 

void *t_function(void *data)
{	
	pthread_t id = pthread_self();

	size_t i = (size_t) data;
	//printf("therad : %d \n",i);  
	//pthread_exit((void *) 0); 

	char szAuthString[1024], szRemotePath[1024], szLocalPath[1024];

	char* pAuthString = NULL;
#ifndef _SP_SDK_
	pAuthString = (char*) sh_get_auth_string(ID, PWD, SERVICE, AUTHSTR, FILE_PATH, time(NULL) + 86400);
#else // _SP_SDK_
	char userid[256] = {0};
	sprintf(userid,"%s@%s", SERVICE, ID);
	pAuthString = (char*) sh_get_auth_sp_string(userid, PWD);
#endif // _SP_SDK_

	if(!pAuthString)
	{
		fprintf(stderr, "error : get auth string \n");
		return (void *) 0;
	}

	strcpy(szAuthString, pAuthString);
	sh_mem_free((void *)pAuthString);
		
	g_bUp = true;
	HSHSDK hSDK = sh_init(g_szServiceHost, szAuthString, 0, 0);

	// upload 
	sprintf(szRemotePath, "/testx/test_%d", i);
	if(!sh_upload(hSDK, "D:/test_10k.txt", szRemotePath, SHWRITEPOLICY_OVERWRITE, -1))
		printf("sh_upload ERROR 1: %d, %s\n", sh_get_error_number(hSDK), sh_get_error_message(hSDK));
	else
		printf("sh_upload SUCCESS\n");

	//download
	sprintf(szLocalPath, "D:/temp/test_%d", i);
	if (!sh_download(hSDK, szRemotePath, szLocalPath,  SHWRITEPOLICY_OVERWRITE, -1))
	{
		printf("sh_download ERROR : %d, %s\n", sh_get_error_number(g_hshsdk), sh_get_error_message(g_hshsdk));
	}
	else{
		printf("sh_download SUCCESS\n");
	}

	sh_free(hSDK);

	return (void *) 0;
}


int main(int argc, char* argv[])
{
	const char *pServiceHost = sh_get_service_host(ID, PWD, SERVICE);

	if(!pServiceHost)
	{
		fprintf(stderr, "Error : get service host.\n");
		return 1;
	}

	strcpy(g_szServiceHost, pServiceHost);
	sh_mem_free((void *)pServiceHost);

	puts(g_szServiceHost);
	puts("Ready. press enter key to start.");
	getchar();

	int       thr_id,i;
	pthread_t p_thread[NUM_OF_THREADS];
	static time_t tstart = time(0);
	for (i = 0; i < NUM_OF_THREADS; ++i)
	{
		thr_id = pthread_create(&p_thread[i], NULL, t_function, (void *)((int)i));
		if (thr_id < 0) 
		{ 
			perror("thread create error : "); 
			exit(0); 
		} 
		sleep(0);
		//pthread_detach(p_thread[i]); 		
	}

	int rc,status;
	for(i = (NUM_OF_THREADS-1); i >= 0; i--)
	{
		rc = pthread_join(p_thread[i], (void **)&status);
		if( rc == 0 )
		{
			//printf("Completed join with thread %d status= %d\n",i, status); 
		}
		else
		{
			printf("ERROR; return code from pthread_join() is %d, thread %d\n", rc, i); 
			return -1;			
		}		
	}
	printf("Done : %dsec elapsed.\n", time(0) - tstart);
	
	getchar();
	return 0;
}
#endif // WIN32
#endif // _MULT_THRAD_

