void LLUpdateDownloader::Implementation::run(void)
{
	CURLcode code = curl_easy_perform(mCurl);
	mDownloadStream.close();
	if(code == CURLE_OK) {
		LLFile::remove(mDownloadRecordPath);
		if(validateDownload()) {
			LL_INFOS("UpdateDownload") << "download successful" << LL_ENDL;
			mClient.downloadComplete(mDownloadData);
		} else {
			LL_INFOS("UpdateDownload") << "download failed hash check" << LL_ENDL;
			std::string filePath = mDownloadData["path"].asString();
			if(filePath.size() != 0) LLFile::remove(filePath);
			mClient.downloadError("failed hash check");
		}
	} else if(mCancelled && (code == CURLE_WRITE_ERROR)) {
		LL_INFOS("UpdateDownload") << "download canceled by user" << LL_ENDL;
		// Do not call back client.
	} else {
		LL_WARNS("UpdateDownload") << "download failed with error '" << 
			curl_easy_strerror(code) << "'" << LL_ENDL;
		LLFile::remove(mDownloadRecordPath);
		if(mDownloadData.has("path")) LLFile::remove(mDownloadData["path"].asString());
		mClient.downloadError("curl error");
	}
	
	if(mHeaderList) {
		curl_slist_free_all(mHeaderList);
		mHeaderList = 0;
	}
}
bool LLUpdateDownloader::Implementation::validateOrRemove(const std::string& filePath)
{
	bool valid = validateDownload(filePath);
	if (! valid)
	{
		LL_INFOS("UpdaterService") << "removing " << filePath << LL_ENDL;
		LLFile::remove(filePath);
	}
	return valid;
}
void LLUpdateDownloader::Implementation::resume(void)
{
	mCancelled = false;

	if(isDownloading()) {
		mClient.downloadError("download in progress");
	}

	mDownloadRecordPath = downloadMarkerPath();
	llifstream dataStream(mDownloadRecordPath);
	if(!dataStream) {
		mClient.downloadError("no download marker");
		return;
	}
	
	LLSDSerialize::fromXMLDocument(mDownloadData, dataStream);
	
	if(!mDownloadData.asBoolean()) {
		mClient.downloadError("no download information in marker");
		return;
	}
	
	std::string filePath = mDownloadData["path"].asString();
	try {
		if(LLFile::isfile(filePath)) {		
			llstat fileStatus;
			LLFile::stat(filePath, &fileStatus);
			if(fileStatus.st_size != mDownloadData["size"].asInteger()) {
				resumeDownloading(fileStatus.st_size);
			} else if(!validateDownload()) {
				LLFile::remove(filePath);
				download(LLURI(mDownloadData["url"].asString()), 
						 mDownloadData["hash"].asString(),
						 mDownloadData["update_version"].asString(),
						 mDownloadData["required"].asBoolean());
			} else {
				mClient.downloadComplete(mDownloadData);
			}
		} else {
			download(LLURI(mDownloadData["url"].asString()), 
					 mDownloadData["hash"].asString(),
					 mDownloadData["update_version"].asString(),
					 mDownloadData["required"].asBoolean());
		}
	} catch(DownloadError & e) {
		mClient.downloadError(e.what());
	}
}