summaryrefslogtreecommitdiffstats
path: root/kmrml/kmrml/server
diff options
context:
space:
mode:
Diffstat (limited to 'kmrml/kmrml/server')
-rw-r--r--kmrml/kmrml/server/Makefile.am12
-rw-r--r--kmrml/kmrml/server/daemonwatcher.desktop103
-rw-r--r--kmrml/kmrml/server/watcher.cpp280
-rw-r--r--kmrml/kmrml/server/watcher.h107
4 files changed, 502 insertions, 0 deletions
diff --git a/kmrml/kmrml/server/Makefile.am b/kmrml/kmrml/server/Makefile.am
new file mode 100644
index 00000000..875684b0
--- /dev/null
+++ b/kmrml/kmrml/server/Makefile.am
@@ -0,0 +1,12 @@
+kde_module_LTLIBRARIES = kded_daemonwatcher.la
+
+INCLUDES = $(all_includes)
+kded_daemonwatcher_la_SOURCES = watcher.cpp watcher.skel
+# watcher.stub
+kded_daemonwatcher_la_LDFLAGS = $(all_libraries) -module -avoid-version
+kded_daemonwatcher_la_LIBADD = $(LIB_KSYCOCA) $(LIB_KDEUI)
+
+METASOURCES = AUTO
+
+servicesdir = $(kde_servicesdir)/kded
+services_DATA = daemonwatcher.desktop
diff --git a/kmrml/kmrml/server/daemonwatcher.desktop b/kmrml/kmrml/server/daemonwatcher.desktop
new file mode 100644
index 00000000..c29495b4
--- /dev/null
+++ b/kmrml/kmrml/server/daemonwatcher.desktop
@@ -0,0 +1,103 @@
+[Desktop Entry]
+Type=Service
+Name=KDED KMRML Daemon Watcher
+Name[ar]=مراقب KDED KMRML Daemon
+Name[bs]=KDED KMRML nadzor demona
+Name[ca]=Dimoni vigilant KDED KMRL
+Name[cs]=Sledovač KMRML démonů
+Name[cy]=Gwyliwr Ellyll KMRML KDED
+Name[da]=KDED KMRML-dæmon-overvåger
+Name[de]=Überwachung der KDE-Bildersuche
+Name[el]=Επόπτης δαίμονα KMRML KDED
+Name[es]=Guardián del demonio KDED KMRML
+Name[et]=KDED KMRML deemoni jälgija
+Name[eu]=KDED KMRML deabru behatzailea
+Name[fa]=پایشگر شبح KDED KMRML
+Name[fi]=KDED KMRML-palvelimen tarkkailija
+Name[fr]=Observateur KDE du démon KMRML
+Name[gl]=Vixiante do daemon de KDED KMRML
+Name[he]=צופה תהליכי הרקע של KDED KMRML
+Name[hi]=KDED KMRML डेमन वाचर
+Name[hu]=KDED KMRML szolgáltatásfigyelő
+Name[is]=Eftirlit með KDED KMRML þjóninum
+Name[it]=Controllo del demone KDED KMRML
+Name[ja]=KDED KMRML デーモンウォッチャー
+Name[kk]=KDED KMRML қызметі
+Name[km]=កម្មវិធី​ឃ្លាំមើល​ដេមិន KDED KMRML
+Name[lt]=KDED KMRML tarnybos stebėtojas
+Name[ms]=Pemerhati Daemon KDED KMRML
+Name[nb]=KDED KMRML nisseovervåker
+Name[nds]=KMRML-Luerdämoon för KDED
+Name[ne]=KDED KMRML डेइमन दर्शक
+Name[nl]=KDED KMRML-daemonbeheer
+Name[nn]=KDED KMRML-nisseovervaking
+Name[pl]=Monitor usług KMRML
+Name[pt]=Monitor KMRML de Servidores KDED
+Name[pt_BR]=Sentinela de Serviços KDED
+Name[ro]=Demon KDED pentru MRML
+Name[ru]=Служба MRML
+Name[se]=KDED KMRML-duogášprográmmagoziheaddji
+Name[sk]=Sledovanie démona KDED KMRML
+Name[sl]=Opazovalnik demona KMRML za KDED
+Name[sr]=KDED KMRML демон за праћење
+Name[sr@Latn]=KDED KMRML demon za praćenje
+Name[sv]=KDED KMRML-demonbevakare
+Name[ta]=KDED டிமென் வாட்சர்
+Name[tg]=Мудири демони KDED KMRML
+Name[th]=ตัวเฝ้าดูแดมอน KDED KMRML
+Name[tr]=KDED KMRML Aracı İzleyici
+Name[uk]=Спостерігач демону KDED KMRML
+Name[zh_CN]=KDED KMRML 守护程序监视器
+Name[zh_HK]=KDED KMRML 系統程式監察器
+Name[zh_TW]=KDED KMRML 伺服程式監看器
+Comment=Starts daemons on demand and restarts them on failure
+Comment[bg]=Стартиране на демоните при заявка и рестартиране на демони при грешка
+Comment[bs]=Pokreće demone po potrebi i restartuje ih ako se sruše
+Comment[ca]=Engega els dimonis sota petició i els torna a engegar si fallen
+Comment[cs]=Spouští démony na požádání a restartuje je při selhání
+Comment[da]=Starter dæmoner ved forespørgsel og genstarter dem ved fejl
+Comment[de]=Startet KMRML-Dienste bei Bedarf und im Fehlerfall neu
+Comment[el]=Εκκινεί δαίμονες όταν ζητηθεί και τους επανεκκινεί κατά την αποτυχία
+Comment[es]=Inicia los demonios bajo demanda y los reinicia si fallan
+Comment[et]=Käivitab nõudmisel deemoneid ja taaskäivitab neid ebaõnnestumise korral
+Comment[eu]=Demonioak hasi eta bukau egiten ditu eskatzen zaionean
+Comment[fa]=شبحها را بر اساس نیاز آغاز می‌کند و هنگام خرابی آنها را بازآغازی می‌کند
+Comment[fi]=Käynnistää palvelimia tarpeen mukaan ja uudelleenkäynnistää ne virheen yhteydessä
+Comment[fr]=Lance les démons à la demande et les redémarre en cas d'échec
+Comment[gl]=Iniciar daemons cando sexa preciso e reinicialos se fallan.
+Comment[he]=מפעיל תהליכי רקע לפי דרישה ומפעיל אותם מחדש במקרה של כשל
+Comment[hu]=Szükség esetén elindítja, hiba esetén újraindítja a szolgáltatásokat
+Comment[is]=Ræsir þjóna þegar þarf og endurræsir þá ef þeir bregðast
+Comment[it]=Avvia i demoni su richiesta e li riavvia in caso di problemi
+Comment[ja]=デーモンをオンデマンドで起動し、失敗したときは再起動します。
+Comment[kk]=Талап бойынша қызметті жегу, жаңылса қайта жегу
+Comment[km]=ចាប់ផ្ដើម​ដេមិន​នៅ​ពេល​ត្រូវការ ហើយ​ចាប់ផ្ដើម​ពួក​វា​ឡើង​វិញ​នៅ​ពេល​បរាជ័យ
+Comment[lt]=Paleidžia tarnybas pagal pareikalavimą ir paleidžia iš naujo nesėkmės atveju
+Comment[ms]=Mulakan daemons atas permintaan dan mula semula atas kegagalan
+Comment[nb]=Starter nisser på forespørsler og starter dem igjen ved feil.
+Comment[nds]=Start Achtergrundperzessen op Nafraag un bi Fehlers nieg
+Comment[ne]=माग गरेको बेलामा डेइमन सुरु गर्दछ र अफफल भएमा फेरि सुरु गर्दछ
+Comment[nl]=Start achtergrondprogramma's op en herstart deze indien nodig
+Comment[nn]=Startar nissar når dei trengst og startar dei om att ved feil
+Comment[pl]=Uruchamia usługi na żądanie i wznawia je po awarii
+Comment[pt]=Inicia os servidores a pedido e reinicia-os em caso de falha
+Comment[pt_BR]=Inicia serviços sob demanda e reinicia-os em caso de falha
+Comment[ro]=Porneşte demonii la cerere şi îi reporneşte în caz de eroare
+Comment[ru]=Поддержка протокола MRML
+Comment[sk]=Spustí démonov podľa požiadaviek a pri zlyhaní ich reštartuje
+Comment[sl]=Na zahtevo zažene demone in jih ob napaki znova zažene
+Comment[sr]=На захтев покреће демоне и поново их покреће ако се сруше
+Comment[sr@Latn]=Na zahtev pokreće demone i ponovo ih pokreće ako se sruše
+Comment[sv]=Starta demoner vid behov och starta om dem vid fel
+Comment[ta]=அவசிய நேரத்தில் டிமென்னை துவக்குகிறது. இயலாதபோது திரும்ப துவக்குகிறது
+Comment[tg]=Оғози демон аз рӯи дархост ва ҳангоми нуқсони он аз сари нав оғоз намудан.
+Comment[tr]=İstek halinde programı başlatır ve hata durumunda yeniden başlatır.
+Comment[uk]=Запускає демони при потребі та перезапускає їх при аварії
+Comment[zh_CN]=按需启动守护程序并在失败时重新启动
+Comment[zh_HK]=依要求啟動系統程式並在失敗時重新啟動它們。
+Comment[zh_TW]=需要時啟動守護程式,失敗的話重新啟動
+ServiceTypes=KDEDModule
+X-KDE-ModuleType=Library
+X-KDE-Library=daemonwatcher
+X-KDE-FactoryName=daemonwatcher
+X-KDE-Kded-load-on-demand=true
diff --git a/kmrml/kmrml/server/watcher.cpp b/kmrml/kmrml/server/watcher.cpp
new file mode 100644
index 00000000..e6137cc5
--- /dev/null
+++ b/kmrml/kmrml/server/watcher.cpp
@@ -0,0 +1,280 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 Carsten Pfeiffer <pfeiffer@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation, version 2.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <dcopclient.h>
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kdeversion.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+
+#include "watcher.h"
+
+using namespace KMrml;
+
+Watcher::Watcher( const QCString& name )
+ : KDEDModule( name )
+{
+ m_daemons.setAutoDelete( true );
+
+ // safety, for clients that die without unregistering
+ KApplication::dcopClient()->setNotifications( true );
+ connect( KApplication::dcopClient(),
+ SIGNAL( applicationRemoved( const QCString& )),
+ SLOT( slotAppUnregistered( const QCString& )));
+}
+
+Watcher::~Watcher()
+{
+ KApplication::dcopClient()->setNotifications( false );
+}
+
+bool Watcher::requireDaemon( const QCString& clientAppId,
+ const QString& daemonKey,
+ const QString& commandline,
+ uint timeout /* seconds */,
+ int restartOnFailure )
+{
+ if ( !KApplication::dcopClient()->isApplicationRegistered( clientAppId ) )
+ kdWarning() << "Watcher::requireDaemon: " << daemonKey
+ << ": Client AppID is not registered with DCOP: "
+ << clientAppId << endl;
+
+ DaemonData *daemon = m_daemons.find( daemonKey );
+
+ if ( daemon )
+ {
+ if ( !daemon->apps.find( clientAppId ) )
+ daemon->apps.append( clientAppId );
+
+ // timeout, commandline and restart values are: first come, first serve
+ return true; // process already running, all fine
+ }
+
+ else // start daemon
+ {
+ daemon = new DaemonData( daemonKey, commandline,
+ timeout, restartOnFailure );
+ m_daemons.insert( daemonKey, daemon );
+ daemon->apps.append( clientAppId );
+
+#if KDE_VERSION >= 306
+ daemon->process = new KProcess();
+ daemon->process->setUseShell( true );
+#else
+ daemon->process = new KShellProcess();
+#endif
+ daemon->process->setEnvironment( "LC_ALL", "C" );
+ daemon->process->setEnvironment( "LANG", "C" );
+ daemon->process->setEnvironment( "LANGUAGE", "C" );
+ *daemon->process << commandline;
+ connect( daemon->process, SIGNAL( processExited( KProcess * ) ),
+ SLOT( slotProcExited( KProcess * )));
+ return startDaemon( daemon );
+ }
+}
+
+void Watcher::unrequireDaemon( const QCString& clientAppId,
+ const QString& daemonKey )
+{
+ unrequireDaemon( m_daemons.find( daemonKey ), clientAppId );
+}
+
+void Watcher::unrequireDaemon( DaemonData *daemon,
+ const QCString& clientAppId )
+{
+ if ( daemon )
+ {
+ daemon->apps.remove( clientAppId );
+ if ( daemon->apps.isEmpty() )
+ {
+ if ( !daemon->timer )
+ {
+ daemon->timer = new QTimer();
+ connect( daemon->timer, SIGNAL( timeout() ),
+ SLOT( slotTimeout() ));
+ }
+ daemon->timer->start( daemon->timeout * 1000, true );
+ }
+ }
+ else
+ kdWarning() << "Watcher::unrequireDaemon: daemon unknown. client: "
+ << clientAppId << endl;
+}
+
+QStringList Watcher::runningDaemons() const
+{
+ QStringList result;
+ QDictIterator<DaemonData> it( m_daemons );
+ for ( ; it.current(); ++it )
+ result.append( it.current()->commandline );
+
+ return result;
+}
+
+void Watcher::slotProcExited( KProcess *proc )
+{
+ DaemonData *daemon = findDaemonFromProcess( proc );
+
+ if ( proc->normalExit() )
+ {
+ emitExited( daemon );
+ return;
+ }
+
+ if ( daemon )
+ {
+ if ( --daemon->restartOnFailure <= 0 )
+ {
+ if ( KMessageBox::questionYesNo( 0L,
+ i18n("<qt>The server with the command line"
+ "<br>%1<br>"
+ "is not available anymore. Do you want to "
+ "restart it?" ).arg( daemon->commandline ),
+ i18n("Service Failure"), i18n("Restart Server"), i18n("Do Not Restart") )
+ == KMessageBox::Yes )
+ {
+ daemon->restartOnFailure = 1;
+ }
+ }
+
+ if ( daemon->restartOnFailure > 0 )
+ {
+ startDaemon( daemon );
+ return;
+ }
+ }
+
+ emitFailure( daemon );
+}
+
+bool Watcher::startDaemon( DaemonData *daemon )
+{
+ if ( daemon->process->start( KProcess::NotifyOnExit ) )
+ return true;
+
+ else
+ {
+ if ( KMessageBox::questionYesNo( 0L,
+ i18n("Unable to start the server with the "
+ "command line"
+ "<br>%1<br>"
+ "Try again?").arg( daemon->commandline ),
+ i18n("Service Failure"), i18n("Try Again"), i18n("Do Not Try") )
+ == KMessageBox::Yes )
+ {
+ return startDaemon( daemon );
+ }
+ }
+
+ return false;
+}
+
+void Watcher::slotTimeout()
+{
+ QTimer *timer = static_cast<QTimer*>( const_cast<QObject *>( sender() ) );
+ DaemonData *daemon = findDaemonFromTimer( timer );
+ if ( daemon )
+ {
+ if ( daemon->apps.isEmpty() )
+ {
+ // the daemon and KProcess might get deleted by killing the
+ // KProcess (through slotProcExited()), so don't dereference
+ // daemon after proc->kill()
+ QString key = daemon->daemonKey;
+
+ // noone registered during the timeout, so kill the daemon
+ if ( !daemon->process->kill() )
+ daemon->process->kill( SIGKILL );
+
+ m_daemons.remove( key );
+ }
+ }
+}
+
+DaemonData * Watcher::findDaemonFromProcess( KProcess *proc )
+{
+ DaemonData *daemon;
+ QDictIterator<DaemonData> it( m_daemons );
+ for ( ; (daemon = it.current()); ++it )
+ {
+ if ( daemon->process == proc )
+ return daemon;
+ }
+
+ return 0L;
+}
+
+DaemonData * Watcher::findDaemonFromTimer( QTimer *timer )
+{
+ DaemonData *daemon;
+ QDictIterator<DaemonData> it( m_daemons );
+ for ( ; (daemon = it.current()); ++it )
+ {
+ if ( daemon->timer == timer )
+ return daemon;
+ }
+
+ return 0L;
+}
+
+void Watcher::slotAppUnregistered( const QCString& appId )
+{
+ if ( m_daemons.isEmpty() )
+ return;
+
+ DaemonData *daemon;
+ QDictIterator<DaemonData> it( m_daemons );
+ for ( ; (daemon = it.current()); ++it )
+ {
+ if ( daemon->apps.find( appId ) != -1 )
+ unrequireDaemon( daemon, appId );
+ }
+}
+
+void Watcher::emitExited( DaemonData *daemon )
+{
+ if ( daemon )
+ {
+ daemonExited( daemon->daemonKey,
+ daemon->process->pid(),
+ daemon->process->exitStatus() );
+
+ m_daemons.remove( daemon->daemonKey );
+ }
+}
+
+void Watcher::emitFailure( DaemonData *daemon )
+{
+ if ( daemon )
+ {
+ daemonDied( daemon->daemonKey, daemon->process->pid() );
+ m_daemons.remove( daemon->daemonKey ); // deletes daemon + KProcess
+ }
+}
+
+extern "C" {
+ KDE_EXPORT KDEDModule *create_daemonwatcher(const QCString & obj )
+ {
+ return new Watcher( obj );
+ }
+}
+
+
+#include "watcher.moc"
diff --git a/kmrml/kmrml/server/watcher.h b/kmrml/kmrml/server/watcher.h
new file mode 100644
index 00000000..67d9b5e1
--- /dev/null
+++ b/kmrml/kmrml/server/watcher.h
@@ -0,0 +1,107 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 Carsten Pfeiffer <pfeiffer@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation, version 2.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef LAUNCHER_H
+#define LAUNCHER_H
+
+#include <qdict.h>
+#include <qmap.h>
+#include <qstrlist.h>
+#include <qstringlist.h>
+#include <qtimer.h>
+
+#include <kdedmodule.h>
+#include <kprocess.h>
+
+namespace KMrml
+{
+ class DaemonData
+ {
+ public:
+ DaemonData( const QString& key, const QString& cmd,
+ uint time, int numRestarts )
+ : daemonKey( key ),
+ commandline( cmd ),
+ timeout( time ),
+ apps( true ), // deep copies
+ restartOnFailure( numRestarts ),
+ process( 0L ),
+ timer( 0L )
+ {
+ }
+ ~DaemonData()
+ {
+ delete process;
+ delete timer;
+ }
+ QString daemonKey;
+ QString commandline;
+ uint timeout;
+ QStrList apps;
+ int restartOnFailure;
+ KProcess *process;
+ QTimer *timer;
+ };
+
+ class Watcher : public KDEDModule
+ {
+ Q_OBJECT
+ K_DCOP
+
+ public:
+ Watcher( const QCString& name = "daemonwatcher" );
+ ~Watcher();
+
+ k_dcop:
+ virtual bool requireDaemon( const QCString& clientAppId,
+ const QString& daemonKey,
+ const QString& commandline,
+ uint timeout = 60 /* seconds */,
+ int numRestarts = 5 );
+ virtual void unrequireDaemon( const QCString& clientAppId,
+ const QString& daemonKey );
+ virtual QStringList runningDaemons() const;
+
+ k_dcop_signals:
+ void daemonExited(const QString& daemonKey, pid_t pid, int exitStatus);
+ void daemonDied( const QString& daemonKey, pid_t pid );
+
+ protected:
+ bool startDaemon( DaemonData *daemon );
+
+ protected slots:
+ virtual void slotTimeout();
+
+ private:
+ void unrequireDaemon( DaemonData *daemon, const QCString& clientAppId);
+ DaemonData *findDaemonFromProcess( KProcess *proc );
+ DaemonData *findDaemonFromTimer( QTimer *timer );
+
+ void emitExited( DaemonData *daemon );
+ void emitFailure( DaemonData *daemon );
+
+ private slots:
+ void slotProcExited( KProcess *proc );
+ void slotAppUnregistered( const QCString& appId );
+
+ QDict<DaemonData> m_daemons;
+ };
+
+}
+
+#endif // LAUNCHER_H