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 
00011 #include <klocale.h>
00012 #include <ksimpleconfig.h>
00013 #include <kstandarddirs.h>
00014 #include <knotifyclient.h>
00015 #include <dcopclient.h>
00016 #include <kcrash.h>
00017 #include <kglobal.h>
00018 
00019 #include <errno.h>
00020 #include <sys/types.h>
00021 #include <signal.h>
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <unistd.h>
00025 
00026 #undef Status // stupid X headers
00027 
00028 extern "C" {
00029 
00030 // Crash recovery signal handler
00031 void kmsignalHandler(int sigId)
00032 {
00033   kmsetSignalHandler(SIG_DFL);
00034   fprintf(stderr, "*** KMail got signal %d (Exiting)\n", sigId);
00035   // try to cleanup all windows
00036   if (kmkernel) kmkernel->dumpDeadLetters();
00037   ::exit(-1); //
00038 }
00039 
00040 // Crash recovery signal handler
00041 void kmcrashHandler(int sigId)
00042 {
00043   kmsetSignalHandler(SIG_DFL);
00044   fprintf(stderr, "*** KMail got signal %d (Crashing)\n", sigId);
00045   // try to cleanup all windows
00046   kmkernel->dumpDeadLetters();
00047   // Return to DrKonqi.
00048 }
00049 //-----------------------------------------------------------------------------
00050 
00051 
00052 void kmsetSignalHandler(void (*handler)(int))
00053 {
00054   signal(SIGKILL, handler);
00055   signal(SIGTERM, handler);
00056   signal(SIGHUP,  handler);
00057   KCrash::setEmergencySaveFunction(kmcrashHandler);
00058 }
00059 
00060 }
00061 //-----------------------------------------------------------------------------
00062 
00063 namespace {
00064   QString getMyHostName() {
00065     char hostNameC[256];
00066     // null terminate this C string
00067     hostNameC[255] = 0;
00068     // set the string to 0 length if gethostname fails
00069     if(gethostname(hostNameC, 255))
00070       hostNameC[0] = 0;
00071     return QString::fromLocal8Bit(hostNameC);
00072   }
00073 } // anon namespace
00074 
00075 namespace KMail {
00076 
00077 void checkConfigUpdates() {
00078   static const char * const updates[] = {
00079     "9",
00080     "3.1-update-identities",
00081     "3.1-use-identity-uoids",
00082     "3.1-new-mail-notification",
00083     "3.2-update-loop-on-goto-unread-settings",
00084     "3.1.4-dont-use-UOID-0-for-any-identity",
00085     "3.2-misc",
00086     "3.2-moves",
00087   };
00088   static const int numUpdates = sizeof updates / sizeof *updates;
00089 
00090   KConfig * config = KMKernel::config();
00091   KConfigGroup startup( config, "Startup" );
00092   const int configUpdateLevel = startup.readNumEntry( "update-level", 0 );
00093   if ( configUpdateLevel == numUpdates ) // Optimize for the common case that everything is OK
00094     return;
00095 
00096   for ( int i = 0 ; i < numUpdates ; ++i )
00097     config->checkUpdate( updates[i], "kmail.upd" );
00098   startup.writeEntry( "update-level", numUpdates );
00099 }
00100 
00101 void lockOrDie() {
00102 // Check and create a lock file to prevent concurrent access to kmail files
00103   QString lockLocation = locateLocal("data", "kmail/lock");
00104   KSimpleConfig config(lockLocation);
00105   int oldPid = config.readNumEntry("pid", -1);
00106   const QString oldHostName = config.readEntry("hostname");
00107   const QString hostName = getMyHostName();
00108   bool first_instance = false;
00109   if ( oldPid == -1 )
00110       first_instance = true;
00111   // check if the lock file is stale by trying to see if 
00112   // the other pid is currently running.
00113   // Not 100% correct but better safe than sorry
00114   else if (hostName == oldHostName && oldPid != getpid()) {
00115       if ( kill(oldPid, 0) == -1 )
00116           first_instance = ( errno == ESRCH );
00117   }
00118 
00119   if ( !first_instance )
00120   {
00121     QString msg = i18n("Only one instance of KMail can be run at "
00122       "any one time. It is already running "
00123       "with PID %1 on host %2 according to the lock file located "
00124       "at %3.").arg(oldPid).arg(oldHostName).arg(lockLocation);
00125 
00126     KNotifyClient::userEvent( 0, msg,  KNotifyClient::Messagebox,
00127       KNotifyClient::Error );
00128     fprintf(stderr, "*** KMail is already running with PID %d on host %s\n",
00129             oldPid, oldHostName.local8Bit().data());
00130     exit(1);
00131   }
00132 
00133   config.writeEntry("pid", getpid());
00134   config.writeEntry("hostname", hostName);
00135   config.sync();
00136 }
00137 
00138 void insertLibraryCatalogues() {
00139   static const char * const catalogues[] = {
00140     "libkdenetwork",
00141     "libkdepim",
00142     "libktnef",
00143     "libkcal",
00144     "libksieve",
00145   };
00146 
00147   KLocale * l = KGlobal::locale();
00148   for ( unsigned int i = 0 ; i < sizeof catalogues / sizeof *catalogues ; ++i )
00149     l->insertCatalogue( catalogues[i] );
00150 }
00151 
00152 void cleanup()
00153 {
00154   const QString lockLocation = locateLocal("data", "kmail/lock");
00155   KSimpleConfig config(lockLocation);
00156   config.writeEntry("pid", -1);
00157   config.sync();
00158 }
00159 }
KDE Logo
This file is part of the documentation for kmail Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat May 1 11:37:34 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003