void KviSharedFilesManager::save(const QString & szFilename)
{
	KviConfigurationFile cfg(szFilename, KviConfigurationFile::Write);
	cfg.clear();
	cfg.setGroup("PermanentFileOffers");

	KviPointerHashTableIterator<QString, KviSharedFileList> it(*m_pSharedListDict);
	int i = 0;
	while(KviSharedFileList * pList = it.current())
	{
		for(KviSharedFile * pFile = pList->first(); pFile; pFile = pList->next())
		{
			if(((int)(pFile->expireTime())) == 0)
			{
				QString szTmp;
				szTmp = QString("%1FName").arg(i);
				cfg.writeEntry(szTmp, it.currentKey());
				szTmp = QString("%1FilePath").arg(i);
				cfg.writeEntry(szTmp, pFile->absFilePath());
				szTmp = QString("%1UserMask").arg(i);
				cfg.writeEntry(szTmp, pFile->userMask());
				++i;
			}
		}
		++it;
	}
	cfg.writeEntry("NEntries", i);
}
Exemple #2
0
static void dccModuleParseDccGet(KviDccRequest * dcc)
{
	// DCC [TS]GET <filename> [filesize]
	// -> DCC [TS]SEND <filename> <ipaddr> <port> <filesize>
	// ...
	dcc->szParam1 = dcc->pConsole->decodeText(dcc->szParam1);
	bool bOk;
	unsigned int uSize = dcc->szParam2.toUInt(&bOk);
	if(!bOk)
		uSize = 0;

	if(!dcc_module_check_limits(dcc))
		return;
	if(!dcc_module_check_concurrent_transfers_limit(dcc))
		return;

	KviCString szExtensions = dcc->szType;
	szExtensions.cutRight(3); // cut off GET

	bool bTurboExtension = szExtensions.contains('T', false);
#ifdef COMPILE_SSL_SUPPORT
	bool bSSLExtension = szExtensions.contains('S', false);
#else  //!COMPILE_SSL_SUPPORT
	if(szExtensions.contains('S', false))
	{
		dcc_module_request_error(dcc, __tr2qs_ctx("This executable has been compiled without SSL support, the SSL extension to DCC GET is not available", "dcc"));
		return;
	}
#endif //!COMPILE_SSL_SUPPORT

	KviSharedFile * o = g_pSharedFilesManager->lookupSharedFile(dcc->szParam1.ptr(), dcc->ctcpMsg->pSource, uSize);
	if(!o)
	{
		if(!dcc->ctcpMsg->msg->haltOutput())
		{
			QString szError = QString(__tr2qs_ctx("No file offer named '%1' (with size %2) available for %3 [%4@%5]", "dcc")).arg(dcc->szParam1.ptr()).arg(uSize > 0 ? dcc->szParam2.ptr() : __tr_ctx("\"any\"", "dcc")).arg(dcc->ctcpMsg->pSource->nick(), dcc->ctcpMsg->pSource->user(), dcc->ctcpMsg->pSource->host());
			dcc_module_request_error(dcc, szError);
		}
		return;
	}

	//#warning "IF NOT IGNORE DCC GET!"
	//#warning "CREATE IT MINIMIZED ETC..."
	//#warning "MAYBE USE A DIALOG TO ACCEPT THE REQUEST ?"
	//#warning "DO NOT ACCEPT /etc/* requests..."

	if(KVI_OPTION_BOOL(KviOption_boolCantAcceptIncomingDccConnections))
	{
		// we have to use DCC RSEND, otherwise it will not work
		KviCString szSubproto("RSEND");
		szSubproto.prepend(szExtensions);

		QString szFileName = QFileInfo(o->absFilePath()).fileName();
		if(o->name() != szFileName)
		{
			// BUG
			//   If the file offer was added with a name that is senseless (like "mediaXYZ" for an *.mp3 file)
			//   then we would be going to RSEND that name here: the remote user woulnd't be
			//   able to recognize the file.
			//   Here we add another temporary offer with the right filename.

			// now add a file offer, so he we will accept it automatically
			// 120 secs is a reasonable timeout
			QString szMask;
			dcc->ctcpMsg->pSource->mask(szMask, KviIrcMask::NickUserHost);

			KviSharedFile * pOld = o;
			o = g_pSharedFilesManager->addSharedFile(szFileName, o->absFilePath(), szMask, 120);
			if(!o)
				o = pOld; // give up (FIXME: should we notify that ?)
		}

		if(!dcc->ctcpMsg->msg->haltOutput())
		{
			dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
			    __tr2qs_ctx("Accepting file request from %Q [%Q@%Q] for '%s' (real file: %Q), offering DCC %s since we can't accept incoming connections (user option)", "dcc"),
			    &(dcc->ctcpMsg->pSource->nick()),
			    &(dcc->ctcpMsg->pSource->user()),
			    &(dcc->ctcpMsg->pSource->host()), dcc->szParam1.ptr(),
			    &(o->absFilePath()), szSubproto.ptr());
		}

		dcc->pConsole->connection()->sendFmtData("PRIVMSG %s :%cDCC %s %s %s%c",
		    dcc->pConsole->connection()->encodeText(dcc->ctcpMsg->pSource->nick()).data(),
		    0x01, szSubproto.ptr(),
		    dcc->pConsole->connection()->encodeText(dcc->szParam1.ptr()).data(),
		    dcc->pConsole->connection()->encodeText(QString::number(o->fileSize())).data(),
		    0x01);
		return;
	}

	DccDescriptor * d = new DccDescriptor(dcc->pConsole);
	d->szNick = dcc->ctcpMsg->pSource->nick();
	d->szLocalFileName = o->absFilePath();
	d->szUser = dcc->ctcpMsg->pSource->user();
	d->szHost = dcc->ctcpMsg->pSource->host();
	d->bRecvFile = false;
	dcc_fill_local_nick_user_host(d, dcc);

	QString tmp;
	if(!dcc_kvs_get_listen_ip_address(nullptr, d->console(), tmp))
	{
		d->console()->output(KVI_OUT_DCCMSG,
		    __tr2qs_ctx("No suitable interface to listen on, trying to continue anyway...", "dcc"));
		d->szListenIp = "0.0.0.0";
	}
	else
		d->szListenIp = QString(tmp);
	//#warning "DO STH WITH THIS PORT (HOW TO SPECIFY IT ?)"
	d->szListenPort = "0"; // any port is ok

	if(KVI_OPTION_BOOL(KviOption_boolDccSendFakeAddressByDefault))
	{
		d->szFakeIp = KVI_OPTION_STRING(KviOption_stringDefaultDccFakeAddress);
		if(d->szFakeIp.isEmpty())
			KVI_OPTION_BOOL(KviOption_boolDccSendFakeAddressByDefault) = false;
	}

	d->bDoTimeout = true;
	d->szIp = __tr2qs_ctx("(unknown)", "dcc");
	d->szPort = d->szIp;
	d->bActive = false;
	d->bSendRequest = true;
	d->bIsTdcc = bTurboExtension;
#ifdef COMPILE_SSL_SUPPORT
	d->bIsSSL = bSSLExtension;
#endif
	d->bNoAcks = d->bIsTdcc;
	d->bOverrideMinimize = false;

	dcc_module_set_dcc_type(d, "SEND");

	if(!dcc->ctcpMsg->msg->haltOutput())
	{
		dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
		    __tr2qs_ctx("Accepting file request from %Q [%Q@%Q] for '%s' (real file: %Q), offering DCC %Q", "dcc"),
		    &(dcc->ctcpMsg->pSource->nick()),
		    &(dcc->ctcpMsg->pSource->user()),
		    &(dcc->ctcpMsg->pSource->host()),
		    dcc->szParam1.ptr(),
		    &(o->absFilePath()), &(d->szType));
	}
	d->triggerCreationEvent();
	g_pDccBroker->sendFileExecute(nullptr, d);
}
Exemple #3
0
static void dccModuleParseDccRecv(KviDccRequest * dcc)
{
	// DCC [TS]RECV <filename> <ipaddr> <port> <resume-filesize>
	if(!dcc_module_check_limits(dcc))
		return;
	if(!dcc_module_check_concurrent_transfers_limit(dcc))
		return;

	if(!dcc_module_normalize_target_data(dcc, dcc->szParam2, dcc->szParam3))
		return;

	if(!(dcc->szParam4.isUnsignedNum()))
	{
		if(!dcc->ctcpMsg->msg->haltOutput())
		{
			dcc->ctcpMsg->msg->console()->outputNoFmt(KVI_OUT_DCCMSG,
			    __tr2qs_ctx("The above request has resume file size missing, assuming a resume file size of 0", "dcc"));
		}
		dcc->szParam4 = "0";
	}

	if(dcc->szParam1.contains('/'))
	{
		if(!dcc->ctcpMsg->msg->haltOutput())
		{
			dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
			    __tr2qs_ctx("The above request is broken: the filename contains path components, stripping the leading path and trying to continue", "dcc"), dcc->szParam1.ptr());
		}
		dcc->szParam1.cutToLast('/');
	}

	KviCString szExtensions = dcc->szType;
	szExtensions.cutRight(4); // cut off RECV

	bool bTurboExtension = szExtensions.contains('T', false);
#ifdef COMPILE_SSL_SUPPORT
	bool bSSLExtension = szExtensions.contains('S', false);
#else  //!COMPILE_SSL_SUPPORT
	if(szExtensions.contains('S', false))
	{
		dcc_module_request_error(dcc, __tr2qs_ctx("This executable has been compiled without SSL support, the SSL extension to DCC RECV is not available", "dcc"));
		return;
	}
#endif //!COMPILE_SSL_SUPPORT

	// If we have a file offer for this...do it automatically
	KviSharedFile * o = g_pSharedFilesManager->lookupSharedFile(dcc->szParam1.ptr(), dcc->ctcpMsg->pSource, 0);
	if(o)
	{

		unsigned int uResumeSize = dcc->szParam4.toUInt(); // this will NEVER fail
		if(uResumeSize >= o->fileSize())
		{
			// senseless request
			QString szError = QString(__tr2qs_ctx("Invalid RECV request: position %1 is larger than file size", "dcc")).arg(uResumeSize);
			dcc_module_request_error(dcc, szError);
			return;
		}

		// ok...we have requested this send
		//		#warning "Maybe remove this file offer now ?"
		DccDescriptor * d = new DccDescriptor(dcc->pConsole);

		d->szNick = dcc->ctcpMsg->pSource->nick();
		d->szUser = dcc->ctcpMsg->pSource->user();
		d->szHost = dcc->ctcpMsg->pSource->host();

		d->szFileName = dcc->szParam1.ptr();
		d->szFileSize = dcc->szParam4.ptr();

		//d->bResume           = false; // This is actually useless

		d->szLocalFileName = o->absFilePath();
		d->szLocalFileSize.setNum(o->fileSize()); // Should we look it up again ?

		d->bRecvFile = false;
		d->bNoAcks = bTurboExtension;

		d->bAutoAccept = true;
		d->bIsIncomingAvatar = false;

		d->bIsTdcc = bTurboExtension;
#ifdef COMPILE_SSL_SUPPORT
		d->bIsSSL = bSSLExtension;
#endif

		d->bOverrideMinimize = false;

		// We know everything
		dcc_fill_local_nick_user_host(d, dcc);

		d->bDoTimeout = true;

		d->szIp = dcc->szParam2.ptr();
		d->szPort = dcc->szParam3.ptr();

		d->bActive = true;
		dcc_module_set_dcc_type(d, "SEND");
		d->triggerCreationEvent();
		g_pDccBroker->sendFileExecute(nullptr, d);

		return;
	}
	else
	{

		dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
		    __tr2qs_ctx("%Q [%Q@%Q] is ready to receive the file \"%s\"", "dcc"),
		    &(dcc->ctcpMsg->pSource->nick()),
		    &(dcc->ctcpMsg->pSource->user()),
		    &(dcc->ctcpMsg->pSource->host()),
		    dcc->szParam1.ptr());
		dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
		    __tr2qs_ctx("The remote client is listening on interface %s and port %s", "dcc"), dcc->szParam2.ptr(), dcc->szParam3.ptr());
		KviCString szSwitches = "-c";
		if(bTurboExtension)
			szSwitches.prepend("-t ");
#ifdef COMPILE_SSL_SUPPORT
		if(bSSLExtension)
			szSwitches.prepend("-s ");
#endif
		dcc->ctcpMsg->msg->console()->output(KVI_OUT_DCCMSG,
		    __tr2qs_ctx("Use %c\r![!dbl]dcc.send %s -i=%s -p=%s %Q\r/dcc.send %s -i=%s -p=%s %Q\r%c to send the file (or double-click on the socket)", "dcc"),
		    KviControlCodes::Bold,
		    szSwitches.ptr(),
		    dcc->szParam2.ptr(), dcc->szParam3.ptr(), &(dcc->ctcpMsg->pSource->nick()),
		    szSwitches.ptr(),
		    dcc->szParam2.ptr(), dcc->szParam3.ptr(), &(dcc->ctcpMsg->pSource->nick()),
		    KviControlCodes::Bold);
	}
}