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