[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-pim
Subject: [Kde-pim] Threaded ldap search class
From: Sean Harmer <sh () theharmers ! co ! uk>
Date: 2007-04-07 9:49:59
Message-ID: 200704071049.59155.sh () theharmers ! co ! uk
[Download RAW message or body]
Hi All,
I've put together the beginnings of a class to perform ldap searches in a
separate thread so that it doesn't block the calling thread. I've called this
class LdapSearchThread for want of a better name. I've included a patch
against kdepimlibs revision 651209 that incorporates this class. The patch
also includes a small local change that makes ldapconfigwidget and co use
LdapDN objects to represent DNs rather than plain QStrings.
What I would like to know is what would you like me to do with this code?
Should I incorporate similar changes into LdapSearch so that it is
multithreaded by default fo should I add a new class to the kldap library
(better names for the class are welcome)?
I realise that this is only the bare essentials to get something working at
the moment, but I didn't want to go too far until I get some feedback as to
whether this would be useful or not.
Kind regards,
Sean
["ldapsearchthread.diff" (text/x-diff)]
Index: kldap/ldapoperation.cpp
===================================================================
--- kldap/ldapoperation.cpp (revision 651315)
+++ kldap/ldapoperation.cpp (working copy)
@@ -31,8 +31,23 @@
#include <lber.h>
#endif
+#include <QTime>
+
using namespace KLDAP;
+/*
+ Returns the difference between msecs and elapsed. If msecs is -1,
+ however, -1 is returned.
+*/
+static int kldap_timeout_value( int msecs, int elapsed )
+{
+ if ( msecs == -1 )
+ return -1;
+
+ int timeout = msecs - elapsed;
+ return timeout < 0 ? 0 : timeout;
+}
+
class LdapOperation::LdapOperationPrivate {
public:
LdapControls mClientCtrls, mServerCtrls, mControls;
@@ -261,7 +276,7 @@
}
}
-int LdapOperation::search( const QString &base, LdapUrl::Scope scope,
+int LdapOperation::search( const LdapDN &base, LdapUrl::Scope scope,
const QString &filter, const QStringList &attributes )
{
Q_ASSERT( d->mConnection );
@@ -296,10 +311,10 @@
break;
}
- kDebug(5322) << "asyncSearch() base=\"" << base << "\" scope=" << scope <<
+ kDebug(5322) << "asyncSearch() base=\"" << base.toString() << "\" scope=" << scope <<
" filter=\"" << filter << "\" attrs=" << attributes << endl;
int retval =
- ldap_search_ext( ld, base.toUtf8(), lscope,
+ ldap_search_ext( ld, base.toString().toUtf8(), lscope,
filter.isEmpty() ? QByteArray("objectClass=*") : filter.toUtf8(),
attrs, 0, serverctrls, clientctrls, 0,
d->mConnection->sizeLimit(), &msgid );
@@ -690,16 +705,69 @@
LDAP *ld = (LDAP*) d->mConnection->handle();
LDAPMessage *msg;
- int rescode, retval;
+ int rescode;
rescode = ldap_result( ld, id, 0, NULL, &msg );
- if ( rescode == -1 ) {
+ if ( rescode == -1 || processResult( rescode, msg ) == -1 ) {
return -1;
}
+ return rescode;
+}
+
+int LdapOperation::waitForResult( int id, int msecs )
+{
+ //kDebug() << "LdapOperation::waitForResult(" << id << ", " << msecs << ")" << endl;
+
+ Q_ASSERT( d->mConnection );
+ LDAP *ld = (LDAP*) d->mConnection->handle();
+
+ LDAPMessage *msg;
+ int rescode;
+
+ QTime stopWatch;
+ stopWatch.start();
+ int attempt( 1 );
+ int timeout( 0 );
+
+ do {
+ // Calculate the timeout value to use and assign it to a timeval structure
+ // see man select (2) for details
+ timeout = kldap_timeout_value( msecs, stopWatch.elapsed() );
+ kDebug() << "LdapOperation::waitForResult(" << id << ", " << msecs
+ << "):Waiting for " << timeout / 1000.0
+ << " secs for result. Attempt #" << attempt++ << endl;
+ struct timeval tv;
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = ( timeout % 1000 ) * 1000;
+
+ // Wait for a result - or poll if timeout < 0
+ rescode = ldap_result( ld, id, 0, timeout < 0 ? 0 : &tv, &msg );
+
+ // Act on the return code
+ if ( rescode == -1 ) {
+ // No result is ready yet - let's go round again
+ continue;
+ }
+
+ // Some kind of result is available for processing
+ if ( processResult( rescode, msg ) == -1 )
+ return -1;
+ } while ( rescode == -1 && ( msecs == -1 || timeout < msecs ) );
+
+ return rescode;
+}
+
+int LdapOperation::processResult( int rescode, LDAPMessage *msg )
+{
+ kDebug() << "LdapOperation::processResult()" << endl;
+ int retval;
+ LDAP *ld = (LDAP*) d->mConnection->handle();
+
switch ( rescode ) {
case RES_SEARCH_ENTRY:
{
+ kDebug() << "LdapOperation::processResult(): Found search entry" << endl;
d->mObject.clear();
LdapAttrMap attrs;
char *name;
@@ -794,7 +862,7 @@
}
#else
-int LdapOperation::search( const QString &base, LdapUrl::Scope scope,
+int LdapOperation::search( const LdapDN &base, LdapUrl::Scope scope,
const QString &filter, const QStringList &attributes )
{
kError() << "LDAP support not compiled" << endl;
Index: kldap/ldapsearchthread.h
===================================================================
--- kldap/ldapsearchthread.h (revision 0)
+++ kldap/ldapsearchthread.h (revision 0)
@@ -0,0 +1,62 @@
+//
+// C++ Interface: ldapsearchthread
+//
+// Description:
+//
+//
+// Author: <>, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef LDAPSEARCHTHREAD_H
+#define LDAPSEARCHTHREAD_H
+
+#include <QThread>
+
+#include "ldapobject.h"
+#include "ldapserver.h"
+#include "kldap.h"
+
+namespace KLDAP {
+
+/**
+ * \brief A class to easily multithread LDAP searches.
+ */
+class KLDAP_EXPORT LdapSearchThread : public QThread
+{
+ Q_OBJECT
+ public:
+ explicit LdapSearchThread( const LdapServer& server );
+ virtual ~LdapSearchThread();
+
+ void setPollTimeout( int msecs = 100 );
+ int pollTimeout() const;
+
+ void search( const LdapDN &base,
+ LdapUrl::Scope scope = LdapUrl::Sub,
+ const QString &filter = QString(),
+ const QStringList &attributes = QStringList(),
+ int pagesize = 0 );
+
+ signals:
+ void data( LdapSearchThread*, const LdapObject& );
+ void result( LdapSearchThread* );
+
+ protected:
+ void run();
+ bool startSearch( const LdapDN &base, LdapUrl::Scope scope,
+ const QString &filter,
+ const QStringList &attributes,
+ int pagesize );
+ bool pollForMessage();
+
+ private:
+ class LdapSearchThreadPrivate;
+ LdapSearchThreadPrivate *d;
+};
+
+}
+
+#endif
Index: kldap/ldapsearch.cpp
===================================================================
--- kldap/ldapsearch.cpp (revision 651315)
+++ kldap/ldapsearch.cpp (working copy)
@@ -19,6 +19,7 @@
*/
#include "ldapsearch.h"
+#include "ldapdn.h"
#include "ldapdefs.h"
#include <QtCore/QEventLoop>
@@ -39,7 +40,7 @@
void result();
bool connect();
void closeConnection();
- bool startSearch( const QString &base, LdapUrl::Scope scope,
+ bool startSearch( const LdapDN &base, LdapUrl::Scope scope,
const QString &filter, const QStringList &attributes,
int pagesize );
@@ -48,7 +49,8 @@
LdapOperation mOp;
bool mOwnConnection, mAbandoned;
int mId, mPageSize;
- QString mBase, mFilter;
+ LdapDN mBase;
+ QString mFilter;
QStringList mAttributes;
LdapUrl::Scope mScope;
@@ -130,11 +132,11 @@
}
}
-bool LdapSearch::Private::startSearch( const QString &base, LdapUrl::Scope scope,
+bool LdapSearch::Private::startSearch( const LdapDN &base, LdapUrl::Scope scope,
const QString &filter,
const QStringList &attributes, int pagesize )
{
- kDebug(5322) << "search: base=" << base << " scope=" << scope << " filter=" << filter
+ kDebug(5322) << "search: base=" << base.toString() << " scope=" << scope << " filter=" << filter
<< " attributes=" << attributes << " pagesize=" << pagesize << endl;
mAbandoned = false;
mError = 0;
@@ -233,7 +235,7 @@
url.attributes(), pagesize );
}
-bool LdapSearch::search( const QString &base, LdapUrl::Scope scope,
+bool LdapSearch::search( const LdapDN &base, LdapUrl::Scope scope,
const QString &filter, const QStringList &attributes,
int pagesize )
{
Index: kldap/ldapserver.cpp
===================================================================
--- kldap/ldapserver.cpp (revision 651315)
+++ kldap/ldapserver.cpp (working copy)
@@ -29,7 +29,7 @@
public:
QString mHost;
int mPort;
- QString mBaseDn;
+ LdapDN mBaseDn;
QString mUser;
QString mBindDn;
QString mRealm;
@@ -98,7 +98,7 @@
return d->mPort;
}
-QString LdapServer::baseDn() const
+LdapDN LdapServer::baseDn() const
{
return d->mBaseDn;
}
@@ -178,7 +178,7 @@
d->mPort = port;
}
-void LdapServer::setBaseDn( const QString &baseDn )
+void LdapServer::setBaseDn( const LdapDN &baseDn )
{
d->mBaseDn = baseDn;
}
Index: kldap/ldapurl.h
===================================================================
--- kldap/ldapurl.h (revision 651315)
+++ kldap/ldapurl.h (working copy)
@@ -26,6 +26,7 @@
#include <kurl.h>
+#include "ldapdn.h"
#include "kldap.h"
namespace KLDAP {
@@ -67,9 +68,9 @@
* Returns the dn part of the LDAP Url (same as path(), but slash removed
* from the beginning).
*/
- QString dn() const;
+ LdapDN dn() const;
/** Sets the the dn part of the LDAP Url. */
- void setDn( const QString &dn );
+ void setDn( const LdapDN &dn );
/** Returns the attributes part of the LDAP Url */
QStringList attributes() const;
Index: kldap/ldapconfigwidget.h
===================================================================
--- kldap/ldapconfigwidget.h (revision 651315)
+++ kldap/ldapconfigwidget.h (working copy)
@@ -24,6 +24,7 @@
#include <QtCore/QString>
#include <QtGui/QWidget>
+#include "ldapdn.h"
#include "kldap.h"
#include "ldapobject.h"
#include "ldapserver.h"
@@ -54,7 +55,7 @@
Q_PROPERTY( QString host READ host WRITE setHost )
Q_PROPERTY( int port READ port WRITE setPort )
Q_PROPERTY( int version READ version WRITE setVersion )
- Q_PROPERTY( QString dn READ dn WRITE setDn )
+ Q_PROPERTY( LdapDN dn READ dn WRITE setDn )
Q_PROPERTY( QString filter READ filter WRITE setFilter )
Q_PROPERTY( QString mech READ mech WRITE setMech )
Q_PROPERTY( Security security READ security WRITE setSecurity )
@@ -141,9 +142,9 @@
int version() const;
/** Sets the LDAP Base DN. Kconfig widget name: kcfg_ldapdn */
- void setDn( const QString &dn );
+ void setDn( const LdapDN &dn );
/** Gets the LDAP Base DN. Kconfig widget name: kcfg_ldapdn */
- QString dn() const;
+ LdapDN dn() const;
/** Sets the LDAP Filter. Kconfig widget name: kcfg_ldapfilter */
void setFilter( const QString &filter );
Index: kldap/ldapmodel_p.cpp
===================================================================
--- kldap/ldapmodel_p.cpp (revision 651315)
+++ kldap/ldapmodel_p.cpp (working copy)
@@ -70,7 +70,7 @@
const QStringList &attributes,
int pagesize )
{
- return m_search->search( searchBase.toString(), scope, filter, attributes, pagesize );
+ return m_search->search( searchBase, scope, filter, attributes, pagesize );
}
void LdapModel::LdapModelPrivate::setSearchType( SearchType t, LdapModelTreeItem *item )
Index: kldap/tests/testkldap.h
===================================================================
--- kldap/tests/testkldap.h (revision 651315)
+++ kldap/tests/testkldap.h (working copy)
@@ -24,6 +24,7 @@
#include <ldapmodel.h>
#include <ldapobject.h>
#include <ldapsearch.h>
+#include <ldapsearchthread.h>
using namespace KLDAP;
@@ -40,6 +41,7 @@
void testLdapUrl();
void testLdapConnection();
void testLdapSearch();
+ void testLdapSearchThread();
void testLdapDN();
void testLdapModel();
@@ -47,6 +49,9 @@
void searchResult( LdapSearch* );
void searchData( LdapSearch*, const LdapObject& );
+ void searchResult( LdapSearchThread* );
+ void searchData( LdapSearchThread*, const LdapObject& );
+
private:
QString m_url;
LdapSearch* m_search;
Index: kldap/tests/testkldap.cpp
===================================================================
--- kldap/tests/testkldap.cpp (revision 651315)
+++ kldap/tests/testkldap.cpp (working copy)
@@ -31,12 +31,15 @@
#include "ldapmodel.h"
#include "ldapoperation.h"
#include "ldapsearch.h"
+#include "ldapsearchthread.h"
#include "ber.h"
#include "kldap.h"
#include <kdebug.h>
#include <qtest_kde.h>
+#include <unistd.h>
+
#ifdef LDAP_FOUND
#include <ldap.h>
#include <lber.h>
@@ -91,7 +94,7 @@
QCOMPARE( url.user(), QString::fromLatin1("cn=manager,dc=kde,dc=org") );
QCOMPARE( url.password(), QString::fromLatin1("password") );
- QCOMPARE( url.dn(), QString::fromLatin1("dc=kde,dc=org") );
+ QCOMPARE( url.dn().toString(), QString::fromLatin1("dc=kde,dc=org") );
QCOMPARE( url.scope(), LdapUrl::Sub );
QCOMPARE( url.attributes().at(0), QString::fromLatin1("cn") );
QCOMPARE( url.attributes().at(1), QString::fromLatin1("mail") );
@@ -139,24 +142,70 @@
kDebug() << "Search found " << m_objects.size() << " matching entries" << endl;
}
+
void KLdapTest::searchResult( LdapSearch* search )
{
- kDebug() << "KLdapTest::searchResult()" << endl;
- int err = search->error();
- if ( err )
- kDebug() << "Search returned the following error: " << search->errorString() << endl;
- QCOMPARE( err, 0 );
+ kDebug() << "KLdapTest::searchResult()" << endl;
+ int err = search->error();
+ if ( err )
+ kDebug() << "Search returned the following error: " << search->errorString() << endl;
+ QCOMPARE( err, 0 );
}
void KLdapTest::searchData( LdapSearch* /*search*/, const LdapObject& obj )
{
- //kDebug() << "KLdapTest::searchData()" << endl;
- //kDebug() << "Object:" << endl << obj.toString() << endl;
- m_objects.append( obj );
+ //kDebug() << "KLdapTest::searchData()" << endl;
+ //kDebug() << "Object:" << endl << obj.toString() << endl;
+ m_objects.append( obj );
}
+void KLdapTest::testLdapSearchThread()
+{
+ LdapUrl url;
+ url.setUrl( m_url );
+ LdapServer server( url );
+ LdapSearchThread* searchThread = new LdapSearchThread( server );
+
+ qRegisterMetaType<LdapObject>("LdapObject");
+ connect( searchThread, SIGNAL( result( LdapSearchThread* ) ),
+ this, SLOT( searchResult( LdapSearchThread* ) ) );
+ connect( searchThread, SIGNAL( data( LdapSearchThread*, const LdapObject& ) ),
+ this, SLOT( searchData( LdapSearchThread*, const LdapObject& ) ) );
+
+ QStringList attributes = QStringList() << "cn" << "memberuid";
+ searchThread->search( LdapDN( "ou=groups,dc=esrtechnology,dc=com" ),
+ LdapUrl::Sub,
+ QString( "(cn=*)" ),
+ attributes );
+
+ kDebug() << "Sleeping for 5 seconds to allow thread to do stuff" << endl;
+ sleep( 5 );
+
+ while( QCoreApplication::hasPendingEvents() )
+ qApp->processEvents();
+}
+
+
+void KLdapTest::searchResult( LdapSearchThread* /*search*/ )
+{
+ /*
+ kDebug() << "KLdapTest::searchResult()" << endl;
+ int err = search->error();
+ if ( err )
+ kDebug() << "Search returned the following error: " << search->errorString() << endl;
+ QCOMPARE( err, 0 );
+ */
+}
+
+
+void KLdapTest::searchData( LdapSearchThread*, const LdapObject& obj )
+{
+ kDebug() << "Object:" << endl << obj.toString() << endl;
+}
+
+
void KLdapTest::testLdapDN()
{
QString strDN( "uid=Test\\+Person+ou=accounts\\,outgoing,dc=kde,dc=org" );
Index: kldap/CMakeLists.txt
===================================================================
--- kldap/CMakeLists.txt (revision 651315)
+++ kldap/CMakeLists.txt (working copy)
@@ -38,6 +38,7 @@
ldapoperation.cpp
ldapcontrol.cpp
ldapsearch.cpp
+ ldapsearchthread.cpp
ldapconfigwidget.cpp
ldapdn.cpp
ldapmodeltreeitem_p.cpp
@@ -60,5 +61,5 @@
install( FILES ber.h kldap.h ldapdefs.h ldif.h ldapurl.h ldapserver.h ldapobject.h
ldapconnection.h ldapoperation.h
- ldapconfigwidget.h ldapcontrol.h ldapsearch.h
+ ldapconfigwidget.h ldapcontrol.h ldapsearch.h ldapsearchthread.h
ldapdn.h ldapmodel.h DESTINATION ${INCLUDE_INSTALL_DIR}/kldap)
Index: kldap/ldapsearchthread.cpp
===================================================================
--- kldap/ldapsearchthread.cpp (revision 0)
+++ kldap/ldapsearchthread.cpp (revision 0)
@@ -0,0 +1,254 @@
+//
+// C++ Implementation: ldapsearchthread
+//
+// Description:
+//
+//
+// Author: <>, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "ldapsearchthread.h"
+#include "ldapconnection.h"
+#include "ldapoperation.h"
+#include "ldapdefs.h"
+
+#include <QMutex>
+#include <QMutexLocker>
+#include <QWaitCondition>
+
+#include <kdebug.h>
+
+using namespace KLDAP;
+
+class LdapSearchThread::LdapSearchThreadPrivate
+{
+ public:
+ bool connect();
+
+ QMutex mMutex;
+ QWaitCondition mCondition;
+ bool mAbort;
+ bool mRestart;
+
+ LdapConnection mConn;
+ LdapOperation mOp;
+ int mTimeout;
+ int mId, mPageSize;
+ LdapDN mBase;
+ QString mFilter;
+ QStringList mAttributes;
+ LdapUrl::Scope mScope;
+
+ QString mErrorString;
+ int mError;
+};
+
+bool LdapSearchThread::LdapSearchThreadPrivate::connect()
+{
+ int ret = mConn.connect();
+ if ( ret != KLDAP_SUCCESS ) {
+ mConn.close();
+ return false;
+ }
+ ret = mConn.bind();
+ if ( ret != KLDAP_SUCCESS ) {
+ mConn.close();
+ return false;
+ }
+ return true;
+}
+
+
+LdapSearchThread::LdapSearchThread( const LdapServer& server )
+ : d( new LdapSearchThreadPrivate )
+{
+ d->mRestart = false;
+ d->mAbort = false;
+ d->mTimeout = 10 * 1000;
+ d->mConn.setServer( server );
+ d->connect();
+}
+
+LdapSearchThread::~LdapSearchThread()
+{
+ d->mMutex.lock();
+ d->mAbort = true;
+ d->mCondition.wakeOne();
+ d->mMutex.unlock();
+
+ // Wait for run() to exit before we destroy this object
+ wait();
+}
+
+void LdapSearchThread::setPollTimeout( int msecs )
+{
+ QMutexLocker( &(d->mMutex) );
+ d->mTimeout = msecs;
+}
+
+int LdapSearchThread::pollTimeout() const
+{
+ return d->mTimeout;
+}
+
+void LdapSearchThread::search( const LdapDN &base,
+ LdapUrl::Scope scope,
+ const QString &filter,
+ const QStringList &attributes,
+ int pagesize )
+{
+ kDebug() << "LdapSearchThread::search(): " << endl;
+ QMutexLocker locker( &(d->mMutex) );
+
+ d->mBase = base;
+ d->mScope = scope;
+ d->mFilter = filter;
+ d->mAttributes = attributes;
+ d->mPageSize = pagesize;
+
+ if ( !isRunning() ) {
+ kDebug() << "\tCalling start()" << endl;
+ start( LowPriority );
+ } else {
+ kDebug() << "\tCalling wakeOne()" << endl;
+ d->mRestart = true;
+ d->mCondition.wakeOne();
+ }
+}
+
+void LdapSearchThread::run()
+{
+ forever {
+ // Store the search parameters locally to prevent the calling thread from
+ // blocking for very long if it needs to start a different search.
+ d->mMutex.lock();
+ LdapDN base = d->mBase;
+ LdapUrl::Scope scope = d->mScope;
+ QString filter = d->mFilter;
+ QStringList attributes = d->mAttributes;
+ int pagesize = d->mPageSize;
+ d->mMutex.unlock();
+
+ // Start the search off
+ if ( !startSearch( base, scope, filter, attributes, pagesize ) )
+ return;
+
+ // Poll for responses from the server until the results have been
+ // completely returned or we are told to abort
+ bool pollAgain( true );
+ while ( pollAgain ) {
+ // Have we been told to abort or start a new search?
+ if ( d->mAbort )
+ return;
+ else if ( d->mRestart )
+ break;
+
+ // Poll for messages from the LDAP server
+ pollAgain = pollForMessage();
+ }
+
+ // Go to sleep until we are needed for another search
+ d->mMutex.lock();
+ d->mCondition.wait( &(d->mMutex) );
+ d->mMutex.unlock();
+ }
+}
+
+bool LdapSearchThread::startSearch( const LdapDN &base, LdapUrl::Scope scope,
+ const QString &filter,
+ const QStringList &attributes,
+ int pagesize )
+{
+ kDebug() << "search: base=" << base.toString() << " scope=" << scope << " filter=" << filter
+ << " attributes=" << attributes << " pagesize=" << pagesize << endl;
+ d->mAbort = false;
+ d->mError = 0;
+ d->mErrorString = QString();
+ d->mOp.setConnection( d->mConn );
+ d->mPageSize = pagesize;
+ d->mBase = base;
+ d->mScope = scope;
+ d->mFilter = filter;
+ d->mAttributes = attributes;
+
+ LdapControls savedctrls = d->mOp.serverControls();
+ if ( pagesize ) {
+ LdapControls ctrls = savedctrls;
+ ctrls.append( LdapControl::createPageControl( pagesize ) );
+ d->mOp.setServerControls( ctrls );
+ }
+
+ d->mId = d->mOp.search( base, scope, filter, attributes );
+ if ( pagesize ) {
+ d->mOp.setServerControls( savedctrls );
+ }
+
+ if ( d->mId == -1 ) {
+ return false;
+ }
+
+ kDebug() << "search::startSearch msg id=" << d->mId << endl;
+ return true;
+}
+
+bool LdapSearchThread::pollForMessage()
+{
+ kDebug() << endl << "LdapSearchThread::pollForMessage()" << endl;
+ int res = d->mOp.waitForResult( d->mId, d->mTimeout );
+
+ if ( res == -1 || d->mConn.ldapErrorCode() != KLDAP_SUCCESS ) {
+ kDebug() << "Problem with the search" << endl;
+ d->mError = d->mConn.ldapErrorCode();
+ d->mErrorString = d->mConn.ldapErrorString();
+ emit result( this );
+ return false;
+ }
+
+ if ( res == LdapOperation::RES_SEARCH_RESULT ) {
+ kDebug() << "Got search result" << endl;
+ if ( d->mPageSize ) {
+ QByteArray cookie;
+ int estsize = -1;
+ for ( int i = 0; i < d->mOp.controls().count(); ++i ) {
+ estsize = d->mOp.controls()[i].parsePageControl( cookie );
+ if ( estsize != -1 ) {
+ break;
+ }
+ }
+ kDebug() << " estimated size: " << estsize << endl;
+ if ( estsize != -1 && !cookie.isEmpty() ) {
+ LdapControls ctrls, savedctrls;
+ savedctrls = d->mOp.serverControls();
+ ctrls = savedctrls;
+ ctrls.append( LdapControl::createPageControl( d->mPageSize, cookie ) );
+ d->mOp.setServerControls( ctrls );
+ d->mId = d->mOp.search( d->mBase, d->mScope, d->mFilter, d->mAttributes );
+ d->mOp.setServerControls( savedctrls );
+ if ( d->mId == -1 ) {
+ d->mError = d->mConn.ldapErrorCode();
+ d->mErrorString = d->mConn.ldapErrorString();
+ emit result( this );
+ return false;
+ }
+ //QTimer::singleShot( 0, this, SLOT(result()) );
+ return true;
+ }
+ }
+ emit result( this );
+ return false;
+ }
+
+ if ( res == LdapOperation::RES_SEARCH_ENTRY ) {
+ kDebug() << "Found search entry" << endl;
+ //kDebug() << "\tEmitting signal data(" << this << d->mOp.object().toString() << endl;
+ emit data( this, d->mOp.object() );
+ return true;
+ }
+
+ return true;
+}
+
+#include "ldapsearchthread.moc"
Index: kldap/ldapurl.cpp
===================================================================
--- kldap/ldapurl.cpp (revision 651315)
+++ kldap/ldapurl.cpp (working copy)
@@ -82,9 +82,9 @@
delete d;
}
-void LdapUrl::setDn( const QString &dn )
+void LdapUrl::setDn( const LdapDN &dn )
{
- QString tmp = dn;
+ QString tmp = dn.toString();
if ( !QDir::isRelativePath( tmp ) )
#ifdef Q_WS_WIN
tmp.remove( 0, 3 ); // e.g. "c:/"
@@ -94,7 +94,7 @@
setPath( tmp );
}
-QString LdapUrl::dn() const
+LdapDN LdapUrl::dn() const
{
QString tmp = path();
if ( !QDir::isRelativePath( tmp ) )
@@ -103,7 +103,8 @@
#else
tmp.remove( 0, 1 );
#endif
- return tmp;
+ LdapDN tmpDN( tmp );
+ return tmpDN;
}
QStringList LdapUrl::attributes() const
Index: kldap/ldapoperation.h
===================================================================
--- kldap/ldapoperation.h (revision 651315)
+++ kldap/ldapoperation.h (working copy)
@@ -29,8 +29,11 @@
#include "ldapconnection.h"
#include "ldapcontrol.h"
#include "ldapobject.h"
+#include "ldapdn.h"
#include "ldapserver.h"
#include "ldapurl.h"
+#include "ldap.h"
+//typedef struct ldapmsg LDAPMessage;
namespace KLDAP {
@@ -102,7 +105,7 @@
* Starts a search operation with the given base DN, scope, filter and
* result attributes. Returns a message id if successful, -1 if not.
*/
- int search( const QString &base, LdapUrl::Scope scope,
+ int search( const LdapDN &base, LdapUrl::Scope scope,
const QString &filter, const QStringList &attrs );
/**
* Starts an addition operation.
@@ -188,6 +191,8 @@
* connection().ldapErrorCode() to determine if the operation succeeded.
*/
int result( int id );
+
+ int waitForResult( int id, int msecs = 30000 );
/**
* Returns the result object if result() returned RES_SEARCH_ENTRY.
*/
@@ -220,6 +225,9 @@
QList<QByteArray> referrals() const;
private:
+ int processResult( int rescode, LDAPMessage *msg );
+
+ private:
class LdapOperationPrivate;
LdapOperationPrivate *const d;
Index: kldap/ldapconfigwidget.cpp
===================================================================
--- kldap/ldapconfigwidget.cpp (revision 651315)
+++ kldap/ldapconfigwidget.cpp (working copy)
@@ -330,7 +330,7 @@
if ( mPort ) {
_url.setPort( mPort->value() );
}
- _url.setDn( "" );
+ _url.setDn( LdapDN( "" ) );
_url.setAttributes( QStringList( mAttr ) );
_url.setScope( LdapUrl::Base );
if ( mVersion ) {
@@ -558,7 +558,7 @@
_server.setPort( d->mPort->value() );
}
if ( d->mDn ) {
- _server.setBaseDn( d->mDn->text() );
+ _server.setBaseDn( LdapDN( d->mDn->text() ) );
}
if ( d->mFilter ) {
_server.setFilter( d->mFilter->text() );
@@ -717,16 +717,16 @@
return d->mVersion ? d->mVersion->value() : 3;
}
-void LdapConfigWidget::setDn( const QString &dn )
+void LdapConfigWidget::setDn( const LdapDN &dn )
{
if ( d->mDn ) {
- d->mDn->setText( dn );
+ d->mDn->setText( dn.toString() );
}
}
-QString LdapConfigWidget::dn() const
+LdapDN LdapConfigWidget::dn() const
{
- return d->mDn ? d->mDn->text() : QString();
+ return d->mDn ? LdapDN( d->mDn->text() ) : LdapDN();
}
void LdapConfigWidget::setFilter( const QString &filter )
Index: kldap/ldapsearch.h
===================================================================
--- kldap/ldapsearch.h (revision 651315)
+++ kldap/ldapsearch.h (working copy)
@@ -89,7 +89,7 @@
* Starts a search operation if the LdapConnection object already set
* in the constructor.
*/
- bool search( const QString &base,
+ bool search( const LdapDN &base,
LdapUrl::Scope scope = LdapUrl::Sub,
const QString &filter = QString(),
const QStringList &attributes = QStringList(),
Index: kldap/ldapserver.h
===================================================================
--- kldap/ldapserver.h (revision 651315)
+++ kldap/ldapserver.h (working copy)
@@ -24,6 +24,7 @@
#include <QtCore/QString>
#include "ldapurl.h"
+#include "ldapdn.h"
#include "kldap.h"
namespace KLDAP {
@@ -56,7 +57,7 @@
QString host() const;
int port() const;
- QString baseDn() const;
+ LdapDN baseDn() const;
QString user() const;
QString bindDn() const;
QString realm() const;
@@ -74,7 +75,7 @@
void setHost( const QString &host );
void setPort( int port );
- void setBaseDn( const QString &baseDn );
+ void setBaseDn( const LdapDN &baseDn );
void setUser( const QString &user );
void setBindDn( const QString &bindDn );
void setRealm( const QString &realm );
Index: kabc/plugins/ldapkio/resourceldapkioconfig.cpp
===================================================================
--- kabc/plugins/ldapkio/resourceldapkioconfig.cpp (revision 651315)
+++ kabc/plugins/ldapkio/resourceldapkioconfig.cpp (working copy)
@@ -93,7 +93,7 @@
cfg->setVersion( resource->ver() );
cfg->setTimeLimit( resource->timeLimit() );
cfg->setSizeLimit( resource->sizeLimit() );
- cfg->setDn( resource->dn() );
+ cfg->setDn( KLDAP::LdapDN( resource->dn() ) );
cfg->setFilter( resource->filter() );
cfg->setMech( resource->mech() );
if ( resource->isTLS() ) cfg->setSecurity( KLDAP::LdapConfigWidget::TLS );
@@ -129,7 +129,7 @@
resource->setVer( cfg->version() );
resource->setTimeLimit( cfg->timeLimit() );
resource->setSizeLimit( cfg->sizeLimit() );
- resource->setDn( cfg->dn() );
+ resource->setDn( cfg->dn().toString() );
resource->setFilter( cfg->filter() );
resource->setIsAnonymous( cfg->auth() == KLDAP::LdapConfigWidget::Anonymous );
resource->setIsSASL( cfg->auth() == KLDAP::LdapConfigWidget::SASL );
Index: kabc/plugins/ldapkio/resourceldapkio.cpp
===================================================================
--- kabc/plugins/ldapkio/resourceldapkio.cpp (revision 651315)
+++ kabc/plugins/ldapkio/resourceldapkio.cpp (working copy)
@@ -36,6 +36,7 @@
#include <kio/netaccess.h>
#include "kldap/ldif.h"
+#include "kldap/ldapdn.h"
#include "kldap/ldapurl.h"
#include "resourceldapkio.h"
@@ -399,7 +400,7 @@
d->mLDAPUrl.setProtocol( d->mSSL ? "ldaps" : "ldap");
d->mLDAPUrl.setHost( d->mHost );
d->mLDAPUrl.setPort( d->mPort );
- d->mLDAPUrl.setDn( d->mDn );
+ d->mLDAPUrl.setDn( KLDAP::LdapDN( d->mDn ) );
if (!d->mAttributes.empty()) {
QMap<QString,QString>::Iterator it;
_______________________________________________
kde-pim mailing list
kde-pim@kde.org
https://mail.kde.org/mailman/listinfo/kde-pim
kde-pim home page at http://pim.kde.org/
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic