Esempio n. 1
0
KviIrcServer * KviIrcNetwork::findServer(const QString & szHostname)
{
	for (KviIrcServer *s = m_pServerList->first(); s; s = m_pServerList->next())
	{
		if (KviQString::equalCI(s->hostName(), szHostname))
			return s;
	}
	return 0;
}
Esempio n. 2
0
KviIrcServer * KviIrcNetwork::findServer(const KviIrcServer * pServer)
{
	for (KviIrcServer *s = m_pServerList->first(); s; s = m_pServerList->next())
	{
		// we better go with the unique id first
		if(!s->id().isEmpty())
		{
			// at least one of the 2 id is not empty, so if they match we're done
			if(KviQString::equalCI(s->id(), pServer->id()))
				return s;
		} else {
			// failback on the "check everything" method

			if (KviQString::equalCI(s->hostName(), pServer->hostName())
					&& (s->port() == pServer->port()) && (s->useSSL()
					== pServer->useSSL()) && (s->isIPv6() == pServer->isIPv6()))
				return s;
		}
	}
	return 0;
}
Esempio n. 3
0
bool KviIrcServerDataBase::makeCurrentBestServerInNetwork(const QString & szNetName, KviIrcNetwork * pNet, QString & szError)
{
	m_szCurrentNetwork = szNetName;
	// find a round-robin server in that network

	if(pNet->m_pServerList->isEmpty())
	{
		szError = __tr2qs("The specified network has no server entries");
		return false;
	}

	for(KviIrcServer * pServ = pNet->m_pServerList->first(); pServ; pServ = pNet->m_pServerList->next())
	{
		if(pServ->description().contains("random",Qt::CaseInsensitive) ||
			(pServ->description().contains("round",Qt::CaseInsensitive) &&
			(pServ->description().contains("robin",Qt::CaseInsensitive))))
		{
			pNet->setCurrentServer(pServ);
			return true;
		}
	}

	// no explicit round robin... try some common names

	QString szTryAlso1, szTryAlso2, szTryAlso3;

	szTryAlso1 = QString("irc.%1.org").arg(szNetName);
	szTryAlso2 = QString("irc.%1.net").arg(szNetName);
	szTryAlso3 = QString("irc.%1.com").arg(szNetName);

	for(KviIrcServer * pServer = pNet->m_pServerList->first(); pServer; pServer = pNet->m_pServerList->next())
	{
		if(KviQString::equalCI(pServer->hostName(),szTryAlso1) ||
			KviQString::equalCI(pServer->hostName(),szTryAlso2) ||
			KviQString::equalCI(pServer->hostName(),szTryAlso3))
		{
			pNet->setCurrentServer(pServer);
			return true;
		}
	}

	// a random one in this network
	return true;
}
Esempio n. 4
0
void KviIrcContext::connectToCurrentServer()
{
	if(m_pReconnectTimer)
	{
		delete m_pReconnectTimer;
		m_pReconnectTimer = nullptr;
	}

	m_pConsole->outputNoFmt(KVI_OUT_SYSTEMMESSAGE, " "); // spacer

	// No connection target specified.
	// If we have a saved target, reuse it
	if(!m_pAsynchronousConnectionData && m_pSavedAsynchronousConnectionData)
	{
		m_pAsynchronousConnectionData = m_pSavedAsynchronousConnectionData;
		m_pSavedAsynchronousConnectionData = nullptr;
	}

	if(m_pAsynchronousConnectionData)
	{
		// we have a specified connection target (either from outside or saved)
		if(m_pAsynchronousConnectionData->szServer.isEmpty())
		{
			// an empty server might mean "reuse the last server in context"
			if(m_pAsynchronousConnectionData->bUseLastServerInContext && m_pSavedAsynchronousConnectionData)
			{
				// reuse the saved connection data
				// the server for sure
				m_pAsynchronousConnectionData->szServer = m_pSavedAsynchronousConnectionData->szServer;
				m_pAsynchronousConnectionData->szServerId = m_pSavedAsynchronousConnectionData->szServerId;
				m_pAsynchronousConnectionData->uPort = m_pSavedAsynchronousConnectionData->uPort;
				m_pAsynchronousConnectionData->bPortIsOk = true;
				m_pAsynchronousConnectionData->bUseIPv6 = m_pSavedAsynchronousConnectionData->bUseIPv6;
				m_pAsynchronousConnectionData->bUseSSL = m_pSavedAsynchronousConnectionData->bUseSSL;
				m_pAsynchronousConnectionData->bSTARTTLS = m_pSavedAsynchronousConnectionData->bSTARTTLS;

				if(m_pSavedAsynchronousConnectionData->m_pReconnectInfo)
					m_pAsynchronousConnectionData->m_pReconnectInfo = new KviIrcServerReconnectInfo(*(m_pSavedAsynchronousConnectionData->m_pReconnectInfo));
				else
					m_pAsynchronousConnectionData->m_pReconnectInfo = nullptr;

				// and the other info, only if not overridden by the user
				if(m_pAsynchronousConnectionData->szBindAddress.isEmpty())
					m_pAsynchronousConnectionData->szBindAddress = m_pSavedAsynchronousConnectionData->szBindAddress;
				if(m_pAsynchronousConnectionData->szCommandToExecAfterConnect.isEmpty())
					m_pAsynchronousConnectionData->szCommandToExecAfterConnect = m_pSavedAsynchronousConnectionData->szCommandToExecAfterConnect;
				if(m_pAsynchronousConnectionData->szLinkFilter.isEmpty())
					m_pAsynchronousConnectionData->szLinkFilter = m_pSavedAsynchronousConnectionData->szLinkFilter;
				if(m_pAsynchronousConnectionData->szPass.isEmpty())
					m_pAsynchronousConnectionData->szPass = m_pSavedAsynchronousConnectionData->szPass;
				if(m_pAsynchronousConnectionData->szNick.isEmpty())
					m_pAsynchronousConnectionData->szNick = m_pSavedAsynchronousConnectionData->szNick;
				if(m_pAsynchronousConnectionData->szInitUMode.isEmpty())
					m_pAsynchronousConnectionData->szInitUMode = m_pSavedAsynchronousConnectionData->szInitUMode;
			}
			else
			{
				m_pConsole->outputNoFmt(KVI_OUT_SYSTEMWARNING, __tr2qs("This is the first connection in this IRC context: using the global server setting"));
			}
		}

		if(!m_pAsynchronousConnectionData->szServer.isEmpty())
		{
			// !m_pAsynchronousConnectionData->szServer.isEmpty()
			// ok, have a server to look for in the db
			// FIXME: this is a bit ugly... could it be managed in some completely different and nicer way ?
			KviIrcServerDefinition d;
			d.szServer = m_pAsynchronousConnectionData->szServer;
			d.bPortIsValid = m_pAsynchronousConnectionData->bPortIsOk;
			d.uPort = m_pAsynchronousConnectionData->uPort;
			d.bIPv6 = m_pAsynchronousConnectionData->bUseIPv6;
			d.bSSL = m_pAsynchronousConnectionData->bUseSSL;
			d.bSTARTTLS = m_pAsynchronousConnectionData->bSTARTTLS;
			d.szLinkFilter = m_pAsynchronousConnectionData->szLinkFilter;
			d.szPass = m_pAsynchronousConnectionData->szPass;
			d.szNick = m_pAsynchronousConnectionData->szNick;
			d.szInitUMode = m_pAsynchronousConnectionData->szInitUMode;
			d.szId = m_pAsynchronousConnectionData->szServerId;
			QString szError;
			if(!g_pServerDataBase->makeCurrentServer(&d, szError))
			{
				m_pConsole->outputNoFmt(KVI_OUT_SYSTEMERROR, szError);
				destroyAsynchronousConnectionData();
				return;
			}
		} // else we just connect to the globally selected IRC server in the options dialog
	}

	KviIrcNetwork * net = g_pServerDataBase->currentNetwork();
	KviIrcServer * srv = net ? net->currentServer() : nullptr;

	if(!srv)
	{
		if(g_pServerDataBase->networkCount())
			KviKvsScript::run("options.edit -n OptionsWidget_servers", m_pConsole);
		else
			m_pConsole->outputNoFmt(KVI_OUT_SYSTEMERROR, __tr2qs("No servers available. Check the options dialog or use the /SERVER command"));
		destroyAsynchronousConnectionData();
		return;
	}

	KviProxy * prx = srv->proxyServer(g_pProxyDataBase);

	if(!prx && (srv->proxy() != -1) && KVI_OPTION_BOOL(KviOption_boolUseProxyHost))
	{
		prx = g_pProxyDataBase->currentProxy();
		if(!prx)
		{
			m_pConsole->outputNoFmt(KVI_OUT_SYSTEMWARNING, __tr2qs("No proxy hosts available, resuming direct connection"));
		}
	}

	QString szBindAddress;

	srv->clearReconnectInfo();
	if(m_pAsynchronousConnectionData)
	{
		szBindAddress = m_pAsynchronousConnectionData->szBindAddress;
		if(m_pAsynchronousConnectionData->m_pReconnectInfo)
			srv->setReconnectInfo(new KviIrcServerReconnectInfo(*(m_pAsynchronousConnectionData->m_pReconnectInfo)));
	}

	// Find out the identity we'll be using in this connection
	// First check the server for one

	const KviUserIdentity * pIdentity = nullptr;

	QString szUserIdentityId = srv->userIdentityId();
	if(!szUserIdentityId.isEmpty())
		pIdentity = KviUserIdentityManager::instance()->findIdentity(szUserIdentityId);

	// If not found, look in the network instead
	if(!pIdentity)
		szUserIdentityId = net->userIdentityId();

	if(!szUserIdentityId.isEmpty())
		pIdentity = KviUserIdentityManager::instance()->findIdentity(szUserIdentityId);

	// If not found, get the default identity (this is GRANTED to be never null, eventually filled up with defaults)
	pIdentity = KviUserIdentityManager::instance()->defaultIdentity();

	if(m_pConnection)
		delete m_pConnection;

	m_pConnection = new KviIrcConnection(
	    this,
	    new KviIrcConnectionTarget(
	        net,
	        srv,
	        prx,
	        szBindAddress),
	    new KviUserIdentity(*pIdentity));

	setState(Connecting);

	if(m_pAsynchronousConnectionData)
	{
		m_pConnection->stateData()->setCommandToExecAfterConnect(m_pAsynchronousConnectionData->szCommandToExecAfterConnect);
		destroyAsynchronousConnectionData();
	}

	m_pConsole->connectionAttached();

	// save stuff for later

	// FIXME: this management of "next" connection should be reviewed a bit anyway
	if(m_pSavedAsynchronousConnectionData)
		delete m_pSavedAsynchronousConnectionData;

	m_pSavedAsynchronousConnectionData = new KviAsynchronousConnectionData();
	m_pSavedAsynchronousConnectionData->szServer = srv->hostName();
	m_pSavedAsynchronousConnectionData->uPort = srv->port();
	m_pSavedAsynchronousConnectionData->bPortIsOk = true;
	m_pSavedAsynchronousConnectionData->bUseIPv6 = srv->isIPv6();
	m_pSavedAsynchronousConnectionData->bUseSSL = srv->useSSL();
	m_pSavedAsynchronousConnectionData->bSTARTTLS = srv->enabledSTARTTLS();
	m_pSavedAsynchronousConnectionData->szPass = srv->password();
	m_pSavedAsynchronousConnectionData->szServerId = srv->id();
	m_pSavedAsynchronousConnectionData->szInitUMode = srv->initUMode();

	if(srv->reconnectInfo())
		m_pSavedAsynchronousConnectionData->m_pReconnectInfo = new KviIrcServerReconnectInfo(*(srv->reconnectInfo()));
	else
		m_pSavedAsynchronousConnectionData->m_pReconnectInfo = nullptr;

	// this never fails!
	m_pConnection->start();
}
Esempio n. 5
0
bool KviIrcServerDataBase::makeCurrentServer(KviIrcServerDefinition * pDef, QString & szError)
{
	KviIrcServer * pServer = 0;

	KviPointerHashTableIterator<QString,KviIrcNetwork> it(*m_pRecords);
	KviIrcNetwork * pNet = 0;
	KviIrcServer * pServ;

	if(KviQString::equalCIN(pDef->szServer,"net:",4))
	{
		// net:networkname form
		QString szNet = pDef->szServer;
		szNet.remove(0,4);
		KviIrcNetwork * pNet = m_pRecords->find(szNet);
		if(pNet)
			return makeCurrentBestServerInNetwork(szNet,pNet,szError);
		szError = __tr2qs("The server specification seems to be in the net:<string> but the network couldn't be found in the database");
		return false;
	}

	if(KviQString::equalCIN(pDef->szServer,"id:",3))
	{
		// id:serverid form
		QString szId = pDef->szServer;
		szId.remove(0,3);

		while((pNet = it.current()))
		{
			for(pServ = pNet->serverList()->first(); pServ && (!pServer); pServ = pNet->serverList()->next())
			{
				if(KviQString::equalCI(pServ->id(),szId))
				{
					pServer = pServ;
					goto search_finished;
				}
			}
			++it;
		}
		szError = __tr2qs("The server specification seems to be in the id:<string> form but the identifier couldn't be found in the database");
		return false;
	}

	it.toFirst();

	while((pNet = it.current()))
	{
		for(pServ = pNet->serverList()->first(); pServ && (!pServer); pServ = pNet->serverList()->next())
		{
			if(KviQString::equalCI(pServ->hostName(),pDef->szServer))
			{
				if(pDef->szId.isEmpty() || KviQString::equalCI(pServ->id(),pDef->szId))
				{
					if(pDef->bIPv6 == pServ->isIPv6())
					{
						if(pDef->bSSL == pServ->useSSL())
						{
							if(pDef->bPortIsValid)
							{
								// must match the port
								if(pDef->uPort == pServ->port())
								{
									// port matches
									if(!pDef->szLinkFilter.isEmpty())
									{
										// must match the link filter
										if(KviQString::equalCI(pDef->szLinkFilter,pServ->linkFilter()))
										{
											// link filter matches
											pServer = pServ;
											goto search_finished;
										} // else link filter doesn't match
									} else {
										// no need to match the link filter
										pServer = pServ;
										goto search_finished;
									}
								} // else port doesn't match
							} else {
								// no need to match the port
								if(!pDef->szLinkFilter.isEmpty())
								{
									// must match the link filter
									if(KviQString::equalCI(pDef->szLinkFilter,pServ->linkFilter()))
									{
										// link filter matches
										pServer = pServ;
										goto search_finished;
									} // else link filter doesn't match
								} else {
									// no need to match the link filter
									pServer = pServ;
									goto search_finished;
								}
							}
						}
					}
				}
			}
		}
		++it;
	}

search_finished:

	if(pNet && pServer)
	{
		m_szCurrentNetwork = pNet->name();
		pNet->setCurrentServer(pServer);
		return true;
	}

	// no such server: is it a valid ip address or hostname ?
	bool bIsValidIPv4 = KviNetUtils::isValidStringIp(pDef->szServer);
#ifdef COMPILE_IPV6_SUPPORT
	bool bIsValidIPv6 = KviNetUtils::isValidStringIPv6(pDef->szServer);
#else
	bool bIsValidIPv6 = false;
#endif

	if(!(bIsValidIPv4 || bIsValidIPv6))
	{
		// is it a valid hostname ? (must contain at least one dot)
		if(!pDef->szServer.contains('.'))
		{
			// assume it is a network name!
			KviIrcNetwork * pNet = m_pRecords->find(pDef->szServer);
			if(pNet)
				return makeCurrentBestServerInNetwork(pDef->szServer,pNet,szError);
			// else probably not a network name
		}
	}

	// a valid hostname or ip address, not found in list : add it and make it current

	pNet = m_pRecords->find(__tr2qs("Standalone Servers"));
	if(!pNet)
	{
		pNet = new KviIrcNetwork(__tr2qs("Standalone Servers"));
		m_pRecords->replace(pNet->name(),pNet);
	}

	KviIrcServer * pSrv = new KviIrcServer();
	pSrv->setHostName(pDef->szServer);
	if(bIsValidIPv4)
	{
		pSrv->setIp(pDef->szServer);
		pSrv->setCacheIp(true);
#ifdef COMPILE_IPV6_SUPPORT
	} else {
		if(bIsValidIPv6)
		{
			pSrv->setIp(pDef->szServer);
			pSrv->setCacheIp(true);
			pDef->bIPv6 = true;
		}
	}
#else
	}
Esempio n. 6
0
int KviIrcUrl::run(const QString & text, int contextSpec, KviConsoleWindow * pConsole)
{
	// first, sanity check the url
	QString cmdBuffer;
	QString szJoinCommand;
	KviIrcUrlParts parts;
	bool bAlreadyConnected = false;

	KviIrcUrl::split(text, parts);
	if(parts.iError & KviIrcUrl::InvalidProtocol || parts.iError & KviIrcUrl::InvalidUrl)
	{
		// invalid proto
		return parts.iError;
	}

	g_pApp->addRecentUrl(text);
	makeJoinCmd(parts.chanList, szJoinCommand);

	// then, get a context
	if((contextSpec & CurrentContext) && !pConsole)
		contextSpec = FirstFreeContext;

	if(contextSpec & TryCurrentContext)
	{
		if(pConsole)
		{
			KviConsoleWindow * pTmpConsole = pConsole;
			pConsole = nullptr;

			if(pTmpConsole->connection())
			{
				KviIrcServer * server = pTmpConsole->connection()->target()->server();
				if(
				    (server->hostName() == parts.szHost) && (server->port() == parts.iPort) && (server->useSSL() == parts.bSsl) && (server->isIPv6() == parts.bIPv6))
				{
					pConsole = pTmpConsole;
					bAlreadyConnected = true;
				}
			}

			if(!pConsole)
				contextSpec = FirstFreeContext;
		}
		else
		{
			contextSpec = FirstFreeContext;
		}
	}

	if(contextSpec & TryEveryContext)
	{
		KviConsoleWindow * pTmpConsole = nullptr;
		pConsole = nullptr;

		for(auto & wnd : g_pGlobalWindowDict)
		{
			if(wnd.second->type() == KviWindow::Console)
			{
				pTmpConsole = (KviConsoleWindow *)wnd.second;

				if(pTmpConsole->connection())
				{
					KviIrcServer * server = pTmpConsole->connection()->target()->server();
					if(
					    (server->hostName() == parts.szHost) && (server->port() == parts.iPort) && (server->useSSL() == parts.bSsl) && (server->isIPv6() == parts.bIPv6))
					{
						pConsole = pTmpConsole;
						bAlreadyConnected = true;
						break;
					}
				}
			}
		}

		if(!pConsole)
			contextSpec = FirstFreeContext;
	}

	if(contextSpec & FirstFreeContext)
	{
		if(pConsole)
		{
			if(pConsole->connectionInProgress())
			{
				pConsole = g_pMainWindow->firstNotConnectedConsole();
				if(!pConsole)
				{
					pConsole = g_pMainWindow->createNewConsole();
				}
			}
		}
		else
		{
			pConsole = g_pMainWindow->firstNotConnectedConsole();
			if(!pConsole)
			{
				pConsole = g_pMainWindow->createNewConsole();
			}
		}
	}

	if(bAlreadyConnected)
	{
		// we already have a connected context to the right server on pConsole
		// just check if thr user want us to join or part any channel
		QString tmp;
		QString toPart;
		for(auto & c : pConsole->connection()->channelList())
		{
			tmp = c->target();
			if(c->hasChannelMode('k'))
			{
				tmp.append("?");
				tmp.append(c->channelModeParam('k'));
			}
			if(!parts.chanList.removeAll(tmp))
			{
				toPart.append(c->target());
				toPart.append(",");
			}
		}
		if(!(contextSpec & DoNotPartChans))
		{
			makeJoinCmd(parts.chanList, szJoinCommand);
			if(!toPart.isEmpty())
			{
				toPart.prepend("part ");
				KviKvsScript::run(toPart, pConsole);
			}
		}
		if(!szJoinCommand.isEmpty())
		{
			pConsole->connection()->sendData(pConsole->connection()->encodeText(szJoinCommand).data());
		}
		return parts.iError;
	}
	else
	{
		// we need to create a new connection on the context of pConsole
		QString szCommand("server ");
		if(parts.bSsl)
			szCommand.append("-s ");
		if(parts.bIPv6)
			szCommand.append("-i ");
		if(!szJoinCommand.isEmpty())
		{
			szCommand.append("-c=\"");
			szCommand.append(szJoinCommand);
			szCommand.append("\" ");
		}
		szCommand.append(QString("%1 %2 ").arg(parts.szHost).arg(parts.iPort));

		KviKvsScript::run(szCommand, (contextSpec & TryCurrentContext) ? g_pMainWindow->createNewConsole() : pConsole);
		return parts.iError;
	}
}
Esempio n. 7
0
int KviMircServersIniImport::doImport(const QString& filename)
{
	KviConfigurationFile cfg(filename,KviConfigurationFile::Read,true);
	int iCount = 0;
	if(cfg.hasGroup("servers"))
	{
		cfg.setGroup("servers");
		int i = 0;
		QString key;
		QString entry;
		do {
			key = QString("n%1").arg(i);
			entry = cfg.readEntry(key,"");
			if(!entry.isEmpty())
			{
				QString description;
				QString serv;
				QString port;
				kvi_u32_t uPort = 0;
				// <description>SERVER:<server:port>GROUP:<network>
				int idx = entry.indexOf("SERVER:",0,Qt::CaseSensitive);
				if(idx != -1)
				{
					description = entry.left(idx);
					entry.remove(0,idx + 7);
					idx = entry.indexOf("GROUP:",0,Qt::CaseSensitive);
					if(idx != -1)
					{
						port = entry.left(idx);
						entry.remove(0,idx + 6);
					}
					idx = port.indexOf(':',0,Qt::CaseSensitive);
					if(idx != -1)
					{
						serv = port.left(idx);
						port.remove(0,idx + 1);
						bool bOk;
						uPort = port.toUInt(&bOk);
						if(!bOk)
							uPort = 6667;
					} else {
						serv = port;
						uPort = 6667;
					}
				}
				if(entry.isEmpty())
					entry = __tr2qs("Standalone Servers");
				if(!serv.isEmpty())
				{
					KviIrcServer s;
					s.setHostName(serv);
					s.setDescription(description);
					s.setPort(uPort);
					iCount++;
					emit server(s,entry);
				}
				++i;
			}
		} while(!entry.isEmpty());
	} else {
		QString szTmp = QString(__tr2qs("%1 doesn't look like a servers.ini file.\nImport failed.")).arg(filename);
		QMessageBox::warning(0,__tr2qs("Warning - KVIrc"),szTmp);
	}
	return iCount;
}