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); } } } }
KviTalWizardPageData * findNextEnabledPage(QWidget * pReference) { if(!pReference) return findFirstEnabledPage(); KviTalWizardPageData * pData = findPage(pReference); if(!pData) return NULL; for(pData = pPageList->next();pData;pData = pPageList->next()) { if(pData->bEnabled) return pData; } return NULL; }
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; } } }
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); } }
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); }
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; } } } }
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; } } } }
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 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(); } }
KviTalWizardPageData * findPage(QWidget * pWidget) { for(KviTalWizardPageData * pData = pPageList->first();pData;pData = pPageList->next()) { if(pData->pWidget == pWidget) return pData; } return NULL; }
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(); }
KviTalWizardPageData * findFirstEnabledPage() { KviTalWizardPageData * pData; for(pData = pPageList->first();pData;pData = pPageList->next()) { if(pData->bEnabled) return pData; } return NULL; }
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); }
int reindexPages() { int iEnabledCount = 0; for(KviTalWizardPageData * pData = pPageList->first();pData;pData = pPageList->next()) { if(pData->bEnabled) { iEnabledCount++; pData->iVisibleIndex = iEnabledCount; } } return iEnabledCount; }
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); }
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 }
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; } }
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; } }
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 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 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; } }
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); } }
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); } }
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; }
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 }
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; }
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; }
void KviKvsKernel::completeModuleFunction(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->completeFunction(szCommandBegin,&lModuleMatches); for(QString * pszModuleMatch = lModuleMatches.first();pszModuleMatch;pszModuleMatch = lModuleMatches.next()) { QString * pszMatch = new QString(*pszModuleMatch); pszMatch->prepend("."); pszMatch->prepend(szModuleName); pszMatch->prepend("$"); pMatches->append(pszMatch); } }
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; }