Example #1
0
void OptionsDialog::fillTreeWidget(QTreeWidgetItem * p,KviPointerList<OptionsWidgetInstanceEntry> * l,const QString &szGroup,bool bNotContainedOnly)
{
    if(!l)return;

    OptionsDialogTreeWidgetItem * it;
    OptionsWidgetInstanceEntry * e;

    KviPointerList<OptionsWidgetInstanceEntry> tmp;
    tmp.setAutoDelete(false);


    for(e = l->first(); e; e = l->next())
    {
        // must be in the correct group
        // if we want only containers then well.. must be one
        e->bDoInsert = KviQString::equalCI(szGroup,e->szGroup) && ((!bNotContainedOnly) || e->bIsContainer || e->bIsNotContained);
        OptionsWidgetInstanceEntry * ee = tmp.first();
        int idx = 0;
        while(ee)
        {
            if(ee->iPriority >= e->iPriority)break;
            idx++;
            ee = tmp.next();
        }
        tmp.insert(idx,e);
    }

    for(e = tmp.first(); e; e = tmp.next())
    {
        if(e->bDoInsert)
        {
            if(p)it = new OptionsDialogTreeWidgetItem(p,e);
            else it = new OptionsDialogTreeWidgetItem(m_pTreeWidget,e);
            if(!it->m_pOptionsWidget)
            {
                it->m_pOptionsWidget = g_pOptionsInstanceManager->getInstance(it->m_pInstanceEntry,m_pWidgetStack);

                if(it->m_pOptionsWidget)
                    m_pWidgetStack->addWidget(it->m_pOptionsWidget);
            }
        } else {
            it = (OptionsDialogTreeWidgetItem *)p;
        }

        if(e->pChildList)
        {
            if(e->bIsContainer)
            {
                // it's a container: add only eventual not contained children (containers or explicitly marked as not contained)
                fillTreeWidget(it,e->pChildList,szGroup,true);
            } else {
                // it's not a container, add any children
                fillTreeWidget(it,e->pChildList,szGroup,false);
            }
        }
    }
}
void KviKvsEventManager::removeAllScriptRawHandlers()
{
	for(int i=0;i< KVI_KVS_NUM_RAW_EVENTS;i++)
	{
		if(m_rawEventTable[i])
		{
			KviPointerList<KviKvsEventHandler> dl;
			dl.setAutoDelete(false);
			KviKvsEventHandler * e;
			for(e = m_rawEventTable[i]->first();e;e = m_rawEventTable[i]->next())
			{
				if(e->type() == KviKvsEventHandler::Script)dl.append(e);
			}

			for(e = dl.first();e;e = dl.next())
			{
				m_rawEventTable[i]->removeRef(e);
			}

			if(m_rawEventTable[i]->isEmpty())
			{
				delete m_rawEventTable[i];
				m_rawEventTable[i] = 0;
			}
		}
	}
}
Example #3
0
void KviModuleExtensionManager::unregisterExtensionsByModule(KviModule * m)
{
	KviPointerHashTableIterator<const char *,KviModuleExtensionDescriptorList> it(*m_pExtensionDict);
	KviPointerList<KviCString> dying;
	dying.setAutoDelete(true);
	while(KviModuleExtensionDescriptorList * l = it.current())
	{
		KviPointerList<KviModuleExtensionDescriptor> dying2;
		dying2.setAutoDelete(true);

		for(KviModuleExtensionDescriptor * d = l->first();d;d = l->next())
		{
			if(d->module() == m)dying2.append(d);
		}

		for(KviModuleExtensionDescriptor * de = dying2.first();de;de = dying2.next())
		{
			l->removeRef(de);
		}

		if(l->isEmpty())dying.append(new KviCString(it.currentKey()));
		++it;
	}
	for(KviCString * li = dying.first();li;li = dying.next())
	{
		m_pExtensionDict->remove(li->ptr());
	}
}
void KviModuleManager::cleanupUnusedModules()
{
	KviPointerHashTableIterator<QString,KviModule> it(*m_pModuleDict);

	KviPointerList<KviModule> lModulesToUnload;
	lModulesToUnload.setAutoDelete(false);

	while(it.current())
	{
		if(it.current()->secondsSinceLastAccess() > KVI_OPTION_UINT(KviOption_uintModuleCleanupTimeout))
		{
			if(it.current()->moduleInfo()->can_unload)
			{
				if((it.current()->moduleInfo()->can_unload)(it.current()))
					lModulesToUnload.append(it.current());
				else {
					// the module don't want to be unloaded
					// keep it memory for a while
					it.current()->updateAccessTime();
				}
			} else {
				if(!(it.current()->isLocked()))
					lModulesToUnload.append(it.current());
			}
		}
		++it;
	}

	for(KviModule * pModule = lModulesToUnload.first();pModule;pModule = lModulesToUnload.next())
		unloadModule(pModule);
}
Example #5
0
void KviKvsEventManager::removeAllScriptRawHandlers()
{
	for(auto & i : m_rawEventTable)
	{
		if(i)
		{
			KviPointerList<KviKvsEventHandler> dl;
			dl.setAutoDelete(false);
			KviKvsEventHandler * e;
			for(e = i->first(); e; e = i->next())
			{
				if(e->type() == KviKvsEventHandler::Script)
					dl.append(e);
			}

			for(e = dl.first(); e; e = dl.next())
			{
				i->removeRef(e);
			}

			if(i->isEmpty())
			{
				delete i;
				i = nullptr;
			}
		}
	}
}
Example #6
0
void KviKvsEventManager::removeAllModuleRawHandlers(KviKvsModuleInterface * pIface)
{
	KviKvsEventHandler * h;
	for(auto & i : m_rawEventTable)
	{
		if(!i)
			continue;

		KviPointerList<KviKvsEventHandler> l;
		l.setAutoDelete(false);
		for(h = i->first(); h; h = i->next())
		{
			if(h->type() == KviKvsEventHandler::Module)
			{
				if(((KviKvsModuleEventHandler *)h)->moduleInterface() == pIface)
				{
					l.append(h);
				}
			}
		}
		for(h = l.first(); h; h = l.next())
			i->removeRef(h);
		if(i->isEmpty())
		{
			delete i;
			i = nullptr;
		}
	}
}
Example #7
0
void KviKvsAliasManager::load(const QString & filename)
{
	m_pAliasDict->clear();
	KviConfigurationFile cfg(filename,KviConfigurationFile::Read);

	KviConfigurationFileIterator it(*(cfg.dict()));

	KviPointerList<QString> l;
	l.setAutoDelete(true);

	while(it.current())
	{
		l.append(new QString(it.currentKey()));
		++it;
	}

	for(QString * s = l.first();s;s = l.next())
	{
		cfg.setGroup(*s);
		QString szCode = cfg.readEntry("_Buffer","");
		if(!szCode.isEmpty())
		{
			KviKvsScript * m = new KviKvsScript(*s,szCode);
			m_pAliasDict->insert(*s,m);
		}
		++it;
	}
}
void KviKvsEventManager::removeAllModuleAppHandlers(KviKvsModuleInterface *pIface)
{
	KviKvsEventHandler * h;
	for(unsigned int i =0;i< KVI_KVS_NUM_APP_EVENTS;i++)
	{
		if(!m_appEventTable[i].handlers())continue;

		KviPointerList<KviKvsEventHandler> l;
		l.setAutoDelete(false);
		for(h = m_appEventTable[i].handlers()->first();h;h = m_appEventTable[i].handlers()->next())
		{
			if(h->type() == KviKvsEventHandler::Module)
			{
				if(((KviKvsModuleEventHandler *)h)->moduleInterface() == pIface)
				{
					l.append(h);
				}
			}
			// COMPAT
			/*
			} else if(h->type() == KviKvsEventHandler::OldModule)
			{
				if(((KviKvsOldModuleEventHandler *)h)->module() == pIface)
				{
					l.append(h);
				}
			}
			*/
			// END COMPAT

		}
		for(h = l.first();h;h = l.next())m_appEventTable[i].removeHandler(h);
	}
}
Example #9
0
void KviKvsObjectController::killAllObjectsWithClass(KviKvsObjectClass * pClass)
{
	if(!m_pObjectDict)
		return; // no more objects at all...

	KviPointerList< QPointer<KviKvsObject> > lDying;
	lDying.setAutoDelete(true);

	KviKvsObject * pObject;

	for(pObject = m_pTopLevelObjectList->first();pObject;pObject = m_pTopLevelObjectList->next())
	{
		if(pObject->getClass() == pClass)
		{
			lDying.append(new QPointer<KviKvsObject>(pObject));
		} else {
			pObject->killAllChildrenWithClass(pClass);
		}
	}

	for(QPointer<KviKvsObject> * pObject = lDying.first();pObject;pObject = lDying.next())
	{
		if(pObject->isNull())
			continue; // already dead ?
		(*pObject)->dieNow();
	}
}
Example #10
0
	KviTalWizardPageData * findPage(QWidget * pWidget)
	{
		for(KviTalWizardPageData * pData = pPageList->first();pData;pData = pPageList->next())
		{
			if(pData->pWidget == pWidget) return pData;
		}
		return NULL;
	}
Example #11
0
void KviSharedFilesManager::cleanup()
{
	KviPointerHashTableIterator<QString, KviSharedFileList> it(*m_pSharedListDict);
	time_t curTime = time(nullptr);

	bool bOtherStuffToCleanup = false;

	KviPointerList<QString> lDying;
	lDying.setAutoDelete(true);

	while(KviSharedFileList * l = it.current())
	{
		KviPointerList<KviSharedFile> tmp;
		tmp.setAutoDelete(false);
		for(KviSharedFile * o = l->first(); o; o = l->next())
		{
			if(o->expireTime() > 0)
			{
				if(((int)o->expireTime()) <= ((int)curTime))
				{
					tmp.append(o);
				}
				else
				{
					bOtherStuffToCleanup = true;
				}
			}
		}
		for(KviSharedFile * fo = tmp.first(); fo; fo = tmp.next())
		{
			l->removeRef(fo);
			emit sharedFileRemoved(fo);
		}
		if(l->count() == 0)
			lDying.append(new QString(it.currentKey()));

		++it;
	}

	for(QString * pDyingKey = lDying.first(); pDyingKey; pDyingKey = lDying.next())
		m_pSharedListDict->remove(*pDyingKey);

	if(!bOtherStuffToCleanup)
		m_pCleanupTimer->stop();
}
Example #12
0
	KviTalWizardPageData * findFirstEnabledPage()
	{
		KviTalWizardPageData * pData;
		for(pData = pPageList->first();pData;pData = pPageList->next())
		{
			if(pData->bEnabled) return pData;
		}
		return NULL;
	}
Example #13
0
	int reindexPages()
	{
		int iEnabledCount = 0;
		for(KviTalWizardPageData * pData = pPageList->first();pData;pData = pPageList->next())
		{
			if(pData->bEnabled)
			{
				iEnabledCount++;
				pData->iVisibleIndex = iEnabledCount;
			}
		}
		return iEnabledCount;
	}
Example #14
0
void KviLagMeter::lagCheckAbort(const char * key)
{
	KviPointerList<KviLagCheck> l;
	l.setAutoDelete(false);
	KviLagCheck * c;

	if(_OUTPUT_PARANOIC)
		m_pConnection->console()->output(KVI_OUT_VERBOSE,__tr2qs("Lag check aborted (%s)"),key);

	for(c = m_pCheckList->first();c;c = m_pCheckList->next())
		if(kvi_strEqualCS(c->szKey.ptr(),key))l.append(c);
	for(c = l.first();c;c = l.next())m_pCheckList->removeRef(c);
}
void KviModuleManager::unloadAllModules()
{
	KviPointerHashTableIterator<QString,KviModule> it(*m_pModuleDict);

	KviPointerList<KviModule> lModulesToUnload;
	lModulesToUnload.setAutoDelete(false);
	while(KviModule * pModule = it.current())
	{
		lModulesToUnload.append(pModule);
		++it;
	}

	for(KviModule * pModule = lModulesToUnload.first();pModule;pModule = lModulesToUnload.next())
		unloadModule(pModule);
}
Example #16
0
void KviKvsKernel::completeModuleCommand(const QString &szModuleName,const QString &szCommandBegin,KviPointerList<QString> * pMatches)
{
	KviModule * pModule = g_pModuleManager->getModule(szModuleName);
	if(!pModule)return;

	KviPointerList<QString> lModuleMatches;
	lModuleMatches.setAutoDelete(true);
	pModule->completeCommand(szCommandBegin,&lModuleMatches);
	for(QString * pszModuleMatch = lModuleMatches.first();pszModuleMatch;pszModuleMatch = lModuleMatches.next())
	{
		QString * pszMatch = new QString(*pszModuleMatch);
		pszMatch->prepend(".");
		pszMatch->prepend(szModuleName);
		pMatches->append(pszMatch);
	}
}
Example #17
0
void KviThreadManager::killPendingEventsByReceiver(QObject * receiver)
{
#if !defined(COMPILE_ON_WINDOWS) && !defined(COMPILE_ON_MINGW)
	KviPointerList<KviThreadPendingEvent> l;
	l.setAutoDelete(false);
	m_pMutex->lock();
	for(KviThreadPendingEvent * ev = m_pEventQueue->first(); ev; ev = m_pEventQueue->next())
	{
		if(ev->o == receiver)
			l.append(ev);
	}
	for(KviThreadPendingEvent * ev = l.first(); ev; ev = l.next())
	{
		delete ev->e;
		m_pEventQueue->removeRef(ev);
	}
	m_pMutex->unlock();
#endif
}
Example #18
0
void KviKvsObjectController::clearUserClasses()
{
	flushUserClasses();
	KviPointerHashTableIterator<QString,KviKvsObjectClass> it(*m_pClassDict);
	KviPointerList<KviKvsObjectClass> lDying;
	lDying.setAutoDelete(false);
	while(it.current())
	{
		if(!(it.current()->isBuiltin()))
			lDying.append(it.current());
		++it;
	}

	for(KviKvsObjectClass * pDyingClass = lDying.first();pDyingClass;pDyingClass = lDying.next())
	{
		if(!m_pClassDict->findRef(pDyingClass))
			continue; // already deleted (by parent <-> child relations)
		delete pDyingClass;
	}
}
Example #19
0
void KviKvsEvent::clearScriptHandlers()
{
    if(!m_pHandlers)return;
    KviPointerList<KviKvsEventHandler> dl;
    dl.setAutoDelete(false);
    KviKvsEventHandler * e;
    for(e = m_pHandlers->first(); e; e = m_pHandlers->next())
    {
        if(e->type() == KviKvsEventHandler::Script)dl.append(e);
    }
    for(e = dl.first(); e; e = dl.next())
    {
        m_pHandlers->removeRef(e);
    }
    if(m_pHandlers->isEmpty())
    {
        delete m_pHandlers;
        m_pHandlers = 0;
    }
}
Example #20
0
void KviKvsKernel::completeFunction(const QString &szFunctionBegin,KviPointerList<QString> * pMatches)
{
	int idx = szFunctionBegin.indexOf(QChar('.'));
	if(idx == -1)
	{
		// no module name inside

		KviPointerHashTableIterator<QString,KviKvsCoreFunctionExecRoutine> it(*m_pCoreFunctionExecRoutineDict);
		int l = szFunctionBegin.length();
		while(it.current())
		{
			if(KviQString::equalCIN(szFunctionBegin,it.currentKey(),l))
			{
				QString * pMatch = new QString(it.currentKey());
				//pMatch->prepend("$");
				pMatches->append(pMatch);
			}
			++it;
		}

		g_pModuleManager->completeModuleNames(szFunctionBegin,pMatches);

		KviPointerList<QString> lAliases;
		lAliases.setAutoDelete(true);

		KviKvsAliasManager::instance()->completeCommand(szFunctionBegin,&lAliases);
		for(QString * pszAlias = lAliases.first();pszAlias;pszAlias = lAliases.next())
		{
			QString * pszAliasMatch = new QString(*pszAlias);
			//pszAliasMatch->prepend("$");
			pMatches->append(pszAliasMatch);
		}
	} else {
		// contains a module name
		QString szModuleName = szFunctionBegin.left(idx);
		QString szRight = szFunctionBegin.right(szFunctionBegin.length() - (idx+1));
		completeModuleFunction(szModuleName,szRight,pMatches);
	}
}
void KviKvsEventManager::removeAllModuleRawHandlers(KviKvsModuleInterface *pIface)
{
	KviKvsEventHandler * h;
	for(unsigned int i =0;i< KVI_KVS_NUM_RAW_EVENTS;i++)
	{
		if(!m_rawEventTable[i])continue;

		KviPointerList<KviKvsEventHandler> l;
		l.setAutoDelete(false);
		for(h = m_rawEventTable[i]->first();h;h = m_rawEventTable[i]->next())
		{
			if(h->type() == KviKvsEventHandler::Module)
			{
				if(((KviKvsModuleEventHandler *)h)->moduleInterface() == pIface)
				{
					l.append(h);
				}
			}
			// COMPAT
			/*
			} else if(h->type() == KviKvsEventHandler::OldModule)
			{
				if(((KviKvsOldModuleEventHandler *)h)->module() == pIface)
				{
					l.append(h);
				}
			}
			*/
			// END COMPAT

		}
		for(h = l.first();h;h = l.next())m_rawEventTable[i]->removeRef(h);
		if(m_rawEventTable[i]->isEmpty())
		{
			delete m_rawEventTable[i];
			m_rawEventTable[i] = 0;
		}
	}
}
void KviCustomToolBarDescriptor::fillToolBar()
{
	if(m_pActions->count() == 0)
	{
		// force layout of the toolbar
		QApplication::postEvent(m_pToolBar, new QEvent(QEvent::LayoutRequest));
	}
	else
	{
		KviPointerList<QString> dying;
		dying.setAutoDelete(false);
		for(QString * p = m_pActions->first(); p; p = m_pActions->next())
		{
			KviAction * a = KviActionManager::instance()->getAction(*p);
			if(a)
				a->addToCustomToolBar(m_pToolBar);
			else
				dying.append(p);
		}
		for(QString * d = dying.first(); d; d = dying.next())
			m_pActions->removeRef(d);
	}
}
Example #23
0
void ActionEditor::deleteActions()
{
	KviPointerList<ActionEditorTreeWidgetItem> l;
	l.setAutoDelete(false);

	for (int i=0;i<m_pTreeWidget->topLevelItemCount();i++)
	{
		if(m_pTreeWidget->topLevelItem(i)->isSelected())
		l.append((ActionEditorTreeWidgetItem * )m_pTreeWidget->topLevelItem(i));
	}

	if(l.isEmpty())return;

	//if(QMessageBox::question(this,__tr2qs_ctx("Confirm Deletion","editor"),__tr2qs_ctx("Do you really want to delete the selected actions ?","editor"),__tr2qs_ctx("Yes","editor"),__tr2qs_ctx("No","editor")) != 0)
	//	return;

	for(ActionEditorTreeWidgetItem * i = l.first();i;i = l.next())
	{
		if(m_pSingleActionEditor->actionData() == i->actionData())
			m_pSingleActionEditor->setActionData(0);
		delete i;
	}
}
Example #24
0
void KviKvsEventManager::removeAllModuleAppHandlers(KviKvsModuleInterface * pIface)
{
	KviKvsEventHandler * h;
	for(auto & i : m_appEventTable)
	{
		if(!i.handlers())
			continue;

		KviPointerList<KviKvsEventHandler> l;
		l.setAutoDelete(false);
		for(h = i.handlers()->first(); h; h = i.handlers()->next())
		{
			if(h->type() == KviKvsEventHandler::Module)
			{
				if(((KviKvsModuleEventHandler *)h)->moduleInterface() == pIface)
				{
					l.append(h);
				}
			}
		}
		for(h = l.first(); h; h = l.next())
			i.removeHandler(h);
	}
}
Example #25
0
	bool packageThemes(
			const QString &szPackagePath,
			const QString &szPackageName,
			const QString &szPackageVersion,
			const QString &szPackageDescription,
			const QString &szPackageAuthor,
			const QString &szPackageImagePath,
			KviPointerList<KviThemeInfo> &lThemeInfoList,
			QString &szError
		)
	{
		if(szPackagePath.isEmpty())
		{
			szError = __tr2qs_ctx("Invalid empty package path","theme");
			return false;
		}

		if(szPackageName.isEmpty())
		{
			szError = __tr2qs_ctx("Invalid empty package name","theme");
			return false;
		}

		QPixmap out;

		if(!szPackageImagePath.isEmpty())
		{
			QImage pix(szPackageImagePath);
			if(pix.isNull())
			{
				szError = __tr2qs_ctx("Failed to load the selected image: please fix it","theme");
				return false;
			}

			if((pix.width() > 300) || (pix.height() > 225))
				out = out.fromImage(pix.scaled(300,225,Qt::KeepAspectRatio));
			else
				out=out.fromImage(pix);
		}

		KviPackageWriter f;

		f.addInfoField("PackageType","ThemePack");
		f.addInfoField("ThemePackVersion",KVI_CURRENT_THEME_ENGINE_VERSION);
		f.addInfoField("Name",szPackageName);
		f.addInfoField("Version",szPackageVersion.isEmpty() ? "1.0.0" : szPackageVersion);
		f.addInfoField("Author",szPackageAuthor);
		f.addInfoField("Description",szPackageDescription);
		// this is the equivalent to an empty date.toString() call, but it's needed
		// to ensure qt4 will use the default() locale and not the system() one
		f.addInfoField("Date",QDateTime::currentDateTime().toString(Qt::ISODate));
		f.addInfoField("Application","KVIrc " KVI_VERSION "." KVI_SOURCES_DATE);

		if(!out.isNull())
		{
			QByteArray * pba = new QByteArray();
			QBuffer buffer(pba,0);
			buffer.open(QIODevice::WriteOnly);
			out.save(&buffer,"PNG");
			buffer.close();
			f.addInfoField("Image",pba); // cool :) [no disk access needed]
		}

		QString szTmp;

		szTmp.setNum(lThemeInfoList.count());
		f.addInfoField("ThemeCount",szTmp);

		int iIdx = 0;
		for(KviThemeInfo * pInfo = lThemeInfoList.first();pInfo;pInfo = lThemeInfoList.next())
		{
			if(pInfo->name().isEmpty())
			{
				szError = __tr2qs_ctx("Invalid theme name","theme");
				return false;
			}
			if(pInfo->version().isEmpty())
			{
				szError = __tr2qs_ctx("Invalid theme version","theme");
				return false;
			}

			QString szSubdir = pInfo->name() + QString("-") + pInfo->version();
			szSubdir.replace(QRegExp("[^a-zA-Z0-9_\\-.][^a-zA-Z0-9_\\-.]*"),"_");

			szTmp = QString("Theme%1Name").arg(iIdx);
			f.addInfoField(szTmp,pInfo->name());
			szTmp = QString("Theme%1Version").arg(iIdx);
			f.addInfoField(szTmp,pInfo->version());
			szTmp = QString("Theme%1Description").arg(iIdx);
			f.addInfoField(szTmp,pInfo->description());
			szTmp = QString("Theme%1Date").arg(iIdx);
			f.addInfoField(szTmp,pInfo->date());
			szTmp = QString("Theme%1Subdirectory").arg(iIdx);
			f.addInfoField(szTmp,szSubdir);
			szTmp = QString("Theme%1Author").arg(iIdx);
			f.addInfoField(szTmp,pInfo->author());
			szTmp = QString("Theme%1Application").arg(iIdx);
			f.addInfoField(szTmp,pInfo->application());
			szTmp = QString("Theme%1ThemeEngineVersion").arg(iIdx);
			f.addInfoField(szTmp,pInfo->themeEngineVersion());
			QPixmap pixScreenshot = pInfo->smallScreenshot();
			if(!pixScreenshot.isNull())
			{
				szTmp = QString("Theme%1Screenshot").arg(iIdx);
				QByteArray * pba = new QByteArray();

				QBuffer bufferz(pba,0);
				bufferz.open(QIODevice::WriteOnly);
				pixScreenshot.save(&bufferz,"PNG");
				bufferz.close();
				f.addInfoField(szTmp,pba);
			}

			if(!f.addDirectory(pInfo->directory(),szSubdir))
			{
				szError = __tr2qs_ctx("Packaging failed","theme");
				szError += ": ";
				szError += f.lastError();
				return false;
			}

			iIdx++;
		}

		if(!f.pack(szPackagePath))
		{
			szError = __tr2qs_ctx("Packaging failed","theme");
			szError += ": ";
			szError += f.lastError();
			return false;
		}

		return true;
	}
Example #26
0
bool KviIsOnNotifyListManager::handleUserhost(KviIrcMessage * msg)
{
	if(!m_bExpectingUserhost)
		return false;
	// first check for consistency: all the replies must be on the USERHOST list
	KviPointerList<KviIrcMask> tmplist;
	tmplist.setAutoDelete(true);

	KviCString nk;
	const char * aux = msg->trailing();

	while(*aux)
	{
		nk = "";
		aux = kvi_extractToken(nk, aux, ' ');
		if(nk.hasData())
		{
			// split it in a mask
			KviCString nick;
			KviCString user;
			KviCString host;

			int idx = nk.findFirstIdx('=');
			if(idx != -1)
			{
				nick = nk.left(idx);
				if(nick.lastCharIs('*'))
					nick.cutRight(1);
				nk.cutLeft(idx + 1);
				if(nk.firstCharIs('+') || nk.firstCharIs('-'))
					nk.cutLeft(1);

				idx = nk.findFirstIdx('@');
				if(idx != -1)
				{
					user = nk.left(idx);
					nk.cutLeft(idx + 1);
					host = nk;
				}
				else
				{
					user = "******";
					host = nk;
				}

				bool bGotIt = false;
				QString szNick = m_pConnection->decodeText(nick.ptr());
				QString szUser = m_pConnection->decodeText(user.ptr());
				QString szHost = m_pConnection->decodeText(host.ptr());

				for(QString * s = m_pUserhostList->first(); s && (!bGotIt); s = m_pUserhostList->next())
				{
					if(KviQString::equalCI(*s, szNick))
					{
						KviIrcMask * mk = new KviIrcMask(szNick, szUser, szHost);
						tmplist.append(mk);
						bGotIt = true;
						m_pUserhostList->removeRef(s);
					}
				}

				if(!bGotIt)
				{
					// ops...not my userhost!
					if(_OUTPUT_VERBOSE)
						m_pConsole->output(KVI_OUT_SYSTEMWARNING, __tr2qs("Notify list: Hey! You've used USERHOST behind my back? (I might be confused now...)"));
					return false;
				}
			}
			else
			{
				if(_OUTPUT_VERBOSE)
					m_pConsole->output(KVI_OUT_SYSTEMWARNING, __tr2qs("Notify list: Broken USERHOST reply from the server? (%s)"), nk.ptr());
			}
		}
	}

	// Ok...looks to be my usershot (still not sure at 100%, but can't do better)

	if(m_pConnection->lagMeter())
		m_pConnection->lagMeter()->lagCheckComplete("@notify_userhost");

	m_bExpectingUserhost = false;

	for(KviIrcMask * mk = tmplist.first(); mk; mk = tmplist.next())
	{
		if(!doMatchUser(mk->nick(), *mk))
			return true; // have to restart!!!
	}

	if(!(m_pUserhostList->isEmpty()))
	{
		// ops...someone is no longer online ?
		while(QString * s = m_pUserhostList->first())
		{
			if(_OUTPUT_VERBOSE)
				m_pConsole->output(KVI_OUT_SYSTEMMESSAGE, __tr2qs("Notify list: \r!n\r%Q\r appears to have gone offline before USERHOST reply was received, will recheck in the next loop"), s);
			m_pUserhostList->removeFirst();
		}
	}

	if(m_pOnlineList->isEmpty())
	{
		if(m_pNotifyList->isEmpty())
			delayedNotifySession();
		else
			delayedIsOnSession();
	}
	else
		delayedUserhostSession();

	return true;
}
Example #27
0
bool KviIsOnNotifyListManager::handleIsOn(KviIrcMessage * msg)
{
	if(!m_bExpectingIsOn)
		return false;

	// Check if it is our ISON
	// all the nicks must be on the IsOnList

	KviPointerList<QString> tmplist;
	tmplist.setAutoDelete(false);

	KviCString nk;
	const char * aux = msg->trailing();

	while(*aux)
	{
		nk = "";
		aux = kvi_extractToken(nk, aux, ' ');
		if(nk.hasData())
		{
			bool bGotIt = false;
			QString dnk = m_pConnection->decodeText(nk.ptr());
			for(QString * s = m_pIsOnList->first(); s && (!bGotIt); s = m_pIsOnList->next())
			{
				if(KviQString::equalCI(*s, dnk))
				{
					tmplist.append(s);
					bGotIt = true;
				}
			}
			if(!bGotIt)
			{
				// ops...not my userhost!
				if(_OUTPUT_VERBOSE)
					m_pConsole->output(KVI_OUT_SYSTEMMESSAGE, __tr2qs("Notify list: Hey! You've used ISON behind my back? (I might be confused now...)"));
				return false;
			}
		}
	}

	// Ok...looks to be my ison (still not sure at 100%, but can't do better)
	if(m_pConnection->lagMeter())
		m_pConnection->lagMeter()->lagCheckComplete("@notify_ison");

	m_bExpectingIsOn = false;

	m_pOnlineList->clear();

	m_pIsOnList->setAutoDelete(false);

	// Ok...we have an IsOn reply here
	// The nicks in the IsOnList that are also in the reply are online, and go to the OnlineList
	// the remaining in the IsOnList are offline

	QString * s;

	for(s = tmplist.first(); s; s = tmplist.next())
	{
		m_pIsOnList->removeRef(s);
		m_pOnlineList->append(s);
	}

	m_pIsOnList->setAutoDelete(true);
	// Ok...all the users that are online, are on the OnlineList
	// the remaining users are in the m_pIsOnList, and are no longer online

	// first the easy step: remove the users that have just left irc or have never been online
	// we're clearling the m_pIsOnList
	while((s = m_pIsOnList->first()))
	{
		if(m_pConsole->notifyListView()->findEntry(*s))
		{
			// has just left IRC... make him part
			notifyOffLine(*s);
		} // else has never been here

		m_pIsOnList->removeFirst(); // autodelete is true
	}

	// ok... complex step now: the remaining users in the userhost list are online
	// if they have been online before, just remove them from the list
	// otherwise they must be matched for masks
	// and eventually inserted in the notify view later

	KviIrcUserDataBase * db = console()->connection()->userDataBase();

	KviPointerList<QString> l;
	l.setAutoDelete(false);

	for(s = m_pOnlineList->first(); s; s = m_pOnlineList->next())
	{
		if(KviUserListEntry * ent = m_pConsole->notifyListView()->findEntry(*s))
		{
			// the user was online from a previous notify session
			// might the mask have been changed ? (heh...this is tricky, maybe too much even)
			if(KVI_OPTION_BOOL(KviOption_boolNotifyListSendUserhostForOnlineUsers))
			{
				// user wants to be sure about online users....
				// check if he is on some channels
				if(ent->globalData()->nRefs() > 1)
				{
					// mmmh...we have more than one ref, so the user is at least in one query or channel
					// look him up on channels, if we find his entry, we can be sure that he is
					// still the right user
					KviPointerList<KviChannelWindow> * chlist = m_pConsole->connection()->channelList();
					for(KviChannelWindow * ch = chlist->first(); ch; ch = chlist->next())
					{
						if(KviUserListEntry * le = ch->findEntry(*s))
						{
							l.append(s); // ok...found on a channel...we don't need a userhost to match him
							KviIrcMask mk(*s, le->globalData()->user(), le->globalData()->host());
							if(!doMatchUser(*s, mk))
								return true; // critical problems = have to restart!!!
							break;
						}
					}
				} // else Only one ref...we need a userhost to be sure (don't remove from the list)
			}
			else
			{
				// user wants no userhost for online users...we "hope" that everything will go ok.
				l.append(s);
			}
			//l.append(s); // we will remove him from the list
		}
		else
		{
			// the user was not online!
			// check if we have a cached mask
			if(db)
			{
				if(KviIrcUserEntry * ue = db->find(*s))
				{
					// already in the db... do we have a mask ?
					if(ue->hasUser() && ue->hasHost())
					{
						// yup! we have a complete mask to match on
						KviIrcMask mk(*s, ue->user(), ue->host());
						// lookup the user's name in the m_pRegUserDict
						if(!doMatchUser(*s, mk))
							return true; // critical problems = have to restart!!!
						l.append(s);     // remove anyway
					}
				}
			}
		}
	}

	for(s = l.first(); s; s = l.next())
	{
		m_pOnlineList->removeRef(s); // autodelete is true
	}

	if(m_pOnlineList->isEmpty())
	{
		if(m_pNotifyList->isEmpty())
			delayedNotifySession();
		else
			delayedIsOnSession();
	}
	else
		delayedUserhostSession();

	return true;
}
Example #28
0
bool KviHttpRequest::processHeader(KviCString &szHeader)
{
	int idx = szHeader.findFirstIdx("\r\n");
	KviCString szResponse;
	if(idx != -1)
	{
		szResponse = szHeader.left(idx);
		szHeader.cutLeft(idx + 2);
	} else {
		szResponse = szHeader;
		szHeader = "";
	}

	szResponse.trim();

	bool bValid = false;

	unsigned int uStatus = 0;

	// check the response value
	if(kvi_strEqualCSN(szResponse.ptr(),"HTTP",4))
	{
		KviCString szR = szResponse;
		szR.cutToFirst(' ');
		szR.trim();
		int idx = szR.findFirstIdx(' ');
		KviCString szNumber;
		if(idx != -1)szNumber = szR.left(idx);
		else szNumber = szR;
		bool bOk;
		uStatus = szNumber.toUInt(&bOk);
		if(bOk)bValid = true;
	}

	QString szUniResponse = QString::fromUtf8(szResponse.ptr());

	if(!bValid)
	{
		// the response is invalid ?
		resetInternalStatus();
		m_szLastError = __tr2qs("Invalid HTTP response: %1").arg(szUniResponse);
		emit terminated(false);
		return false;
	}

	emit status(__tr2qs("Received HTTP response: %1").arg(szUniResponse));

	KviPointerList<KviCString> hlist;
	hlist.setAutoDelete(true);

	idx = szHeader.findFirstIdx("\r\n");
	while(idx != -1)
	{
		if(idx > 0)
		{
			hlist.append(new KviCString(szHeader.ptr(),idx));
			szHeader.cutLeft(idx + 2);
		}
		idx = szHeader.findFirstIdx("\r\n");
	}
	if(szHeader.hasData())hlist.append(new KviCString(szHeader));

	KviPointerHashTable<const char *,KviCString> hdr(11,false,true);
	hdr.setAutoDelete(true);

	for(KviCString * s = hlist.first();s;s = hlist.next())
	{
		idx = s->findFirstIdx(":");
		if(idx != -1)
		{
			KviCString szName = s->left(idx);
			s->cutLeft(idx + 1);
			s->trim();
			hdr.replace(szName.ptr(),new KviCString(*s));
			//qDebug("FOUND HEADER (%s)=(%s)",szName.ptr(),s->ptr());
		}
	}

	KviCString * size = hdr.find("Content-length");
	if(size)
	{
		bool bOk;
		m_uTotalSize = size->toUInt(&bOk);
		if(!bOk)m_uTotalSize = 0;
	}

	KviCString * contentEncoding = hdr.find("Content-encoding");
	if(contentEncoding)
	{
		m_bGzip = contentEncoding->equalsCI("gzip");
	}

	KviCString * transferEncoding = hdr.find("Transfer-Encoding");
	if(transferEncoding)
	{
		if(kvi_strEqualCI(transferEncoding->ptr(),"chunked"))
		{
			// be prepared to handle the chunked transfer encoding as required by HTTP/1.1
			m_bChunkedTransferEncoding = true;
			m_uRemainingChunkSize = 0;
		}
	}

	// check the status

	//				case 200: // OK
	//				case 206: // Partial content

	//				case 100: // Continue ??
	//				case 101: // Switching protocols ???
	//				case 201: // Created
	//				case 202: // Accepted
	//				case 203: // Non-Authoritative Information
	//				case 204: // No content
	//				case 205: // Reset content
	//				case 300: // Multiple choices
	//				case 301: // Moved permanently
	//				case 302: // Found
	//				case 303: // See Other
	//				case 304: // Not modified
	//				case 305: // Use Proxy
	//				case 306: // ???
	//				case 307: // Temporary Redirect
	//				case 400: // Bad request
	//				case 401: // Unauthorized
	//				case 402: // Payment Required
	//				case 403: // Forbidden
	//				case 404: // Not found
	//				case 405: // Method not allowed
	//				case 406: // Not acceptable
	//				case 407: // Proxy authentication required
	//				case 408: // Request timeout
	//				case 409: // Conflict
	//				case 410: // Gone
	//				case 411: // Length required
	//				case 412: // Precondition failed
	//				case 413: // Request entity too large
	//				case 414: // Request-URI Too Long
	//				case 415: // Unsupported media type
	//				case 416: // Requested range not satisfiable
	//				case 417: // Expectation Failed
	//				case 500: // Internal server error
	//				case 501: // Not implemented
	//				case 502: // Bad gateway
	//				case 503: // Service unavailable
	//				case 504: // Gateway timeout
	//				case 505: // HTTP Version not supported

	if(
		(uStatus != 200) && // OK
		(uStatus != 206)    // Partial content
	)
	{
		// This is not "OK" and not "Partial content"
		// Error, redirect or something confusing
		if(m_eProcessingType != HeadersOnly)
		{
			switch(uStatus)
			{
				case 301: // Moved permanently
				case 302: // Found
				case 303: // See Other
				case 307: // Temporary Redirect
				{
					if(!m_bFollowRedirects)
					{
						resetInternalStatus();
						m_szLastError = szResponse.ptr();
						emit terminated(false);
						return false;
					}
					
					m_uRedirectCount++;
					
					if(m_uRedirectCount > m_uMaximumRedirectCount)
					{
						resetInternalStatus();
						m_szLastError = __tr2qs("Too many redirects");
						emit terminated(false);
						return false;
					}
					
					KviCString * location = hdr.find("Location");

					if(!location)
					{
						resetInternalStatus();
						m_szLastError = __tr2qs("Bad redirect");
						emit terminated(false);
						return false;
					}
					
					KviUrl url(location->ptr());
					
					if(
							(url.url() == m_connectionUrl.url()) ||
							(url.url() == m_url.url())
						)
					{
						resetInternalStatus();
						m_szLastError = __tr2qs("Redirect loop");
						emit terminated(false);
						return false;
					}

					m_connectionUrl = url;

					emit status(__tr2qs("Following Redirect to %1").arg(url.url()));

					if(!start())
						emit terminated(false);

					return false; // will exit the call stack
				}
				break;
				break;
				default:
					// assume error
					resetInternalStatus();
					m_szLastError = szResponse.ptr();
					emit terminated(false);
					return false;
				break;
			}
			// this is an error then
		} // else the server will terminate (it was a HEAD request)
	}

	emit receivedResponse(szUniResponse);

	emit header(&hdr);

	if((m_uMaxContentLength > 0) && (m_uTotalSize > ((unsigned int)m_uMaxContentLength)))
	{
		resetInternalStatus();
		m_szLastError=__tr2qs("The amount of received data exceeds the maximum length");
		emit terminated(false);
		return false;
	}

	// fixme: could check for data type etc...

	return true;
}
Example #29
0
void KviAvatarCache::cleanup()
{
	// first do a quick run deleting the avatars really too old
	KviPointerHashTableIterator<QString,KviAvatarCacheEntry> it(*m_pAvatarDict);

	kvi_time_t tNow = kvi_unixTime();

	KviPointerList<QString> l;
	l.setAutoDelete(false);

	KviAvatarCacheEntry * e;

	while((e = it.current()))
	{
		if((tNow - e->tLastAccess) > MAX_UNACCESSED_TIME)
		{
			l.append(new QString(it.currentKey()));
		}
		++it;
	}

	for(QString *s = l.first();s;s = l.next())m_pAvatarDict->remove(*s);

	if(m_pAvatarDict->count() < CACHE_GUARD_LEVEL)return;

	// not done.. need to kill the last accessed :/

	it.toFirst();

	KviPointerList<KviAvatarCacheEntry> ll;
	ll.setAutoDelete(true);

	// here we use the cache entries in another way
	// szAvatar is the KEY instead of the avatar name

	while((e = it.current()))
	{
		KviAvatarCacheEntry * current = ll.first();
		unsigned int idx = 0;
		while(current)
		{
			// if the current is newer than the inserted one
			// then stop searching and insert it just before
			if(current->tLastAccess > e->tLastAccess)break;
			// otherwise the current is older and the inserted
			// one goes after
			current = ll.next();
			idx++;
		}

		KviAvatarCacheEntry * xx = new KviAvatarCacheEntry;
		xx->szIdString = it.currentKey();
		xx->tLastAccess = e->tLastAccess;

		if(current)ll.insert(idx,xx);
		else ll.append(xx);
		++it;
	}

	// the oldest keys are at the beginning
	int uRemove = ll.count() - CACHE_GUARD_LEVEL;
	if(uRemove < 1)return; // huh ?

	// remember that szAvatar contains the key!
	for(e = ll.first();e && (uRemove > 0);e = ll.next())
	{
		m_pAvatarDict->remove(e->szIdString);
		uRemove--;
	}
	// now we should be ok
}