bool UploadDump(const char* file, const char* user, int build, int branch, DelegateI<Prog_s>* progress)
{
	Logger log;
	log.write("---------------------------------------\r\n");

	time_t ltime; /* calendar time */
	ltime=time(NULL); /* get current cal time */

	
#ifdef WIN32
	char buff[255] = {0};

	struct tm t;
	localtime_s(&t, &ltime);
	asctime_s(buff, 255, &t);
#else
	struct tm *t = localtime(&ltime);
	char* buff = asctime(t);
#endif

	log.write("%s\r\n", buff);
	log.write("---------------------------------------\r\n");

	log.write("Uploaded crash dump: [%s]\r\n", file);


	gcString dump(file);

	if (PrepDumpForUpload(dump) == false)
	{
		log.write("Failed to prepare crash dump.\r\n");
		return false;
	}
	else
	{
		log.write("Prepared crash dump to: [%s]\r\n", dump.c_str());
	}

	std::string os = UTIL::OS::getOSString();

	HttpHandle hh(DUMP_UPLOAD_URL);

	if (progress)
		hh->getProgressEvent() += progress;

	hh->setUserAgent(DUMP_UPLOAD_AGENT);

	hh->cleanUp();
	hh->addPostText("os", os.c_str());
	hh->addPostText("build", build);
	hh->addPostText("appid", branch);

	if (user)
		hh->addPostText("user", user);

	hh->addPostFile("crashfile", dump.c_str());

	try
	{
		hh->postWeb();
	}
	catch (gcException &except)
	{
		log.write("Failed to upload crash: %s [%d.%d].\r\n", except.getErrMsg(), except.getErrId(), except.getSecErrId());
		return false;
	}

	TiXmlDocument doc;
	doc.LoadBuffer(const_cast<char*>(hh->getData()), hh->getDataSize());
	
	try
	{
		XML::processStatus(doc, "crashupload");
		log.write("Uploaded dump\r\n");
		UTIL::FS::delFile(UTIL::FS::Path(dump, "", true));		
	}
	catch (gcException &)
	{
		log.write("Bad status returned from upload crash dump.\r\n");

		gcString res;
		res.assign(hh->getData(), hh->getDataSize());

		log.write("Result: \r\n\r\n%s\r\n\r\n", res.c_str());
		
		return false;	
	}

	return true;
}
bool UploadDump(const char* file, const char* user, int build, int branch, DelegateI<Prog_s&>* progress, const char* szTracer)
{
	if (build == 0)
		build = 9999;

	if (branch == 0)
		branch = BUILDID_PUBLIC;

	g_Logger.write("---------------------------------------\r\n");

	time_t ltime; /* calendar time */
	ltime=time(nullptr); /* get current cal time */

	
#if defined(WIN32) && !defined(__MINGW32__)
	char buff[255] = {0};

	struct tm t;
	localtime_s(&t, &ltime);
	asctime_s(buff, 255, &t);
#else
	struct tm *t = localtime(&ltime);
	char* buff = asctime(t);
#endif

	g_Logger.write("%s\r\n", buff);
	g_Logger.write("---------------------------------------\r\n");

	g_Logger.write("Uploaded crash dump: [%s]\r\n", file);


	gcString dump(file);
	gcString tracer(szTracer);
	gcString log(dump + ".log");

	if (PrepDumpForUpload(dump) == false)
	{
		g_Logger.write("Failed to prepare crash dump.\r\n");
		return false;
	}
	else
	{
		g_Logger.write("Prepared crash dump to: [%s]\r\n", dump.c_str());
	}

	if (!tracer.empty())
	{
		try
		{
			auto valid = false;
			UTIL::FS::FileHandle fh;

			std::function<void(const char*, uint32)> write = [&fh, &valid, log](const char* szData, uint32 nSize)
			{
				if (!valid)
					fh.open(log.c_str(), UTIL::FS::FILE_WRITE);

				valid = true;
				fh.write(szData, nSize);
			};

			DumpTracerToFile(tracer, write);

			if (!valid)
				log = "";
		}
		catch (...)
		{
			log = "";
		}

		if (!log.empty())
			PrepDumpForUpload(log);

#ifdef WIN32
		//Let desura exit now.
		gcString tracerEventName("Global\\{0}Event", tracer);

		auto hHandle = OpenEvent(EVENT_MODIFY_STATE, FALSE, tracerEventName.c_str());

		if (hHandle)
		{
			SetEvent(hHandle);
			CloseHandle(hHandle);
		}
#endif
	}

	std::string os = UTIL::OS::getOSString();

	HttpHandle hh(DUMP_UPLOAD_URL);

	if (progress)
		hh->getProgressEvent() += progress;

	hh->setUserAgent(DUMP_UPLOAD_AGENT);

	hh->cleanUp();
	hh->addPostText("os", os.c_str());
	hh->addPostText("build", build);
	hh->addPostText("appid", branch);

	if (user)
		hh->addPostText("user", user);

	hh->addPostFile("crashfile", dump.c_str());

	if (!log.empty())
		hh->addPostFile("crashlog", log.c_str());

	try
	{
		hh->postWeb();
	}
	catch (gcException &except)
	{
		g_Logger.write("Failed to upload crash: %s [%d.%d].\r\n", except.getErrMsg(), except.getErrId(), except.getSecErrId());
		return false;
	}

	XML::gcXMLDocument doc(const_cast<char*>(hh->getData()), hh->getDataSize());

	try
	{
		doc.ProcessStatus("crashupload");
		g_Logger.write("Uploaded dump\r\n");
		UTIL::FS::delFile(UTIL::FS::Path(dump, "", true));		
	}
	catch (gcException &)
	{
		g_Logger.write("Bad status returned from upload crash dump.\r\n");

		gcString res;
		res.assign(hh->getData(), hh->getDataSize());

		g_Logger.write("Result: \r\n\r\n%s\r\n\r\n", res.c_str());
		return false;	
	}

	return true;
}