Esempio n. 1
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. 2
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. 3
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
	}