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 "3.5.4"
00118 };
00119 static const int numUpdates = sizeof updates / sizeof *updates;
00120
00121
00122 KConfig * config = KMKernel::config();
00123 KConfigGroup startup( config, "Startup" );
00124 const int configUpdateLevel = startup.readNumEntry( "update-level", 0 );
00125 if ( configUpdateLevel == numUpdates )
00126 return;
00127
00128 for ( int i = configUpdateLevel ; i < numUpdates ; ++i ) {
00129 config->checkUpdate( updates[i], "kmail.upd" );
00130 }
00131 startup.writeEntry( "update-level", numUpdates );
00132 }
00133
00134 void lockOrDie() {
00135
00136 QString appName = kapp->instanceName();
00137 if ( appName.isEmpty() )
00138 appName = "kmail";
00139
00140 QString programName;
00141 const KAboutData *about = kapp->aboutData();
00142 if ( about )
00143 programName = about->programName();
00144 if ( programName.isEmpty() )
00145 programName = i18n("KMail");
00146
00147 QString lockLocation = locateLocal("data", "kmail/lock");
00148 KSimpleConfig config(lockLocation);
00149 int oldPid = config.readNumEntry("pid", -1);
00150 const QString oldHostName = config.readEntry("hostname");
00151 const QString oldAppName = config.readEntry( "appName", appName );
00152 const QString oldProgramName = config.readEntry( "programName", programName );
00153 const QString hostName = getMyHostName();
00154 bool first_instance = false;
00155 if ( oldPid == -1 )
00156 first_instance = true;
00157
00158
00159
00160 else if (hostName == oldHostName && oldPid != getpid()) {
00161 if ( kill(oldPid, 0) == -1 )
00162 first_instance = ( errno == ESRCH );
00163 }
00164
00165 if ( !first_instance ) {
00166 QString msg;
00167 if ( oldHostName == hostName ) {
00168
00169
00170
00171 if ( oldAppName == appName )
00172 msg = i18n("%1 already seems to be running on another display on "
00173 "this machine. Running %2 more than once "
00174 "can cause the loss of mail. You should not start %1 "
00175 "unless you are sure that it is not already running.")
00176 .arg( programName, programName );
00177
00178
00179
00180
00181 else
00182 msg = i18n("%1 seems to be running on another display on this "
00183 "machine. Running %1 and %2 at the same "
00184 "time can cause the loss of mail. You should not start %2 "
00185 "unless you are sure that %1 is not running.")
00186 .arg( oldProgramName, programName );
00187 }
00188 else {
00189 if ( oldAppName == appName )
00190 msg = i18n("%1 already seems to be running on %2. Running %1 more "
00191 "than once can cause the loss of mail. You should not "
00192 "start %1 on this computer unless you are sure that it is "
00193 "not already running on %2.")
00194 .arg( programName, oldHostName );
00195 else
00196 msg = i18n("%1 seems to be running on %3. Running %1 and %2 at the "
00197 "same time can cause the loss of mail. You should not "
00198 "start %2 on this computer unless you are sure that %1 is "
00199 "not running on %3.")
00200 .arg( oldProgramName, programName, oldHostName );
00201 }
00202
00203 KCursorSaver idle( KBusyPtr::idle() );
00204 if ( KMessageBox::No ==
00205 KMessageBox::warningYesNo( 0, msg, QString::null,
00206 i18n("Start %1").arg( programName ),
00207 i18n("Exit") ) ) {
00208 exit(1);
00209 }
00210 }
00211
00212 config.writeEntry("pid", getpid());
00213 config.writeEntry("hostname", hostName);
00214 config.writeEntry( "appName", appName );
00215 config.writeEntry( "programName", programName );
00216 config.sync();
00217 }
00218
00219 void insertLibraryCataloguesAndIcons() {
00220 static const char * const catalogues[] = {
00221 "libkdepim",
00222 "libksieve",
00223 "libkleopatra",
00224 "libkmime"
00225 };
00226
00227 KLocale * l = KGlobal::locale();
00228 KIconLoader * il = KGlobal::iconLoader();
00229 for ( unsigned int i = 0 ; i < sizeof catalogues / sizeof *catalogues ; ++i ) {
00230 l->insertCatalogue( catalogues[i] );
00231 il->addAppDir( catalogues[i] );
00232 }
00233
00234 }
00235
00236 void cleanup()
00237 {
00238 const QString lockLocation = locateLocal("data", "kmail/lock");
00239 KSimpleConfig config(lockLocation);
00240 config.writeEntry("pid", -1);
00241 config.sync();
00242 }
00243 }