[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-core-devel
Subject: Question: KIO Scheduler
From: Dawit Alemayehu <adawit () kde ! org>
Date: 2000-10-30 3:08:04
[Download RAW message or body]
Hello,
I am trying to add support for automatic deletion of passwords when the applications \
that cached them are closed by the user. To achieve this I put the code that tracks \
and deletes cached passwords in KIO's scheduler since there is one instance of it per \
app (unlike the slaves and the jobs). Hence, when the app exists we are able to \
correctly deal with the cached passwords (remove them as necessary). However, I \
cannot get this to work no matter what I tried and need help. From what I gathered \
so far it seems to me that my problem stems from the fact that the scheduler is a \
static object. I have attached a patch below to show what I have done. Below is a \
brief description of how this deletion is supposed(intended) to work:
1.) Whenever a unique new password is cached the SlaveBase responsible for this stuff \
sends a message to the application-side of the house (SlaveInterface). The message \
is the key under which the password is cached in the kdesud daemon.
2.) When the SlaveInterface gets this message it emits a signal with this key at \
hand. And since the scheduler is connected to this signal when it first created the \
io-slave, it gets its hand on it.
3) The SLOT connected to the signal in KIO::Scheduler then store the key in a list \
(QValueList) and registers itself with the kdesu daemon as an owner of this key.
So far so good. I was able to get this to work for a while consistently, but now for \
whatever reason it seems not to anymore. I do not get the debug statements I should \
when I test it. But do not worry about this as it seems to be something wrong on my \
end
4.) When the application is then destroyed, I put a statement that calls \
delCachedAuthKeys in KIO::Scheduler's dtor. The above method determines whether or \
not the cached entries should be deleted or not. This is the point of failure. I \
always get the following FATAL error and konqueror aborts in the process of shutting \
down.
Fatal error: you need to have a KInstance object before
you do anything that requires it! Examples of this are config
objects, standard directories or translations.
zsh: 9755 abort konqueror
If I then remove the method that attempts to call the afformentioned method from the \
destructor, I do not get the above message.
Thus, the question is where is the correct place to put this stuff such that when \
this static object is destroyed or about to be destroyed the cached entries, if any, \
can be cleaned as well...
Any suggestions, comments, flames etc are all welcome...
Regards,
Dawit A.
["scheduler.diff" (text/x-c)]
Index: scheduler.cpp
===================================================================
RCS file: /home/kde/kdelibs/kio/scheduler.cpp,v
retrieving revision 1.38
diff -u -r1.38 scheduler.cpp
--- scheduler.cpp 2000/10/16 01:20:39 1.38
+++ scheduler.cpp 2000/10/30 03:00:47
@@ -26,6 +26,7 @@
#include <kprotocolmanager.h>
#include <assert.h>
#include <kstaticdeleter.h>
+#include <kdesu/client.h>
//
// Slaves may be idle for MAX_SLAVE_IDLE time before they are being returned
@@ -36,6 +37,19 @@
Scheduler *Scheduler::instance = 0;
+/*
+* Structure to cache authorization info from io-slaves.
+*/
+struct KIO::AuthKey
+{
+ AuthKey() {}
+ AuthKey(const QString& k,int d,bool p):key(k),duration(d),persist(p) {}
+ QString key;
+ int duration;
+ bool persist;
+};
+
+
class KIO::Scheduler::ProtocolInfo
{
public:
@@ -97,7 +111,13 @@
Scheduler::~Scheduler()
{
-//fprintf(stderr, "Destructing KIO::Scheduler...\n");
+ fprintf(stdout, "Destructing KIO::Scheduler...\n");
+ kdDebug(7600) << "Destructing KIO::Scheduler..." << endl;
+
+ // Delete any stored authorization info now...
+ if( !cachedAuthKeys.isEmpty() )
+ delCachedAuthKeys( cachedAuthKeys );
+
protInfoDict->setAutoDelete(true);
delete protInfoDict; protInfoDict = 0;
delete idleSlaves; idleSlaves = 0;
@@ -268,6 +288,7 @@
SLOT(slotSlaveDied(KIO::Slave *)));
connect(slave, SIGNAL(slaveStatus(pid_t,const QCString &,const \
QString &, bool)),
SLOT(slotSlaveStatus(pid_t,const QCString &, const QString \
&, bool))); + connect(slave,SIGNAL(authKey(const \
QString&)),SLOT(slotAuthKey(const QString&))); }
else
{
@@ -350,6 +371,96 @@
}
}
+bool Scheduler::pingCacheDaemon() const
+{
+ KDEsuClient client;
+ int sucess = client.ping();
+ if( sucess == -1 )
+ {
+ kdDebug(7006) << "No running \"kdesu\" daemon found. Attempting to start \
one..." << endl; + sucess = client.startServer();
+ if( sucess == -1 )
+ {
+ kdDebug(7006) << "Cannot start a new \"kdesu\" deamon!!" << endl;
+ return false;
+ }
+ kdDebug(7006) << "New \"kdesu\" daemon was sucessfully started..." << endl;
+ }
+ return true;
+}
+
+void Scheduler::slotAuthKey( const QString& auth_key )
+{
+ cachedAuthKeys.append( AuthKey( auth_key, 0, false ) );
+ regCachedAuthKey( auth_key );
+}
+
+void Scheduler::slotDestroyed()
+{
+ kdDebug(7006) << "About to destroy the scheduler..." << endl;
+ kdDebug(7006) << "Is authentication cache empty ? "<< cachedAuthKeys.isEmpty() \
<< endl; + if( !cachedAuthKeys.isEmpty() )
+ delCachedAuthKeys( cachedAuthKeys );
+}
+
+bool Scheduler::regCachedAuthKey( const QString& grpname )
+{
+ kdDebug(7006) << "Register authentication key for: " << grpname << endl;
+ KDEsuClient client;
+ if( pingCacheDaemon() && !client.getVar((grpname + \
"-hasEntry").utf8()).isEmpty() ) + {
+ bool ok;
+ int count = client.getVar( (grpname + "-refcount").utf8() ).toInt( &ok );
+ if( ok )
+ client.setVar( (grpname + "-refcount").utf8(), \
QString("%1").arg(count+1).utf8(), 0, grpname.utf8() ); + else
+ client.setVar( (grpname + "-refcount").utf8(), "2", 0, grpname.utf8() );
+ return true;
+ }
+ return false;
+}
+
+void Scheduler::delCachedAuthKeys( const AuthKeyList& grpname )
+{
+ kdDebug(7006) << "Attempting to delete cached Authentication..." << endl;
+
+ if( !pingCacheDaemon() )
+ return;
+
+ bool ok;
+ int count;
+ KDEsuClient client;
+ AuthKeyList::ConstIterator it = grpname.begin();
+ for( ; it != grpname.end(); ++it )
+ {
+ // Do not delete passwords that are meant to
+ // be persistant!
+ if( (*it).persist )
+ continue;
+
+ count = client.getVar( ((*it).key + "-refcount").utf8() ).toInt( &ok );
+ // Test point though I know that this value is going to be an integer
+ kdDebug(7006) << "Delete key " << (*it).key << "? " << ok << endl;
+ if( ok )
+ {
+ if( count > 1 )
+ {
+ client.setVar(((*it).key + "-refcount").utf8(),
+ QString("%1").arg( count - 1 ).utf8(), 0,
+ (*it).key.utf8() );
+ kdDebug(7006) << "Key registered by multiple processes. "
+ << "Decrementing reference count to: "
+ << count-1 << endl;
+ }
+ else
+ {
+ kdDebug(7006) << "Last reference. Deleting the whole group..." << \
endl; + client.delGroup((*it).key.utf8());
+ }
+ }
+ }
+}
+
void Scheduler::slotSlaveDied(KIO::Slave *slave)
{
ProtocolInfo *protInfo = protInfoDict->get(slave->protocol());
@@ -438,8 +549,9 @@
static KStaticDeleter<Scheduler> ksds;
Scheduler* Scheduler::self() {
- if ( !instance )
- instance = ksds.setObject(new Scheduler);
+ if ( !instance ) {
+ instance = ksds.setObject(new Scheduler);
+ }
return instance;
}
Index: scheduler.h
===================================================================
RCS file: /home/kde/kdelibs/kio/scheduler.h,v
retrieving revision 1.19
diff -u -r1.19 scheduler.h
--- scheduler.h 2000/09/22 17:19:47 1.19
+++ scheduler.h 2000/10/30 03:00:49
@@ -31,6 +31,7 @@
class Slave;
class SlaveList;
+ struct AuthKey;
class Scheduler : public QObject, virtual public DCOPObject {
Q_OBJECT
@@ -46,7 +47,7 @@
{ self()->_cancelJob(job); }
static void jobFinished(KIO::SimpleJob *job, KIO::Slave *slave)
{ self()->_jobFinished(job, slave); }
-
+
static void putSlaveOnHold(KIO::SimpleJob *job, const KURL &url)
{ self()->_putSlaveOnHold(job, url); }
@@ -68,6 +69,8 @@
protected slots:
void startStep();
void slotCleanIdleSlaves();
+ void slotAuthKey( const QString& auth_key );
+ void slotDestroyed();
protected:
bool startStep(ProtocolInfo *protInfo);
@@ -100,12 +103,47 @@
*/
SlaveList *slaveList;
SlaveList *idleSlaves;
-
+
ProtocolInfoDict *protInfoDict;
-
+
Slave *slaveOnHold;
KURL urlOnHold;
- };
+
+
+ typedef QValueList<AuthKey> AuthKeyList;
+ AuthKeyList cachedAuthKeys;
+
+ /**
+ * Checks whether the password daemon kdesud is
+ * running or if it can be started if it is not.
+ *
+ * @return true if password daemon is/can be started successfully.
+ */
+ bool pingCacheDaemon() const;
+
+ /**
+ * Increments the reference count for application using the
+ * give authorization key.
+ *
+ * The reference counting is used by @ref delCachedAuthentication
+ * to determine when it is safe to delete the key from the cache.
+ *
+ * A call to this function will fail, i.e. return false, if there
+ * is no entry for the given @p groupname value and/or the cache
+ * deamon, @p kdesud, cannot be contacted.
+ *
+ * @return true if the registration succeeds.
+ */
+ bool regCachedAuthKey( const QString& grpname );
+
+ /**
+ * Deletes any cached keys for the given group.
+ *
+ * @param grpname cached authentication key to be deleted.
+ */
+ void delCachedAuthKeys( const AuthKeyList& grpname );
+
};
+};
#endif
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic