kmail Library API Documentation

kmstartup.cpp

00001 // Author: Don Sanders <sanders@kde.org>
00002 // License GPL
00003 
00004 
00005 #include <config.h>
00006 
00007 #include "kmstartup.h"
00008 
00009 #include "kmkernel.h" //control center
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 // Crash recovery signal handler
00035 void kmsignalHandler(int sigId)
00036 {
00037   kmsetSignalHandler(SIG_DFL);
00038   fprintf(stderr, "*** KMail got signal %d (Exiting)\n", sigId);
00039   // try to cleanup all windows
00040   if (kmkernel) kmkernel->dumpDeadLetters();
00041   ::exit(-1); //
00042 }
00043 
00044 // Crash recovery signal handler
00045 void kmcrashHandler(int sigId)
00046 {
00047   kmsetSignalHandler(SIG_DFL);
00048   fprintf(stderr, "*** KMail got signal %d (Crashing)\n", sigId);
00049   // try to cleanup all windows
00050   if (kmkernel) kmkernel->dumpDeadLetters();
00051   // Return to DrKonqi.
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     // null terminate this C string
00071     hostNameC[255] = 0;
00072     // set the string to 0 length if gethostname fails
00073     if(gethostname(hostNameC, 255))
00074       hostNameC[0] = 0;
00075     return QString::fromLocal8Bit(hostNameC);
00076   }
00077 } // anon namespace
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   // Warning: do not remove entries in the above array, or the update-level check below will break
00102 
00103   KConfig * config = KMKernel::config();
00104   KConfigGroup startup( config, "Startup" );
00105   const int configUpdateLevel = startup.readNumEntry( "update-level", 0 );
00106   if ( configUpdateLevel == numUpdates ) // Optimize for the common case that everything is OK
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 // Check and create a lock file to prevent concurrent access to kmail files
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   // check if the lock file is stale by trying to see if
00138   // the other pid is currently running.
00139   // Not 100% correct but better safe than sorry
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       // this can only happen if the user is running this application on
00149       // different displays on the same machine. All other cases will be
00150       // taken care of by KUniqueApplication()
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               // QString::arg( st ) only replaces the first occurrence of %1
00158               // with st while QString::arg( s1, s2 ) replacess all occurrences
00159               // of %1 with s1 and all occurrences of %2 with s2. So don't
00160               // even think about changing the above to .arg( programName ).
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 }
KDE Logo
This file is part of the documentation for kmail Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu May 3 20:23:33 2007 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003