00001
00002
00003
00004
00005 #include <config.h>
00006
00007 #include "kmstartup.h"
00008
00009 #include "kmkernel.h"
00010 #include "kcursorsaver.h"
00011
00012 #include <klocale.h>
00013 #include <ksimpleconfig.h>
00014 #include <kstandarddirs.h>
00015 #include <kmessagebox.h>
00016 #include <dcopclient.h>
00017 #include <kcrash.h>
00018 #include <kglobal.h>
00019 #include <kapplication.h>
00020 #include <kaboutdata.h>
00021 #include <kiconloader.h>
00022
00023 #include <errno.h>
00024 #include <sys/types.h>
00025 #include <signal.h>
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <unistd.h>
00029
00030 #undef Status // stupid X headers
00031
00032 extern "C" {
00033
00034
00035 void kmsignalHandler(int sigId)
00036 {
00037 kmsetSignalHandler(SIG_DFL);
00038 fprintf(stderr, "*** KMail got signal %d (Exiting)\n", sigId);
00039
00040 if (kmkernel) kmkernel->dumpDeadLetters();
00041 ::exit(-1);
00042 }
00043
00044
00045 void kmcrashHandler(int sigId)
00046 {
00047 kmsetSignalHandler(SIG_DFL);
00048 fprintf(stderr, "*** KMail got signal %d (Crashing)\n", sigId);
00049
00050 if (kmkernel) kmkernel->dumpDeadLetters();
00051
00052 }
00053
00054
00055
00056 void kmsetSignalHandler(void (*handler)(int))
00057 {
00058 signal(SIGKILL, handler);
00059 signal(SIGTERM, handler);
00060 signal(SIGHUP, handler);
00061 KCrash::setEmergencySaveFunction(kmcrashHandler);
00062 }
00063
00064 }
00065
00066
00067 namespace {
00068 QString getMyHostName() {
00069 char hostNameC[256];
00070
00071 hostNameC[255] = 0;
00072
00073 if(gethostname(hostNameC, 255))
00074 hostNameC[0] = 0;
00075 return QString::fromLocal8Bit(hostNameC);
00076 }
00077 }
00078
00079 namespace KMail {
00080
00081 void checkConfigUpdates() {
00082 static const char * const updates[] = {
00083 "9",
00084 "3.1-update-identities",
00085 "3.1-use-identity-uoids",
00086 "3.1-new-mail-notification",
00087 "3.2-update-loop-on-goto-unread-settings",
00088 "3.1.4-dont-use-UOID-0-for-any-identity",
00089 "3.2-misc",
00090 "3.2-moves",
00091 "3.3-use-ID-for-accounts",
00092 "3.3-update-filter-rules",
00093 "3.3-move-identities-to-own-file",
00094 "3.3-aegypten-kpgprc-to-kmailrc",
00095 "3.3-aegypten-kpgprc-to-libkleopatrarc",
00096 "3.3-aegypten-emailidentities-split-sign-encr-keys",
00097 "3.3-misc",
00098 "3.3b1-misc"
00099 };
00100 static const int numUpdates = sizeof updates / sizeof *updates;
00101
00102
00103 KConfig * config = KMKernel::config();
00104 KConfigGroup startup( config, "Startup" );
00105 const int configUpdateLevel = startup.readNumEntry( "update-level", 0 );
00106 if ( configUpdateLevel == numUpdates )
00107 return;
00108
00109 for ( int i = 0 ; i < numUpdates ; ++i )
00110 config->checkUpdate( updates[i], "kmail.upd" );
00111 startup.writeEntry( "update-level", numUpdates );
00112 }
00113
00114 void lockOrDie() {
00115
00116 QString appName = kapp->instanceName();
00117 if ( appName.isEmpty() )
00118 appName = "kmail";
00119
00120 QString programName;
00121 const KAboutData *about = kapp->aboutData();
00122 if ( about )
00123 programName = about->programName();
00124 if ( programName.isEmpty() )
00125 programName = i18n("KMail");
00126
00127 QString lockLocation = locateLocal("data", "kmail/lock");
00128 KSimpleConfig config(lockLocation);
00129 int oldPid = config.readNumEntry("pid", -1);
00130 const QString oldHostName = config.readEntry("hostname");
00131 const QString oldAppName = config.readEntry( "appName", appName );
00132 const QString oldProgramName = config.readEntry( "programName", programName );
00133 const QString hostName = getMyHostName();
00134 bool first_instance = false;
00135 if ( oldPid == -1 )
00136 first_instance = true;
00137
00138
00139
00140 else if (hostName == oldHostName && oldPid != getpid()) {
00141 if ( kill(oldPid, 0) == -1 )
00142 first_instance = ( errno == ESRCH );
00143 }
00144
00145 if ( !first_instance ) {
00146 QString msg;
00147 if ( oldHostName == hostName ) {
00148
00149
00150
00151 if ( oldAppName == appName )
00152 msg = i18n("%1 already seems to be running on another display on "
00153 "this machine. Running %2 more than once "
00154 "can cause the loss of mail. You should not start %1 "
00155 "unless you are sure that it is not already running.")
00156 .arg( programName, programName );
00157
00158
00159
00160
00161 else
00162 msg = i18n("%1 seems to be running on another display on this "
00163 "machine. Running %1 and %2 at the same "
00164 "time can cause the loss of mail. You should not start %2 "
00165 "unless you are sure that %1 is not running.")
00166 .arg( oldProgramName, programName );
00167 }
00168 else {
00169 if ( oldAppName == appName )
00170 msg = i18n("%1 already seems to be running on %2. Running %1 more "
00171 "than once can cause the loss of mail. You should not "
00172 "start %1 on this computer unless you are sure that it is "
00173 "not already running on %2.")
00174 .arg( programName, oldHostName );
00175 else
00176 msg = i18n("%1 seems to be running on %3. Running %1 and %2 at the "
00177 "same time can cause the loss of mail. You should not "
00178 "start %2 on this computer unless you are sure that %1 is "
00179 "not running on %3.")
00180 .arg( oldProgramName, programName, oldHostName );
00181 }
00182
00183 KCursorSaver idle( KBusyPtr::idle() );
00184 if ( KMessageBox::No ==
00185 KMessageBox::warningYesNo( 0, msg, QString::null,
00186 i18n("Start %1").arg( programName ),
00187 i18n("Exit") ) ) {
00188 exit(1);
00189 }
00190 }
00191
00192 config.writeEntry("pid", getpid());
00193 config.writeEntry("hostname", hostName);
00194 config.writeEntry( "appName", appName );
00195 config.writeEntry( "programName", programName );
00196 config.sync();
00197 }
00198
00199 void insertLibraryCataloguesAndIcons() {
00200 static const char * const catalogues[] = {
00201 "libkdenetwork",
00202 "libkdepim",
00203 "libksieve",
00204 "libkleopatra",
00205 };
00206
00207 KLocale * l = KGlobal::locale();
00208 KIconLoader * il = KGlobal::iconLoader();
00209 for ( unsigned int i = 0 ; i < sizeof catalogues / sizeof *catalogues ; ++i ) {
00210 l->insertCatalogue( catalogues[i] );
00211 il->addAppDir( catalogues[i] );
00212 }
00213
00214 }
00215
00216 void cleanup()
00217 {
00218 const QString lockLocation = locateLocal("data", "kmail/lock");
00219 KSimpleConfig config(lockLocation);
00220 config.writeEntry("pid", -1);
00221 config.sync();
00222 }
00223 }