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.
413 lines
13 KiB
413 lines
13 KiB
//=============================================================================
|
|
//
|
|
// File : kvi_main.cpp
|
|
// Creation date : Sun Jun 18 2000 12:38:45 by Szymon Stefanek
|
|
//
|
|
// This file is part of the KVirc irc client distribution
|
|
// Copyright (C) 1999-2000 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_app.h"
|
|
#include "kvi_string.h"
|
|
#include "kvi_settings.h"
|
|
#include "kvi_ircurl.h"
|
|
#include "kvi_defaults.h"
|
|
#include "kvi_sourcesdate.h"
|
|
#include "kvi_msgbox.h"
|
|
|
|
#ifndef COMPILE_NO_IPC
|
|
extern bool kvi_sendIpcMessage(const char * message); // kvi_ipc.cpp
|
|
#endif
|
|
|
|
#include <tqglobal.h> //for debug()
|
|
|
|
#include <tqmessagebox.h>
|
|
|
|
#define KVI_ARGS_RETCODE_OK 0
|
|
#define KVI_ARGS_RETCODE_ERROR 1
|
|
#define KVI_ARGS_RETCODE_STOP 2
|
|
|
|
typedef struct _ParseArgs
|
|
{
|
|
int argc;
|
|
char ** argv;
|
|
char * configFile;
|
|
bool createFile;
|
|
bool bForceNewSession;
|
|
bool bShowPopup;
|
|
bool bShowSplashScreen;
|
|
bool bExecuteCommandAndClose;
|
|
KviStr szExecCommand;
|
|
KviStr szExecRemoteCommand;
|
|
} ParseArgs;
|
|
|
|
int parseArgs(ParseArgs * a)
|
|
{
|
|
KviStr szServer;
|
|
KviStr szPort;
|
|
int idx;
|
|
|
|
if(a->argc < 2)return KVI_ARGS_RETCODE_OK;
|
|
|
|
for(idx = 1;idx < a->argc;idx++)
|
|
{
|
|
TQString szMessage;
|
|
char * p = a->argv[idx];
|
|
|
|
if((kvi_strLen(p) > 3) && (*p == '-') && (*(p+1) == '-'))p++;
|
|
|
|
if(kvi_strEqualCI("-v",p) || kvi_strEqualCI("-version",p))
|
|
{
|
|
KviTQString::appendFormatted(szMessage,"KVIrc %s '%s'\n",KVI_VERSION,KVI_RELEASE_NAME);
|
|
KviTQString::appendFormatted(szMessage,"Sources date: %s\n",KVI_SOURCES_DATE);
|
|
KviTQString::appendFormatted(szMessage,"Build date: %s\n",KVI_BUILD_DATE);
|
|
KviTQString::appendFormatted(szMessage,"Home page: http://www.kvirc.net/\n");
|
|
|
|
#ifdef COMPILE_ON_WINDOWS
|
|
MessageBox(0,szMessage.local8Bit().data(),"KVIrc",0);
|
|
#else
|
|
debug(szMessage);
|
|
#endif
|
|
|
|
return KVI_ARGS_RETCODE_STOP;
|
|
}
|
|
|
|
if(kvi_strEqualCI("-h",p) || kvi_strEqualCI("-help",p))
|
|
{
|
|
KviTQString::appendFormatted(szMessage,"Usage:\n");
|
|
KviTQString::appendFormatted(szMessage," %s [options] [server [port]] [ircurl [ircurl [...]]]\n",a->argv[0]);
|
|
KviTQString::appendFormatted(szMessage," \n");
|
|
KviTQString::appendFormatted(szMessage,"Available options:\n");
|
|
KviTQString::appendFormatted(szMessage," -h, --help : Print this help and exit\n");
|
|
KviTQString::appendFormatted(szMessage," -v, --version: Print version information and exit\n");
|
|
KviTQString::appendFormatted(szMessage," -c <file> : Use <file> as config file instead of ~/%s\n",KVI_HOME_CONFIG_FILE_NAME);
|
|
KviTQString::appendFormatted(szMessage," (defaults to $HOME/%s if <file> does not exist)\n",KVI_HOME_CONFIG_FILE_NAME);
|
|
KviTQString::appendFormatted(szMessage," -n <file> : Use <file> as config file instead of $HOME/%s\n",KVI_HOME_CONFIG_FILE_NAME);
|
|
KviTQString::appendFormatted(szMessage," (create <file> if it does not exist)\n");
|
|
#ifdef COMPILE_NO_IPC
|
|
KviTQString::appendFormatted(szMessage," -f : Accepted but ignored (for compatibility)\n");
|
|
#else
|
|
KviTQString::appendFormatted(szMessage," -f : Force a new KVIrc session, even if there is already\n");
|
|
KviTQString::appendFormatted(szMessage," a running one.\n");
|
|
#endif
|
|
KviTQString::appendFormatted(szMessage," -e <commands>: If a KVIrc session is already running, execute\n");
|
|
KviTQString::appendFormatted(szMessage," the <commands> in that session, otherwise start up\n");
|
|
KviTQString::appendFormatted(szMessage," normally and execute <commands>\n");
|
|
KviTQString::appendFormatted(szMessage," <commands> must be a single shell token.\n");
|
|
KviTQString::appendFormatted(szMessage," You can eventually use this switch more than once\n");
|
|
KviTQString::appendFormatted(szMessage," -x <commands>: If a KVIrc session is already running, execute\n");
|
|
KviTQString::appendFormatted(szMessage," the <commands> in that session, otherwise exit from application without doing anything/\n");
|
|
KviTQString::appendFormatted(szMessage," <commands> must be a single shell token.\n");
|
|
KviTQString::appendFormatted(szMessage," You can eventually use this switch more than once\n");
|
|
KviTQString::appendFormatted(szMessage," -r <commands>: If a KVIrc session is already running, execute the <commands>\n");
|
|
KviTQString::appendFormatted(szMessage," in that session, otherwise start up normally (do not execute).\n");
|
|
KviTQString::appendFormatted(szMessage," <commands> must be a single shell token.\n");
|
|
KviTQString::appendFormatted(szMessage," You can eventually use this switch more than once\n");
|
|
KviTQString::appendFormatted(szMessage," -m : If a KVIrc session is already running, show an informational\n");
|
|
KviTQString::appendFormatted(szMessage," popup dialog instead of writing to the console");
|
|
KviTQString::appendFormatted(szMessage," --nosplash : Do not show the splash screen at startup\n");
|
|
KviTQString::appendFormatted(szMessage," [server] : Connect to this server after startup\n");
|
|
KviTQString::appendFormatted(szMessage," [port] : Use this port for connection\n");
|
|
KviTQString::appendFormatted(szMessage," [ircurl] : URL in the following form:\n");
|
|
KviTQString::appendFormatted(szMessage," irc[6]://<server>[:<port>][/<channel>[?<pass>]]\n");
|
|
|
|
#ifdef COMPILE_ON_WINDOWS
|
|
MessageBox(0,szMessage.local8Bit().data(),"KVIrc",0);
|
|
#else
|
|
debug(szMessage);
|
|
#endif
|
|
return KVI_ARGS_RETCODE_STOP;
|
|
}
|
|
|
|
if(kvi_strEqualCI("-c",p))
|
|
{
|
|
idx++;
|
|
if(idx >= a->argc)
|
|
{
|
|
debug("Option -c requires a config file name");
|
|
return KVI_ARGS_RETCODE_ERROR;
|
|
}
|
|
p = a->argv[idx];
|
|
a->configFile = p;
|
|
debug("Using file %s as config",p);
|
|
continue;
|
|
}
|
|
|
|
if(kvi_strEqualCI("-e",p))
|
|
{
|
|
idx++;
|
|
if(idx >= a->argc)
|
|
{
|
|
debug("Option -e requires a command");
|
|
return KVI_ARGS_RETCODE_ERROR;
|
|
}
|
|
p = a->argv[idx];
|
|
if(a->szExecCommand.hasData())a->szExecCommand.append("\n");
|
|
a->szExecCommand.append(p);
|
|
continue;
|
|
}
|
|
|
|
if(kvi_strEqualCI("-x",p))
|
|
{
|
|
idx++;
|
|
if(idx >= a->argc)
|
|
{
|
|
debug("Option -x requires a command");
|
|
return KVI_ARGS_RETCODE_ERROR;
|
|
}
|
|
p = a->argv[idx];
|
|
if(a->szExecCommand.hasData())a->szExecCommand.append("\n");
|
|
a->szExecCommand.append(p);
|
|
a->bExecuteCommandAndClose=true;
|
|
continue;
|
|
}
|
|
|
|
if(kvi_strEqualCI("-r",p))
|
|
{
|
|
idx++;
|
|
if(idx >= a->argc)
|
|
{
|
|
debug("Option -r requires a command");
|
|
return KVI_ARGS_RETCODE_ERROR;
|
|
}
|
|
p = a->argv[idx];
|
|
if(a->szExecRemoteCommand.hasData())a->szExecRemoteCommand.append("\n");
|
|
a->szExecRemoteCommand.append(p);
|
|
continue;
|
|
}
|
|
|
|
if(kvi_strEqualCI("-m",p))
|
|
{
|
|
a->bShowPopup = true;
|
|
continue;
|
|
}
|
|
|
|
if(kvi_strEqualCI("-n",p))
|
|
{
|
|
idx++;
|
|
if(idx >= a->argc)
|
|
{
|
|
debug("Option -n requires a config file name");
|
|
return KVI_ARGS_RETCODE_ERROR;
|
|
}
|
|
p = a->argv[idx];
|
|
a->configFile = p;
|
|
a->createFile=true;
|
|
debug("Using file %s as config",p);
|
|
continue;
|
|
}
|
|
|
|
if(kvi_strEqualCI("-nosplash",p))
|
|
{
|
|
a->bShowSplashScreen = false;
|
|
continue;
|
|
}
|
|
|
|
if(kvi_strEqualCI("-f",p))
|
|
{
|
|
a->bForceNewSession = true;
|
|
continue;
|
|
}
|
|
|
|
if(kvi_strEqualCI("-session",p)||kvi_strEqualCI("-display",p))
|
|
{
|
|
// TQt apps are supposed to handle the params to these switches, but we'll skip arg for now
|
|
idx++;
|
|
continue;
|
|
}
|
|
|
|
if(*p != '-')
|
|
{
|
|
// no dash
|
|
if(kvi_strEqualCIN(p,"irc://",6) || kvi_strEqualCIN(p,"irc6://",7) || kvi_strEqualCIN(p,"ircs://",7) || kvi_strEqualCIN(p,"ircs6://",8))
|
|
{
|
|
KviStr tmp = TQString(TQString::fromLocal8Bit(p));
|
|
if(a->szExecCommand.hasData())a->szExecCommand.append('\n');
|
|
a->szExecCommand.append("openurl ");
|
|
tmp.replaceAll("$",""); // the urls can't contain $ signs
|
|
tmp.replaceAll(";",""); // the urls can't contain ; signs
|
|
a->szExecCommand.append(tmp);
|
|
} else {
|
|
TQString tmp = TQString::fromLocal8Bit(p);
|
|
bool bOk;
|
|
tmp.toUInt(&bOk);
|
|
if(bOk)szPort = tmp;
|
|
else {
|
|
TQString ri = tmp.right(4);
|
|
if(KviTQString::equalCI(ri,".kvs"))
|
|
{
|
|
if(a->szExecCommand.hasData())a->szExecCommand.append('\n');
|
|
a->szExecCommand.append("parse \"");
|
|
tmp.replace('$',"\\$");
|
|
tmp.replace('\\',"\\\\");
|
|
a->szExecCommand.append(tmp);
|
|
a->szExecCommand.append('"');
|
|
} else if(KviTQString::equalCI(ri,".kvt"))
|
|
{
|
|
if(a->szExecCommand.hasData())a->szExecCommand.append('\n');
|
|
a->szExecCommand.append("theme.install \"");
|
|
tmp.replace('$',"\\$");
|
|
tmp.replace('\\',"\\\\");
|
|
a->szExecCommand.append(tmp);
|
|
a->szExecCommand.append('"');
|
|
} else
|
|
szServer = tmp; // assume a plain server name
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(szServer.hasData())
|
|
{
|
|
if(a->szExecCommand.hasData())a->szExecCommand.append('\n');
|
|
a->szExecCommand.append("server -u ");
|
|
a->szExecCommand.append(szServer);
|
|
if(szPort.hasData())
|
|
{
|
|
a->szExecCommand.append(' ');
|
|
a->szExecCommand.append(szPort);
|
|
}
|
|
}
|
|
|
|
return KVI_ARGS_RETCODE_OK;
|
|
}
|
|
|
|
#if defined(Q_OS_MACX) && (__GNUC__ == 3 && __GNUC_MINOR__ == 3)
|
|
// Repair broken colour definitions due to "lazy" static object initialization
|
|
void repair_colors(void)
|
|
{
|
|
if(TQt::white.red() == 0)
|
|
{
|
|
TQt::color0 = (tqRgb(255,255,255 ),0);
|
|
TQt::color1 = (tqRgb(0,0,0),1);
|
|
TQt::black.setRgb(0,0,0);
|
|
TQt::white.setRgb(255,255,255);
|
|
TQt::darkGray.setRgb(128,128,128);
|
|
TQt::gray.setRgb(160,160,164);
|
|
TQt::lightGray.setRgb(192,192,192);
|
|
TQt::red.setRgb(255,0,0);
|
|
TQt::green.setRgb(0,255,0);
|
|
TQt::blue.setRgb(0,0,255);
|
|
TQt::cyan.setRgb(0,255,255);
|
|
TQt::magenta.setRgb(255,0,255);
|
|
TQt::yellow.setRgb(255,255,0);
|
|
TQt::darkRed.setRgb(128,0,0);
|
|
TQt::darkGreen.setRgb(0,128,0);
|
|
TQt::darkBlue.setRgb(0,0,128);
|
|
TQt::darkCyan.setRgb(0,128,128);
|
|
TQt::darkMagenta.setRgb(128,0,128);
|
|
TQt::darkYellow.setRgb(128,128,0);
|
|
}
|
|
}
|
|
#endif //Q_OS_MACX
|
|
|
|
int main(int argc,char ** argv)
|
|
{
|
|
|
|
#if defined(Q_OS_MACX) && (__GNUC__ == 3 && __GNUC_MINOR__ == 3)
|
|
repair_colors();
|
|
#endif //Q_OS_MACX
|
|
|
|
ParseArgs a;
|
|
a.argc = argc;
|
|
a.argv = argv;
|
|
a.configFile = 0;
|
|
a.createFile = false;
|
|
a.bForceNewSession = false;
|
|
a.bShowPopup = false,
|
|
a.bShowSplashScreen = true;
|
|
a.bExecuteCommandAndClose = false;
|
|
|
|
int retCode = parseArgs(&a);
|
|
|
|
if(retCode != KVI_ARGS_RETCODE_OK)return ((retCode == KVI_ARGS_RETCODE_ERROR) ? (-1) : 0);
|
|
|
|
// Need to have the X socket open before IPC startup
|
|
KviApp * theApp = new KviApp(argc,argv);
|
|
|
|
KviStr szRemoteCommand = a.szExecCommand;
|
|
if(a.szExecRemoteCommand.hasData())
|
|
{
|
|
if(szRemoteCommand.hasData())szRemoteCommand.append('\n');
|
|
szRemoteCommand.append(a.szExecRemoteCommand);
|
|
}
|
|
|
|
/*
|
|
FIXME: There is a race condition in the IPC mechanism.
|
|
If one starts two instances of kvirc one immediately after another
|
|
then both instances may run through kvi_sendIpcMessage
|
|
without finding the sentinel window and thus both may decide
|
|
to start.
|
|
A weak file locking mechanism should be used too...
|
|
|
|
#ifdef COMPILE_ON_WINDOWS
|
|
TQString szLock = convertSeparators(cleanDirPath(TQDir::homeDirPath() + "/.kvirc.lock"));
|
|
#else
|
|
TQString szLock = convertSeparators(cleanDirPath(TQDir::homeDirPath() + "/.kvirc.lock"));
|
|
#endif
|
|
|
|
TQFileInfo inf(szLock);
|
|
bool bLocked = false;
|
|
if(inf.exists())
|
|
{
|
|
iLocked = inf.lastModified().secsTo(TQDateTime::currentDateTime());
|
|
}
|
|
*/
|
|
|
|
#ifndef COMPILE_NO_IPC
|
|
if(!a.bForceNewSession)
|
|
{
|
|
// here we could use CreateMutex on win and semget() on linux
|
|
// in order to get a shared semaphore to ensure instance unicity.
|
|
|
|
if(kvi_sendIpcMessage(szRemoteCommand.ptr()))
|
|
{
|
|
if(szRemoteCommand.isEmpty())
|
|
{
|
|
KviStr tmp(KviStr::Format,"Another KVIrc session is already running on this display and with this user id.\nUse %s -f if you want to force a new session.",argv[0]);
|
|
if(a.bShowPopup)
|
|
TQMessageBox::information(0,"Session - KVIrc",tmp.ptr(),TQMessageBox::Ok);
|
|
else
|
|
debug(tmp.ptr());
|
|
}
|
|
delete theApp;
|
|
return 0;
|
|
} else if(a.bExecuteCommandAndClose) {
|
|
delete theApp;
|
|
return 0;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
theApp->m_bCreateConfig = a.createFile;
|
|
theApp->m_szConfigFile = a.configFile;
|
|
theApp->m_szExecAfterStartup = a.szExecCommand;
|
|
theApp->m_bShowSplashScreen = a.bShowSplashScreen;
|
|
theApp->setup();
|
|
|
|
// YEAH!
|
|
int retVal = theApp->exec();
|
|
// :)
|
|
|
|
delete theApp;
|
|
theApp = 0;
|
|
return retVal;
|
|
}
|