コード例 #1
0
void WebServerManager::Stop()
{
	if (!started)
		return;
	{
		CFlyFastLock(cs);
		if (!started)
			return;
			
		started = false;
	}
	try
	{
		socket.removeListener(this);
		socket.disconnect();
	}
	catch (const SocketException&) {} //-V565
	safe_delete(page404);
	for (auto p = pages.begin(); p != pages.end(); ++p)
	{
		safe_delete(p->second);
	}
	head.clear();
	foot.clear();
	search_delay.clear();
#ifdef _DEBUG_WEB_SERVER_
	FreeConsole();
#endif
}
コード例 #2
0
bool PGLoader::check(uint32_t p_ip4)
{
#ifdef _DEBUG
	//boost::system::error_code ec;
	//const auto l_ip_boost = boost::asio::ip::address_v4::from_string("10.91.2.180", ec);
	//p_ip4 = l_ip_boost.to_ulong();
	static boost::atomic_int g_count(0);
	dcdebug("PGLoader::check  count = %d\n", int(++g_count));
#endif
	if (BOOLSETTING(ENABLE_IPTRUST))
	{
		CFlyFastLock(g_cs);
		if (!g_ipTrustListBlock.empty())
		{
			if (g_ipTrustListBlock.checkIp(p_ip4))
			{
				return true;
			}
		}
		if (!g_ipTrustListAllow.empty())
		{
			const auto l_ipguard = g_ipTrustListAllow.checkIp(p_ip4);
			return !l_ipguard;
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
}
コード例 #3
0
void
RSSFeed::clearNewsList()
{
	CFlyFastLock(csNews);
	for (auto i = m_newsList.cbegin(); i != m_newsList.cend(); ++i)
	{
		delete *i;
	}
	m_newsList.clear();
}
コード例 #4
0
BOOL PortalBrowserFrame::PreTranslateMessage(MSG* pMsg)
{
	BOOL bRet = FALSE;
	if (!g_portal_frames.empty())
	{
		CFlyFastLock(g_cs);
		auto i = g_portal_frames.begin();
		while (i != g_portal_frames.end())
		{
			bRet |= i->second->PreTranslateMessage_ByInstance(pMsg);
			++i;
		}
	}
	return bRet;
}
コード例 #5
0
PortalBrowserFrame::~PortalBrowserFrame()
{
	{
		CFlyFastLock(g_cs);
		auto i = g_portal_frames.begin();
		
		while (i != g_portal_frames.end())
		{
			if (i->second == this)
			{
				g_portal_frames.erase(i);
				break;
			}
			++i;
		}
	}
	
	Cleanup();
}
コード例 #6
0
RSSManager::~RSSManager(void)
{
	TimerManager::getInstance()->removeListener(this);
	waitShutdown();
	{
		CFlyFastLock(g_csNews);
		for (auto j = g_newsList.cbegin(); j != g_newsList.cend(); ++j)
		{
			delete *j;
		}
	}
	{
		CFlyLock(g_csFeed);
		for (auto i = g_feeds.cbegin(); i != g_feeds.cend(); ++i)
		{
			delete *i;
		}
	}
}
コード例 #7
0
void
RSSManager::updateAllFeeds()
{
	unsigned int iNewNews = 0;
	NewsList l_fire_added_array;
	{
		CFlyLock(g_csFeed); // [+] IRainman fix.
		for (auto i = g_feeds.cbegin(); i != g_feeds.cend(); ++i)
		{
			if ((*i)->UpdateFeedNewXML())
			{
				const RSSFeed::RSSItemList& list = (*i)->getNewsList();
				for (auto j = list.cbegin(); j != list.cend(); ++j)
				{
					const RSSItem *l_item = new RSSItem(*j);
					CFlyFastLock(g_csNews);
					if (canAdd(l_item))
					{
						g_newsList.push_back(l_item);
						l_fire_added_array.push_back(l_item);
					}
					else
					{
						safe_delete(l_item);
					}
				}
				iNewNews += list.size();
			}
		}
	}
	for (auto i = l_fire_added_array.begin(); i !=  l_fire_added_array.end(); ++i)
	{
		fly_fire1(RSSListener::Added(), *i);
	}
	
	if (iNewNews)
	{
		fly_fire1(RSSListener::NewRSS(), iNewNews);
	}
}
コード例 #8
0
void WebServerManager::Start() noexcept
{
	if (started)
		return;
	{
		CFlyFastLock(cs);
		if (started)
			return;
			
		started = true;
	}
	page404 = new WebPageInfo(PAGE_404, STRING(WEBSERVER_PAGE_NOT_FOUND));
	pages["/"] = new WebPageInfo(INDEX, "");
	pages["/index.htm"] = new WebPageInfo(INDEX, "");
	pages["/dlqueue.htm"] = new WebPageInfo(DOWNLOAD_QUEUE, STRING(DOWNLOAD_QUEUE));
	pages["/dlfinished.htm"] = new WebPageInfo(DOWNLOAD_FINISHED, STRING(FINISHED_DOWNLOAD));
	pages["/ulqueue.htm"] = new WebPageInfo(UPLOAD_QUEUE, STRING(SETTINGS_LOG_UPLOADS));
	pages["/ulfinished.htm"] = new WebPageInfo(UPLOAD_FINISHED, STRING(FINISHED_UPLOADS));
	pages["/weblog.htm"] = new WebPageInfo(LOG, STRING(SETTINGS_LOG_WEBSERVER));
	pages["/syslog.htm"] = new WebPageInfo(SYSLOG, STRING(SETTINGS_LOG_SYSTEM_MESSAGES));
	pages["/search.htm"] = new WebPageInfo(SEARCH, STRING(WEBSERVER_SEARCH_PAGE_NAME));
	pages["/settings.htm"] = new WebPageInfo(SETTINGS, STRING(SETTINGS));
	pages["/logs.htm"] = new WebPageInfo(LOGS, STRING(SETTINGS_LOGS));
	pages["/logout.htm"] = new WebPageInfo(LOGOUT, STRING(LOG_OUT));
#ifdef _DEBUG_WEB_SERVER_
	AllocConsole();
	freopen("con:", "w", stdout);
	printf("WebServer debug log:\n");
#endif
	try
	{
		socket.listen(static_cast<uint16_t>(SETTING(WEBSERVER_PORT)), SETTING(WEBSERVER_BIND_ADDRESS));
		socket.addListener(this);
		fly_fire(WebServerListener::Setup());
	}
	catch (const SocketException&) {} //-V565
}
コード例 #9
0
void PGLoader::load(const string& p_data /*= Util::emptyString*/)
{
	string l_data;
	const string l_url = SETTING(URL_IPTRUST);
	bool l_is_download = false;
	CFlyLog l_IPTrust_log("[IPTrust]");
	if (p_data.empty())
	{
		if (!l_url.empty())
		{
			try
			{
				const string l_log_message = STRING(DOWNLOAD) + ": " + l_url;
				if (Util::getDataFromInet(true, l_url, l_data, 0) == 0)
				{
					l_IPTrust_log.step(l_log_message + " [" + STRING(ERROR_STRING) + ']');
				}
				else
				{
					l_IPTrust_log.step(l_log_message + " [OK]");
					// "распарсим" ответ (TODO - перейти на regexp)
					{
						string::size_type linestart = 0;
						string::size_type lineend = 0;
						for (;;)
						{
							lineend = l_data.find('\n', linestart);
							if (lineend == string::npos)
								break;
							const string line = l_data.substr(linestart, lineend - linestart - 1);
							int u1, u2, u3, u4, u5, u6, u7, u8;
							int iItems = sscanf_s(line.c_str(), "%u.%u.%u.%u - %u.%u.%u.%u", &u1, &u2, &u3, &u4, &u5, &u6, &u7, &u8);
							if (iItems == 8 || iItems == 4)
							{
								l_is_download = true;
								break;
							}
							iItems = sscanf_s(line.c_str(), "#%u.%u.%u.%u - %u.%u.%u.%u", &u1, &u2, &u3, &u4, &u5, &u6, &u7, &u8);
							if (iItems == 8 || iItems == 4)
							{
								l_is_download = true;
								break;
							}
							linestart = lineend + 1;
						}
					}
					if (l_is_download)
					{
						const auto l_IPTrust_ini = getConfigFileName();
						File(l_IPTrust_ini, File::WRITE, File::CREATE | File::TRUNCATE).write(l_data);
						l_IPTrust_log.step(l_IPTrust_ini + " [" + STRING(SAVE) + ']');
					}
				}
			}
			catch (const FileException& e)
			{
				l_IPTrust_log.step("Can't write IPTrust.ini file: " + e.getError());
				dcdebug("IPTrust::save: %s\n", e.getError().c_str());
			}
		}
		if (l_data.empty())
		{
			const string l_IPTrust_ini = getConfigFileName();
			if (File::isExist(l_IPTrust_ini))
			{
				try
				{
					l_data = File(l_IPTrust_ini, File::READ, File::OPEN).read();
				}
				catch (const FileException& e)
				{
					l_IPTrust_log.step("Can't read IPTrust.ini file: " + e.getError());
					dcdebug("IPTrust::load: %s\n", e.getError().c_str());
				}
			}
			else
			{
				Util::WriteTextResourceToFile(IDR_IPTRUST_EXAMPLE, Text::toT(l_IPTrust_ini));
				l_IPTrust_log.step("IPTrust.ini restored from internal resources");
			}
		}
	}
	else
	{
		l_data = p_data;
	}
	
	CFlyFastLock(g_cs);
	l_IPTrust_log.step("parse IPTrust.ini");
	g_ipTrustListAllow.clear();
	g_ipTrustListBlock.clear();
	
	if (!l_data.empty())
	{
		string::size_type linestart = 0;
		string::size_type lineend = 0;
		for (;;)
		{
			lineend = l_data.find('\n', linestart);
			if (lineend == string::npos)
			{
				string l_line = l_data.substr(linestart);
				addLine(l_line, l_IPTrust_log);
				break;
			}
			else
			{
				string l_line = l_data.substr(linestart, lineend - linestart - 1);
				addLine(l_line, l_IPTrust_log);
				linestart = lineend + 1;
			}
		}
	}
	l_IPTrust_log.step("parse IPTrust.ini done");
}
コード例 #10
0
void shutdown(GUIINITPROC pGuiInitProc, void *pGuiParam)
{
	// Сохраним маркеры времени завершения
#ifndef _DEBUG
	extern crash_rpt::CrashRpt g_crashRpt;
	g_crashRpt.SetCustomInfo(_T("StopCore"));
#endif
	
	{
#ifdef FLYLINKDC_COLLECT_UNKNOWN_TAG
		string l_debugTag;
		{
			CFlyFastLock(NmdcSupports::g_debugCsUnknownNmdcTagParam);
			//dcassert(NmdcSupports::g_debugUnknownNmdcTagParam.empty());
			const auto& l_debugUnknownNmdcTagParam = NmdcSupports::g_debugUnknownNmdcTagParam;
			for (auto i = l_debugUnknownNmdcTagParam.begin(); i != l_debugUnknownNmdcTagParam.end(); ++i)
			{
				l_debugTag += i->first + "(" + Util::toString(i->second) + ")" + ',';
			}
			NmdcSupports::g_debugUnknownNmdcTagParam.clear();
		}
		if (!l_debugTag.empty())
		{
			LogManager::message("Founded unknown NMDC tag param: " + l_debugTag);
		}
#endif
		
#ifdef FLYLINKDC_COLLECT_UNKNOWN_FEATURES
		// [!] IRainman fix: supports cleanup.
		string l_debugFeatures;
		string l_debugConnections;
		{
			CFlyFastLock(AdcSupports::g_debugCsUnknownAdcFeatures);
			// dcassert(AdcSupports::g_debugUnknownAdcFeatures.empty());
			const auto& l_debugUnknownFeatures = AdcSupports::g_debugUnknownAdcFeatures;
			for (auto i = l_debugUnknownFeatures.begin(); i != l_debugUnknownFeatures.end(); ++i)
			{
				l_debugFeatures += i->first + "[" + i->second + "]" + ',';
			}
			AdcSupports::g_debugUnknownAdcFeatures.clear();
		}
		{
			CFlyFastLock(NmdcSupports::g_debugCsUnknownNmdcConnection);
			dcassert(NmdcSupports::g_debugUnknownNmdcConnection.empty());
			const auto& l_debugUnknownConnections = NmdcSupports::g_debugUnknownNmdcConnection;
			for (auto i = l_debugUnknownConnections.begin(); i != l_debugUnknownConnections.end(); ++i)
			{
				l_debugConnections += *i + ',';
			}
			NmdcSupports::g_debugUnknownNmdcConnection.clear();
		}
		if (!l_debugFeatures.empty())
		{
			LogManager::message("Founded unknown ADC supports: " + l_debugFeatures);
		}
		if (!l_debugConnections.empty())
		{
			LogManager::message("Founded unknown NMDC connections: " + l_debugConnections);
		}
#endif // FLYLINKDC_COLLECT_UNKNOWN_FEATURES
		
#ifdef FLYLINKDC_USE_GATHER_STATISTICS
		CFlyTickDelta l_delta(g_fly_server_stat.m_time_mark[CFlyServerStatistics::TIME_SHUTDOWN_CORE]);
#endif
#ifdef _DEBUG
		dcdebug("shutdown start - User::g_user_counts = %d OnlineUser::g_online_user_counts = %d\n", int(User::g_user_counts), int(OnlineUser::g_online_user_counts));
#endif
#ifdef STRONG_USE_DHT
		dht::DHT::getInstance()->stop(true); // [+] IRainman fix.
#ifdef _DEBUG
		dcdebug("shutdown (after closing last hub (DHT::stop) - User::g_user_counts = %d OnlineUser::g_online_user_counts = %d\n", int(User::g_user_counts), int(OnlineUser::g_online_user_counts)); // [+] IRainman fix.
#endif
#endif
#ifdef FLYLINKDC_USE_TORRENT
		DownloadManager::getInstance()->shutdown_torrent();
#endif
		QueueManager::getInstance()->saveQueue(true);
		SettingsManager::getInstance()->save();
		ConnectionManager::getInstance()->shutdown();
		MappingManager::getInstance()->close();
		
		preparingCoreToShutdown(); // Зовем тут второй раз т.к. вероятно при автообновлении оно не зовется.
		
#ifdef FLYLINKDC_USE_DNS
		Socket::dnsCache.waitShutdown(); // !SMT!-IP
#endif
#ifdef FLYLINKDC_USE_SOCKET_COUNTER
		BufferedSocket::waitShutdown();
#endif
		
#ifdef IRAINMAN_USE_STRING_POOL
		StringPool::deleteInstance(); // [+] IRainman opt.
#endif
		MappingManager::deleteInstance();
		ConnectivityManager::deleteInstance();
		WebServerManager::deleteInstance();
		if (pGuiInitProc)
		{
			pGuiInitProc(pGuiParam);
		}
		ADLSearchManager::deleteInstance();
		FinishedManager::deleteInstance();
		ShareManager::deleteInstance();
#ifdef STRONG_USE_DHT
		dht::DHT::deleteInstance();
#endif
#ifdef USE_FLYLINKDC_VLD
		VLDDisable(); // TODO VLD показывает там лики - не понял пока как победить OpenSSL
#endif
// FLYLINKDC_CRYPTO_DISABLE
		CryptoManager::deleteInstance();
#ifdef USE_FLYLINKDC_VLD
		VLDEnable(); // TODO VLD показывает там лики - не понял пока как победить OpenSSL
#endif
		ThrottleManager::deleteInstance();
		DownloadManager::deleteInstance();
		UploadManager::deleteInstance();
		QueueManager::deleteInstance();
		ConnectionManager::deleteInstance();
		SearchManager::deleteInstance();
		UserManager::deleteInstance(); // [+] IRainman core
		FavoriteManager::deleteInstance();
		ClientManager::deleteInstance();
		HashManager::deleteInstance();
#ifdef FLYLINKDC_USE_GPU_TTH
		GPGPUTTHManager::deleteInstance();
#endif // FLYLINKDC_USE_GPU_TTH
		
		CFlylinkDBManager::deleteInstance();
		CFlylinkDBManager::shutdown_engine();
		TimerManager::deleteInstance();
		SettingsManager::deleteInstance();
		ToolbarManager::shutdown();
		extern SettingsManager* g_settings;
		g_settings = nullptr;
		
#ifdef FLYLINKDC_USE_SYSLOG
		closelog();
#endif
		
		::WSACleanup();
#ifdef _DEBUG
		dcdebug("shutdown end - User::g_user_counts = %d OnlineUser::g_online_user_counts = %d\n", int(User::g_user_counts), int(OnlineUser::g_online_user_counts));
		//dcassert(User::g_user_counts == 2);
		// ClientManager::g_uflylinkdc and ClientManager::g_me destroyed only with the full completion of the program, all the other user must be destroyed already by this time.
		dcassert(OnlineUser::g_online_user_counts == 0);
		dcassert(UploadQueueItem::g_upload_queue_item_count == 0);
		dcdebug("shutdown start - UploadQueueItem::g_upload_queue_item_count = %d \n", int(UploadQueueItem::g_upload_queue_item_count));
#endif
		
		// [~] IRainman fix.
	}
	
#ifdef FLYLINKDC_USE_GATHER_STATISTICS
	g_fly_server_stat.saveShutdownMarkers();
#endif
}
コード例 #11
0
bool
RSSFeed::ProcessAtom(void* data, RSSParser parser, bool isUtf8)
{
	time_t maxLastDate = 0;
	if (parser == XML_PARSER)
	{
		XMLParser::XMLNode* rootNode = reinterpret_cast<XMLParser::XMLNode*>(data);
		if (rootNode != nullptr)
		{
			XMLParser::XMLNode feedNode = rootNode->getChildNode("feed");
			if (!feedNode.isEmpty())
			{
				// Search items
				int i = 0;
				XMLParser::XMLNode itemNode = feedNode.getChildNode("entry", &i);
				while (!itemNode.isEmpty())
				{
					string title;
					string url;
					string desc;
					time_t pubDate = 0;
					string author;
					string category;
					XMLParser::XMLNode titleNode = itemNode.getChildNode("title");
					if (!titleNode.isEmpty())
					{
						if (titleNode.nText())
							title = titleNode.getText();
						else if (titleNode.nClear())
							title = titleNode.getClear().lpszValue;
						if (isUtf8) title = Text::fromUtf8(title);
					}
					int j = 0;
					XMLParser::XMLNode linkNode = itemNode.getChildNode("link", &j);
					while (!linkNode.isEmpty())
					{
						if (linkNode.nAttribute() && linkNode.isAttributeSet("rel") && linkNode.isAttributeSet("href"))
						{
							string relation = linkNode.getAttribute("rel");
							if (relation == "alternate")
							{
								url = linkNode.getAttribute("href");
								// [!] SSA Can be problems
								if (isUtf8) url = Text::utf8ToAcp(Text::fromUtf8(url));
								break;
							}
						}
						linkNode = itemNode.getChildNode("link", &j);
					}
					XMLParser::XMLNode descNode = itemNode.getChildNode("content");
					if (!descNode.isEmpty())
					{
						if (descNode.nText())
							desc = descNode.getText();
						else if (descNode.nClear())
							desc = descNode.getClear().lpszValue;
						if (isUtf8) desc = Text::fromUtf8(desc);
					}
					XMLParser::XMLNode pubDateNode = itemNode.getChildNode("published");
					if (!pubDateNode.isEmpty())
					{
						string pDate;
						if (pubDateNode.nText())
							pDate = pubDateNode.getText();
						else if (pubDateNode.nClear())
							pDate = pubDateNode.getClear().lpszValue;
							
						if (pDate.length() > 0)
						{
							/*
							SYSTEMTIME pTime = {0};
							InternetTimeToSystemTimeA(pDate.c_str(), &pTime, 0);
							*/
							// Using format in atom 2012-08-20T11:57:53.000Z
							
							std::string date_string, tod_string;
							boost::date_time::split(pDate, 'T', date_string, tod_string);
							tod_string = tod_string.substr(0, 8) + ".000";
							
							boost::posix_time::time_duration td = boost::date_time::parse_delimited_time_duration<boost::posix_time::time_duration>(tod_string);
							
							tm l_tm = {0};
							///
							l_tm.tm_year = atoi(date_string.substr(0, 4).c_str()) - 1900;
							l_tm.tm_mon = atoi(date_string.substr(5, 2).c_str())  - 1;
							l_tm.tm_mday = atoi(date_string.substr(8, 2).c_str());
							
							l_tm.tm_hour = td.hours();
							l_tm.tm_min = td.minutes();
							l_tm.tm_sec = td.seconds();
							
							pubDate = mktime(&l_tm);
							
						}
					}
					XMLParser::XMLNode authorNode =  itemNode.getChildNode("author");
					if (!authorNode.isEmpty())
					{
						XMLParser::XMLNode authorName = authorNode.getChildNode("name");
						if (!authorName.isEmpty())
						{
							if (authorName.nText())
								author =  authorName.getText();
							else if (authorName.nClear())
								author = authorName.getClear().lpszValue;
							if (isUtf8) author = Text::fromUtf8(author);
						}
					}
					int k = 0;
					XMLParser::XMLNode categoryNode =  itemNode.getChildNode("category", &k);
					while (!categoryNode.isEmpty())
					{
						if (categoryNode.nAttribute())
						{
							if (categoryNode.isAttributeSet("term"))
							{
								if (!category.empty())
									category += ",";
								category += categoryNode.getAttribute("term");
							}
						}
						categoryNode =  itemNode.getChildNode("category", &k);
					}
					if (isUtf8) category = Text::fromUtf8(category);
					
					if (pubDate == 0 || lastNewsDate < pubDate)
					{
						if (pubDate > maxLastDate)
							maxLastDate = pubDate;
							
						RSSItem* item = new RSSItem(Util::ConvertFromHTML(title), url, Util::ConvertFromHTML(desc), pubDate, author, category, source);
						CFlyFastLock(csNews);
						m_newsList.push_back(item);
					}
					
					itemNode = feedNode.getChildNode("entry", &i);
				}
				if (maxLastDate > lastNewsDate)
					lastNewsDate = maxLastDate;
					
				CFlyFastLock(csNews);
				return !m_newsList.empty();
			}
		}
	}
	else if (parser == XML_SIMPLE)
	{
		// [!] SSA - todo if needed?
		SimpleXML* xml = reinterpret_cast<SimpleXML*>(data);
		if (xml != nullptr)
		{
		}
	}
	return false;
}
コード例 #12
0
bool
RSSFeed::ProcessRSS(void* data, RSSParser parser, bool isUtf8)
{
	time_t maxLastDate = 0;
	if (parser == XML_PARSER)
	{
		XMLParser::XMLNode* rootNode = reinterpret_cast<XMLParser::XMLNode*>(data);
		if (rootNode != nullptr)
		{
			XMLParser::XMLNode rssNode = rootNode->getChildNode("rss");
			if (!rssNode.isEmpty())
			{
				XMLParser::XMLNode channelNode = rssNode.getChildNode("channel");
				if (!channelNode.isEmpty())
				{
					// Search items
					int i = 0;
					XMLParser::XMLNode itemNode = channelNode.getChildNode("item", &i);
					while (!itemNode.isEmpty())
					{
						string title;
						string url;
						string desc;
						time_t pubDate = 0;
						string author;
						string category;
						XMLParser::XMLNode titleNode = itemNode.getChildNode("title");
						if (!titleNode.isEmpty())
						{
							if (titleNode.nText())
								title = titleNode.getText();
							else if (titleNode.nClear())
								title = titleNode.getClear().lpszValue;
							if (isUtf8) title = Text::fromUtf8(title);
						}
						XMLParser::XMLNode linkNode = itemNode.getChildNode("link");
						if (!linkNode.isEmpty())
						{
							if (linkNode.nText())
								url = linkNode.getText();
							else if (linkNode.nClear())
								url = linkNode.getClear().lpszValue;
							// [!] SSA Can be problems
							if (isUtf8) url = Text::utf8ToAcp(Text::fromUtf8(url));
						}
						XMLParser::XMLNode descNode = itemNode.getChildNode("description");
						if (!descNode.isEmpty())
						{
							if (descNode.nText())
								desc = descNode.getText();
							else if (descNode.nClear())
								desc = descNode.getClear().lpszValue;
							if (isUtf8) desc = Text::fromUtf8(desc);
						}
						XMLParser::XMLNode pubDateNode = itemNode.getChildNode("pubDate");
						if (!pubDateNode.isEmpty())
						{
							string pDate;
							if (pubDateNode.nText())
								pDate = pubDateNode.getText();
							else if (pubDateNode.nClear())
								pDate = pubDateNode.getClear().lpszValue;
								
							pubDate = convertPubDate(pDate);
						}
						XMLParser::XMLNode authorNode =  itemNode.getChildNode("author");
						if (!authorNode.isEmpty())
						{
							if (authorNode.nText())
								author =  authorNode.getText();
							else if (authorNode.nClear())
								author = authorNode.getClear().lpszValue;
							if (isUtf8) author = Text::fromUtf8(author);
						}
						XMLParser::XMLNode categoryNode =  itemNode.getChildNode("category");
						if (!categoryNode.isEmpty())
						{
							if (categoryNode.nText())
								category = categoryNode.getText();
							else if (categoryNode.nClear())
								category = categoryNode.getClear().lpszValue;
							if (isUtf8) category = Text::fromUtf8(category);
						}
						
						if (pubDate == 0 || lastNewsDate < pubDate)
						{
							if (pubDate > maxLastDate)
								maxLastDate = pubDate;
								
							RSSItem* item = new RSSItem(Util::ConvertFromHTML(title), url, Util::ConvertFromHTML(desc), pubDate, author, category, source);
							CFlyFastLock(csNews);
							m_newsList.push_back(item);
						}
						
						itemNode = channelNode.getChildNode("item", &i);
					}
					if (maxLastDate > lastNewsDate)
						lastNewsDate = maxLastDate;
						
					CFlyFastLock(csNews);
					return !m_newsList.empty();
				}
			}
		}
	}
	else if (parser == XML_SIMPLE)
	{
		SimpleXML* xml = reinterpret_cast<SimpleXML*>(data);
		if (xml != nullptr)
		{
			xml->resetCurrentChild();
			
			if (xml->findChild("rss"))
			{
				xml->stepIn();
				if (xml->findChild("channel"))
				{
					xml->stepIn();
					while (xml->findChild("item"))
					{
						xml->stepIn();
						string title;
						string url;
						string desc;
						time_t pubDate = 0;
						string author;
						string category;
						if (xml->findChild("title"))
							removeCDATA(xml->getChildData(), title);
						xml->resetCurrentChild();
						if (xml->findChild("link"))
							removeCDATA(xml->getChildData(), url);
						xml->resetCurrentChild();
						if (xml->findChild("description"))
							removeCDATA(xml->getChildData(), desc);
						xml->resetCurrentChild();
						if (xml->findChild("pubDate"))
						{
							string pDate;
							removeCDATA(xml->getChildData(), pDate);
							pubDate = convertPubDate(pDate);
						}
						xml->resetCurrentChild();
						
						if (xml->findChild("author"))
							removeCDATA(xml->getChildData(), author);
						xml->resetCurrentChild();
						if (xml->findChild("category"))
							removeCDATA(xml->getChildData(), category);
						xml->resetCurrentChild();
						
						if (pubDate == 0 || lastNewsDate < pubDate)
						{
							if (pubDate > maxLastDate)
								maxLastDate = pubDate;
								
							RSSItem* item = new RSSItem(Util::ConvertFromHTML(title), url, desc, pubDate, author, category, source);
							CFlyFastLock(csNews);
							m_newsList.push_back(item);
						}
						xml->stepOut();
					}
				}
			}
			if (maxLastDate > lastNewsDate)
				lastNewsDate = maxLastDate;
				
			CFlyFastLock(csNews);
			return !m_newsList.empty();
		}
	}
	return false;
}