00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <qdir.h>
00021
00022 #include "kded.h"
00023 #include "kdedmodule.h"
00024
00025 #include <kresourcelist.h>
00026 #include <kcrash.h>
00027
00028 #include <unistd.h>
00029 #include <stdlib.h>
00030 #include <signal.h>
00031 #include <time.h>
00032
00033 #include <qfile.h>
00034 #include <qtimer.h>
00035
00036 #include <dcopclient.h>
00037
00038 #include <kuniqueapplication.h>
00039 #include <kcmdlineargs.h>
00040 #include <kaboutdata.h>
00041 #include <klocale.h>
00042 #include <kglobal.h>
00043 #include <kprocess.h>
00044 #include <kdebug.h>
00045 #include <kdirwatch.h>
00046 #include <kstandarddirs.h>
00047 #include <kdatastream.h>
00048 #include <kio/global.h>
00049 #include <kservicetype.h>
00050
00051 #ifdef Q_WS_X11
00052 #include <X11/Xlib.h>
00053 #include <fixx11h.h>
00054 #endif
00055
00056 Kded *Kded::_self = 0;
00057
00058 static bool checkStamps = true;
00059 static bool delayedCheck = false;
00060
00061 static void runBuildSycoca(QObject *callBackObj=0, const char *callBackSlot=0)
00062 {
00063 QStringList args;
00064 args.append("--incremental");
00065 if(checkStamps)
00066 args.append("--checkstamps");
00067 if(delayedCheck)
00068 args.append("--nocheckfiles");
00069 else
00070 checkStamps = false;
00071 if (callBackObj)
00072 {
00073 QByteArray data;
00074 QDataStream dataStream( data, IO_WriteOnly );
00075 dataStream << QString("kbuildsycoca") << args;
00076 QCString _launcher = KApplication::launcher();
00077
00078 kapp->dcopClient()->callAsync(_launcher, _launcher, "kdeinit_exec_wait(QString,QStringList)", data, callBackObj, callBackSlot);
00079 }
00080 else
00081 {
00082 KApplication::kdeinitExecWait( "kbuildsycoca", args );
00083 }
00084 }
00085
00086 static void runKonfUpdate()
00087 {
00088 KApplication::kdeinitExecWait( "kconf_update", QStringList(), 0, 0, "0" );
00089 }
00090
00091 static void runDontChangeHostname(const QCString &oldName, const QCString &newName)
00092 {
00093 QStringList args;
00094 args.append(QFile::decodeName(oldName));
00095 args.append(QFile::decodeName(newName));
00096 KApplication::kdeinitExecWait( "kdontchangethehostname", args );
00097 }
00098
00099 Kded::Kded(bool checkUpdates)
00100 : DCOPObject("kbuildsycoca"), DCOPObjectProxy(),
00101 b_checkUpdates(checkUpdates),
00102 m_needDelayedCheck(false)
00103 {
00104 _self = this;
00105 QCString cPath;
00106 QCString ksycoca_env = getenv("KDESYCOCA");
00107 if (ksycoca_env.isEmpty())
00108 cPath = QFile::encodeName(KGlobal::dirs()->saveLocation("tmp")+"ksycoca");
00109 else
00110 cPath = ksycoca_env;
00111 m_pTimer = new QTimer(this);
00112 connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recreate()));
00113
00114 QTimer::singleShot(100, this, SLOT(installCrashHandler()));
00115
00116 m_pDirWatch = 0;
00117
00118 m_windowIdList.setAutoDelete(true);
00119
00120 m_recreateCount = 0;
00121 m_recreateBusy = false;
00122 }
00123
00124 Kded::~Kded()
00125 {
00126 _self = 0;
00127 m_pTimer->stop();
00128 delete m_pTimer;
00129 delete m_pDirWatch;
00130
00131 m_modules.setAutoDelete(true);
00132 }
00133
00134 bool Kded::process(const QCString &obj, const QCString &fun,
00135 const QByteArray &data,
00136 QCString &replyType, QByteArray &replyData)
00137 {
00138 if (obj == "ksycoca") return false;
00139
00140 if (m_dontLoad[obj])
00141 return false;
00142
00143 KDEDModule *module = loadModule(obj, true);
00144 if (!module)
00145 return false;
00146
00147 module->setCallingDcopClient(kapp->dcopClient());
00148 return module->process(fun, data, replyType, replyData);
00149 }
00150
00151 void Kded::initModules()
00152 {
00153 m_dontLoad.clear();
00154 KConfig *config = kapp->config();
00155 bool kde_running = !( getenv( "KDE_FULL_SESSION" ) == NULL || getenv( "KDE_FULL_SESSION" )[ 0 ] == '\0' );
00156
00157
00158 KService::List kdedModules = KServiceType::offers("KDEDModule");
00159 for(KService::List::ConstIterator it = kdedModules.begin(); it != kdedModules.end(); ++it)
00160 {
00161 KService::Ptr service = *it;
00162 bool autoload = service->property("X-KDE-Kded-autoload", QVariant::Bool).toBool();
00163 config->setGroup(QString("Module-%1").arg(service->desktopEntryName()));
00164 autoload = config->readBoolEntry("autoload", autoload);
00165 if (autoload && kde_running)
00166 loadModule(service, false);
00167
00168 bool dontLoad = false;
00169 QVariant p = service->property("X-KDE-Kded-load-on-demand", QVariant::Bool);
00170 if (p.isValid() && (p.toBool() == false))
00171 dontLoad = true;
00172 if (dontLoad)
00173 noDemandLoad(service->desktopEntryName());
00174
00175 if (dontLoad && !autoload)
00176 unloadModule(service->desktopEntryName().latin1());
00177 }
00178 }
00179
00180
00181 void Kded::noDemandLoad(const QString &obj)
00182 {
00183 m_dontLoad.insert(obj.latin1(), this);
00184 }
00185
00186 KDEDModule *Kded::loadModule(const QCString &obj, bool onDemand)
00187 {
00188 KDEDModule *module = m_modules.find(obj);
00189 if (module)
00190 return module;
00191 KService::Ptr s = KService::serviceByDesktopPath("kded/"+obj+".desktop");
00192 return loadModule(s, onDemand);
00193 }
00194
00195 KDEDModule *Kded::loadModule(const KService *s, bool onDemand)
00196 {
00197 KDEDModule *module = 0;
00198 if (s && !s->library().isEmpty())
00199 {
00200 QCString obj = s->desktopEntryName().latin1();
00201 KDEDModule *oldModule = m_modules.find(obj);
00202 if (oldModule)
00203 return oldModule;
00204
00205 if (onDemand)
00206 {
00207 QVariant p = s->property("X-KDE-Kded-load-on-demand", QVariant::Bool);
00208 if (p.isValid() && (p.toBool() == false))
00209 {
00210 noDemandLoad(s->desktopEntryName());
00211 return 0;
00212 }
00213 }
00214
00215
00216 KLibLoader *loader = KLibLoader::self();
00217
00218 QVariant v = s->property("X-KDE-FactoryName", QVariant::String);
00219 QString factory = v.isValid() ? v.toString() : QString::null;
00220 if (factory.isEmpty())
00221 {
00222
00223 v = s->property("X-KDE-Factory", QVariant::String);
00224 factory = v.isValid() ? v.toString() : QString::null;
00225 }
00226 if (factory.isEmpty())
00227 factory = s->library();
00228
00229 factory = "create_" + factory;
00230 QString libname = "kded_"+s->library();
00231
00232 KLibrary *lib = loader->library(QFile::encodeName(libname));
00233 if (!lib)
00234 {
00235 kdWarning() << k_funcinfo << "Could not load library. [ "
00236 << loader->lastErrorMessage() << " ]" << endl;
00237 libname.prepend("lib");
00238 lib = loader->library(QFile::encodeName(libname));
00239 }
00240 if (lib)
00241 {
00242
00243 void *create = lib->symbol(QFile::encodeName(factory));
00244
00245 if (create)
00246 {
00247
00248 KDEDModule* (*func)(const QCString &);
00249 func = (KDEDModule* (*)(const QCString &)) create;
00250 module = func(obj);
00251 if (module)
00252 {
00253 m_modules.insert(obj, module);
00254 m_libs.insert(obj, lib);
00255 connect(module, SIGNAL(moduleDeleted(KDEDModule *)), SLOT(slotKDEDModuleRemoved(KDEDModule *)));
00256 kdDebug(7020) << "Successfully loaded module '" << obj << "'\n";
00257 return module;
00258 }
00259 }
00260 loader->unloadLibrary(QFile::encodeName(libname));
00261 }
00262 else
00263 {
00264 kdWarning() << k_funcinfo << "Could not load library. [ "
00265 << loader->lastErrorMessage() << " ]" << endl;
00266 }
00267 kdDebug(7020) << "Could not load module '" << obj << "'\n";
00268 }
00269 return 0;
00270 }
00271
00272 bool Kded::unloadModule(const QCString &obj)
00273 {
00274 KDEDModule *module = m_modules.take(obj);
00275 if (!module)
00276 return false;
00277 kdDebug(7020) << "Unloading module '" << obj << "'\n";
00278 delete module;
00279 return true;
00280 }
00281
00282
00283 QCStringList Kded::loadedModules()
00284 {
00285 QCStringList modules;
00286 QAsciiDictIterator<KDEDModule> it( m_modules );
00287 for ( ; it.current(); ++it)
00288 modules.append( it.currentKey() );
00289
00290 return modules;
00291 }
00292
00293 QCStringList Kded::functions()
00294 {
00295 QCStringList res = DCOPObject::functions();
00296 res += "ASYNC recreate()";
00297 return res;
00298 }
00299
00300 void Kded::slotKDEDModuleRemoved(KDEDModule *module)
00301 {
00302 m_modules.remove(module->objId());
00303 KLibrary *lib = m_libs.take(module->objId());
00304 if (lib)
00305 lib->unload();
00306 }
00307
00308 void Kded::slotApplicationRemoved(const QCString &appId)
00309 {
00310 for(QAsciiDictIterator<KDEDModule> it(m_modules); it.current(); ++it)
00311 {
00312 it.current()->removeAll(appId);
00313 }
00314
00315 QValueList<long> *windowIds = m_windowIdList.find(appId);
00316 if (windowIds)
00317 {
00318 for( QValueList<long>::ConstIterator it = windowIds->begin();
00319 it != windowIds->end(); ++it)
00320 {
00321 long windowId = *it;
00322 m_globalWindowIdList.remove(windowId);
00323 for(QAsciiDictIterator<KDEDModule> it(m_modules); it.current(); ++it)
00324 {
00325 emit it.current()->windowUnregistered(windowId);
00326 }
00327 }
00328 m_windowIdList.remove(appId);
00329 }
00330 }
00331
00332 void Kded::updateDirWatch()
00333 {
00334 if (!b_checkUpdates) return;
00335
00336 delete m_pDirWatch;
00337 m_pDirWatch = new KDirWatch;
00338
00339 QObject::connect( m_pDirWatch, SIGNAL(dirty(const QString&)),
00340 this, SLOT(update(const QString&)));
00341 QObject::connect( m_pDirWatch, SIGNAL(created(const QString&)),
00342 this, SLOT(update(const QString&)));
00343 QObject::connect( m_pDirWatch, SIGNAL(deleted(const QString&)),
00344 this, SLOT(dirDeleted(const QString&)));
00345
00346
00347 for( QStringList::ConstIterator it = m_allResourceDirs.begin();
00348 it != m_allResourceDirs.end();
00349 ++it )
00350 {
00351 readDirectory( *it );
00352 }
00353 }
00354
00355 void Kded::updateResourceList()
00356 {
00357 delete KSycoca::self();
00358
00359 if (!b_checkUpdates) return;
00360
00361 if (delayedCheck) return;
00362
00363 QStringList dirs = KSycoca::self()->allResourceDirs();
00364
00365 for( QStringList::ConstIterator it = dirs.begin();
00366 it != dirs.end();
00367 ++it )
00368 {
00369 if (m_allResourceDirs.find(*it) == m_allResourceDirs.end())
00370 {
00371 m_allResourceDirs.append(*it);
00372 readDirectory(*it);
00373 }
00374 }
00375 }
00376
00377 void Kded::crashHandler(int)
00378 {
00379 DCOPClient::emergencyClose();
00380 if (_self)
00381 system("kded");
00382 qWarning("Last DCOP call before KDED crash was from application '%s'\n"
00383 "to object '%s', function '%s'.",
00384 DCOPClient::postMortemSender(),
00385 DCOPClient::postMortemObject(),
00386 DCOPClient::postMortemFunction());
00387 }
00388
00389 void Kded::installCrashHandler()
00390 {
00391 KCrash::setEmergencySaveFunction(crashHandler);
00392 }
00393
00394 void Kded::recreate()
00395 {
00396 recreate(false);
00397 }
00398
00399 void Kded::runDelayedCheck()
00400 {
00401 if( m_needDelayedCheck )
00402 recreate(false);
00403 m_needDelayedCheck = false;
00404 }
00405
00406 void Kded::recreate(bool initial)
00407 {
00408 m_recreateBusy = true;
00409
00410
00411
00412 if (!initial)
00413 {
00414 updateDirWatch();
00415 runBuildSycoca(this, SLOT(recreateDone()));
00416 }
00417 else
00418 {
00419 if(!delayedCheck)
00420 updateDirWatch();
00421 runBuildSycoca();
00422 recreateDone();
00423 if(delayedCheck)
00424 {
00425
00426 QTimer::singleShot( 60000, this, SLOT( runDelayedCheck()));
00427 m_needDelayedCheck = true;
00428 delayedCheck = false;
00429 }
00430 else
00431 m_needDelayedCheck = false;
00432 }
00433 }
00434
00435 void Kded::recreateDone()
00436 {
00437 updateResourceList();
00438
00439 for(; m_recreateCount; m_recreateCount--)
00440 {
00441 QCString replyType = "void";
00442 QByteArray replyData;
00443 DCOPClientTransaction *transaction = m_recreateRequests.first();
00444 if (transaction)
00445 kapp->dcopClient()->endTransaction(transaction, replyType, replyData);
00446 m_recreateRequests.remove(m_recreateRequests.begin());
00447 }
00448 m_recreateBusy = false;
00449
00450
00451 if (!m_recreateRequests.isEmpty())
00452 {
00453 m_pTimer->start(2000, true );
00454 m_recreateCount = m_recreateRequests.count();
00455 }
00456 }
00457
00458 void Kded::dirDeleted(const QString& path)
00459 {
00460 update(path);
00461 }
00462
00463 void Kded::update(const QString& )
00464 {
00465 if (!m_recreateBusy)
00466 {
00467 m_pTimer->start( 2000, true );
00468 }
00469 else
00470 {
00471 m_recreateRequests.append(0);
00472 }
00473 }
00474
00475 bool Kded::process(const QCString &fun, const QByteArray &data,
00476 QCString &replyType, QByteArray &replyData)
00477 {
00478 if (fun == "recreate()") {
00479 if (!m_recreateBusy)
00480 {
00481 if (m_recreateRequests.isEmpty())
00482 {
00483 m_pTimer->start(0, true );
00484 m_recreateCount = 0;
00485 }
00486 m_recreateCount++;
00487 }
00488 m_recreateRequests.append(kapp->dcopClient()->beginTransaction());
00489 replyType = "void";
00490 return true;
00491 } else {
00492 return DCOPObject::process(fun, data, replyType, replyData);
00493 }
00494 }
00495
00496
00497 void Kded::readDirectory( const QString& _path )
00498 {
00499 QString path( _path );
00500 if ( path.right(1) != "/" )
00501 path += "/";
00502
00503 if ( m_pDirWatch->contains( path ) )
00504 return;
00505
00506 QDir d( _path, QString::null, QDir::Unsorted, QDir::Readable | QDir::Executable | QDir::Dirs | QDir::Hidden );
00507
00508
00509
00510
00511
00512
00513
00514 m_pDirWatch->addDir(path);
00515
00516 if ( !d.exists() )
00517 {
00518 kdDebug(7020) << QString("Does not exist! (%1)").arg(_path) << endl;
00519 return;
00520 }
00521
00522
00523
00524
00525
00526
00527 QString file;
00528 unsigned int i;
00529 unsigned int count = d.count();
00530 for( i = 0; i < count; i++ )
00531 {
00532 if (d[i] == "." || d[i] == ".." || d[i] == "magic")
00533 continue;
00534
00535 file = path;
00536 file += d[i];
00537
00538 readDirectory( file );
00539 }
00540 }
00541
00542 bool Kded::isWindowRegistered(long windowId)
00543 {
00544 return m_globalWindowIdList.find(windowId) != 0;
00545
00546 }
00547
00548
00549 void Kded::registerWindowId(long windowId)
00550 {
00551 m_globalWindowIdList.replace(windowId, &windowId);
00552 QCString sender = callingDcopClient()->senderId();
00553 if( sender.isEmpty())
00554 sender = callingDcopClient()->appId();
00555 QValueList<long> *windowIds = m_windowIdList.find(sender);
00556 if (!windowIds)
00557 {
00558 windowIds = new QValueList<long>;
00559 m_windowIdList.insert(sender, windowIds);
00560 }
00561 windowIds->append(windowId);
00562
00563
00564 for(QAsciiDictIterator<KDEDModule> it(m_modules); it.current(); ++it)
00565 {
00566 emit it.current()->windowRegistered(windowId);
00567 }
00568 }
00569
00570
00571 void Kded::unregisterWindowId(long windowId)
00572 {
00573 m_globalWindowIdList.remove(windowId);
00574 QCString sender = callingDcopClient()->senderId();
00575 if( sender.isEmpty())
00576 sender = callingDcopClient()->appId();
00577 QValueList<long> *windowIds = m_windowIdList.find(sender);
00578 if (windowIds)
00579 {
00580 windowIds->remove(windowId);
00581 if (windowIds->isEmpty())
00582 m_windowIdList.remove(sender);
00583 }
00584
00585 for(QAsciiDictIterator<KDEDModule> it(m_modules); it.current(); ++it)
00586 {
00587 emit it.current()->windowUnregistered(windowId);
00588 }
00589 }
00590
00591
00592 static void sighandler(int )
00593 {
00594 if (kapp)
00595 kapp->quit();
00596 }
00597
00598 KUpdateD::KUpdateD()
00599 {
00600 m_pDirWatch = new KDirWatch;
00601 m_pTimer = new QTimer;
00602 connect(m_pTimer, SIGNAL(timeout()), this, SLOT(runKonfUpdate()));
00603 QObject::connect( m_pDirWatch, SIGNAL(dirty(const QString&)),
00604 this, SLOT(slotNewUpdateFile()));
00605
00606 QStringList dirs = KGlobal::dirs()->findDirs("data", "kconf_update");
00607 for( QStringList::ConstIterator it = dirs.begin();
00608 it != dirs.end();
00609 ++it )
00610 {
00611 QString path = *it;
00612 if (path[path.length()-1] != '/')
00613 path += "/";
00614
00615 if (!m_pDirWatch->contains(path))
00616 m_pDirWatch->addDir(path);
00617 }
00618 }
00619
00620 KUpdateD::~KUpdateD()
00621 {
00622 delete m_pDirWatch;
00623 delete m_pTimer;
00624 }
00625
00626 void KUpdateD::runKonfUpdate()
00627 {
00628 ::runKonfUpdate();
00629 }
00630
00631 void KUpdateD::slotNewUpdateFile()
00632 {
00633 m_pTimer->start( 500, true );
00634 }
00635
00636 KHostnameD::KHostnameD(int pollInterval)
00637 {
00638 m_Timer.start(pollInterval, false );
00639 connect(&m_Timer, SIGNAL(timeout()), this, SLOT(checkHostname()));
00640 checkHostname();
00641 }
00642
00643 KHostnameD::~KHostnameD()
00644 {
00645
00646 }
00647
00648 void KHostnameD::checkHostname()
00649 {
00650 char buf[1024+1];
00651 if (gethostname(buf, 1024) != 0)
00652 return;
00653 buf[sizeof(buf)-1] = '\0';
00654
00655 if (m_hostname.isEmpty())
00656 {
00657 m_hostname = buf;
00658 return;
00659 }
00660
00661 if (m_hostname == buf)
00662 return;
00663
00664 QCString newHostname = buf;
00665
00666 runDontChangeHostname(m_hostname, newHostname);
00667 m_hostname = newHostname;
00668 }
00669
00670
00671 static KCmdLineOptions options[] =
00672 {
00673 { "check", I18N_NOOP("Check Sycoca database only once"), 0 },
00674 KCmdLineLastOption
00675 };
00676
00677 class KDEDQtDCOPObject : public DCOPObject
00678 {
00679 public:
00680 KDEDQtDCOPObject() : DCOPObject("qt/kded") { }
00681
00682 virtual bool process(const QCString &fun, const QByteArray &data,
00683 QCString& replyType, QByteArray &replyData)
00684 {
00685 if ( kapp && (fun == "quit()") )
00686 {
00687 kapp->quit();
00688 replyType = "void";
00689 return true;
00690 }
00691 return DCOPObject::process(fun, data, replyType, replyData);
00692 }
00693
00694 QCStringList functions()
00695 {
00696 QCStringList res = DCOPObject::functions();
00697 res += "void quit()";
00698 return res;
00699 }
00700 };
00701
00702 class KDEDApplication : public KUniqueApplication
00703 {
00704 public:
00705 KDEDApplication() : KUniqueApplication( )
00706 {
00707 startup = true;
00708 dcopClient()->connectDCOPSignal( "DCOPServer", "", "terminateKDE()",
00709 objId(), "quit()", false );
00710 }
00711
00712 int newInstance()
00713 {
00714 if (startup) {
00715 startup = false;
00716 QTimer::singleShot(500, Kded::self(), SLOT(initModules()));
00717 } else
00718 runBuildSycoca();
00719
00720 return 0;
00721 }
00722
00723 QCStringList functions()
00724 {
00725 QCStringList res = KUniqueApplication::functions();
00726 res += "bool loadModule(QCString)";
00727 res += "bool unloadModule(QCString)";
00728 res += "void registerWindowId(long int)";
00729 res += "void unregisterWindowId(long int)";
00730 res += "QCStringList loadedModules()";
00731 res += "void reconfigure()";
00732 res += "void quit()";
00733 return res;
00734 }
00735
00736 bool process(const QCString &fun, const QByteArray &data,
00737 QCString &replyType, QByteArray &replyData)
00738 {
00739 if (fun == "loadModule(QCString)") {
00740 QCString module;
00741 QDataStream arg( data, IO_ReadOnly );
00742 arg >> module;
00743 bool result = (Kded::self()->loadModule(module, false) != 0);
00744 replyType = "bool";
00745 QDataStream _replyStream( replyData, IO_WriteOnly );
00746 _replyStream << result;
00747 return true;
00748 }
00749 else if (fun == "unloadModule(QCString)") {
00750 QCString module;
00751 QDataStream arg( data, IO_ReadOnly );
00752 arg >> module;
00753 bool result = Kded::self()->unloadModule(module);
00754 replyType = "bool";
00755 QDataStream _replyStream( replyData, IO_WriteOnly );
00756 _replyStream << result;
00757 return true;
00758 }
00759 else if (fun == "registerWindowId(long int)") {
00760 long windowId;
00761 QDataStream arg( data, IO_ReadOnly );
00762 arg >> windowId;
00763 Kded::self()->setCallingDcopClient(callingDcopClient());
00764 Kded::self()->registerWindowId(windowId);
00765 replyType = "void";
00766 return true;
00767 }
00768 else if (fun == "unregisterWindowId(long int)") {
00769 long windowId;
00770 QDataStream arg( data, IO_ReadOnly );
00771 arg >> windowId;
00772 Kded::self()->setCallingDcopClient(callingDcopClient());
00773 Kded::self()->unregisterWindowId(windowId);
00774 replyType = "void";
00775 return true;
00776 }
00777 else if (fun == "loadedModules()") {
00778 replyType = "QCStringList";
00779 QDataStream _replyStream(replyData, IO_WriteOnly);
00780 _replyStream << Kded::self()->loadedModules();
00781 return true;
00782 }
00783 else if (fun == "reconfigure()") {
00784 config()->reparseConfiguration();
00785 Kded::self()->initModules();
00786 replyType = "void";
00787 return true;
00788 }
00789 else if (fun == "quit()") {
00790 quit();
00791 replyType = "void";
00792 return true;
00793 }
00794 return KUniqueApplication::process(fun, data, replyType, replyData);
00795 }
00796
00797 bool startup;
00798 KDEDQtDCOPObject kdedQtDcopObject;
00799 };
00800
00801 extern "C" KDE_EXPORT int kdemain(int argc, char *argv[])
00802 {
00803 KAboutData aboutData( "kded", I18N_NOOP("KDE Daemon"),
00804 "$Id: kded.cpp 469257 2005-10-10 15:02:57Z coolo $",
00805 I18N_NOOP("KDE Daemon - triggers Sycoca database updates when needed"));
00806
00807 KApplication::installSigpipeHandler();
00808
00809 KCmdLineArgs::init(argc, argv, &aboutData);
00810
00811 KUniqueApplication::addCmdLineOptions();
00812
00813 KCmdLineArgs::addCmdLineOptions( options );
00814
00815
00816 KLocale::setMainCatalogue("kdelibs");
00817
00818
00819 putenv(strdup("SESSION_MANAGER="));
00820
00821
00822 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00823
00824
00825 {
00826 DCOPClient testDCOP;
00827 QCString dcopName = testDCOP.registerAs("kded", false);
00828 if (dcopName.isEmpty())
00829 {
00830 kdFatal() << "DCOP communication problem!" << endl;
00831 return 1;
00832 }
00833 }
00834
00835 KInstance *instance = new KInstance(&aboutData);
00836 KConfig *config = instance->config();
00837
00838 if (args->isSet("check"))
00839 {
00840 config->setGroup("General");
00841 checkStamps = config->readBoolEntry("CheckFileStamps", true);
00842 runBuildSycoca();
00843 runKonfUpdate();
00844 exit(0);
00845 }
00846
00847 if (!KUniqueApplication::start())
00848 {
00849 fprintf(stderr, "KDE Daemon (kded) already running.\n");
00850 exit(0);
00851 }
00852
00853 KUniqueApplication::dcopClient()->setQtBridgeEnabled(false);
00854
00855 config->setGroup("General");
00856 int HostnamePollInterval = config->readNumEntry("HostnamePollInterval", 5000);
00857 bool bCheckSycoca = config->readBoolEntry("CheckSycoca", true);
00858 bool bCheckUpdates = config->readBoolEntry("CheckUpdates", true);
00859 bool bCheckHostname = config->readBoolEntry("CheckHostname", true);
00860 checkStamps = config->readBoolEntry("CheckFileStamps", true);
00861 delayedCheck = config->readBoolEntry("DelayedCheck", false);
00862
00863 Kded *kded = new Kded(bCheckSycoca);
00864
00865 signal(SIGTERM, sighandler);
00866 signal(SIGHUP, sighandler);
00867 KDEDApplication k;
00868
00869 kded->recreate(true);
00870
00871 if (bCheckUpdates)
00872 (void) new KUpdateD;
00873
00874 runKonfUpdate();
00875
00876 if (bCheckHostname)
00877 (void) new KHostnameD(HostnamePollInterval);
00878
00879 DCOPClient *client = kapp->dcopClient();
00880 QObject::connect(client, SIGNAL(applicationRemoved(const QCString&)),
00881 kded, SLOT(slotApplicationRemoved(const QCString&)));
00882 client->setNotifications(true);
00883 client->setDaemonMode( true );
00884
00885
00886
00887
00888
00889
00890
00891 QByteArray data;
00892 client->send( "*", "ksycoca", "notifyDatabaseChanged()", data );
00893 client->send( "ksplash", "", "upAndRunning(QString)", QString("kded"));
00894 #ifdef Q_WS_X11
00895 XEvent e;
00896 e.xclient.type = ClientMessage;
00897 e.xclient.message_type = XInternAtom( qt_xdisplay(), "_KDE_SPLASH_PROGRESS", False );
00898 e.xclient.display = qt_xdisplay();
00899 e.xclient.window = qt_xrootwin();
00900 e.xclient.format = 8;
00901 strcpy( e.xclient.data.b, "kded" );
00902 XSendEvent( qt_xdisplay(), qt_xrootwin(), False, SubstructureNotifyMask, &e );
00903 #endif
00904 int result = k.exec();
00905
00906 delete kded;
00907 delete instance;
00908
00909 return result;
00910 }
00911
00912 #include "kded.moc"