Esempio n. 1
0
File: 02.cpp Progetto: Jerryang/cdec
int print_out_key(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
{
	StringPairList* spl = (StringPairList*)cls;
	printf("%s: %s\n", key, value);
	if (spl != NULL)
		spl->push_back(StringPairList::value_type(key, value));
	return MHD_YES;
}
Esempio n. 2
0
StringPairList ShareManager::getDirectories() const noexcept {
	Lock l(cs);
	StringPairList ret;
	for(auto& i: shares) {
		ret.emplace_back(i.second, i.first);
	}
	return ret;
}
Esempio n. 3
0
StringPairList ClientManager::getHubs(const CID& cid) const {
	Lock l(cs);
	StringPairList lst;
	auto op = onlineUsers.equal_range(cid);
	for(auto i = op.first; i != op.second; ++i) {
		lst.push_back(make_pair(i->second->getClient().getHubUrl(), i->second->getClient().getHubName()));
	}
	return lst;
}
Esempio n. 4
0
	websocketpp::http::status_code::value FileServer::handlePostRequest(const websocketpp::http::parser::request& aRequest,
		std::string& output_, StringPairList& headers_, const SessionPtr& aSession) noexcept {

		const auto& requestPath = aRequest.get_uri();
		if (requestPath == "/temp") {
			if (!aSession || !aSession->getUser()->hasPermission(Access::FILESYSTEM_EDIT)) {
				output_ = "Not authorized";
				return websocketpp::http::status_code::unauthorized;
			}

			const auto fileName = Util::toString(Util::rand());
			const auto filePath = Util::getTempPath() + fileName;

			try {
				File file(filePath, File::WRITE, File::TRUNCATE | File::CREATE, File::BUFFER_SEQUENTIAL);
				file.write(aRequest.get_body());
			} catch (const FileException& e) {
				output_ = "Failed to write the file: " + e.getError();
				return websocketpp::http::status_code::internal_server_error;
			}

			{
				WLock l(cs);
				tempFiles.emplace(fileName, filePath);
			}

			headers_.emplace_back("Location", fileName);
			return websocketpp::http::status_code::created;
		}

		output_ = "Requested resource was not found";
		return websocketpp::http::status_code::not_found;
	}
Esempio n. 5
0
ShareDirModel::ShareDirModel(QObject *parent){
    QDirModel::setParent(parent);
    QDirModel::setFilter((QDir::AllDirs | QDir::NoDotAndDotDot));

    StringPairList directories = ShareManager::getInstance()->getDirectories();
    for (auto it = directories.begin(); it != directories.end(); ++it){
        QString path = it->second.c_str();

        if (path.endsWith(QDir::separator()))
            path = path.left(path.lastIndexOf(QDir::separator()));

        emit expandMe(index(path));

        checked.insert(path);
    }
}
Esempio n. 6
0
File: 02.cpp Progetto: Jerryang/cdec
int ahc_echo(void* servctx, MHD_Connection* connection, const char* url, const char* method, const char* version, const char* upload_data, size_t* upload_data_size, void** reqctx)
{
	static int dummy;
	if (reqctx == NULL)
	{
		// The first time only the headers are valid, do not respond in the first round.
		*reqctx = &dummy;
		return MHD_YES;
	}

	ServerContext* pServCtx = (ServerContext*)servctx;	// Not used yet
	printf("%s %s %s\n", method, url, version);

	if (strcmp(method, "GET") == 0)
	{
		if (*upload_data_size != 0)
			return MHD_NO;	// No upload data expected in HTTP GET method
 
		// Parse headers
		puts("[HEADERS]");
		MHD_get_connection_values(connection, MHD_HEADER_KIND, &print_out_key, NULL);

		// Parse GET parameters
		puts("[GET PARAMS]");
		StringPairList spl;
		MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, &print_out_key, &spl);

		std::string text = "<html><body>\n";
		text += "<p>URL="; text += url; 
		text += "</p>\n<p>Parameters</p>\n<ul>\n";
		for (StringPairList::iterator it = spl.begin(); it != spl.end(); ++it)
		{
			text += "<li>"; text += it->first; text += '='; text += it->second; text += "</li>\n";
		}
		text += "</body></html>\n";

		MHD_Response* response = MHD_create_response_from_buffer(text.size(), (void*)text.c_str(), MHD_RESPMEM_MUST_COPY);
		MHD_add_response_header(response, "Content-Type", "text/html");
		int ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
		MHD_destroy_response(response);

		*reqctx = NULL; // clear context pointer
		return ret;
	}
	else
		return MHD_NO;	// Not supported yet
}
Esempio n. 7
0
void SettingsSharing::updateShareView(){
    if (checkBox_SIMPLE_SHARE_MODE->isChecked()){
        treeWidget_SIMPLE_MODE->clear();

        StringPairList directories = ShareManager::getInstance()->getDirectories();
        for (auto it = directories.begin(); it != directories.end(); ++it){
            QTreeWidgetItem *item = new QTreeWidgetItem(treeWidget_SIMPLE_MODE);

            item->setText(0, it->second.c_str());
            item->setText(1, it->first.c_str());
            item->setText(2, Util::formatBytes(ShareManager::getInstance()->getShareSize(it->second)).c_str());
            item->setText(3, QString().setNum(ShareManager::getInstance()->getShareSize(it->second)));
        }
    }

    label_TOTALSHARED->setText(tr("Total shared: %1")
                               .arg(WulforUtil::formatBytes(ShareManager::getInstance()->getShareSize())));
}
Esempio n. 8
0
LRESULT FavoriteDirsPage::onInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
	PropPage::translate((HWND)(*this), texts);
	ctrlDirectories.Attach(GetDlgItem(IDC_FAVORITE_DIRECTORIES));
	ctrlDirectories.SetExtendedListViewStyle(LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);
		
	// Prepare shared dir list
	CRect rc; 
	ctrlDirectories.GetClientRect(rc); 
	ctrlDirectories.InsertColumn(0, CTSTRING(FAVORITE_DIR_NAME), LVCFMT_LEFT, rc.Width()/4, 0); 
	ctrlDirectories.InsertColumn(1, CTSTRING(DIRECTORY), LVCFMT_LEFT, rc.Width()*3 /4, 1);
	StringPairList directories = FavoriteManager::getInstance()->getFavoriteDirs();
	for(StringPairIter j = directories.begin(); j != directories.end(); j++)
	{
		int i = ctrlDirectories.insert(ctrlDirectories.GetItemCount(), Text::toT(j->second));
		ctrlDirectories.SetItemText(i, 1, Text::toT(j->first).c_str());
	}
	
	return TRUE;
}
FavoriteDirsPage::FavoriteDirsPage(dwt::Widget* parent) : PropPage(parent) {
	createDialog(IDD_FAVORITE_DIRSPAGE);
	setHelpId(IDH_FAVORITE_DIRSPAGE);

	WinUtil::setHelpIds(this, helpItems);
	PropPage::translate(handle(), texts);

	attachChild(directories, IDC_FAVORITE_DIRECTORIES);
	directories->setTableStyle(LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT);

	TStringList columns;
	columns.push_back(T_("Favorite name"));
	columns.push_back(T_("Directory"));
	directories->createColumns(columns);
	directories->setColumnWidth(0, 100);
	directories->setColumnWidth(1, directories->getSize().x - 120);

	StringPairList dirs = FavoriteManager::getInstance()->getFavoriteDirs();
	for(StringPairIter j = dirs.begin(); j != dirs.end(); j++) {
		TStringList row;
		row.push_back(Text::toT(j->second));
		row.push_back(Text::toT(j->first));
		directories->insert(row);
	}

	directories->onDblClicked(std::tr1::bind(&FavoriteDirsPage::handleDoubleClick, this));
	directories->onKeyDown(std::tr1::bind(&FavoriteDirsPage::handleKeyDown, this, _1));
	directories->onRaw(std::tr1::bind(&FavoriteDirsPage::handleItemChanged, this, _1, _2), dwt::Message(WM_NOTIFY, LVN_ITEMCHANGED));

	onDragDrop(std::tr1::bind(&FavoriteDirsPage::handleDragDrop, this, _1));

	attachChild<Button>(IDC_RENAME)->onClicked(std::tr1::bind(&FavoriteDirsPage::handleRenameClicked, this));

	attachChild<Button>(IDC_REMOVE)->onClicked(std::tr1::bind(&FavoriteDirsPage::handleRemoveClicked, this));

	attachChild<Button>(IDC_ADD)->onClicked(std::tr1::bind(&FavoriteDirsPage::handleAddClicked, this));
}
Esempio n. 10
0
	websocketpp::http::status_code::value FileServer::handleRequest(const string& aResource, const websocketpp::http::parser::request& aRequest,
		string& output_, StringPairList& headers_) noexcept {

		dcassert(!resourcePath.empty());
		dcdebug("Requesting file %s\n", aResource.c_str());

		// Get the disk path path
		string request;
		if (aResource.length() >= 6 && aResource.compare(0, 6, "/view/") == 0) {
			try {
				request = parseViewFilePath(aResource.substr(6));
			} catch (const std::exception& e) {
				output_ = e.what();
				return websocketpp::http::status_code::bad_request;
			}
		} else {
			request = parseResourcePath(aResource, aRequest, headers_);
		}

		// Read file
		try {
			File f(request, File::READ, File::OPEN);
			output_ = f.read();
		} catch (const FileException& e) {
			output_ = e.getError();
			return websocketpp::http::status_code::not_found;
		}

		// Get the mime type
		auto extension = getExtension(request);
		for (int i = 0; mimes[i].ext != NULL; i++) {
			if (extension == mimes[i].ext) {
				headers_.emplace_back("Content-Type", mimes[i].type);
				break;
			}
		}

		return websocketpp::http::status_code::ok;
	}
Esempio n. 11
0
	string FileServer::parseResourcePath(const string& aResource, const websocketpp::http::parser::request& aRequest, StringPairList& headers_) const noexcept {
		auto request = aResource;

		auto extension = getExtension(request);
		if (!extension.empty()) {
			// Strip the dot
			extension = extension.substr(1);

			// We have compressed versions only for JS files
			if (extension == "js" && aRequest.get_header("Accept-Encoding").find("gzip") != string::npos) {
				request += ".gz";
				headers_.emplace_back("Content-Encoding", "gzip");
			}
		} else if (request.find("/build") != 0 && request != "/favicon.ico") {
			// Forward all requests for non-static files to index
			request = "/index.html";
		}

		// For windows
		Util::replace(request, "/", PATH_SEPARATOR_STR);

		return resourcePath + request;
	}
Esempio n. 12
0
	websocketpp::http::status_code::value FileServer::handleGetRequest(const websocketpp::http::parser::request& aRequest,
		string& output_, StringPairList& headers_, const SessionPtr& aSession) noexcept {

		const auto& requestUrl = aRequest.get_uri();
		dcdebug("Requesting file %s\n", requestUrl.c_str());

		// Get the disk path
		string filePath;
		try {
			if (requestUrl.length() >= 6 && requestUrl.compare(0, 6, "/view/") == 0) {
				filePath = parseViewFilePath(requestUrl.substr(6), headers_, aSession);
			} else {
				filePath = parseResourcePath(requestUrl, aRequest, headers_);
			}
		} catch (const RequestException& e) {
			output_ = e.what();
			return e.getCode();
		}

		auto fileSize = File::getSize(filePath);
		int64_t startPos = 0, endPos = fileSize - 1;

		auto partialContent = parsePartialRange(aRequest.get_header("Range"), startPos, endPos);

		// Read file
		try {
			File f(filePath, File::READ, File::OPEN);
			f.setPos(startPos);
			output_ = f.read(static_cast<size_t>(endPos) + 1);
		} catch (const FileException& e) {
			dcdebug("Failed to serve the file %s: %s\n", filePath.c_str(), e.getError().c_str());
			output_ = e.getError();
			return websocketpp::http::status_code::not_found;
		} catch (const std::bad_alloc&) {
			output_ = "Not enough memory on the server to serve this request";
			return websocketpp::http::status_code::internal_server_error;
		}

		{
			const auto ext = Util::getFileExt(filePath);
			if (ext == ".nfo") {
				string encoding;

				// Platform-independent encoding conversion function could be added if there is more use for it
#ifdef _WIN32
				encoding = "CP.437";
#else
				encoding = "cp437";
#endif
				output_ = Text::toUtf8(output_, encoding);
			} else if (ext == ".gz" && aRequest.get_header("Accept-Encoding").find("gzip") != string::npos) {
				headers_.emplace_back("Content-Encoding", "gzip");
			}
		}

		{
			// Get the mime type (but get it from the original request with gzipped content)
			auto usingEncoding = find_if(headers_.begin(), headers_.end(), CompareFirst<string, string>("Content-Encoding")) != headers_.end();
			auto type = getMimeType(usingEncoding ? requestUrl : filePath);
			if (type) {
				headers_.emplace_back("Content-Type", type);
			}
		}

		if (partialContent) {
			headers_.emplace_back("Content-Range", formatPartialRange(startPos, endPos, fileSize));
			headers_.emplace_back("Accept-Ranges", "bytes");
			return websocketpp::http::status_code::partial_content;
		}

		return websocketpp::http::status_code::ok;
	}
Esempio n. 13
0
	void FileServer::addCacheControlHeader(StringPairList& headers_, int aDaysValid) noexcept {
		headers_.emplace_back("Cache-Control", aDaysValid == 0 ? "no-store" : "max-age=" + Util::toString(aDaysValid * 24 * 60 * 60));
	}
Esempio n. 14
0
void Parser::startTag(const string& name_, StringPairList& attribs, bool simple) {
	auto name = boost::algorithm::trim_copy(name_);

	if(name == "br") {
		ret += _T("\\line\n");
	}

	if(simple) {
		return;
	}

	contexts.push_back(contexts.back());
	ScopedFunctor([this] { ret += contexts.back().getBegin(); });

	if(name == "b") {
		contexts.back().setFlag(Context::Bold);
	} else if(name == "i") {
		contexts.back().setFlag(Context::Italic);
	} else if(name == "u") {
		contexts.back().setFlag(Context::Underlined);
	}

	if(attribs.empty()) {
		return;
	}

	if(name == "a") {
		const auto& link = getAttrib(attribs, "href", 0);
		if(!link.empty()) {
			auto& context = contexts.back();
			context.link = link;
			if ((WinUtil::m_TextStyleURL.dwMask & CFE_UNDERLINE) == CFE_UNDERLINE)
				context.setFlag(Context::Underlined);
			context.textColor = addColor(WinUtil::m_TextStyleURL.crTextColor); /// @todo move to styles
		}
	}

	const auto& style = getAttrib(attribs, "style", 0);

	enum { Declaration, Font, Decoration, TextColor, BgColor, FontSize, Unknown } state = Declaration;

	string tmp;
	size_t i = 0, j;
	while((j = style.find_first_of(":;", i)) != string::npos) {
		tmp = style.substr(i, j - i);
		i = j + 1;

		boost::algorithm::trim(tmp);

		switch(state) {
		case Declaration:
			{
				if(tmp == "font") { state = Font; }
				else if(tmp == "color") { state = TextColor; }
				else if(tmp == "text-decoration") { state = Decoration; }
				else if(tmp == "background-color") { state = BgColor; }
				else if(tmp == "font-size") { state = FontSize; }
				else { state = Unknown; }
				break;
			}

		case Font:
			{
				parseFont(tmp);
				state = Declaration;
				break;
			}
		case FontSize:
			{
				parseFontSize(tmp);
				state = Declaration;
				break;
			}

		case Decoration:
			{
				parseDecoration(tmp);
				state = Declaration;
				break;
			}

		case TextColor:
			{
				parseColor(contexts.back().textColor, tmp);
				state = Declaration;
				break;
			}

		case BgColor:
			{
				parseColor(contexts.back().bgColor, tmp);
				state = Declaration;
				break;
			}

		case Unknown:
			{
				state = Declaration;
				break;
			}
		}
	}
}
Esempio n. 15
0
void ListLoader::startTag(const string& name, StringPairList& attribs, bool simple)
{
#ifdef _DEBUG
	static size_t g_max_attribs_size = 0;
	if (g_max_attribs_size != attribs.size())
	{
		g_max_attribs_size = attribs.size();
		// dcdebug("ListLoader::startTag g_max_attribs_size = %d , attribs.capacity() = %d\n", g_max_attribs_size, attribs.capacity());
	}
#endif
	if (ClientManager::isBeforeShutdown())
	{
		throw AbortException("ListLoader::startTag - ClientManager::isBeforeShutdown()");
	}
	if (m_list->getAbort())
	{
		throw AbortException("ListLoader::startTag - " + STRING(ABORT_EM));
	}
	
	if (m_is_in_listing)
	{
		if (name == g_SFile)
		{
			dcassert(attribs.size() >= 3); // Иногда есть Shared - 4-тый атрибут.
			// это тэг от грея. его тоже можно обработать и записать в TS. хотя там 64 битное время
			const string& l_name = getAttrib(attribs, g_SName, 0);
			if (l_name.empty())
			{
				dcassert(0);
				return;
			}
			
			const string& l_s = getAttrib(attribs, g_SSize, 1);
			if (l_s.empty())
			{
				dcassert(0);
				return;
			}
			const auto l_size = Util::toInt64(l_s);
			
			const string& l_h = getAttrib(attribs, g_STTH, 2);
			
			if (l_h.empty() || (m_is_own_list == false && l_h.compare(0, 39, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 39) == 0))
			{
				//dcassert(0);
				return;
			}
			const TTHValue l_tth(l_h); /// @todo verify validity?
			dcassert(l_tth != TTHValue());
			
			if (m_is_updating)
			{
				// just update the current file if it is already there.
				for (auto i = m_cur->m_files.cbegin(); i != m_cur->m_files.cend(); ++i)
				{
					auto& file = **i;
					/// @todo comparisons should be case-insensitive but it takes too long - add a cache
					if (file.getName() == l_name || file.getTTH() == l_tth)
					{
						file.setName(l_name);
						file.setSize(l_size);
						file.setTTH(l_tth);
						return;
					}
				}
			}
			// [+] FlylinkDC
			std::shared_ptr<CFlyMediaInfo> l_mediaXY;
			uint32_t l_i_ts = 0;
			int l_i_hit     = 0;
			string l_hit;
#ifdef FLYLINKDC_USE_DIRLIST_FILE_EXT_STAT
			auto& l_item = DirectoryListing::g_ext_stat[Util::getFileExtWithoutDot(Text::toLower(l_name))];
			l_item.m_count++;
			if (l_size > l_item.m_max_size)
				l_item.m_max_size = l_size;
			if (l_size < l_item.m_min_size)
				l_item.m_min_size = l_size;
				
#endif
			if (attribs.size() >= 4) // 3 - стандартный DC++, 4 - GreyLinkDC++
			{
				if (attribs.size() == 4 ||
				        attribs.size() >= 11)  // Хитрый расширенный формат от http://p2p.toom.su/fs/hms/FCYECUWQ7F5A2FABW32UTMCT6MEMI3GPXBZDQCQ/)
				{
					const string l_sharedGL = getAttrib(attribs, g_SShared, 4);
					if (!l_sharedGL.empty())
					{
						const int64_t tmp_ts = _atoi64(l_sharedGL.c_str()) - 116444736000000000L ;
						if (tmp_ts <= 0L)
							l_i_ts = 0;
						else
							l_i_ts = uint32_t(tmp_ts / 10000000L);
					}
				}
				string l_ts;
				if (l_i_ts == 0)
				{
					l_ts = getAttrib(attribs, g_STS, 3); // TODO проверить  attribs.size() >= 4 если = 4 или 3 то TS нет и можно не искать
				}
				if (!m_is_first_check_mediainfo_list)
				{
					m_is_first_check_mediainfo_list = true;
					m_is_mediainfo_list = !l_ts.empty();
				}
				if (!l_ts.empty()  // Extended tags - exists only FlylinkDC++ or StrongDC++ sqlite or clones
				        || l_i_ts // Грейлинк - время расшаривания
				   )
				{
					if (!l_ts.empty())
					{
						l_i_ts = atoi(l_ts.c_str());
					}
					
					if (attribs.size() > 4) // TODO - собрать комбинации всех случаев
					{
						l_hit = getAttrib(attribs, g_SHit, 3);
						const std::string& l_audio = getAttrib(attribs, g_SMAudio, 3);
						const std::string& l_video = getAttrib(attribs, g_SMVideo, 3);
						if (!l_audio.empty() || !l_video.empty())
						{
							const string& l_br = getAttrib(attribs, g_SBR, 4);
							l_mediaXY = std::make_shared<CFlyMediaInfo>(getAttrib(attribs, g_SWH, 3),
							                                            atoi(l_br.c_str()),
							                                            l_audio,
							                                            l_video
							                                           );
						}
					}
					
#if 0
					if (attribs.size() > 4) // TODO - собрать комбинации всех случаев
					{
						CFlyMediainfoRAW l_media_item;
						{
							l_media_item.m_audio = getAttrib(attribs, g_SMAudio, 3);
							const size_t l_pos = l_media_item.m_audio.find('|', 0);
							if (l_pos != string::npos && l_pos)
							{
								if (l_pos + 2 < l_media_item.m_audio.length())
								{
									l_media_item.m_audio = l_media_item.m_audio.substr(l_pos + 2);
								}
							}
						}
						
						l_media_item.m_video = getAttrib(attribs, g_SMVideo, 3);
						l_hit = getAttrib(attribs, g_SHit, 3);
						l_media_item.m_WH = getAttrib(attribs, g_SWH, 3);
						if (!l_media_item.m_audio.empty() || !l_media_item.m_video.empty())
						{
							l_media_item.m_br = getAttrib(attribs, g_SBR, 4);
							auto& l_find_mi = g_cache_mediainfo[l_media_item];
							if (!l_find_mi)
							{
							
								l_find_mi = std::make_shared<CFlyMediaInfo>(l_media_item.m_WH,
								                                            atoi(l_media_item.m_br.c_str()),
								                                            l_media_item.m_audio,
								                                            l_media_item.m_video
								                                           );
								l_mediaXY = l_find_mi;
							}
						}
					}
#endif
				}
				l_i_hit = l_hit.empty() ? 0 : atoi(l_hit.c_str());
			}
			auto f = new DirectoryListing::File(m_cur, l_name, l_size, l_tth, l_i_hit, l_i_ts, l_mediaXY);
			m_cur->m_virus_detect.add(l_name, l_size);
			m_cur->m_files.push_back(f);
			if (l_size)
			{
				if (m_is_own_list)//[+] FlylinkDC++
				{
					f->setFlag(DirectoryListing::FLAG_SHARED_OWN);  // TODO - убить FLAG_SHARED_OWN
				}
				else
				{
					if (ShareManager::isTTHShared(f->getTTH()))
					{
						f->setFlag(DirectoryListing::FLAG_SHARED);
					}
					else
					{
						if (QueueManager::is_queue_tth(f->getTTH()))
						{
							f->setFlag(DirectoryListing::FLAG_QUEUE);
						}
						// TODO if(l_size >= 100 * 1024 *1024)
						{
							if (!CFlyServerConfig::isParasitFile(f->getName())) // TODO - опимизнуть по расширениям
							{
								f->setFlag(DirectoryListing::FLAG_NOT_SHARED);
								const auto l_status_file = CFlylinkDBManager::getInstance()->get_status_file(f->getTTH()); // TODO - унести в отдельную нитку?
								if (l_status_file & CFlylinkDBManager::PREVIOUSLY_DOWNLOADED)
									f->setFlag(DirectoryListing::FLAG_DOWNLOAD);
								if (l_status_file & CFlylinkDBManager::VIRUS_FILE_KNOWN)
									f->setFlag(DirectoryListing::FLAG_VIRUS_FILE);
								if (l_status_file & CFlylinkDBManager::PREVIOUSLY_BEEN_IN_SHARE)
									f->setFlag(DirectoryListing::FLAG_OLD_TTH);
							}
						}
					}
				}//[+] FlylinkDC++
			}
		}
		else if (name == g_SDirectory)
		{
			string l_file_name = getAttrib(attribs, g_SName, 0);
			if (l_file_name.empty())
			{
				//  throw SimpleXMLException("Directory missing name attribute");
				l_file_name = "empty_file_name_" + Util::toString(++m_empty_file_name_counter);
			}
			const bool incomp = getAttrib(attribs, sIncomplete, 1) == "1";
			DirectoryListing::Directory* d = nullptr;
			if (m_is_updating)
			{
				for (auto i  = m_cur->directories.cbegin(); i != m_cur->directories.cend(); ++i)
				{
					/// @todo comparisons should be case-insensitive but it takes too long - add a cache
					if ((*i)->getName() == l_file_name)
					{
						d = *i;
						if (!d->getComplete())
						{
							d->setComplete(!incomp);
						}
						break;
					}
				}
			}
			if (d == nullptr)
			{
				d = new DirectoryListing::Directory(m_list, m_cur, l_file_name, false, !incomp, isMediainfoList());
				m_cur->directories.push_back(d);
			}
			m_cur = d;
			
			if (simple)
			{
				// To handle <Directory Name="..." />
				endTag(name, Util::emptyString);
			}
		}
	}
	else if (name == sFileListing)
	{
		const string& b = getAttrib(attribs, sBase, 2);
		if (b.size() >= 1 && b[0] == '/' && b[b.size() - 1] == '/')
		{
			m_base = b;
		}
		if (m_base.size() > 1) // [+]PPA fix for [4](("Version", "1"),("CID", "EDI7OWB6TZWH6X6L2D3INC6ORQSG6RQDJ6AJ5QY"),("Base", "/"),("Generator", "DC++ 0.785"))
		{
			const StringTokenizer<string> sl(m_base.substr(1), '/');
			for (auto i = sl.getTokens().cbegin(); i != sl.getTokens().cend(); ++i)
			{
				DirectoryListing::Directory* d = nullptr;
				for (auto j = m_cur->directories.cbegin(); j != m_cur->directories.cend(); ++j)
				{
					if ((*j)->getName() == *i)
					{
						d = *j;
						break;
					}
				}
				if (d == nullptr)
				{
					d = new DirectoryListing::Directory(m_list, m_cur, *i, false, false, isMediainfoList());
					m_cur->directories.push_back(d);
				}
				m_cur = d;
			}
		}
		m_cur->setComplete(true);
		
		// [+] IRainman Delayed loading (dclst support)
		const string& l_cidStr = getAttrib(attribs, sCID, 2);
		if (l_cidStr.size() == 39)
		{
			const CID l_CID(l_cidStr);
			if (!l_CID.isZero())
			{
				if (!m_user)
				{
					m_user = ClientManager::createUser(l_CID, "", 0);
					m_list->setHintedUser(HintedUser(m_user, Util::emptyString));
				}
			}
		}
		const string& l_getIncludeSelf = getAttrib(attribs, sIncludeSelf, 2);
		m_list->setIncludeSelf(l_getIncludeSelf == "1");
		// [~] IRainman Delayed loading (dclst support)
		
		m_is_in_listing = true;
		
		if (simple)
		{
			// To handle <Directory Name="..." />
			endTag(name, Util::emptyString);
		}
	}
}