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.
223 lines
7.0 KiB
223 lines
7.0 KiB
// Author: Don Sanders <sanders@kde.org> |
|
// License GPL |
|
|
|
|
|
#include <config.h> |
|
|
|
#include "kmstartup.h" |
|
|
|
#include "kmkernel.h" //control center |
|
#include "kcursorsaver.h" |
|
|
|
#include <klocale.h> |
|
#include <ksimpleconfig.h> |
|
#include <kstandarddirs.h> |
|
#include <kmessagebox.h> |
|
#include <dcopclient.h> |
|
#include <kcrash.h> |
|
#include <kglobal.h> |
|
#include <kapplication.h> |
|
#include <kaboutdata.h> |
|
#include <kiconloader.h> |
|
|
|
#include <errno.h> |
|
#include <sys/types.h> |
|
#include <signal.h> |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <unistd.h> |
|
|
|
#undef Status // stupid X headers |
|
|
|
extern "C" { |
|
|
|
// Crash recovery signal handler |
|
void kmsignalHandler(int sigId) |
|
{ |
|
kmsetSignalHandler(SIG_DFL); |
|
fprintf(stderr, "*** KMail got signal %d (Exiting)\n", sigId); |
|
// try to cleanup all windows |
|
if (kmkernel) kmkernel->dumpDeadLetters(); |
|
::exit(-1); // |
|
} |
|
|
|
// Crash recovery signal handler |
|
void kmcrashHandler(int sigId) |
|
{ |
|
kmsetSignalHandler(SIG_DFL); |
|
fprintf(stderr, "*** KMail got signal %d (Crashing)\n", sigId); |
|
// try to cleanup all windows |
|
if (kmkernel) kmkernel->dumpDeadLetters(); |
|
// Return to DrKonqi. |
|
} |
|
//----------------------------------------------------------------------------- |
|
|
|
|
|
void kmsetSignalHandler(void (*handler)(int)) |
|
{ |
|
signal(SIGKILL, handler); |
|
signal(SIGTERM, handler); |
|
signal(SIGHUP, handler); |
|
KCrash::setEmergencySaveFunction(kmcrashHandler); |
|
} |
|
|
|
} |
|
//----------------------------------------------------------------------------- |
|
|
|
namespace { |
|
QString getMyHostName() { |
|
char hostNameC[256]; |
|
// null terminate this C string |
|
hostNameC[255] = 0; |
|
// set the string to 0 length if gethostname fails |
|
if(gethostname(hostNameC, 255)) |
|
hostNameC[0] = 0; |
|
return QString::fromLocal8Bit(hostNameC); |
|
} |
|
} // anon namespace |
|
|
|
namespace KMail { |
|
|
|
void checkConfigUpdates() { |
|
static const char * const updates[] = { |
|
"9", |
|
"3.1-update-identities", |
|
"3.1-use-identity-uoids", |
|
"3.1-new-mail-notification", |
|
"3.2-update-loop-on-goto-unread-settings", |
|
"3.1.4-dont-use-UOID-0-for-any-identity", |
|
"3.2-misc", |
|
"3.2-moves", |
|
"3.3-use-ID-for-accounts", |
|
"3.3-update-filter-rules", |
|
"3.3-move-identities-to-own-file", |
|
"3.3-aegypten-kpgprc-to-kmailrc", |
|
"3.3-aegypten-kpgprc-to-libkleopatrarc", |
|
"3.3-aegypten-emailidentities-split-sign-encr-keys", |
|
"3.3-misc", |
|
"3.3b1-misc" |
|
}; |
|
static const int numUpdates = sizeof updates / sizeof *updates; |
|
// Warning: do not remove entries in the above array, or the update-level check below will break |
|
|
|
KConfig * config = KMKernel::config(); |
|
KConfigGroup startup( config, "Startup" ); |
|
const int configUpdateLevel = startup.readNumEntry( "update-level", 0 ); |
|
if ( configUpdateLevel == numUpdates ) // Optimize for the common case that everything is OK |
|
return; |
|
|
|
for ( int i = 0 ; i < numUpdates ; ++i ) |
|
config->checkUpdate( updates[i], "kmail.upd" ); |
|
startup.writeEntry( "update-level", numUpdates ); |
|
} |
|
|
|
void lockOrDie() { |
|
// Check and create a lock file to prevent concurrent access to kmail files |
|
QString appName = kapp->instanceName(); |
|
if ( appName.isEmpty() ) |
|
appName = "kmail"; |
|
|
|
QString programName; |
|
const KAboutData *about = kapp->aboutData(); |
|
if ( about ) |
|
programName = about->programName(); |
|
if ( programName.isEmpty() ) |
|
programName = i18n("KMail"); |
|
|
|
QString lockLocation = locateLocal("data", "kmail/lock"); |
|
KSimpleConfig config(lockLocation); |
|
int oldPid = config.readNumEntry("pid", -1); |
|
const QString oldHostName = config.readEntry("hostname"); |
|
const QString oldAppName = config.readEntry( "appName", appName ); |
|
const QString oldProgramName = config.readEntry( "programName", programName ); |
|
const QString hostName = getMyHostName(); |
|
bool first_instance = false; |
|
if ( oldPid == -1 ) |
|
first_instance = true; |
|
// check if the lock file is stale by trying to see if |
|
// the other pid is currently running. |
|
// Not 100% correct but better safe than sorry |
|
else if (hostName == oldHostName && oldPid != getpid()) { |
|
if ( kill(oldPid, 0) == -1 ) |
|
first_instance = ( errno == ESRCH ); |
|
} |
|
|
|
if ( !first_instance ) { |
|
QString msg; |
|
if ( oldHostName == hostName ) { |
|
// this can only happen if the user is running this application on |
|
// different displays on the same machine. All other cases will be |
|
// taken care of by KUniqueApplication() |
|
if ( oldAppName == appName ) |
|
msg = i18n("%1 already seems to be running on another display on " |
|
"this machine. Running %2 more than once " |
|
"can cause the loss of mail. You should not start %1 " |
|
"unless you are sure that it is not already running.") |
|
.arg( programName, programName ); |
|
// QString::arg( st ) only replaces the first occurrence of %1 |
|
// with st while QString::arg( s1, s2 ) replacess all occurrences |
|
// of %1 with s1 and all occurrences of %2 with s2. So don't |
|
// even think about changing the above to .arg( programName ). |
|
else |
|
msg = i18n("%1 seems to be running on another display on this " |
|
"machine. Running %1 and %2 at the same " |
|
"time can cause the loss of mail. You should not start %2 " |
|
"unless you are sure that %1 is not running.") |
|
.arg( oldProgramName, programName ); |
|
} |
|
else { |
|
if ( oldAppName == appName ) |
|
msg = i18n("%1 already seems to be running on %2. Running %1 more " |
|
"than once can cause the loss of mail. You should not " |
|
"start %1 on this computer unless you are sure that it is " |
|
"not already running on %2.") |
|
.arg( programName, oldHostName ); |
|
else |
|
msg = i18n("%1 seems to be running on %3. Running %1 and %2 at the " |
|
"same time can cause the loss of mail. You should not " |
|
"start %2 on this computer unless you are sure that %1 is " |
|
"not running on %3.") |
|
.arg( oldProgramName, programName, oldHostName ); |
|
} |
|
|
|
KCursorSaver idle( KBusyPtr::idle() ); |
|
if ( KMessageBox::No == |
|
KMessageBox::warningYesNo( 0, msg, QString::null, |
|
i18n("Start %1").arg( programName ), |
|
i18n("Exit") ) ) { |
|
exit(1); |
|
} |
|
} |
|
|
|
config.writeEntry("pid", getpid()); |
|
config.writeEntry("hostname", hostName); |
|
config.writeEntry( "appName", appName ); |
|
config.writeEntry( "programName", programName ); |
|
config.sync(); |
|
} |
|
|
|
void insertLibraryCataloguesAndIcons() { |
|
static const char * const catalogues[] = { |
|
"libkdenetwork", |
|
"libkdepim", |
|
"libksieve", |
|
"libkleopatra", |
|
}; |
|
|
|
KLocale * l = KGlobal::locale(); |
|
KIconLoader * il = KGlobal::iconLoader(); |
|
for ( unsigned int i = 0 ; i < sizeof catalogues / sizeof *catalogues ; ++i ) { |
|
l->insertCatalogue( catalogues[i] ); |
|
il->addAppDir( catalogues[i] ); |
|
} |
|
|
|
} |
|
|
|
void cleanup() |
|
{ |
|
const QString lockLocation = locateLocal("data", "kmail/lock"); |
|
KSimpleConfig config(lockLocation); |
|
config.writeEntry("pid", -1); |
|
config.sync(); |
|
} |
|
}
|
|
|