Hello community,
here is the log from the commit of package PolicyKit-kde
checked in at Mon Nov 3 14:18:05 CET 2008.
--------
--- KDE/PolicyKit-kde/PolicyKit-kde.changes 2008-05-20 11:13:31.000000000 +0200
+++ /mounts/work_src_done/STABLE/PolicyKit-kde/PolicyKit-kde.changes 2008-10-29 21:13:10.858570000 +0100
@@ -1,0 +2,5 @@
+Wed Oct 29 18:36:47 CET 2008 - llunak@suse.cz
+
+- update to 0.2, which actually can authorize (bnc#389415)
+
+-------------------------------------------------------------------
calling whatdependson for head-i586
Old:
----
PolicyKit-kde-0.0.svn810196.tar.bz2
New:
----
PolicyKit-kde-0.2.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ PolicyKit-kde.spec ++++++
--- /var/tmp/diff_new_pack.z12872/_old 2008-11-03 14:17:45.000000000 +0100
+++ /var/tmp/diff_new_pack.z12872/_new 2008-11-03 14:17:45.000000000 +0100
@@ -1,10 +1,17 @@
#
-# spec file for package PolicyKit-kde (Version 0.0.svn810196)
+# spec file for package PolicyKit-kde (Version 0.2)
#
# Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany.
-# This file and all modifications and additions to the pristine
-# package are under the same license as the package itself.
#
+# All modifications and additions to the file contributed by third parties
+# remain the property of their copyright owners, unless otherwise agreed
+# upon. The license for this file, and modifications and additions to the
+# file, is the same license as for the pristine package itself (unless the
+# license for the pristine package is not an Open Source License, in which
+# case the license is the MIT License). An "Open Source License" is a
+# license that conforms to the Open Source Definition (Version 1.9)
+# published by the Open Source Initiative.
+
# Please submit bugfixes or comments via http://bugs.opensuse.org/
#
@@ -18,7 +25,7 @@
Group: System/GUI/KDE
Summary: PolicyKit Authentication Agent for KDE
BuildRoot: %{_tmppath}/%{name}-%{version}-build
-Version: 0.0.svn810196
+Version: 0.2
Release: 1
Source0: %name-%{version}.tar.bz2
%kde4_runtime_requires
@@ -34,7 +41,7 @@
Dirk Mueller
%prep
-%setup -q
+%setup -q -n PolicyKit-kde-%version
%build
%cmake_kde4 -d build
@@ -51,9 +58,11 @@
/usr/share/autostart/policykit-kde.desktop
%changelog
+* Wed Oct 29 2008 llunak@suse.cz
+- update to 0.2, which actually can authorize (bnc#389415)
* Tue May 20 2008 llunak@suse.cz
- don't restart one more additional instance every login
-* Wed May 14 2008 dmueller@suse.de
+* Tue May 13 2008 dmueller@suse.de
- add missing runtime requires
* Sun Apr 13 2008 dmueller@suse.de
- Initial package
++++++ PolicyKit-kde-0.0.svn810196.tar.bz2 -> PolicyKit-kde-0.2.tar.bz2 ++++++
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/PolicyKit-kde-0.0.svn810196/policykit-kde.desktop new/PolicyKit-kde-0.2/policykit-kde.desktop
--- old/PolicyKit-kde-0.0.svn810196/policykit-kde.desktop 2008-04-24 18:01:37.000000000 +0200
+++ new/PolicyKit-kde-0.2/policykit-kde.desktop 2008-10-21 13:53:30.000000000 +0200
@@ -9,7 +9,17 @@
X-KDE-StartupNotify=false
X-DBUS-StartupType=Unique
GenericName=PolicyKit Authentication Agent
+GenericName[el]=Πελάτης ταυτοποίησης PolicyKit
GenericName[et]=PolicyKiti autentimisagent
-GenericName[sv]=Policykit agent för behörighetskontroll
+GenericName[fr]=Agent d'authentification PolicyKit
+GenericName[gl]=Cliente de autenticación de PolicyKit
+GenericName[km]=hភ្នាក់ងារការផ្ទៀងផ្ទាត់ភាពត្រឹមត្រូវរបស់ PolicyKit
+GenericName[pt]=Agente de Autenticação do PolicyKit
+GenericName[pt_BR]=Agente de Autenticação do PolicyKit
+GenericName[sv]=Policykit-modul för behörighetskontroll
+GenericName[tr]=PolicyKit Kimlik Doğrulama Uygulaması
+GenericName[uk]=Агент автентифікації PolicyKit
+GenericName[x-test]=xxPolicyKit Authentication Agentxx
Name=PolicyKit-KDE
Name[sv]=Policykit-KDE
+Name[x-test]=xxPolicyKit-KDExx
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/PolicyKit-kde-0.0.svn810196/src/authdialog.cpp new/PolicyKit-kde-0.2/src/authdialog.cpp
--- old/PolicyKit-kde-0.0.svn810196/src/authdialog.cpp 2008-04-12 02:06:13.000000000 +0200
+++ new/PolicyKit-kde-0.2/src/authdialog.cpp 2008-10-29 18:25:13.000000000 +0100
@@ -41,8 +41,7 @@
* The dialog will by default be modeless, unless you set 'modal' to
* TRUE to construct a modal dialog.
*/
-AuthDialog::AuthDialog( const QString &header,
- PolKitResult type)
+AuthDialog::AuthDialog( const QString &header, const QPixmap& pix, const QString& vendor, const KUrl& vendorUrl )
: KDialog(0), AuthDialogUI()
{
setButtons(Ok|Cancel);
@@ -52,99 +51,78 @@
setupUi(w);
setMainWidget(w);
- if (type == POLKIT_RESULT_UNKNOWN || \
- type == POLKIT_RESULT_NO || \
- type == POLKIT_RESULT_YES || \
- type == POLKIT_RESULT_N_RESULTS )
- kDebug() << "Unexpected PolkitResult type sent: " << polkit_result_to_string_representation(type);
-
- KIconLoader* iconloader = KIconLoader::global();
- lblPixmap->setPixmap(iconloader->loadIcon("dialog-password", KIconLoader::NoGroup,
- KIconLoader::SizeHuge));
-
+ lblPixmap->setPixmap( pix );
+ // TODO vendor info
cbUsers->hide();
-
- setType(type);
- setHeader(header);
- setContent();
+ lePassword->setFocus();
+ setHeader( header );
}
AuthDialog::~AuthDialog()
{
}
-void AuthDialog::setHeader(const QString &header)
+void AuthDialog::accept()
{
- lblHeader->setText("<h3>" + header + "</h3>");
+ // Do nothing, do not close the dialog. This is needed so that the dialog stays
+ return;
}
-void AuthDialog::setContent(const QString &msg)
+void AuthDialog::setHeader(const QString &header)
{
- lblContent->setText(msg);
+ lblHeader->setText("<h3>" + header + "</h3>");
}
-// set content according to m_type, that is a PolKitResult
-void AuthDialog::setContent()
+void AuthDialog::setContent(const QString &msg)
{
- QString msg;
- switch(m_type)
- {
- //TODO: Authentication as one of the users below...
- case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH:
- case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_SESSION:
- case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_ALWAYS:
- msg = i18n("An application is attempting to perform an action that requires privileges."
- " Authentication as the super user is required to perform this action.");
- break;
- default:
- msg = i18n("An application is attempting to perform an action that requires privileges."
- " Authentication is required to perform this action.");
-
- }
lblContent->setText(msg);
}
-
-void AuthDialog::showUsersCombo()
+void AuthDialog::setPasswordPrompt(const QString& prompt)
{
- cbUsers->show();
+ lblPassword->setText( prompt );
}
-void AuthDialog::hideUsersCombo()
+QString AuthDialog::password() const
{
- cbUsers->hide();
+ return lePassword->text();
}
-void AuthDialog::setPasswordFor(bool set, const QString& user)
+void AuthDialog::clearPassword()
{
- if (set)
- lblPassword->setText(i18n("Password for root") + ":");
- else if (!user.isEmpty())
- lblPassword->setText(i18n("Password for user(%1)").arg(user) + ":");
- else
- lblPassword->setText(i18n("Password") + ":");
+ lePassword->clear();
}
-void AuthDialog::setType(PolKitResult res)
+void AuthDialog::showKeepPassword( KeepPassword keep )
{
- if (res == POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH || \
- res == POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_SESSION || \
- res == POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_ALWAYS)
- setPasswordFor(true);
-
- if (res == POLKIT_RESULT_ONLY_VIA_SELF_AUTH || \
- res == POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION || \
- res == POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS)
- setPasswordFor(false);
-
- if (res == POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH || res == POLKIT_RESULT_ONLY_VIA_SELF_AUTH)
+ switch( keep )
{
- cbRemember->hide();
- cbSession->hide();
+ case KeepPasswordNo:
+ cbRemember->hide();
+ cbSessionOnly->hide();
+ break;
+ case KeepPasswordSession:
+ cbRemember->setText( i18n( "Remember authorization for this session" ));
+ cbRemember->show();
+ cbSessionOnly->hide();
+ break;
+ case KeepPasswordAlways:
+ cbRemember->setText( i18n( "Remember authorization" ));
+ cbRemember->show();
+ cbSessionOnly->show();
+ break;
}
+}
- if (res == POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_SESSION || res == POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION)
- cbRemember->hide();
-
- m_type = res;
+KeepPassword AuthDialog::keepPassword() const
+{
+ if( cbRemember->isHidden()) // cannot make it keep
+ return KeepPasswordNo;
+ if( cbSessionOnly->isHidden()) // can keep only for session
+ return cbRemember->isChecked() ? KeepPasswordSession : KeepPasswordNo;
+ // can keep either way
+ if( cbRemember->isChecked())
+ return cbSessionOnly->isChecked() ? KeepPasswordSession : KeepPasswordAlways;
+ return KeepPasswordNo;
}
+
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/PolicyKit-kde-0.0.svn810196/src/authdialog.h new/PolicyKit-kde-0.2/src/authdialog.h
--- old/PolicyKit-kde-0.0.svn810196/src/authdialog.h 2008-04-12 02:06:13.000000000 +0200
+++ new/PolicyKit-kde-0.2/src/authdialog.h 2008-10-29 18:25:13.000000000 +0100
@@ -27,21 +27,22 @@
#include "ui_authdialogui.h"
+#include "policykitkde.h"
+
class AuthDialog : public KDialog, public Ui::AuthDialogUI
{
public:
- AuthDialog( const QString &header, PolKitResult type);
+ AuthDialog( const QString &header, const QPixmap& pix, const QString& vendor, const KUrl& vendorUrl );
~AuthDialog();
- void setType(PolKitResult type);
- void setContent(const QString &);
- void setContent();
- void setHeader(const QString &);
-
-private:
- void showUsersCombo();
- void hideUsersCombo();
- void setPasswordFor(bool set, const QString& user = NULL);
- PolKitResult m_type;
+ void setHeader( const QString& header );
+ void setContent( const QString& content );
+ void setPasswordPrompt( const QString& prompt );
+ void showKeepPassword( KeepPassword keep );
+ QString password() const;
+ void clearPassword();
+ KeepPassword keepPassword() const;
+public slots:
+ virtual void accept();
};
#endif // AUTHDIALOG_H
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/PolicyKit-kde-0.0.svn810196/src/authdialogui.ui new/PolicyKit-kde-0.2/src/authdialogui.ui
--- old/PolicyKit-kde-0.0.svn810196/src/authdialogui.ui 2008-04-12 02:06:13.000000000 +0200
+++ new/PolicyKit-kde-0.2/src/authdialogui.ui 2008-10-29 16:14:46.000000000 +0100
@@ -64,7 +64,7 @@
<item>
<widget class="QLabel" name="lblContent" >
<property name="text" >
- <string>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</string>
+ <string/>
</property>
<property name="alignment" >
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
@@ -104,7 +104,7 @@
</spacer>
</item>
<item>
- <widget class="QCheckBox" name="cbSession" >
+ <widget class="QCheckBox" name="cbSessionOnly" >
<property name="enabled" >
<bool>false</bool>
</property>
@@ -168,8 +168,9 @@
</customwidgets>
<tabstops>
<tabstop>cbUsers</tabstop>
+ <tabstop>lePassword</tabstop>
<tabstop>cbRemember</tabstop>
- <tabstop>cbSession</tabstop>
+ <tabstop>cbSessionOnly</tabstop>
</tabstops>
<includes>
<include location="local" >kcombobox.h</include>
@@ -179,7 +180,7 @@
<connection>
<sender>cbRemember</sender>
<signal>toggled(bool)</signal>
- <receiver>cbSession</receiver>
+ <receiver>cbSessionOnly</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/PolicyKit-kde-0.0.svn810196/src/CMakeLists.txt new/PolicyKit-kde-0.2/src/CMakeLists.txt
--- old/PolicyKit-kde-0.0.svn810196/src/CMakeLists.txt 2008-04-12 02:06:13.000000000 +0200
+++ new/PolicyKit-kde-0.2/src/CMakeLists.txt 2008-10-29 11:24:37.000000000 +0100
@@ -8,6 +8,7 @@
set(policykit_SRCS
authdialog.cpp
policykitkde.cpp
+ processwatcher.cpp
main.cpp
)
@@ -17,6 +18,6 @@
kde4_add_ui_files(policykit_SRCS authdialogui.ui)
kde4_add_executable(policykit-kde ${policykit_SRCS})
-target_link_libraries(policykit-kde ${KDE4_KDEUI_LIBS} ${QT_QT3SUPPORT_LIBRARY} polkit-dbus)
+target_link_libraries(policykit-kde ${KDE4_KDEUI_LIBS} ${QT_QT3SUPPORT_LIBRARY} polkit-dbus polkit-grant)
install(TARGETS policykit-kde DESTINATION ${INSTALL_TARGETS_DEFAULT_ARGS})
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/PolicyKit-kde-0.0.svn810196/src/main.cpp new/PolicyKit-kde-0.2/src/main.cpp
--- old/PolicyKit-kde-0.0.svn810196/src/main.cpp 2008-05-20 10:52:39.000000000 +0200
+++ new/PolicyKit-kde-0.2/src/main.cpp 2008-10-29 18:46:01.000000000 +0100
@@ -31,11 +31,12 @@
int main (int argc, char *argv[])
{
- KAboutData aboutData( "policykit-kde", "", ki18n( "PolicyKit-kde" ), "0.1",
+ KAboutData aboutData( "policykit-kde", "", ki18n( "PolicyKit-kde" ), "0.2",
ki18n( "PolicyKit-kde" ), KAboutData::License_GPL,
ki18n( "(c) 2005-2007, TUBITAK - UEKAE" ) );
aboutData.addAuthor( ki18n("Gökçen Eraslan"), ki18n( "KDE 3 Code" ), "gokcen@pardus.org.tr" );
aboutData.addAuthor( ki18n("Dirk Müller"), ki18n( "Author" ), "mueller@kde.org" );
+ aboutData.addAuthor( ki18n("Luboš Luňák"), ki18n( "Developer" ), "l.lunak@kde.org" );
KCmdLineArgs::init( argc, argv, &aboutData );
KApplication app;
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/PolicyKit-kde-0.0.svn810196/src/policykitkde.cpp new/PolicyKit-kde-0.2/src/policykitkde.cpp
--- old/PolicyKit-kde-0.0.svn810196/src/policykitkde.cpp 2008-04-12 00:50:34.000000000 +0200
+++ new/PolicyKit-kde-0.2/src/policykitkde.cpp 2008-10-29 19:13:01.000000000 +0100
@@ -1,6 +1,7 @@
/* This file is part of the KDE project
Copyright (C) 2007-2008 Gökçen Eraslan
Copyright (C) 2008 Dirk Mueller
+ Copyright (C) 2008 Lubos Lunak
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
@@ -22,9 +23,12 @@
#include "policykitkde.h"
#include "authenticationagentadaptor.h"
-#include
+#include
+#include
#include
#include
+#include
+#include
#include "qdbusconnection.h"
@@ -33,8 +37,10 @@
//policykit header
#include
+#include
#include "authdialog.h"
+#include "processwatcher.h"
PolicyKitKDE* PolicyKitKDE::m_self;
@@ -42,10 +48,10 @@
PolicyKitKDE::PolicyKitKDE(QObject* parent)
: QObject(parent)
+ , inProgress( false )
{
Q_ASSERT(!m_self);
m_self = this;
- m_error = 0;
(void) new AuthenticationAgentAdaptor(this);
if (!QDBusConnection::sessionBus().registerService("org.freedesktop.PolicyKit.AuthenticationAgent"))
@@ -53,7 +59,6 @@
if (!QDBusConnection::sessionBus().registerObject("/", this)) {
kError() << "unable to register service interface to dbus";
-
}
m_context = polkit_context_new();
@@ -63,26 +68,27 @@
return;
}
- //TODO: handle name owner changed signal
-
polkit_context_set_load_descriptions(m_context);
- //TODO: polkit_context_set_config_changed
- //TODO: polkit_context_set_io_watch_functions
-
- polkit_context_set_io_watch_functions (m_context, polkit_add_watch, polkit_remove_watch);
+#if 0 // TODO Does not seem to be needed?
+ polkit_context_set_config_changed( m_context, polkit_config_changed, NULL );
+ polkit_context_set_io_watch_functions (m_context, add_io_watch, remove_io_watch);
+#endif
- if (!polkit_context_init (m_context, &m_error))
+ PolKitError* error = NULL;
+ if (!polkit_context_init (m_context, &error))
{
QString msg("Could not initialize PolKitContext");
- if (polkit_error_is_set(m_error))
+ if (polkit_error_is_set(error))
{
- kError() << msg << ": " << polkit_error_get_error_message(m_error);
+ kError() << msg << ": " << polkit_error_get_error_message(error);
+ polkit_error_free( error );
}
else
kError() << msg;
}
- //TODO: add kill_timer
+ //TODO: polkit_tracker?
+ //TODO: add kill_timer?
}
//----------------------------------------------------------------------------
@@ -92,66 +98,49 @@
m_self = 0L;
}
-
-//----------------------------------------------------------------------------
-
-void PolicyKitKDE::watchActivated(int fd)
-{
- Q_ASSERT(m_watches.contains(fd));
-
- kDebug() << "watchActivated" << fd;
-
- polkit_context_io_func (m_context, fd);
-}
-
-//----------------------------------------------------------------------------
-
-int PolicyKitKDE::polkit_add_watch(PolKitContext *context, int fd)
-{
- kDebug() << "polkit_add_watch" << context << fd;
- //TODO: delete notify
-
- QSocketNotifier *notify = new QSocketNotifier(fd, QSocketNotifier::Read);
- m_self->m_watches[fd] = notify;
-
- notify->connect(notify, SIGNAL(activated(int)), m_self, SLOT(watchActivated(int)));
-
- return 0;
-}
-
-
-//----------------------------------------------------------------------------
-
-void PolicyKitKDE::polkit_remove_watch(PolKitContext *context, int fd)
-{
- kDebug() << "polkit_remove_watch" << context << fd;
- Q_ASSERT(m_self->m_watches.contains(fd));
-
- QSocketNotifier* notify = m_self->m_watches.take(fd);
- delete notify;
-}
-
//----------------------------------------------------------------------------
bool PolicyKitKDE::ObtainAuthorization(const QString& actionId, uint wid, uint pid)
{
- PolKitError *error = NULL;
+ kDebug() << "Start obtain authorization:" << actionId << wid << pid;
+
+ if( inProgress )
+ {
+ // TODO this is lame
+ sendErrorReply( "pk_auth_in_progress",
+ i18n( "Another client is already authenticating, please try again later." ));
+ return false;
+ }
+ inProgress = true;
+ obtainedPrivilege = false;
+ requireAdmin = false;
+ keepPassword = KeepPasswordNo;
+ cancelled = false;
- PolKitAction *action = polkit_action_new();
+ action = polkit_action_new();
if (action == NULL)
{
kError() << "Could not create new polkit action.";
return false;
}
-
- polkit_bool_t setActionResult = polkit_action_set_action_id(action, actionId.toLatin1());
- if (!setActionResult)
+ if( !polkit_action_set_action_id(action, actionId.toLatin1()))
{
kError() << "Could not set actionid.";
return false;
}
+ DBusError dbuserror;
+ dbus_error_init (&dbuserror);
+ DBusConnection *bus = dbus_bus_get (DBUS_BUS_SYSTEM, &dbuserror);
+ caller = polkit_caller_new_from_pid(bus, pid, &dbuserror);
+ if (caller == NULL)
+ {
+ kError() << QString("Could not define caller from pid: %1")
+ .arg(QDBusError((const DBusError *)&dbuserror).message());
+ // TODO this all leaks and is probably pretty paranoid
+ return false;
+ }
+ dbus_connection_unref( bus );
- kError() << "Getting policy cache...";
PolKitPolicyCache *cache = polkit_context_get_policy_cache(m_context);
if (cache == NULL)
{
@@ -168,55 +157,319 @@
}
kDebug() << "Getting action message...";
- QByteArray message = polkit_policy_file_entry_get_action_message(entry);
- if (message.isEmpty())
+ QString actionMessage = QString::fromLocal8Bit(polkit_policy_file_entry_get_action_message(entry));
+ if( actionMessage.isEmpty())
{
kWarning() << "Could not get action message for action.";
// return false;
}
else
{
- kDebug() << "Message of action: " << message;
+ kDebug() << "Message of action: " << actionMessage;
}
+ QString vendor = polkit_policy_file_entry_get_action_vendor( entry );
+ KUrl vendorUrl( polkit_policy_file_entry_get_action_vendor_url( entry ));
+ QPixmap icon = KIconLoader::global()->loadIcon( polkit_policy_file_entry_get_action_icon_name( entry ),
+ KIconLoader::NoGroup, KIconLoader::SizeHuge, KIconLoader::DefaultState, QStringList(), NULL, true );
+ if( icon.isNull())
+ icon = KIconLoader::global()->loadIcon( "dialog-password",
+ KIconLoader::NoGroup, KIconLoader::SizeHuge );
+
+ dialog = new AuthDialog( actionMessage, icon, vendor, vendorUrl );
+ connect( dialog, SIGNAL( okClicked()), SLOT( dialogAccepted()));
+ connect( dialog, SIGNAL( cancelClicked()), SLOT( dialogCancelled()));
+ if( wid != 0 )
+ KWindowSystem::setMainWindow( dialog, wid );
+ else
+ kapp->updateUserTimestamp(); // make it get focus unconditionally :-/
+ parent_wid = wid;
- DBusError dbuserror;
- dbus_error_init (&dbuserror);
- DBusConnection *bus = dbus_bus_get (DBUS_BUS_SYSTEM, &dbuserror);
- if (bus == NULL)
+ grant = polkit_grant_new();
+ polkit_grant_set_functions( grant, add_io_watch, add_child_watch, remove_watch,
+ conversation_type, conversation_select_admin_user, conversation_pam_prompt_echo_off,
+ conversation_pam_prompt_echo_on, conversation_pam_error_msg, conversation_pam_text_info,
+ conversation_override_grant_type, conversation_done, this );
+ if( !polkit_grant_initiate_auth( grant, action, caller ))
{
- kError() << "Could not connect to system bus.";
+ kError() << "Failed to initiate privilege grant.";
return false;
}
+ mes = message();
+ setDelayedReply( true );
+ return false;
+}
- PolKitCaller *caller = polkit_caller_new_from_pid(bus, pid, &dbuserror);
- if (caller == NULL)
- {
- QDBusError *qerror = new QDBusError((const DBusError *)&dbuserror);
- kError() << QString("Could not define caller from pid: %1").arg(qerror->message());
- return false;
+void PolicyKitKDE::finishObtainPrivilege()
+{
+ assert( inProgress );
+ polkit_grant_unref( grant );
+ if( dialog->isVisible() && !cancelled && !obtainedPrivilege )
+ {
+ dialog->clearPassword();
+ // TODO this should probably just show it directly in the dialog, like KPasswordDialog does
+ KMessageBox::sorry( dialog, i18n( "Incorrect password, please try again." ));
+ grant = polkit_grant_new();
+ polkit_grant_set_functions( grant, add_io_watch, add_child_watch, remove_watch,
+ conversation_type, conversation_select_admin_user, conversation_pam_prompt_echo_off,
+ conversation_pam_prompt_echo_on, conversation_pam_error_msg, conversation_pam_text_info,
+ conversation_override_grant_type, conversation_done, this );
+ if( !polkit_grant_initiate_auth( grant, action, caller ))
+ {
+ kError() << "Failed to initiate privilege grant.";
+ }
+ return;
}
+ polkit_caller_unref( caller );
+ polkit_action_unref( action );
+ dialog->deleteLater();
+ inProgress = false;
+ kdDebug() << "Finish obtain authorization:" << obtainedPrivilege;
+ QDBusConnection::sessionBus().send( mes.createReply( obtainedPrivilege ));
+}
- PolKitResult polkitresult;
+void PolicyKitKDE::conversation_type( PolKitGrant* grant, PolKitResult type, void* )
+{
+ kDebug() << "conversation_type" << grant << type;
+ m_self->requireAdmin = false;
+ m_self->keepPassword = KeepPasswordNo;
+ switch( type )
+ {
+ case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_ONE_SHOT:
+ case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH:
+ m_self->requireAdmin = true;
+ break;
+ case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_SESSION:
+ m_self->requireAdmin = true;
+ m_self->keepPassword = KeepPasswordSession;
+ break;
+ case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_ALWAYS:
+ m_self->requireAdmin = true;
+ m_self->keepPassword = KeepPasswordAlways;
+ break;
+ case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_ONE_SHOT:
+ case POLKIT_RESULT_ONLY_VIA_SELF_AUTH:
+ break;
+ case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION:
+ m_self->keepPassword = KeepPasswordSession;
+ break;
+ case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS:
+ m_self->keepPassword = KeepPasswordAlways;
+ break;
+ default:
+ abort();
+ }
+}
- polkitresult = polkit_context_is_caller_authorized(m_context, action, caller, false, &error);
- if (polkit_error_is_set (error))
+char* PolicyKitKDE::conversation_select_admin_user(PolKitGrant* grant, char** users, void* )
+{
+ kDebug() << "conversation_select_admin_user" << grant << users[ 0 ];
+ return strdup( users[ 0 ] ); // TODO
+}
+
+char* PolicyKitKDE::conversation_pam_prompt_echo_off(PolKitGrant* grant, const char* request, void* )
+{
+ kDebug() << "conversation_pam_prompt_echo_off" << grant << request;
+ if( m_self->requireAdmin )
{
- kError() << "Could not determine if caller is authorized for this action.";
- return false;
+ m_self->dialog->setContent( i18n("An application is attempting to perform an action that requires privileges."
+ " Authentication as the super user is required to perform this action." ));
+ m_self->dialog->setPasswordPrompt( i18n("Password for root") + ":" );
}
+ else
+ {
+ m_self->dialog->setContent( i18n("An application is attempting to perform an action that requires privileges."
+ " Authentication is required to perform this action." ));
+ m_self->dialog->setPasswordPrompt( i18n("Password") + ":" );
+ }
+ m_self->dialog->showKeepPassword( m_self->keepPassword );
+ m_self->dialog->show();
+ QEventLoop loop;
+ connect( m_self->dialog, SIGNAL( okClicked()), &loop, SLOT( quit()));
+ connect( m_self->dialog, SIGNAL( cancelClicked()), &loop, SLOT( quit()));
+ loop.exec(); // TODO this really sucks, policykit API is blocking
+ if( m_self->cancelled )
+ return NULL;
+ return strdup( m_self->dialog->password().toLocal8Bit());
+}
- //TODO: Determine AdminAuthType, user, group...
+void PolicyKitKDE::dialogAccepted()
+{
+ m_self->keepPassword = dialog->keepPassword();
+ kDebug() << "Password dialog confirmed.";
+}
- AuthDialog* dia = new AuthDialog(message, polkitresult);
- dia->exec();
+void PolicyKitKDE::dialogCancelled()
+{
+ m_self->cancelled = true;
+ kDebug() << "Password dialog cancelled.";
+ polkit_grant_cancel_auth( grant );
+}
- // check again if user is authorized
- polkitresult = polkit_context_is_caller_authorized(m_context, action, caller, false, &error);
- if (polkit_error_is_set (error))
- {
- kError() << "Could not determine if caller is authorized for this action.";
- return false;
+char* PolicyKitKDE::conversation_pam_prompt_echo_on(PolKitGrant* grant, const char* request, void* )
+{
+ kDebug() << "conversation_pam_prompt_echo_on" << grant << request;
+ return strdup( "test" );
+}
+
+void PolicyKitKDE::conversation_pam_error_msg(PolKitGrant* grant, const char* msg, void* )
+{
+ kDebug() << "conversation_pam_error_msg" << grant << msg;
+ KMessageBox::errorWId( m_self->dialog->isVisible() ? m_self->dialog->winId() : m_self->parent_wid,
+ QString::fromLocal8Bit( msg ));
+}
+
+void PolicyKitKDE::conversation_pam_text_info(PolKitGrant* grant, const char* msg, void* )
+{
+ kDebug() << "conversation_pam_text_info" << grant << msg;
+ KMessageBox::informationWId( m_self->dialog->isVisible() ? m_self->dialog->winId() : m_self->parent_wid,
+ QString::fromLocal8Bit( msg ));
+}
+
+PolKitResult PolicyKitKDE::conversation_override_grant_type(PolKitGrant* grant, PolKitResult type, void* )
+{
+ kDebug() << "conversation_override_grant_type" << grant << type;
+ bool keep_session = false;
+ bool keep_always = false;
+ switch( type )
+ {
+ case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_ONE_SHOT:
+ case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_ONE_SHOT:
+ case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH:
+ case POLKIT_RESULT_ONLY_VIA_SELF_AUTH:
+ break;
+ case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_SESSION:
+ case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION:
+ if( m_self->keepPassword == KeepPasswordSession )
+ keep_session = true;
+ break;
+ case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_ALWAYS:
+ case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS:
+ if( m_self->keepPassword == KeepPasswordAlways )
+ keep_always = true;
+ else if( m_self->keepPassword == KeepPasswordSession )
+ keep_session = true;
+ break;
+ default:
+ abort();
+ }
+ kDebug() << "Keep password, session:" << keep_session << ", always:" << keep_always;
+ PolKitResult ret;
+ switch( type )
+ {
+ case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_ONE_SHOT:
+ case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH:
+ case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_SESSION:
+ case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_ALWAYS:
+ if( keep_session )
+ ret = POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_SESSION;
+ else if( keep_always )
+ ret = POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_ALWAYS;
+ else
+ ret = POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH;
+ break;
+ case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_ONE_SHOT:
+ case POLKIT_RESULT_ONLY_VIA_SELF_AUTH:
+ case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION:
+ case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS:
+ if( keep_session )
+ ret = POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION;
+ else if( keep_always )
+ ret = POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS;
+ else
+ ret = POLKIT_RESULT_ONLY_VIA_SELF_AUTH;
+ break;
+ default:
+ abort();
}
+ return ret;
+}
- return false;
+void PolicyKitKDE::conversation_done(PolKitGrant* grant, polkit_bool_t obtainedPrivilege,
+ polkit_bool_t invalidData, void* )
+{
+ kDebug() << "conversation_done" << grant << obtainedPrivilege << invalidData;
+ m_self->obtainedPrivilege = obtainedPrivilege;
+ QTimer::singleShot( 0, m_self, SLOT( finishObtainPrivilege()));
+}
+
+//----------------------------------------------------------------------------
+
+void PolicyKitKDE::watchActivated(int fd)
+{
+ Q_ASSERT(m_watches.contains(fd));
+
+// kDebug() << "watchActivated" << fd;
+
+ polkit_grant_io_func (grant, fd);
+}
+
+//----------------------------------------------------------------------------
+
+int PolicyKitKDE::add_io_watch(PolKitGrant* grant, int fd)
+{
+ kDebug() << "add_watch" << grant << fd;
+
+ QSocketNotifier *notify = new QSocketNotifier(fd, QSocketNotifier::Read, m_self);
+ m_self->m_watches[fd] = notify;
+
+ notify->connect(notify, SIGNAL(activated(int)), m_self, SLOT(watchActivated(int)));
+
+ return fd; // use simply the fd as the unique id for the watch
+}
+
+
+//----------------------------------------------------------------------------
+
+void PolicyKitKDE::remove_io_watch(PolKitGrant* grant, int id)
+{
+ assert( id > 0 );
+ kDebug() << "remove_watch" << grant << id;
+ Q_ASSERT(m_self->m_watches.contains(id));
+
+ QSocketNotifier* notify = m_self->m_watches.take(id);
+ notify->deleteLater();
+}
+
+//----------------------------------------------------------------------------
+
+int PolicyKitKDE::add_child_watch( PolKitGrant*, pid_t pid )
+{
+ ProcessWatch *watch = new ProcessWatch(pid);
+ connect( watch, SIGNAL( terminated( pid_t, int )), m_self, SLOT( childTerminated( pid_t, int )));
+ // return negative so that remove_watch() can tell io and child watches apart
+ return - ProcessWatcher::instance()->add(watch);
+}
+
+//----------------------------------------------------------------------------
+
+void PolicyKitKDE::remove_child_watch( PolKitGrant*, int id )
+{
+ assert( id < 0 );
+ ProcessWatcher::instance()->remove( -id );
+}
+
+//----------------------------------------------------------------------------
+
+void PolicyKitKDE::childTerminated( pid_t pid, int exitStatus )
+{
+ polkit_grant_child_func( grant, pid, exitStatus );
+}
+
+//----------------------------------------------------------------------------
+
+void PolicyKitKDE::remove_watch( PolKitGrant* grant, int id )
+{
+ if( id > 0 ) // io watches are +, child watches are -
+ remove_io_watch( grant, id );
+ else
+ remove_child_watch( grant, id );
+}
+
+//----------------------------------------------------------------------------
+#if 0
+void PolicyKitKDE::polkit_config_changed( PolKitContext* context, void* )
+{
+ kDebug() << "polkit_config_changed" << context;
+ // Nothing to do here it seems (?).
}
+#endif
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/PolicyKit-kde-0.0.svn810196/src/policykitkde.h new/PolicyKit-kde-0.2/src/policykitkde.h
--- old/PolicyKit-kde-0.0.svn810196/src/policykitkde.h 2008-04-12 00:50:34.000000000 +0200
+++ new/PolicyKit-kde-0.2/src/policykitkde.h 2008-10-29 18:25:13.000000000 +0100
@@ -25,10 +25,21 @@
#include
#include
#include
+#include
+#include
+#include
#include
+#include
-class PolicyKitKDE : public QObject
+enum KeepPassword
+ {
+ KeepPasswordNo, KeepPasswordSession, KeepPasswordAlways
+ };
+
+class AuthDialog;
+
+class PolicyKitKDE : public QObject, protected QDBusContext
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.freedesktop.PolicyKit.AuthenticationAgent")
@@ -42,18 +53,43 @@
private Q_SLOTS:
void watchActivated(int fd);
+ void childTerminated( pid_t, int );
+ void finishObtainPrivilege();
+ void dialogAccepted();
+ void dialogCancelled();
private:
PolKitContext *m_context;
- PolKitError * m_error;
+ WId parent_wid;
+ AuthDialog* dialog;
+ bool inProgress;
+ bool cancelled;
+ PolKitGrant* grant;
+ PolKitCaller* caller;
+ PolKitAction* action;
+ bool obtainedPrivilege;
+ bool requireAdmin;
+ KeepPassword keepPassword;
+ QDBusMessage mes;
static PolicyKitKDE* m_self;
QMap m_watches;
- static int polkit_add_watch(PolKitContext *context, int fd);
- static void polkit_remove_watch(PolKitContext *context, int fd);
- static void polkit_watch_have_data(PolKitContext *context, int fd);
+ static int add_io_watch(PolKitGrant *grant, int fd);
+ static void remove_io_watch(PolKitGrant *grant, int fd);
+ static void io_watch_have_data(PolKitGrant *grant, int fd);
+ static int add_child_watch(PolKitGrant* grant, pid_t pid);
+ static void remove_child_watch(PolKitGrant* grant, int id);
+ static void remove_watch(PolKitGrant* grant, int id);
+ static void conversation_type(PolKitGrant* grant, PolKitResult type, void* d);
+ static char* conversation_select_admin_user(PolKitGrant* grant, char** users, void* d);
+ static char* conversation_pam_prompt_echo_off(PolKitGrant* grant, const char* request, void* d );
+ static char* conversation_pam_prompt_echo_on(PolKitGrant* grant, const char* request, void* d );
+ static void conversation_pam_error_msg(PolKitGrant* grant, const char* msg, void* d );
+ static void conversation_pam_text_info(PolKitGrant* grant, const char* msg, void* d );
+ static PolKitResult conversation_override_grant_type(PolKitGrant* grant, PolKitResult type, void* d);
+ static void conversation_done(PolKitGrant* grant, polkit_bool_t obtainedPrivilege, polkit_bool_t invalidData, void* d);
};
#endif
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/PolicyKit-kde-0.0.svn810196/src/processwatcher.cpp new/PolicyKit-kde-0.2/src/processwatcher.cpp
--- old/PolicyKit-kde-0.0.svn810196/src/processwatcher.cpp 1970-01-01 01:00:00.000000000 +0100
+++ new/PolicyKit-kde-0.2/src/processwatcher.cpp 2008-10-28 18:53:03.000000000 +0100
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2008 Fredrik Höglund
+ *
+ * Based on qprocess_unix.cpp from Qt,
+ * Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License version 2 or at your option version 3 as published
+ * by the Free Software Foundation.
+ *
+ * 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 "processwatcher.h"
+
+#include <QApplication>
+#include <QSocketNotifier>
+
+#include
+#include
+#include
+#include
+#include
+
+static qint64 native_write(int fd, const char *data, qint64 len)
+{
+ qint64 ret = 0;
+ do {
+ ret = ::write(fd, data, len);
+ } while (ret == -1 && errno == EINTR);
+ return ret;
+}
+
+static qint64 native_read(int fd, char *data, qint64 maxlen)
+{
+ qint64 ret = 0;
+ do {
+ ret = ::read(fd, data, maxlen);
+ } while (ret == -1 && errno == EINTR);
+ return ret;
+}
+
+static void native_close(int fd)
+{
+ int ret;
+ do {
+ ret = ::close(fd);
+ } while (ret == -1 && errno == EINTR);
+}
+
+static void native_sigaction(int signum, const struct sigaction *act,
+ struct sigaction *oldact)
+{
+ int ret;
+ do {
+ ret = ::sigaction(signum, act, oldact);
+ } while (ret == -1 && errno == EINTR);
+}
+
+static int deadchild_pipe[2];
+static void (*old_sigchld_handler)(int) = 0;
+
+static void sigchld_handler(int signum)
+{
+ native_write(deadchild_pipe[1], "", 1);
+
+ if (old_sigchld_handler && old_sigchld_handler != SIG_IGN)
+ old_sigchld_handler(signum);
+}
+
+
+
+// ----------------------------------------------------------------------------
+
+
+
+ProcessWatch::ProcessWatch(pid_t pid)
+ : QObject(0), pid(pid)
+{
+#ifdef Q_OS_IRIX
+ ::socketpair(AF_UNIX, SOCK_STREAM, 0, pipe);
+#else
+ ::pipe(deathPipe);
+#endif
+ ::fcntl(deathPipe[0], F_SETFD, FD_CLOEXEC);
+ ::fcntl(deathPipe[1], F_SETFD, FD_CLOEXEC);
+ deathNotifier = new QSocketNotifier(deathPipe[0], QSocketNotifier::Read, this);
+ connect(deathNotifier, SIGNAL(activated(int)), SLOT(childDied()));
+}
+
+ProcessWatch::~ProcessWatch()
+{
+ native_close(deathPipe[0]);
+ native_close(deathPipe[1]);
+}
+
+void ProcessWatch::childDied()
+{
+ // read a byte from the death pipe
+ char c;
+ native_read(deathPipe[0], &c, 1);
+
+ int exitStatus;
+ pid_t waitResult = 0;
+
+ do {
+ waitResult = waitpid(pid, &exitStatus, WNOHANG);
+ } while ((waitResult == -1 && errno == EINTR));
+
+ if (waitResult > 0) {
+ emit terminated( pid, WEXITSTATUS(exitStatus));
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+
+
+ProcessWatcher *ProcessWatcher::s_inst = 0;
+
+ProcessWatcher *ProcessWatcher::instance()
+{
+ if (!s_inst)
+ s_inst = new ProcessWatcher;
+
+ return s_inst;
+}
+
+ProcessWatcher::ProcessWatcher()
+{
+ // Initialize the atomic ID counter
+ idCounter.fetchAndStoreRelaxed(1);
+
+ // initialize the dead child pipe and make it non-blocking. in the
+ // extremely unlikely event that the pipe fills up, we do not under any
+ // circumstances want to block.
+ ::pipe(deadchild_pipe);
+ ::fcntl(deadchild_pipe[0], F_SETFD, FD_CLOEXEC);
+ ::fcntl(deadchild_pipe[1], F_SETFD, FD_CLOEXEC);
+ ::fcntl(deadchild_pipe[0], F_SETFL,
+ ::fcntl(deadchild_pipe[0], F_GETFL) | O_NONBLOCK);
+ ::fcntl(deadchild_pipe[1], F_SETFL,
+ ::fcntl(deadchild_pipe[1], F_GETFL) | O_NONBLOCK);
+
+ // set up the SIGCHLD handler, which writes a single byte to the dead
+ // child pipe every time a child dies.
+ struct sigaction action;
+ struct sigaction old_action;
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = sigchld_handler;
+ action.sa_flags = SA_NOCLDSTOP;
+ native_sigaction(SIGCHLD, &action, &old_action);
+
+ old_sigchld_handler = old_action.sa_handler;
+
+ start();
+}
+
+ProcessWatcher::~ProcessWatcher()
+{
+ // notify the thread that we're shutting down.
+ native_write(deadchild_pipe[1], "@", 1);
+ native_close(deadchild_pipe[1]);
+ wait();
+
+ // on certain unixes, closing the reading end of the pipe will cause
+ // select in run() to block forever, rather than return with EBADF.
+ native_close(deadchild_pipe[0]);
+
+ deadchild_pipe[0] = -1;
+ deadchild_pipe[1] = -1;
+}
+
+int ProcessWatcher::add(ProcessWatch *watch)
+{
+ QMutexLocker locker(&mutex);
+
+ int serial = idCounter.fetchAndAddRelaxed(1);
+ children.insert(serial, watch);
+
+ return serial;
+}
+
+void ProcessWatcher::remove(int serial)
+{
+ QMutexLocker locker(&mutex);
+
+ ProcessWatch *watch = children.value(serial);
+ if (!watch)
+ return;
+
+ children.remove(serial);
+ delete watch;
+}
+
+void ProcessWatcher::run()
+{
+ forever {
+ fd_set readset;
+ FD_ZERO(&readset);
+ FD_SET(deadchild_pipe[0], &readset);
+
+ // block forever, or until activity is detected on the dead child
+ // pipe. the only other peers are the SIGCHLD signal handler, and the
+ // ProcessWatcher destructor.
+ int nselect = select(deadchild_pipe[0] + 1, &readset, 0, 0, 0);
+ if (nselect < 0) {
+ if (errno == EINTR)
+ continue;
+ break;
+ }
+
+ // empty only one byte from the pipe, even though several SIGCHLD
+ // signals may have been delivered in the meantime, to avoid race
+ // conditions.
+ char c;
+ if (native_read(deadchild_pipe[0], &c, 1) < 0 || c == '@')
+ break;
+
+ // catch any and all children that we can.
+ catchDeadChildren();
+ }
+}
+
+void ProcessWatcher::catchDeadChildren()
+{
+ QMutexLocker locker(&mutex);
+
+ // try to catch all children whose pid we have registered, and whose
+ // deathPipe is still valid (i.e, we have not already notified it).
+ QMap::Iterator it = children.begin();
+ while (it != children.end()) {
+ // notify all children that they may have died. they need to run
+ // waitpid() in their own thread.
+ ProcessWatch *watch = it.value();
+ native_write(watch->deathPipe[1], "", 1);
+ ++it;
+ }
+}
+
+// kate: space-indent on; indent-width 4; replace-tabs on;
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/PolicyKit-kde-0.0.svn810196/src/processwatcher.h new/PolicyKit-kde-0.2/src/processwatcher.h
--- old/PolicyKit-kde-0.0.svn810196/src/processwatcher.h 1970-01-01 01:00:00.000000000 +0100
+++ new/PolicyKit-kde-0.2/src/processwatcher.h 2008-10-27 15:00:43.000000000 +0100
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2008 Fredrik Höglund
+ *
+ * Based on qprocess_unix.cpp from Qt,
+ * Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License version 2 or at your option version 3 as published
+ * by the Free Software Foundation.
+ *
+ * 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 PROCESSWATCHER_H
+#define PROCESSWATCHER_H
+
+#include <QThread>
+#include <QMutex>
+#include <QMap>
+#include <QAtomicInt>
+
+class ProcessInfo;
+class QSocketNotifier;
+
+/**
+ * This class represents a child process being watched.
+ */
+class ProcessWatch : public QObject
+{
+ Q_OBJECT
+
+public:
+ ProcessWatch(pid_t pid);
+ ~ProcessWatch();
+
+signals:
+ void terminated( pid_t pid, int exitStatus );
+private slots:
+ void childDied();
+
+private:
+ QSocketNotifier *deathNotifier;
+ int deathPipe[2];
+ pid_t pid;
+
+friend class ProcessWatcher;
+};
+
+
+/**
+ * This class watches child processes spawned by PolicyKitGrant
+ * on its behalf, and notifies it when a process dies.
+ *
+ * Only one instance of this class should be created.
+ */
+class ProcessWatcher : public QThread
+{
+public:
+ ~ProcessWatcher();
+
+ static ProcessWatcher *instance();
+
+ /**
+ * Adds a watch and returns a unique identifier for this watch.
+ * Ownership is transferred to the process watcher.
+ */
+ int add(ProcessWatch *watch);
+
+ /**
+ * Removes and deletes the watch identified by @p id
+ */
+ void remove(int id);
+
+private:
+ ProcessWatcher();
+ void run();
+ void catchDeadChildren();
+
+private:
+ QMutex mutex;
+ QAtomicInt idCounter;
+ QMap children;
+ static ProcessWatcher *s_inst;
+};
+
+#endif
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Remember to have fun...
--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org