You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
364 lines
9.3 KiB
364 lines
9.3 KiB
//
|
|
// File : kvi_ircurl.cpp
|
|
// Creation date : Sun Mar 04 2001 14:20:12 by Szymon Stefanek
|
|
//
|
|
// This file is part of the KVirc irc client distribution
|
|
// Copyright (C) 2001 Szymon Stefanek (pragma at kvirc dot net)
|
|
//
|
|
// This program is FREE software. You can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; either version 2
|
|
// of the License, or (at your opinion) any later version.
|
|
//
|
|
// This program is distributed in the HOPE that it will be USEFUL,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
// See the GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, write to the Free Software Foundation,
|
|
// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
//
|
|
#define __KVIRC__
|
|
#include "kvi_string.h"
|
|
#include "kvi_inttypes.h"
|
|
#include "kvi_qstring.h"
|
|
#include "kvi_ircserver.h"
|
|
#include "kvi_kvs_script.h"
|
|
#include "kvi_msgbox.h"
|
|
#include "kvi_channel.h"
|
|
#include "kvi_app.h"
|
|
#include "kvi_locale.h"
|
|
#include "kvi_ircconnectiontarget.h"
|
|
#include "kvi_ircconnection.h"
|
|
#include "kvi_irccontext.h"
|
|
#include "kvi_console.h"
|
|
#include "kvi_frame.h"
|
|
|
|
#define _KVI_IRCURL_CPP_
|
|
#include "kvi_ircurl.h"
|
|
|
|
|
|
bool KviIrcUrl::parse(const char * url,KviStr &cmdBuffer,int contextSpec)
|
|
{
|
|
// irc[6]://<server>[:<port>][/<channel>[?<pass>]]
|
|
KviStr szUrl = url;
|
|
//szUrl.replaceAll("$","\\$");
|
|
//szUrl.replaceAll(";","\\;");
|
|
bool bIpV6 = false;
|
|
bool bSSL = false;
|
|
KviStr szServer;
|
|
kvi_u32_t uPort = 0;
|
|
bool bGotPort = false;
|
|
if(kvi_strEqualCIN(szUrl.ptr(),"irc://",6))
|
|
{
|
|
szUrl.cutLeft(6);
|
|
} else if(kvi_strEqualCIN(szUrl.ptr(),"irc6://",7))
|
|
{
|
|
bIpV6 = true;
|
|
szUrl.cutLeft(7);
|
|
} else if(kvi_strEqualCIN(szUrl.ptr(),"ircs://",7))
|
|
{
|
|
bSSL = true;
|
|
szUrl.cutLeft(7);
|
|
} else if(kvi_strEqualCIN(szUrl.ptr(),"ircs6://",8))
|
|
{
|
|
bIpV6 = true;
|
|
bSSL = true;
|
|
szUrl.cutLeft(8);
|
|
} else return false;
|
|
|
|
KviStr szServerAndPort;
|
|
|
|
int idx = szUrl.findFirstIdx('/');
|
|
if(idx != -1)
|
|
{
|
|
szServerAndPort = szUrl.left(idx);
|
|
szUrl.cutLeft(idx + 1);
|
|
} else {
|
|
szServerAndPort = szUrl;
|
|
szUrl = "";
|
|
}
|
|
|
|
if(szServerAndPort.isEmpty())return false;
|
|
|
|
idx = szServerAndPort.findFirstIdx(':');
|
|
|
|
if(idx != -1)
|
|
{
|
|
szServer = szServerAndPort.left(idx);
|
|
szServerAndPort.cutLeft(idx + 1);
|
|
bool bOk;
|
|
uPort = szServerAndPort.toUInt(&bOk);
|
|
if(!bOk)uPort = 6667;
|
|
bGotPort = true;
|
|
} else {
|
|
szServer = szServerAndPort;
|
|
}
|
|
|
|
cmdBuffer = "server ";
|
|
switch(contextSpec)
|
|
{
|
|
case KVI_IRCURL_CONTEXT_FIRSTFREE:
|
|
cmdBuffer.append("-u ");
|
|
break;
|
|
case KVI_IRCURL_CONTEXT_NEW:
|
|
cmdBuffer.append("-n ");
|
|
break;
|
|
}
|
|
if(bIpV6)cmdBuffer.append(" -i ");
|
|
if(bSSL)cmdBuffer.append(" -s ");
|
|
|
|
if(szUrl.hasData())
|
|
{
|
|
KviStr szChannel;
|
|
KviStr szPass;
|
|
|
|
idx = szUrl.findFirstIdx('?');
|
|
if(idx != -1)
|
|
{
|
|
szChannel = szUrl.left(idx);
|
|
szUrl.cutLeft(idx + 1);
|
|
szPass = szUrl;
|
|
} else {
|
|
szChannel = szUrl;
|
|
szPass = "";
|
|
}
|
|
|
|
if(!(szChannel.firstCharIs('#') || szChannel.firstCharIs('!') || szChannel.firstCharIs('&')))
|
|
szChannel.prepend('#');
|
|
|
|
if(szPass.isEmpty())cmdBuffer.append(KviStr::Format," -c=\"join %s\" ",szChannel.ptr());
|
|
else cmdBuffer.append(KviStr::Format," -c=\"join %s %s\" ",szChannel.ptr(),szPass.ptr());
|
|
|
|
}
|
|
|
|
cmdBuffer.append(szServer);
|
|
if(bGotPort)cmdBuffer.append(KviStr::Format," %d",uPort);
|
|
|
|
cmdBuffer.append(';');
|
|
|
|
return true;
|
|
}
|
|
|
|
void KviIrcUrl::split(TQString url, KviIrcUrlParts& result)
|
|
{
|
|
// irc[s][6]://<server>[:<port>][/<channel>[?<pass>]][[,<channel>[?<pass>]]
|
|
|
|
//defaults
|
|
result.bSsl=false;
|
|
result.bIpV6=false;
|
|
result.iPort = 6667;
|
|
result.iError=0;
|
|
|
|
int iProtoLen = url.find("://");
|
|
if(iProtoLen!=-1) {
|
|
if(KviTQString::equalCIN(url,"irc",3)) {
|
|
// OK, seems to be a valid proto;
|
|
url = url.right(url.length()-3);
|
|
if(KviTQString::equalCIN(url,"s",1)) {
|
|
result.bSsl=true;
|
|
url = url.right(url.length()-1);
|
|
}
|
|
if(KviTQString::equalCIN(url,"6",1)) {
|
|
result.bIpV6=true;
|
|
url = url.right(url.length()-1);
|
|
}
|
|
if(!KviTQString::equalCIN(url,"://",3)) {
|
|
//irc(???):// proto??
|
|
result.iError |= InvalidProtocol;
|
|
}
|
|
iProtoLen = url.find("://");
|
|
url = url.right(url.length()-iProtoLen-3);
|
|
} else {
|
|
result.iError |= InvalidProtocol;
|
|
}
|
|
}
|
|
//Ok, we understand a protocol.. Now we shuld find a server name:)
|
|
int iTmp;
|
|
iTmp = url.find(':');
|
|
if(iTmp!=-1) {
|
|
result.szHost = url.left(iTmp);
|
|
url = url.right(url.length()-iTmp-1);
|
|
// Accepted, now the time for the port:)
|
|
bool bOk;
|
|
if( (iTmp = url.find('/')) != -1) { // any channels pending?
|
|
result.iPort = url.left(iTmp).toUInt(&bOk);
|
|
if(!bOk) {
|
|
result.iPort = 6667;
|
|
result.iError |= InvalidPort;
|
|
}
|
|
url = url.right(url.length()-iTmp-1);
|
|
} else {
|
|
result.iPort = url.toUInt(&bOk);
|
|
if(!bOk) {
|
|
result.iPort = 6667;
|
|
result.iError |= InvalidPort;
|
|
}
|
|
url = "";
|
|
}
|
|
} else if( (iTmp = url.find('/')) != -1) { // have channels??
|
|
result.szHost = url.left(iTmp);
|
|
url = url.right(url.length()-iTmp-1);
|
|
} else {
|
|
result.szHost = url;
|
|
url = "";
|
|
}
|
|
|
|
//and, finally, channels:D
|
|
|
|
result.chanList = TQStringList::split(',',url);
|
|
|
|
}
|
|
|
|
void KviIrcUrl::join(TQString &uri, KviIrcServer* server)
|
|
{
|
|
if(server)
|
|
{
|
|
uri="irc";
|
|
|
|
if(server->useSSL()) uri.append("s");
|
|
if(server->isIpV6()) uri.append("6");
|
|
|
|
uri.append("://");
|
|
uri.append(server->hostName());
|
|
if(server->port()!=6667) uri.append(TQString(":%1").arg(server->port()));
|
|
uri.append("/");
|
|
}
|
|
}
|
|
|
|
void KviIrcUrl::makeJoinCmd(const TQStringList& chans, TQString& szJoinCommand)
|
|
{
|
|
TQString szChannels,szProtectedChannels,szPasswords,szCurPass,szCurChan;
|
|
if(chans.count()!=0)
|
|
{
|
|
|
|
for ( TQStringList::ConstIterator it = chans.begin(); it != chans.end(); ++it ) {
|
|
|
|
szCurPass=(*it).section('?',1);
|
|
if(szCurPass.isEmpty())
|
|
{
|
|
if(!szChannels.isEmpty())
|
|
szChannels.append(",");
|
|
szCurChan = (*it).section('?',0,0);
|
|
if(!(szCurChan[0]=='#' || szCurChan[0]=='&' || szCurChan[0]=='!'))
|
|
szCurChan.prepend('#');
|
|
szChannels.append(szCurChan);
|
|
} else {
|
|
if(!szProtectedChannels.isEmpty())
|
|
szProtectedChannels.append(",");
|
|
szCurChan = (*it).section('?',0,0);
|
|
if(!(szCurChan[0]=='#' || szCurChan[0]=='&' || szCurChan[0]=='!'))
|
|
szCurChan.prepend('#');
|
|
szProtectedChannels.append(szCurChan);
|
|
if(!szPasswords.isEmpty())
|
|
szPasswords.append(",");
|
|
szPasswords.append(szCurPass);
|
|
}
|
|
}
|
|
szJoinCommand = "JOIN ";
|
|
szJoinCommand.append(szProtectedChannels);
|
|
if(!szProtectedChannels.isEmpty() && !szChannels.isEmpty())
|
|
szJoinCommand.append(',');
|
|
szJoinCommand.append(szChannels);
|
|
szJoinCommand.append(" ");
|
|
szJoinCommand.append(szPasswords);
|
|
}
|
|
}
|
|
|
|
int KviIrcUrl::run(const TQString& text,int contextSpec,KviConsole* pConsole)
|
|
{
|
|
KviIrcUrlParts parts;
|
|
KviIrcUrl::split(text,parts);
|
|
TQString cmdBuffer;
|
|
|
|
if( (contextSpec & CurrentContext) && !pConsole) {
|
|
contextSpec = FirstFreeContext;
|
|
}
|
|
|
|
if( (contextSpec & TryCurrentContext) && !pConsole) {
|
|
contextSpec = FirstFreeContext;
|
|
}
|
|
|
|
if(contextSpec & FirstFreeContext) {
|
|
if(pConsole) {
|
|
if(pConsole->connectionInProgress())
|
|
{
|
|
pConsole = g_pFrame->firstNotConnectedConsole();
|
|
if(!pConsole) {
|
|
pConsole = g_pFrame->createNewConsole();
|
|
}
|
|
}
|
|
} else {
|
|
pConsole = g_pFrame->firstNotConnectedConsole();
|
|
if(!pConsole) {
|
|
pConsole = g_pFrame->createNewConsole();
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!(parts.iError & KviIrcUrl::InvalidProtocol)) {
|
|
g_pApp->addRecentUrl(text);
|
|
|
|
TQString szJoinCommand;
|
|
makeJoinCmd(parts.chanList,szJoinCommand);
|
|
TQString 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(TQString("%1 %2 ").arg(parts.szHost).arg(parts.iPort));
|
|
|
|
if(pConsole->connection()) {
|
|
KviIrcServer* server = pConsole->connection()->target()->server();
|
|
if(
|
|
( server->hostName() != parts.szHost ) ||
|
|
( server->port() != parts.iPort ) ||
|
|
( server->useSSL() != parts.bSsl ) ||
|
|
( server->isIpV6() != parts.bIpV6) )
|
|
{ // New server, try to reconnect
|
|
KviKvsScript::run(szCommand,(contextSpec & TryCurrentContext) ? g_pFrame->createNewConsole() : pConsole);
|
|
return parts.iError;
|
|
} else {
|
|
// the same server, but probably new chanlist
|
|
TQString tmp;
|
|
TQString toPart;
|
|
for(KviChannel * c = pConsole->connection()->channelList()->first();c;c = pConsole->connection()->channelList()->next())
|
|
{
|
|
tmp=c->name();
|
|
if(c->hasChannelKey()) {
|
|
tmp.append("?");
|
|
tmp.append(c->channelKey());
|
|
}
|
|
if(!parts.chanList.remove(tmp))
|
|
{
|
|
toPart.append(c->name());
|
|
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;
|
|
}
|
|
}
|
|
// New server
|
|
KviKvsScript::run(szCommand,pConsole);
|
|
}
|
|
//!invalid proto
|
|
return parts.iError;
|
|
}
|