summaryrefslogtreecommitdiffabout
path: root/kabc
Unidiff
Diffstat (limited to 'kabc') (more/less context) (ignore whitespace changes)
-rw-r--r--kabc/plugins/dir/resourcedir.cpp7
-rw-r--r--kabc/plugins/file/resourcefile.cpp7
-rw-r--r--kabc/plugins/ldap/resourceldap.cpp7
3 files changed, 21 insertions, 0 deletions
diff --git a/kabc/plugins/dir/resourcedir.cpp b/kabc/plugins/dir/resourcedir.cpp
index e2b7b08..c61664b 100644
--- a/kabc/plugins/dir/resourcedir.cpp
+++ b/kabc/plugins/dir/resourcedir.cpp
@@ -1,374 +1,381 @@
1/* 1/*
2 This file is part of libkabc. 2 This file is part of libkabc.
3 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org> 3 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public 6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version. 8 version 2 of the License, or (at your option) any later version.
9 9
10 This library is distributed in the hope that it will be useful, 10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details. 13 Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public License 15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to 16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20 20
21/* 21/*
22Enhanced Version of the file for platform independent KDE tools. 22Enhanced Version of the file for platform independent KDE tools.
23Copyright (c) 2004 Ulf Schenk 23Copyright (c) 2004 Ulf Schenk
24 24
25$Id$ 25$Id$
26*/ 26*/
27 27
28 28
29#include <sys/types.h> 29#include <sys/types.h>
30#include <sys/stat.h> 30#include <sys/stat.h>
31#ifndef _WIN32_ 31#ifndef _WIN32_
32#include <unistd.h> 32#include <unistd.h>
33#endif 33#endif
34 34
35#include <qregexp.h> 35#include <qregexp.h>
36#include <qtimer.h> 36#include <qtimer.h>
37#include <qwidget.h> 37#include <qwidget.h>
38 38
39#include <kapplication.h> 39#include <kapplication.h>
40#include <kconfig.h> 40#include <kconfig.h>
41#include <kdebug.h> 41#include <kdebug.h>
42//US #include <kgenericfactory.h> 42//US #include <kgenericfactory.h>
43#include <kglobal.h> 43#include <kglobal.h>
44#include <klocale.h> 44#include <klocale.h>
45#include <kstandarddirs.h> 45#include <kstandarddirs.h>
46#include <kurlrequester.h> 46#include <kurlrequester.h>
47#include <kmessagebox.h> 47#include <kmessagebox.h>
48 48
49#include "addressbook.h" 49#include "addressbook.h"
50 50
51#include "formatfactory.h" 51#include "formatfactory.h"
52 52
53#include "resourcedirconfig.h" 53#include "resourcedirconfig.h"
54#include "stdaddressbook.h" 54#include "stdaddressbook.h"
55 55
56//US 56//US
57#include <qdir.h> 57#include <qdir.h>
58 58
59#define NO_DIRWATCH 59#define NO_DIRWATCH
60#include "resourcedir.h" 60#include "resourcedir.h"
61 61
62//#define ALLOW_LOCKING 62//#define ALLOW_LOCKING
63 63
64using namespace KABC; 64using namespace KABC;
65 65
66extern "C" 66extern "C"
67#ifdef _WIN32_ 67#ifdef _WIN32_
68__declspec(dllexport) 68__declspec(dllexport)
69#else 69#else
70{ 70{
71#endif 71#endif
72 72
73//US void *init_kabc_dir() 73//US void *init_kabc_dir()
74 void *init_microkabc_dir() 74 void *init_microkabc_dir()
75 { 75 {
76 return new KRES::PluginFactory<ResourceDir,ResourceDirConfig>(); 76 return new KRES::PluginFactory<ResourceDir,ResourceDirConfig>();
77 } 77 }
78#ifndef _WIN32_ 78#ifndef _WIN32_
79} 79}
80#endif 80#endif
81 81
82ResourceDir::ResourceDir( const KConfig *config ) 82ResourceDir::ResourceDir( const KConfig *config )
83 : Resource( config ) 83 : Resource( config )
84{ 84{
85 QString path; 85 QString path;
86 86
87 KConfig *cfg = (KConfig *)config; 87 KConfig *cfg = (KConfig *)config;
88 if ( cfg ) { 88 if ( cfg ) {
89#ifdef _WIN32_
90 // we use plugins on win32. the group is stored in a static variable
91 // such that group info not available on win32 plugins
92 // to fix that, it would be a looooot of work
93 if ( !cfg->tempGroup().isEmpty() )
94 cfg->setGroup( cfg->tempGroup() );
95#endif
89//US path = config->readEntry( "FilePath" ); 96//US path = config->readEntry( "FilePath" );
90 path = cfg->readEntry( "FilePath", StdAddressBook::directoryName() ); 97 path = cfg->readEntry( "FilePath", StdAddressBook::directoryName() );
91//US mFormatName = config->readEntry( "FileFormat" ); 98//US mFormatName = config->readEntry( "FileFormat" );
92 mFormatName = cfg->readEntry( "FileFormat", "vcard" ); 99 mFormatName = cfg->readEntry( "FileFormat", "vcard" );
93 } else { 100 } else {
94 path = StdAddressBook::directoryName(); 101 path = StdAddressBook::directoryName();
95 mFormatName = "vcard"; 102 mFormatName = "vcard";
96 } 103 }
97 104
98 105
99 FormatFactory *factory = FormatFactory::self(); 106 FormatFactory *factory = FormatFactory::self();
100 mFormat = factory->format( mFormatName ); 107 mFormat = factory->format( mFormatName );
101 108
102 if ( !mFormat ) { 109 if ( !mFormat ) {
103 mFormatName = "vcard"; 110 mFormatName = "vcard";
104 mFormat = factory->format( mFormatName ); 111 mFormat = factory->format( mFormatName );
105 } 112 }
106 113
107/*US 114/*US
108//US qDebug("ResourceDir::ResourceDir initialized with format %s ", mFormatName.latin1()); 115//US qDebug("ResourceDir::ResourceDir initialized with format %s ", mFormatName.latin1());
109 if (mFormatName == "vcard") 116 if (mFormatName == "vcard")
110 mFormat = new VCardFormatPlugin2(); 117 mFormat = new VCardFormatPlugin2();
111 else if (mFormatName == "binary") 118 else if (mFormatName == "binary")
112 mFormat = new BinaryFormat(); 119 mFormat = new BinaryFormat();
113 else 120 else
114 qDebug("ResourceFile::init format unknown !!! %s ", mFormatName.latin1()); 121 qDebug("ResourceFile::init format unknown !!! %s ", mFormatName.latin1());
115*/ 122*/
116#ifndef NO_DIRWATCH 123#ifndef NO_DIRWATCH
117 connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( pathChanged() ) ); 124 connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( pathChanged() ) );
118 connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( pathChanged() ) ); 125 connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( pathChanged() ) );
119 connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( pathChanged() ) ); 126 connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( pathChanged() ) );
120#endif 127#endif
121 setPath( path ); 128 setPath( path );
122} 129}
123 130
124ResourceDir::~ResourceDir() 131ResourceDir::~ResourceDir()
125{ 132{
126 delete mFormat; 133 delete mFormat;
127 mFormat = 0; 134 mFormat = 0;
128} 135}
129 136
130void ResourceDir::writeConfig( KConfig *config ) 137void ResourceDir::writeConfig( KConfig *config )
131{ 138{
132 config->setGroup( "Resource_" + identifier() ); 139 config->setGroup( "Resource_" + identifier() );
133 Resource::writeConfig( config ); 140 Resource::writeConfig( config );
134 141
135 config->writeEntry( "FilePath", mPath ); 142 config->writeEntry( "FilePath", mPath );
136 config->writeEntry( "FileFormat", mFormatName ); 143 config->writeEntry( "FileFormat", mFormatName );
137} 144}
138 145
139Ticket *ResourceDir::requestSaveTicket() 146Ticket *ResourceDir::requestSaveTicket()
140{ 147{
141 148
142 149
143 if ( !addressBook() ) return 0; 150 if ( !addressBook() ) return 0;
144#ifdef ALLOW_LOCKING 151#ifdef ALLOW_LOCKING
145 if ( !lock( mPath ) ) { 152 if ( !lock( mPath ) ) {
146 153
147 return 0; 154 return 0;
148 } 155 }
149#endif 156#endif
150 return createTicket( this ); 157 return createTicket( this );
151 158
152} 159}
153 160
154 161
155bool ResourceDir::doOpen() 162bool ResourceDir::doOpen()
156{ 163{
157 QDir dir( mPath ); 164 QDir dir( mPath );
158 if ( !dir.exists() ) { // no directory available 165 if ( !dir.exists() ) { // no directory available
159 return dir.mkdir( dir.path() ); 166 return dir.mkdir( dir.path() );
160 } else { 167 } else {
161 QString testName = dir.entryList( QDir::Files )[0]; 168 QString testName = dir.entryList( QDir::Files )[0];
162 if ( testName.isNull() || testName.isEmpty() ) // no file in directory 169 if ( testName.isNull() || testName.isEmpty() ) // no file in directory
163 return true; 170 return true;
164 171
165 QFile file( mPath + "/" + testName ); 172 QFile file( mPath + "/" + testName );
166 if ( file.open( IO_ReadOnly ) ) 173 if ( file.open( IO_ReadOnly ) )
167 return true; 174 return true;
168 175
169 if ( file.size() == 0 ) 176 if ( file.size() == 0 )
170 return true; 177 return true;
171 178
172 bool ok = mFormat->checkFormat( &file ); 179 bool ok = mFormat->checkFormat( &file );
173 file.close(); 180 file.close();
174 return ok; 181 return ok;
175 } 182 }
176} 183}
177 184
178void ResourceDir::doClose() 185void ResourceDir::doClose()
179{ 186{
180} 187}
181 188
182bool ResourceDir::load() 189bool ResourceDir::load()
183{ 190{
184 QDir dir( mPath ); 191 QDir dir( mPath );
185 QStringList files = dir.entryList( QDir::Files ); 192 QStringList files = dir.entryList( QDir::Files );
186 193
187 QStringList::Iterator it; 194 QStringList::Iterator it;
188 bool ok = true; 195 bool ok = true;
189 for ( it = files.begin(); it != files.end(); ++it ) { 196 for ( it = files.begin(); it != files.end(); ++it ) {
190 QFile file( mPath + "/" + (*it) ); 197 QFile file( mPath + "/" + (*it) );
191 198
192 if ( !file.open( IO_ReadOnly ) ) { 199 if ( !file.open( IO_ReadOnly ) ) {
193 addressBook()->error( i18n( "Unable to open file '%1' for reading" ).arg( file.name() ) ); 200 addressBook()->error( i18n( "Unable to open file '%1' for reading" ).arg( file.name() ) );
194 ok = false; 201 ok = false;
195 continue; 202 continue;
196 } 203 }
197 204
198 if ( !mFormat->loadAll( addressBook(), this, &file ) ) 205 if ( !mFormat->loadAll( addressBook(), this, &file ) )
199 ok = false; 206 ok = false;
200 207
201 file.close(); 208 file.close();
202 } 209 }
203 210
204 return ok; 211 return ok;
205} 212}
206 213
207bool ResourceDir::save( Ticket *ticket ) 214bool ResourceDir::save( Ticket *ticket )
208{ 215{
209 AddressBook::Iterator it; 216 AddressBook::Iterator it;
210 bool ok = true; 217 bool ok = true;
211#ifndef NO_DIRWATCH 218#ifndef NO_DIRWATCH
212 mDirWatch.stopScan(); 219 mDirWatch.stopScan();
213#endif 220#endif
214 for ( it = addressBook()->begin(); it != addressBook()->end(); ++it ) { 221 for ( it = addressBook()->begin(); it != addressBook()->end(); ++it ) {
215 if ( (*it).resource() != this || !(*it).changed() ) 222 if ( (*it).resource() != this || !(*it).changed() )
216 continue; 223 continue;
217 224
218 QFile file( mPath + "/" + (*it).uid() ); 225 QFile file( mPath + "/" + (*it).uid() );
219 if ( !file.open( IO_WriteOnly ) ) { 226 if ( !file.open( IO_WriteOnly ) ) {
220 addressBook()->error( i18n( "Unable to open file '%1' for writing" ).arg( file.name() ) ); 227 addressBook()->error( i18n( "Unable to open file '%1' for writing" ).arg( file.name() ) );
221 continue; 228 continue;
222 } 229 }
223 230
224 mFormat->save( *it, &file ); 231 mFormat->save( *it, &file );
225 232
226 // mark as unchanged 233 // mark as unchanged
227 (*it).setChanged( false ); 234 (*it).setChanged( false );
228 235
229 file.close(); 236 file.close();
230 } 237 }
231#ifndef NO_DIRWATCH 238#ifndef NO_DIRWATCH
232 mDirWatch.startScan(); 239 mDirWatch.startScan();
233#endif 240#endif
234 delete ticket; 241 delete ticket;
235#ifdef ALLOW_LOCKING 242#ifdef ALLOW_LOCKING
236 unlock( mPath ); 243 unlock( mPath );
237#endif 244#endif
238 return ok; 245 return ok;
239} 246}
240 247
241bool ResourceDir::lock( const QString &path ) 248bool ResourceDir::lock( const QString &path )
242{ 249{
243#ifdef ALLOW_LOCKING 250#ifdef ALLOW_LOCKING
244 QString p = path; 251 QString p = path;
245//US change the implementation how the lockfilename is getting created 252//US change the implementation how the lockfilename is getting created
246//US p.replace( QRegExp("/"), "_" ); 253//US p.replace( QRegExp("/"), "_" );
247//US QString lockName = locateLocal( "data", "kabc/lock/" + p + ".lock" ); 254//US QString lockName = locateLocal( "data", "kabc/lock/" + p + ".lock" );
248 KURL url(p); 255 KURL url(p);
249 QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" ); 256 QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" );
250 257
251 258
252 if ( QFile::exists( lockName ) ) return false; 259 if ( QFile::exists( lockName ) ) return false;
253 260
254 QString lockUniqueName; 261 QString lockUniqueName;
255 lockUniqueName = p + KApplication::randomString( 8 ); 262 lockUniqueName = p + KApplication::randomString( 8 );
256 263
257 url = lockUniqueName; 264 url = lockUniqueName;
258//US mLockUniqueName = locateLocal( "data", "kabc/lock/" + lockUniqueName ); 265//US mLockUniqueName = locateLocal( "data", "kabc/lock/" + lockUniqueName );
259 mLockUniqueName = locateLocal( "data", "kabc/lock/" + url.fileName() ); 266 mLockUniqueName = locateLocal( "data", "kabc/lock/" + url.fileName() );
260 267
261 // Create unique file 268 // Create unique file
262 QFile file( mLockUniqueName ); 269 QFile file( mLockUniqueName );
263 file.open( IO_WriteOnly ); 270 file.open( IO_WriteOnly );
264 file.close(); 271 file.close();
265 272
266 // Create lock file 273 // Create lock file
267 int result = 0; 274 int result = 0;
268#ifndef _WIN32_ 275#ifndef _WIN32_
269 result = ::link( QFile::encodeName( mLockUniqueName ), 276 result = ::link( QFile::encodeName( mLockUniqueName ),
270 QFile::encodeName( lockName ) ); 277 QFile::encodeName( lockName ) );
271#endif 278#endif
272 if ( result == 0 ) { 279 if ( result == 0 ) {
273 addressBook()->emitAddressBookLocked(); 280 addressBook()->emitAddressBookLocked();
274 return true; 281 return true;
275 } 282 }
276 283
277 // TODO: check stat 284 // TODO: check stat
278 285
279 return false; 286 return false;
280#else 287#else
281 return true; 288 return true;
282#endif 289#endif
283} 290}
284 291
285void ResourceDir::unlock( const QString &path ) 292void ResourceDir::unlock( const QString &path )
286{ 293{
287#ifdef ALLOW_LOCKING 294#ifdef ALLOW_LOCKING
288 QString p = path; 295 QString p = path;
289//US change the implementation how the lockfilename is getting created 296//US change the implementation how the lockfilename is getting created
290//US p.replace( QRegExp( "/" ), "_" ); 297//US p.replace( QRegExp( "/" ), "_" );
291//US QString lockName = locate( "data", "kabc/lock/" + p + ".lock" ); 298//US QString lockName = locate( "data", "kabc/lock/" + p + ".lock" );
292 KURL url(p); 299 KURL url(p);
293 QString lockName = locate( "data", "kabc/lock/" + url.fileName() + ".lock" ); 300 QString lockName = locate( "data", "kabc/lock/" + url.fileName() + ".lock" );
294 301
295 ::unlink( QFile::encodeName( lockName ) ); 302 ::unlink( QFile::encodeName( lockName ) );
296 QFile::remove( mLockUniqueName ); 303 QFile::remove( mLockUniqueName );
297 addressBook()->emitAddressBookUnlocked(); 304 addressBook()->emitAddressBookUnlocked();
298#else 305#else
299 return; 306 return;
300#endif 307#endif
301} 308}
302 309
303void ResourceDir::setPath( const QString &path ) 310void ResourceDir::setPath( const QString &path )
304{ 311{
305#ifndef NO_DIRWATCH 312#ifndef NO_DIRWATCH
306 mDirWatch.stopScan(); 313 mDirWatch.stopScan();
307 mDirWatch.removeDir( mPath ); 314 mDirWatch.removeDir( mPath );
308 315
309 mPath = path; 316 mPath = path;
310 317
311 mDirWatch.addDir( mPath, true ); 318 mDirWatch.addDir( mPath, true );
312 mDirWatch.startScan(); 319 mDirWatch.startScan();
313#else 320#else
314 mPath = path; 321 mPath = path;
315#endif 322#endif
316//US simulate KDirWatch event 323//US simulate KDirWatch event
317//US pathChanged(); 324//US pathChanged();
318 325
319} 326}
320 327
321QString ResourceDir::path() const 328QString ResourceDir::path() const
322{ 329{
323 return mPath; 330 return mPath;
324} 331}
325 332
326void ResourceDir::setFormat( const QString &format ) 333void ResourceDir::setFormat( const QString &format )
327{ 334{
328 mFormatName = format; 335 mFormatName = format;
329 336
330 if ( mFormat ) 337 if ( mFormat )
331 delete mFormat; 338 delete mFormat;
332 339
333 FormatFactory *factory = FormatFactory::self(); 340 FormatFactory *factory = FormatFactory::self();
334 mFormat = factory->format( mFormatName ); 341 mFormat = factory->format( mFormatName );
335/*US 342/*US
336qDebug("ResourceDir::setFormat initialized with format %s ", format.latin1()); 343qDebug("ResourceDir::setFormat initialized with format %s ", format.latin1());
337 if (mFormatName == "vcard") 344 if (mFormatName == "vcard")
338 mFormat = new VCardFormatPlugin2(); 345 mFormat = new VCardFormatPlugin2();
339 else if (mFormatName == "binary") 346 else if (mFormatName == "binary")
340 mFormat = new BinaryFormat(); 347 mFormat = new BinaryFormat();
341 else 348 else
342 qDebug("ResourceDir::setFormat format unknown !!! %s ", format.latin1()); 349 qDebug("ResourceDir::setFormat format unknown !!! %s ", format.latin1());
343*/ 350*/
344 351
345} 352}
346 353
347QString ResourceDir::format() const 354QString ResourceDir::format() const
348{ 355{
349 return mFormatName; 356 return mFormatName;
350} 357}
351 358
352void ResourceDir::pathChanged() 359void ResourceDir::pathChanged()
353{ 360{
354 if ( !addressBook() ) 361 if ( !addressBook() )
355 return; 362 return;
356 363
357 QString text( i18n( "Dir resource '%1'<br> has been changed by third party.<br>Do you want to reload?").arg( mPath ) ); 364 QString text( i18n( "Dir resource '%1'<br> has been changed by third party.<br>Do you want to reload?").arg( mPath ) );
358 if ( readOnly() || KMessageBox::questionYesNo( 0, text ) == KMessageBox::Yes ) { 365 if ( readOnly() || KMessageBox::questionYesNo( 0, text ) == KMessageBox::Yes ) {
359 load(); 366 load();
360 addressBook()->emitAddressBookChanged(); 367 addressBook()->emitAddressBookChanged();
361 } 368 }
362} 369}
363 370
364void ResourceDir::removeAddressee( const Addressee& addr ) 371void ResourceDir::removeAddressee( const Addressee& addr )
365{ 372{
366 QFile::remove( mPath + "/" + addr.uid() ); 373 QFile::remove( mPath + "/" + addr.uid() );
367} 374}
368 375
369void ResourceDir::cleanUp() 376void ResourceDir::cleanUp()
370{ 377{
371 unlock( mPath ); 378 unlock( mPath );
372} 379}
373 380
374//US #include "resourcedir.moc" 381//US #include "resourcedir.moc"
diff --git a/kabc/plugins/file/resourcefile.cpp b/kabc/plugins/file/resourcefile.cpp
index c89939d..dad4571 100644
--- a/kabc/plugins/file/resourcefile.cpp
+++ b/kabc/plugins/file/resourcefile.cpp
@@ -1,469 +1,476 @@
1/* 1/*
2 This file is part of libkabc. 2 This file is part of libkabc.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> 3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public 6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version. 8 version 2 of the License, or (at your option) any later version.
9 9
10 This library is distributed in the hope that it will be useful, 10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details. 13 Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public License 15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to 16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20 20
21/* 21/*
22Enhanced Version of the file for platform independent KDE tools. 22Enhanced Version of the file for platform independent KDE tools.
23Copyright (c) 2004 Ulf Schenk 23Copyright (c) 2004 Ulf Schenk
24 24
25$Id$ 25$Id$
26*/ 26*/
27 27
28#include <sys/types.h> 28#include <sys/types.h>
29#include <sys/stat.h> 29#include <sys/stat.h>
30#ifndef _WIN32_ 30#ifndef _WIN32_
31#include <unistd.h> 31#include <unistd.h>
32#endif 32#endif
33 33
34#include <qfile.h> 34#include <qfile.h>
35#include <qfileinfo.h> 35#include <qfileinfo.h>
36#include <qregexp.h> 36#include <qregexp.h>
37#include <qtimer.h> 37#include <qtimer.h>
38 38
39#include <kapplication.h> 39#include <kapplication.h>
40#include <kconfig.h> 40#include <kconfig.h>
41#include <kdebug.h> 41#include <kdebug.h>
42#include <klocale.h> 42#include <klocale.h>
43//US #include <ksavefile.h> 43//US #include <ksavefile.h>
44#include <kstandarddirs.h> 44#include <kstandarddirs.h>
45#include <kmessagebox.h> 45#include <kmessagebox.h>
46#include <kglobalsettings.h> 46#include <kglobalsettings.h>
47 47
48#include "formatfactory.h" 48#include "formatfactory.h"
49 49
50#include "resource.h" 50#include "resource.h"
51#include "resourcefileconfig.h" 51#include "resourcefileconfig.h"
52#include "stdaddressbook.h" 52#include "stdaddressbook.h"
53#define NO_DIRWATCH 53#define NO_DIRWATCH
54#include "resourcefile.h" 54#include "resourcefile.h"
55 55
56//#define ALLOW_LOCKING 56//#define ALLOW_LOCKING
57 57
58 58
59using namespace KABC; 59using namespace KABC;
60 60
61extern "C" 61extern "C"
62#ifdef _WIN32_ 62#ifdef _WIN32_
63__declspec(dllexport) 63__declspec(dllexport)
64#else 64#else
65{ 65{
66#endif 66#endif
67 67
68//US void *init_kabc_file() 68//US void *init_kabc_file()
69 void *init_microkabc_file() 69 void *init_microkabc_file()
70 { 70 {
71 return new KRES::PluginFactory<ResourceFile,ResourceFileConfig>(); 71 return new KRES::PluginFactory<ResourceFile,ResourceFileConfig>();
72 } 72 }
73#ifndef _WIN32_ 73#ifndef _WIN32_
74} 74}
75#endif 75#endif
76 76
77ResourceFile::ResourceFile( const KConfig *config ) 77ResourceFile::ResourceFile( const KConfig *config )
78 : Resource( config ) , mFormat( 0 ) 78 : Resource( config ) , mFormat( 0 )
79{ 79{
80 QString fileName, formatName, default_fileName; 80 QString fileName, formatName, default_fileName;
81 81
82 default_fileName = StdAddressBook::fileName(); 82 default_fileName = StdAddressBook::fileName();
83 mLastBackupDate = -1; 83 mLastBackupDate = -1;
84 KConfig *cfg = (KConfig *)config; 84 KConfig *cfg = (KConfig *)config;
85 if ( cfg ) { 85 if ( cfg ) {
86#ifdef _WIN32_
87 // we use plugins on win32. the group is stored in a static variable
88 // such that group info not available on win32 plugins
89 // to fix that, it would be a looooot of work
90 if ( !cfg->tempGroup().isEmpty() )
91 cfg->setGroup( cfg->tempGroup() );
92#endif
86 fileName = cfg->readEntry( "FileName", default_fileName ); 93 fileName = cfg->readEntry( "FileName", default_fileName );
87 formatName = cfg->readEntry( "FileFormat", "vcard" ); 94 formatName = cfg->readEntry( "FileFormat", "vcard" );
88 mFamily = cfg->readEntry( "ResourceName", "std" ); 95 mFamily = cfg->readEntry( "ResourceName", "std" );
89 mLastBackupDate = cfg->readNumEntry( "LastBackupDate", 0 ); 96 mLastBackupDate = cfg->readNumEntry( "LastBackupDate", 0 );
90 } else { 97 } else {
91 fileName = default_fileName; 98 fileName = default_fileName;
92 formatName = "vcard"; 99 formatName = "vcard";
93 } 100 }
94 101
95 init( fileName, formatName ); 102 init( fileName, formatName );
96} 103}
97 104
98ResourceFile::ResourceFile( const QString &fileName , 105ResourceFile::ResourceFile( const QString &fileName ,
99 const QString &formatName ) 106 const QString &formatName )
100 : Resource( 0 ) 107 : Resource( 0 )
101{ 108{
102// qDebug("ResourceFile::ResourceFile : 3 %s, %s", fileName.latin1(), formatName.latin1()); 109// qDebug("ResourceFile::ResourceFile : 3 %s, %s", fileName.latin1(), formatName.latin1());
103 110
104 111
105 mLastBackupDate = -1; 112 mLastBackupDate = -1;
106 init( fileName, formatName ); 113 init( fileName, formatName );
107} 114}
108 115
109void ResourceFile::init( const QString &fileName, const QString &formatName ) 116void ResourceFile::init( const QString &fileName, const QString &formatName )
110{ 117{
111 mFormatName = formatName; 118 mFormatName = formatName;
112 119
113 FormatFactory *factory = FormatFactory::self(); 120 FormatFactory *factory = FormatFactory::self();
114 mFormat = factory->format( mFormatName ); 121 mFormat = factory->format( mFormatName );
115 122
116 if ( !mFormat ) { 123 if ( !mFormat ) {
117 mFormatName = "vcard"; 124 mFormatName = "vcard";
118 mFormat = factory->format( mFormatName ); 125 mFormat = factory->format( mFormatName );
119 } 126 }
120 127
121#ifndef NO_DIRWATCH 128#ifndef NO_DIRWATCH
122 connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( fileChanged() ) ); 129 connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( fileChanged() ) );
123 connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( fileChanged() ) ); 130 connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( fileChanged() ) );
124 connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( fileChanged() ) ); 131 connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( fileChanged() ) );
125#endif 132#endif
126 133
127 QString localKdeDir; 134 QString localKdeDir;
128 localKdeDir = readEnvPath("LOCALMICROKDEHOME"); 135 localKdeDir = readEnvPath("LOCALMICROKDEHOME");
129 if ( ! localKdeDir.isEmpty() ) { 136 if ( ! localKdeDir.isEmpty() ) {
130 qDebug("LOCALMICROKDEHOME is set to: %s",localKdeDir.latin1() ); 137 qDebug("LOCALMICROKDEHOME is set to: %s",localKdeDir.latin1() );
131 QFileInfo fi ( fileName ); 138 QFileInfo fi ( fileName );
132 QString localname = localKdeDir + "/apps/kabc/" + fi.fileName (); 139 QString localname = localKdeDir + "/apps/kabc/" + fi.fileName ();
133 QFileInfo fi2 ( localname ); 140 QFileInfo fi2 ( localname );
134 if ( ! fi2.exists() || mFamily == "sync_res" ) { 141 if ( ! fi2.exists() || mFamily == "sync_res" ) {
135 if ( fi.exists() && mFamily == "sync_res") { 142 if ( fi.exists() && mFamily == "sync_res") {
136 qDebug("LOCAL mode SYNC mode using absolute file path "); 143 qDebug("LOCAL mode SYNC mode using absolute file path ");
137 setFileName( fileName ); 144 setFileName( fileName );
138 return; 145 return;
139 } else { 146 } else {
140 KMessageBox::error(0,i18n("Addressbook resource file not found:\n '%1'.\nIn LOCAL mode only resource files in\n'%2'\nare supported.\n(i.e. in the dir ./apps/kabc/ relative to the kapi(.exe) binary.)\n\nIf you are starting KA/Pi for the very first time\nyou will get this error message as well.\nIt will create the missing file automatically for you.").arg(localname).arg(localKdeDir+"/apps/kabc/") ); 147 KMessageBox::error(0,i18n("Addressbook resource file not found:\n '%1'.\nIn LOCAL mode only resource files in\n'%2'\nare supported.\n(i.e. in the dir ./apps/kabc/ relative to the kapi(.exe) binary.)\n\nIf you are starting KA/Pi for the very first time\nyou will get this error message as well.\nIt will create the missing file automatically for you.").arg(localname).arg(localKdeDir+"/apps/kabc/") );
141 setFileName( localname ); 148 setFileName( localname );
142 return; 149 return;
143 } 150 }
144 151
145 } else { 152 } else {
146 qDebug("Local resource file found. Changing filename to: %s",localname.latin1() ); 153 qDebug("Local resource file found. Changing filename to: %s",localname.latin1() );
147 setFileName( localname ); 154 setFileName( localname );
148 return; 155 return;
149 } 156 }
150 157
151 } 158 }
152 setFileName( fileName ); 159 setFileName( fileName );
153} 160}
154 161
155ResourceFile::~ResourceFile() 162ResourceFile::~ResourceFile()
156{ 163{
157 delete mFormat; 164 delete mFormat;
158 mFormat = 0; 165 mFormat = 0;
159} 166}
160 167
161void ResourceFile::writeConfig( KConfig *config ) 168void ResourceFile::writeConfig( KConfig *config )
162{ 169{
163 170
164 config->setGroup( "Resource_" + identifier() ); 171 config->setGroup( "Resource_" + identifier() );
165 Resource::writeConfig( config ); 172 Resource::writeConfig( config );
166 173
167 config->writeEntry( "FileName", fileName() ); 174 config->writeEntry( "FileName", fileName() );
168 config->writeEntry( "FileFormat", mFormatName ); 175 config->writeEntry( "FileFormat", mFormatName );
169 176
170// qDebug("ResourceFile::writeConfig format %s, %s", mFileName.latin1(), mFormatName.latin1()); 177// qDebug("ResourceFile::writeConfig format %s, %s", mFileName.latin1(), mFormatName.latin1());
171 178
172} 179}
173 180
174Ticket *ResourceFile::requestSaveTicket() 181Ticket *ResourceFile::requestSaveTicket()
175{ 182{
176 kdDebug(5700) << "ResourceFile::requestSaveTicket()" << endl; 183 kdDebug(5700) << "ResourceFile::requestSaveTicket()" << endl;
177 184
178 if ( !addressBook() ) return 0; 185 if ( !addressBook() ) return 0;
179 186
180#ifdef ALLOW_LOCKING 187#ifdef ALLOW_LOCKING
181 if ( !lock( mFileName ) ) { 188 if ( !lock( mFileName ) ) {
182 qDebug("unablt to lock file "); 189 qDebug("unablt to lock file ");
183 return 0; 190 return 0;
184 } 191 }
185#endif 192#endif
186 return createTicket( this ); 193 return createTicket( this );
187} 194}
188 195
189 196
190bool ResourceFile::doOpen() 197bool ResourceFile::doOpen()
191{ 198{
192 QFile file( fileName() ); 199 QFile file( fileName() );
193 qDebug("ResourceFile::openfile %s ", fileName().latin1()); 200 qDebug("ResourceFile::openfile %s ", fileName().latin1());
194 201
195 if ( !file.exists() ) { 202 if ( !file.exists() ) {
196 // try to create the file 203 // try to create the file
197 bool ok = file.open( IO_WriteOnly ); 204 bool ok = file.open( IO_WriteOnly );
198 if ( ok ) 205 if ( ok )
199 file.close(); 206 file.close();
200 207
201 return ok; 208 return ok;
202 } else { 209 } else {
203 if ( !file.open( IO_ReadWrite ) ) 210 if ( !file.open( IO_ReadWrite ) )
204 return false; 211 return false;
205 212
206 if ( file.size() < 10 ) { 213 if ( file.size() < 10 ) {
207 file.close(); 214 file.close();
208 return true; 215 return true;
209 } 216 }
210 217
211 bool ok = mFormat->checkFormat( &file ); 218 bool ok = mFormat->checkFormat( &file );
212 file.close(); 219 file.close();
213 220
214 return ok; 221 return ok;
215 } 222 }
216} 223}
217 224
218void ResourceFile::doClose() 225void ResourceFile::doClose()
219{ 226{
220} 227}
221 228
222bool ResourceFile::load() 229bool ResourceFile::load()
223{ 230{
224 231
225 QFile file( fileName() ); 232 QFile file( fileName() );
226 if ( !file.open( IO_ReadOnly ) ) { 233 if ( !file.open( IO_ReadOnly ) ) {
227 addressBook()->error( i18n( "Unable to open file '%1'." ).arg( fileName() ) ); 234 addressBook()->error( i18n( "Unable to open file '%1'." ).arg( fileName() ) );
228 return false; 235 return false;
229 } 236 }
230 237
231// qDebug("ResourceFile::load format %s, %s", mFileName.latin1(), mFormatName.latin1()); 238// qDebug("ResourceFile::load format %s, %s", mFileName.latin1(), mFormatName.latin1());
232 239
233 return mFormat->loadAll( addressBook(), this, &file ); 240 return mFormat->loadAll( addressBook(), this, &file );
234} 241}
235 242
236bool ResourceFile::save( Ticket *ticket ) 243bool ResourceFile::save( Ticket *ticket )
237{ 244{
238// qDebug("ResourceFile::save format %s, %s", mFileName.latin1(), mFormatName.latin1()); 245// qDebug("ResourceFile::save format %s, %s", mFileName.latin1(), mFormatName.latin1());
239 246
240 247
241 // create backup file 248 // create backup file
242 QString extension = "_" + QString::number( QDate::currentDate().dayOfWeek() ); 249 QString extension = "_" + QString::number( QDate::currentDate().dayOfWeek() );
243 250
244/*US we use a simpler method to create a backupfile 251/*US we use a simpler method to create a backupfile
245 252
246 (void) KSaveFile::backupFile( mFileName, QString::null 253 (void) KSaveFile::backupFile( mFileName, QString::null
247 ,extension ); 254 ,extension );
248 255
249 KSaveFile saveFile( mFileName ); 256 KSaveFile saveFile( mFileName );
250 bool ok = false; 257 bool ok = false;
251 if ( saveFile.status() == 0 && saveFile.file() ) 258 if ( saveFile.status() == 0 && saveFile.file() )
252 { 259 {
253 mFormat->saveAll( addressBook(), this, saveFile.file() ); 260 mFormat->saveAll( addressBook(), this, saveFile.file() );
254 ok = saveFile.close(); 261 ok = saveFile.close();
255 } 262 }
256*/ 263*/
257 264
258//US ToDo: write backupfile 265//US ToDo: write backupfile
259#ifndef NO_DIRWATCH 266#ifndef NO_DIRWATCH
260 mDirWatch.stopScan(); 267 mDirWatch.stopScan();
261#endif 268#endif
262 if ( mLastBackupDate >= 0 && mFamily != "sync_res") { 269 if ( mLastBackupDate >= 0 && mFamily != "sync_res") {
263 KConfig conf (locateLocal("config","microkdeglobalrc")); 270 KConfig conf (locateLocal("config","microkdeglobalrc"));
264 conf.setGroup( "BackupSettings" ); 271 conf.setGroup( "BackupSettings" );
265 bool b_enabled = conf.readBoolEntry( "BackupEnabled" ); 272 bool b_enabled = conf.readBoolEntry( "BackupEnabled" );
266 if ( b_enabled ) { 273 if ( b_enabled ) {
267 int num = conf.readNumEntry( "BackupNumbers" ); 274 int num = conf.readNumEntry( "BackupNumbers" );
268 int d_count = conf.readNumEntry( "BackupDayCount" ); 275 int d_count = conf.readNumEntry( "BackupDayCount" );
269 bool stdDir = conf.readBoolEntry( "BackupUseDefaultDir" ); 276 bool stdDir = conf.readBoolEntry( "BackupUseDefaultDir" );
270 QString bupDir = conf.readEntry( "BackupDatadir" ); 277 QString bupDir = conf.readEntry( "BackupDatadir" );
271 QDate reference ( 2000,1,1 ); 278 QDate reference ( 2000,1,1 );
272 int daysTo = reference.daysTo ( QDate::currentDate() ); 279 int daysTo = reference.daysTo ( QDate::currentDate() );
273 bool saveDate = false; 280 bool saveDate = false;
274 if ( daysTo - d_count >= mLastBackupDate ) { 281 if ( daysTo - d_count >= mLastBackupDate ) {
275 qDebug("KA: Last backup was %d days ago ", daysTo - mLastBackupDate ); 282 qDebug("KA: Last backup was %d days ago ", daysTo - mLastBackupDate );
276 if ( stdDir ) 283 if ( stdDir )
277 bupDir = KGlobalSettings::backupDataDir(); 284 bupDir = KGlobalSettings::backupDataDir();
278 int retval = KApplication::createBackup( fileName(), bupDir, num ); 285 int retval = KApplication::createBackup( fileName(), bupDir, num );
279 if ( retval == 0 ) { 286 if ( retval == 0 ) {
280 qDebug("KO: Backup cancelled. Will try again tomorrow "); 287 qDebug("KO: Backup cancelled. Will try again tomorrow ");
281 // retval == 0 : backup skipped for today, try again tomorrow 288 // retval == 0 : backup skipped for today, try again tomorrow
282 mLastBackupDate = daysTo - d_count+1; 289 mLastBackupDate = daysTo - d_count+1;
283 saveDate = true; 290 saveDate = true;
284 } else if ( retval == 1 ){ 291 } else if ( retval == 1 ){
285 qDebug("KO: Backup created."); 292 qDebug("KO: Backup created.");
286 // backup ok 293 // backup ok
287 mLastBackupDate = daysTo; 294 mLastBackupDate = daysTo;
288 saveDate = true; 295 saveDate = true;
289 } else if ( retval == 2 ){ 296 } else if ( retval == 2 ){
290 qDebug("KO: Backup globally cancelled."); 297 qDebug("KO: Backup globally cancelled.");
291 // backup globally cancelled 298 // backup globally cancelled
292 b_enabled = false; 299 b_enabled = false;
293 } 300 }
294 if ( !b_enabled ) { 301 if ( !b_enabled ) {
295 conf.writeEntry( "mBackupEnabled", false ); 302 conf.writeEntry( "mBackupEnabled", false );
296 } 303 }
297 if ( saveDate ) { 304 if ( saveDate ) {
298 KConfig config ( locateLocal("config","kabcrc") ); 305 KConfig config ( locateLocal("config","kabcrc") );
299 config.setGroup( "Resource_" + identifier() ); 306 config.setGroup( "Resource_" + identifier() );
300 config.writeEntry( "LastBackupDate", mLastBackupDate ); 307 config.writeEntry( "LastBackupDate", mLastBackupDate );
301 } 308 }
302 } 309 }
303 } 310 }
304 } 311 }
305 QFile info; 312 QFile info;
306 info.setName( fileName() ); 313 info.setName( fileName() );
307 bool ok = info.open( IO_WriteOnly ); 314 bool ok = info.open( IO_WriteOnly );
308 if ( ok ) { 315 if ( ok ) {
309 mFormat->saveAll( addressBook(), this, &info ); 316 mFormat->saveAll( addressBook(), this, &info );
310 317
311 info.close(); 318 info.close();
312 ok = true; 319 ok = true;
313 } 320 }
314 else { 321 else {
315 322
316 } 323 }
317 324
318 if ( !ok ) 325 if ( !ok )
319 addressBook()->error( i18n( "Unable to save file '%1'." ).arg( fileName() ) ); 326 addressBook()->error( i18n( "Unable to save file '%1'." ).arg( fileName() ) );
320#ifndef NO_DIRWATCH 327#ifndef NO_DIRWATCH
321 mDirWatch.startScan(); 328 mDirWatch.startScan();
322#endif 329#endif
323 delete ticket; 330 delete ticket;
324#ifdef ALLOW_LOCKING 331#ifdef ALLOW_LOCKING
325 unlock( mFileName ); 332 unlock( mFileName );
326#endif 333#endif
327 334
328 return ok; 335 return ok;
329} 336}
330 337
331bool ResourceFile::lock( const QString &fileName ) 338bool ResourceFile::lock( const QString &fileName )
332{ 339{
333#ifdef ALLOW_LOCKING 340#ifdef ALLOW_LOCKING
334 341
335 342
336 QString fn = fileName; 343 QString fn = fileName;
337 344
338//US change the implementation how the lockfilename is getting created 345//US change the implementation how the lockfilename is getting created
339//US fn.replace( QRegExp("/"), "_" ); 346//US fn.replace( QRegExp("/"), "_" );
340//US QString lockName = locateLocal( "data", "kabc/lock/" + fn + ".lock" ); 347//US QString lockName = locateLocal( "data", "kabc/lock/" + fn + ".lock" );
341 348
342 KURL url(fn); 349 KURL url(fn);
343 QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" ); 350 QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" );
344 351
345 352
346 353
347 if (QFile::exists( lockName )) return false; 354 if (QFile::exists( lockName )) return false;
348 355
349 QString lockUniqueName; 356 QString lockUniqueName;
350 lockUniqueName = fn + KApplication::randomString( 8 ); 357 lockUniqueName = fn + KApplication::randomString( 8 );
351 358
352 url = lockUniqueName; 359 url = lockUniqueName;
353//US mLockUniqueName = locateLocal( "data", "kabc/lock/" + lockUniqueName ); 360//US mLockUniqueName = locateLocal( "data", "kabc/lock/" + lockUniqueName );
354 mLockUniqueName = locateLocal( "data", "kabc/lock/" + url.fileName() ); 361 mLockUniqueName = locateLocal( "data", "kabc/lock/" + url.fileName() );
355 kdDebug(5700) << "-- lock unique name: " << mLockUniqueName << endl; 362 kdDebug(5700) << "-- lock unique name: " << mLockUniqueName << endl;
356 363
357 // Create unique file 364 // Create unique file
358 QFile file( mLockUniqueName ); 365 QFile file( mLockUniqueName );
359 file.open( IO_WriteOnly ); 366 file.open( IO_WriteOnly );
360 file.close(); 367 file.close();
361 368
362 // Create lock file 369 // Create lock file
363 int result = 0; 370 int result = 0;
364#ifndef _WIN32_ 371#ifndef _WIN32_
365 result = ::link( QFile::encodeName( mLockUniqueName ), 372 result = ::link( QFile::encodeName( mLockUniqueName ),
366 QFile::encodeName( lockName ) ); 373 QFile::encodeName( lockName ) );
367#endif 374#endif
368 if ( result == 0 ) { 375 if ( result == 0 ) {
369 addressBook()->emitAddressBookLocked(); 376 addressBook()->emitAddressBookLocked();
370 return true; 377 return true;
371 } 378 }
372 379
373 // TODO: check stat 380 // TODO: check stat
374 381
375 return false; 382 return false;
376#else 383#else
377 return true; 384 return true;
378#endif 385#endif
379} 386}
380 387
381void ResourceFile::unlock( const QString &fileName ) 388void ResourceFile::unlock( const QString &fileName )
382{ 389{
383#ifdef ALLOW_LOCKING 390#ifdef ALLOW_LOCKING
384 QString fn = fileName; 391 QString fn = fileName;
385//US change the implementation how the lockfilename is getting created 392//US change the implementation how the lockfilename is getting created
386//US fn.replace( QRegExp( "/" ), "_" ); 393//US fn.replace( QRegExp( "/" ), "_" );
387//US QString lockName = locateLocal( "data", "kabc/lock/" + fn + ".lock" ); 394//US QString lockName = locateLocal( "data", "kabc/lock/" + fn + ".lock" );
388//US QString lockName = fn + ".lock"; 395//US QString lockName = fn + ".lock";
389 KURL url(fn); 396 KURL url(fn);
390 QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" ); 397 QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" );
391 398
392 QFile::remove( lockName ); 399 QFile::remove( lockName );
393 QFile::remove( mLockUniqueName ); 400 QFile::remove( mLockUniqueName );
394 addressBook()->emitAddressBookUnlocked(); 401 addressBook()->emitAddressBookUnlocked();
395#else 402#else
396 return; 403 return;
397#endif 404#endif
398} 405}
399 406
400void ResourceFile::setFileName( const QString &fileName ) 407void ResourceFile::setFileName( const QString &fileName )
401{ 408{
402#ifndef NO_DIRWATCH 409#ifndef NO_DIRWATCH
403 mDirWatch.stopScan(); 410 mDirWatch.stopScan();
404 mDirWatch.removeFile( mFileName ); 411 mDirWatch.removeFile( mFileName );
405 mFileName = fileName; 412 mFileName = fileName;
406 413
407 414
408 mDirWatch.addFile( mFileName ); 415 mDirWatch.addFile( mFileName );
409 mDirWatch.startScan(); 416 mDirWatch.startScan();
410#else 417#else
411 mFileName2 = fileName; 418 mFileName2 = fileName;
412#endif 419#endif
413 420
414//US simulate KDirWatch event 421//US simulate KDirWatch event
415//US fileChanged(); 422//US fileChanged();
416} 423}
417 424
418QString ResourceFile::fileName() const 425QString ResourceFile::fileName() const
419{ 426{
420 return mFileName2; 427 return mFileName2;
421} 428}
422 429
423void ResourceFile::setFormat( const QString &format ) 430void ResourceFile::setFormat( const QString &format )
424{ 431{
425 mFormatName = format; 432 mFormatName = format;
426 delete mFormat; 433 delete mFormat;
427 434
428 FormatFactory *factory = FormatFactory::self(); 435 FormatFactory *factory = FormatFactory::self();
429 mFormat = factory->format( mFormatName ); 436 mFormat = factory->format( mFormatName );
430/*US 437/*US
431//qDebug("ResourceFile::setFormat initialized with format %s ", format.latin1()); 438//qDebug("ResourceFile::setFormat initialized with format %s ", format.latin1());
432 if (mFormatName == "vcard") { 439 if (mFormatName == "vcard") {
433 mFormat = new VCardFormatPlugin2(); 440 mFormat = new VCardFormatPlugin2();
434// qDebug("ResourceFile::setFormat format %s", mFormatName.latin1()); 441// qDebug("ResourceFile::setFormat format %s", mFormatName.latin1());
435 } 442 }
436 else if (mFormatName == "binary") { 443 else if (mFormatName == "binary") {
437 mFormat = new BinaryFormat(); 444 mFormat = new BinaryFormat();
438// qDebug("ResourceFile::setFormat format %s", mFormatName.latin1()); 445// qDebug("ResourceFile::setFormat format %s", mFormatName.latin1());
439 } 446 }
440 else 447 else
441 qDebug("ResourceFile::setFormat format unknown !!! %s ", format.latin1()); 448 qDebug("ResourceFile::setFormat format unknown !!! %s ", format.latin1());
442*/ 449*/
443 450
444} 451}
445 452
446QString ResourceFile::format() const 453QString ResourceFile::format() const
447{ 454{
448 return mFormatName; 455 return mFormatName;
449} 456}
450 457
451void ResourceFile::fileChanged() 458void ResourceFile::fileChanged()
452{ 459{
453 // There is a small theoretical chance that KDirWatch calls us before 460 // There is a small theoretical chance that KDirWatch calls us before
454 // we are fully constructed 461 // we are fully constructed
455 if (!addressBook()) 462 if (!addressBook())
456 return; 463 return;
457 464
458 465
459 QString text( i18n( "File resource '%1'<br> has been changed by third party.<br>Do you want to reload?").arg( fileName() ) ); 466 QString text( i18n( "File resource '%1'<br> has been changed by third party.<br>Do you want to reload?").arg( fileName() ) );
460 if ( readOnly() || KMessageBox::questionYesNo( 0, text ) == KMessageBox::Yes ) { 467 if ( readOnly() || KMessageBox::questionYesNo( 0, text ) == KMessageBox::Yes ) {
461 load(); 468 load();
462 addressBook()->emitAddressBookChanged(); 469 addressBook()->emitAddressBookChanged();
463 } 470 }
464} 471}
465 472
466void ResourceFile::removeAddressee( const Addressee &addr ) 473void ResourceFile::removeAddressee( const Addressee &addr )
467{ 474{
468 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/photos/" ) + addr.uid() ) ); 475 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/photos/" ) + addr.uid() ) );
469 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/logos/" ) + addr.uid() ) ); 476 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/logos/" ) + addr.uid() ) );
diff --git a/kabc/plugins/ldap/resourceldap.cpp b/kabc/plugins/ldap/resourceldap.cpp
index 55c43af..c3097de 100644
--- a/kabc/plugins/ldap/resourceldap.cpp
+++ b/kabc/plugins/ldap/resourceldap.cpp
@@ -1,442 +1,449 @@
1/* 1/*
2 This file is part of libkabc. 2 This file is part of libkabc.
3 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org> 3 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public 6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version. 8 version 2 of the License, or (at your option) any later version.
9 9
10 This library is distributed in the hope that it will be useful, 10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details. 13 Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public License 15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to 16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20 20
21/* 21/*
22Enhanced Version of the file for platform independent KDE tools. 22Enhanced Version of the file for platform independent KDE tools.
23Copyright (c) 2004 Ulf Schenk 23Copyright (c) 2004 Ulf Schenk
24 24
25$Id$ 25$Id$
26*/ 26*/
27 27
28#include <kdebug.h> 28#include <kdebug.h>
29#include <kglobal.h> 29#include <kglobal.h>
30#include <klineedit.h> 30#include <klineedit.h>
31#include <klocale.h> 31#include <klocale.h>
32#include <kconfig.h> 32#include <kconfig.h>
33#include <kstringhandler.h> 33#include <kstringhandler.h>
34 34
35#include <stdlib.h> 35#include <stdlib.h>
36 36
37#include "resourceldap.h" 37#include "resourceldap.h"
38#include "resourceldapconfig.h" 38#include "resourceldapconfig.h"
39 39
40using namespace KABC; 40using namespace KABC;
41 41
42extern "C" 42extern "C"
43{ 43{
44//US void *init_kabc_ldap() 44//US void *init_kabc_ldap()
45 void *init_microkabc_ldap() 45 void *init_microkabc_ldap()
46 { 46 {
47 return new KRES::PluginFactory<ResourceLDAP,ResourceLDAPConfig>(); 47 return new KRES::PluginFactory<ResourceLDAP,ResourceLDAPConfig>();
48 } 48 }
49} 49}
50 50
51void addModOp( LDAPMod ***pmods, const QString &attr, const QString &value ); 51void addModOp( LDAPMod ***pmods, const QString &attr, const QString &value );
52 52
53 53
54ResourceLDAP::ResourceLDAP( const KConfig *config ) 54ResourceLDAP::ResourceLDAP( const KConfig *config )
55 : Resource( config ), mPort( 389 ), mLdap( 0 ) 55 : Resource( config ), mPort( 389 ), mLdap( 0 )
56{ 56{
57 KConfig *cfg = (KConfig *)config; 57 KConfig *cfg = (KConfig *)config;
58 if ( cfg ) { 58 if ( cfg ) {
59#ifdef _WIN32_
60 // we use plugins on win32. the group is stored in a static variable
61 // such that group info not available on win32 plugins
62 // to fix that, it would be a looooot of work
63 if ( !cfg->tempGroup().isEmpty() )
64 cfg->setGroup( cfg->tempGroup() );
65#endif
59 mUser = cfg->readEntry( "LdapUser" ); 66 mUser = cfg->readEntry( "LdapUser" );
60 mPassword = KStringHandler::obscure( cfg->readEntry( "LdapPassword" ) ); 67 mPassword = KStringHandler::obscure( cfg->readEntry( "LdapPassword" ) );
61 mDn = cfg->readEntry( "LdapDn" ); 68 mDn = cfg->readEntry( "LdapDn" );
62 mHost = cfg->readEntry( "LdapHost" ); 69 mHost = cfg->readEntry( "LdapHost" );
63 mPort = cfg->readNumEntry( "LdapPort", 389 ); 70 mPort = cfg->readNumEntry( "LdapPort", 389 );
64 mFilter = cfg->readEntry( "LdapFilter" ); 71 mFilter = cfg->readEntry( "LdapFilter" );
65 mAnonymous = cfg->readBoolEntry( "LdapAnonymous" ); 72 mAnonymous = cfg->readBoolEntry( "LdapAnonymous" );
66 73
67 QStringList attributes = cfg->readListEntry( "LdapAttributes" ); 74 QStringList attributes = cfg->readListEntry( "LdapAttributes" );
68 for ( uint pos = 0; pos < attributes.count(); pos += 2 ) 75 for ( uint pos = 0; pos < attributes.count(); pos += 2 )
69 mAttributes.insert( attributes[ pos ], attributes[ pos + 1 ] ); 76 mAttributes.insert( attributes[ pos ], attributes[ pos + 1 ] );
70 } 77 }
71 78
72 /** 79 /**
73 If you want to add new attributes, append them here, add a 80 If you want to add new attributes, append them here, add a
74 translation string in the ctor of AttributesDialog and 81 translation string in the ctor of AttributesDialog and
75 handle them in the load() method below. 82 handle them in the load() method below.
76 These are the default values from 83 These are the default values from
77 */ 84 */
78 if ( mAttributes.count() == 0 ) { 85 if ( mAttributes.count() == 0 ) {
79 mAttributes.insert( "commonName", "cn" ); 86 mAttributes.insert( "commonName", "cn" );
80 mAttributes.insert( "formattedName", "displayName" ); 87 mAttributes.insert( "formattedName", "displayName" );
81 mAttributes.insert( "familyName", "sn" ); 88 mAttributes.insert( "familyName", "sn" );
82 mAttributes.insert( "givenName", "givenName" ); 89 mAttributes.insert( "givenName", "givenName" );
83 mAttributes.insert( "mail", "mail" ); 90 mAttributes.insert( "mail", "mail" );
84 mAttributes.insert( "mailAlias", "" ); 91 mAttributes.insert( "mailAlias", "" );
85 mAttributes.insert( "phoneNumber", "telephoneNumber" ); 92 mAttributes.insert( "phoneNumber", "telephoneNumber" );
86 mAttributes.insert( "uid", "uid" ); 93 mAttributes.insert( "uid", "uid" );
87 } 94 }
88} 95}
89 96
90void ResourceLDAP::writeConfig( KConfig *config ) 97void ResourceLDAP::writeConfig( KConfig *config )
91{ 98{
92 Resource::writeConfig( config ); 99 Resource::writeConfig( config );
93 100
94 config->writeEntry( "LdapUser", mUser ); 101 config->writeEntry( "LdapUser", mUser );
95 config->writeEntry( "LdapPassword", KStringHandler::obscure( mPassword ) ); 102 config->writeEntry( "LdapPassword", KStringHandler::obscure( mPassword ) );
96 config->writeEntry( "LdapDn", mDn ); 103 config->writeEntry( "LdapDn", mDn );
97 config->writeEntry( "LdapHost", mHost ); 104 config->writeEntry( "LdapHost", mHost );
98 config->writeEntry( "LdapPort", mPort ); 105 config->writeEntry( "LdapPort", mPort );
99 config->writeEntry( "LdapFilter", mFilter ); 106 config->writeEntry( "LdapFilter", mFilter );
100 config->writeEntry( "LdapAnonymous", mAnonymous ); 107 config->writeEntry( "LdapAnonymous", mAnonymous );
101 108
102 QStringList attributes; 109 QStringList attributes;
103 QMap<QString, QString>::Iterator it; 110 QMap<QString, QString>::Iterator it;
104 for ( it = mAttributes.begin(); it != mAttributes.end(); ++it ) 111 for ( it = mAttributes.begin(); it != mAttributes.end(); ++it )
105 attributes << it.key() << it.data(); 112 attributes << it.key() << it.data();
106 113
107 config->writeEntry( "LdapAttributes", attributes ); 114 config->writeEntry( "LdapAttributes", attributes );
108} 115}
109 116
110Ticket *ResourceLDAP::requestSaveTicket() 117Ticket *ResourceLDAP::requestSaveTicket()
111{ 118{
112 if ( !addressBook() ) { 119 if ( !addressBook() ) {
113 kdDebug(5700) << "no addressbook" << endl; 120 kdDebug(5700) << "no addressbook" << endl;
114 return 0; 121 return 0;
115 } 122 }
116 123
117 return createTicket( this ); 124 return createTicket( this );
118} 125}
119 126
120bool ResourceLDAP::doOpen() 127bool ResourceLDAP::doOpen()
121{ 128{
122 if ( mLdap ) 129 if ( mLdap )
123 return false; 130 return false;
124 131
125 if ( !mPort ) 132 if ( !mPort )
126 mPort = 389; 133 mPort = 389;
127 134
128 mLdap = ldap_init( mHost.local8Bit(), mPort ); 135 mLdap = ldap_init( mHost.local8Bit(), mPort );
129 if ( !mLdap ) { 136 if ( !mLdap ) {
130 addressBook()->error( i18n( "Unable to connect to server '%1' on port '%2'" ).arg( mHost ).arg( mPort ) ); 137 addressBook()->error( i18n( "Unable to connect to server '%1' on port '%2'" ).arg( mHost ).arg( mPort ) );
131 return false; 138 return false;
132 } 139 }
133 140
134 if ( !mUser.isEmpty() && !mAnonymous ) { 141 if ( !mUser.isEmpty() && !mAnonymous ) {
135 if ( ldap_simple_bind_s( mLdap, mUser.local8Bit(), mPassword.local8Bit() ) != LDAP_SUCCESS ) { 142 if ( ldap_simple_bind_s( mLdap, mUser.local8Bit(), mPassword.local8Bit() ) != LDAP_SUCCESS ) {
136 addressBook()->error( i18n( "Unable to bind to server '%1'" ).arg( mHost ) ); 143 addressBook()->error( i18n( "Unable to bind to server '%1'" ).arg( mHost ) );
137 return false; 144 return false;
138 } 145 }
139 146
140 kdDebug(5700) << "ResourceLDAP: bind to server successfully" << endl; 147 kdDebug(5700) << "ResourceLDAP: bind to server successfully" << endl;
141 } else { 148 } else {
142 if ( ldap_simple_bind_s( mLdap, NULL, NULL ) != LDAP_SUCCESS ) { 149 if ( ldap_simple_bind_s( mLdap, NULL, NULL ) != LDAP_SUCCESS ) {
143 addressBook()->error( i18n( "Unable to bind anonymously to server '%1'" ).arg( mHost ) ); 150 addressBook()->error( i18n( "Unable to bind anonymously to server '%1'" ).arg( mHost ) );
144 return false; 151 return false;
145 } 152 }
146 153
147 kdDebug( 5700 ) << "ResourceLDAP: bind anonymously to server successfully" << endl; 154 kdDebug( 5700 ) << "ResourceLDAP: bind anonymously to server successfully" << endl;
148 } 155 }
149 156
150 int deref = LDAP_DEREF_ALWAYS; 157 int deref = LDAP_DEREF_ALWAYS;
151 if ( ldap_set_option( mLdap, LDAP_OPT_DEREF, (void *) &deref ) != LDAP_OPT_SUCCESS ) { 158 if ( ldap_set_option( mLdap, LDAP_OPT_DEREF, (void *) &deref ) != LDAP_OPT_SUCCESS ) {
152 kdDebug(5700) << "ResourceLDAP: can't set 'deref' option" << endl; 159 kdDebug(5700) << "ResourceLDAP: can't set 'deref' option" << endl;
153 return false; 160 return false;
154 } 161 }
155 162
156 if ( ldap_set_option( mLdap, LDAP_OPT_REFERRALS, LDAP_OPT_ON ) != LDAP_OPT_SUCCESS ) { 163 if ( ldap_set_option( mLdap, LDAP_OPT_REFERRALS, LDAP_OPT_ON ) != LDAP_OPT_SUCCESS ) {
157 kdDebug(5700) << "ResourceLDAP: can't set 'referrals' option" << endl; 164 kdDebug(5700) << "ResourceLDAP: can't set 'referrals' option" << endl;
158 return false; 165 return false;
159 } 166 }
160 167
161 return true; 168 return true;
162} 169}
163 170
164void ResourceLDAP::doClose() 171void ResourceLDAP::doClose()
165{ 172{
166 if ( ldap_unbind_s( mLdap ) != LDAP_SUCCESS ) { 173 if ( ldap_unbind_s( mLdap ) != LDAP_SUCCESS ) {
167 kdDebug(5700) << "ResourceLDAP: can't unbind from server" << endl; 174 kdDebug(5700) << "ResourceLDAP: can't unbind from server" << endl;
168 return; 175 return;
169 } 176 }
170 177
171 mLdap = 0; 178 mLdap = 0;
172} 179}
173 180
174bool ResourceLDAP::load() 181bool ResourceLDAP::load()
175{ 182{
176 LDAPMessage *res; 183 LDAPMessage *res;
177 LDAPMessage *msg; 184 LDAPMessage *msg;
178 BerElement *track; 185 BerElement *track;
179 char *names; 186 char *names;
180 char **values; 187 char **values;
181 188
182 char **LdapSearchAttr = new char*[ mAttributes.count() + 1 ]; 189 char **LdapSearchAttr = new char*[ mAttributes.count() + 1 ];
183 190
184 QMap<QString, QString>::Iterator it; 191 QMap<QString, QString>::Iterator it;
185 int i = 0; 192 int i = 0;
186 for ( it = mAttributes.begin(); it != mAttributes.end(); ++it ) { 193 for ( it = mAttributes.begin(); it != mAttributes.end(); ++it ) {
187 if ( !it.data().isEmpty() ) { 194 if ( !it.data().isEmpty() ) {
188 unsigned int len = it.data().utf8().length(); 195 unsigned int len = it.data().utf8().length();
189 LdapSearchAttr[ i ] = new char[ len+1 ]; 196 LdapSearchAttr[ i ] = new char[ len+1 ];
190 memcpy( LdapSearchAttr[ i ], it.data().utf8(), len ); 197 memcpy( LdapSearchAttr[ i ], it.data().utf8(), len );
191 LdapSearchAttr[ i ][ len ] = 0; 198 LdapSearchAttr[ i ][ len ] = 0;
192 ++i; 199 ++i;
193 } 200 }
194 } 201 }
195 LdapSearchAttr[ i ] = 0; 202 LdapSearchAttr[ i ] = 0;
196 203
197 QString filter = mFilter; 204 QString filter = mFilter;
198 if ( filter.isEmpty() ) 205 if ( filter.isEmpty() )
199 filter = "cn=*"; 206 filter = "cn=*";
200 207
201 int result; 208 int result;
202 if ( ( result = ldap_search_s( mLdap, mDn.local8Bit(), LDAP_SCOPE_SUBTREE, QString( "(%1)" ).arg( filter ).local8Bit(), 209 if ( ( result = ldap_search_s( mLdap, mDn.local8Bit(), LDAP_SCOPE_SUBTREE, QString( "(%1)" ).arg( filter ).local8Bit(),
203 LdapSearchAttr, 0, &res ) != LDAP_SUCCESS ) ) { 210 LdapSearchAttr, 0, &res ) != LDAP_SUCCESS ) ) {
204 addressBook()->error( i18n( "Unable to search on server '%1': %2" ) 211 addressBook()->error( i18n( "Unable to search on server '%1': %2" )
205 .arg( mHost ) 212 .arg( mHost )
206 .arg( ldap_err2string( result ) ) ); 213 .arg( ldap_err2string( result ) ) );
207 214
208 for ( i = 0; LdapSearchAttr[ i ]; ++i ) 215 for ( i = 0; LdapSearchAttr[ i ]; ++i )
209 delete [] LdapSearchAttr[ i ]; 216 delete [] LdapSearchAttr[ i ];
210 delete [] LdapSearchAttr; 217 delete [] LdapSearchAttr;
211 218
212 return false; 219 return false;
213 } 220 }
214 221
215 for ( msg = ldap_first_entry( mLdap, res ); msg; msg = ldap_next_entry( mLdap, msg ) ) { 222 for ( msg = ldap_first_entry( mLdap, res ); msg; msg = ldap_next_entry( mLdap, msg ) ) {
216 Addressee addr; 223 Addressee addr;
217 addr.setResource( this ); 224 addr.setResource( this );
218 for ( names = ldap_first_attribute( mLdap, msg, &track ); names; names = ldap_next_attribute( mLdap, msg, track ) ) { 225 for ( names = ldap_first_attribute( mLdap, msg, &track ); names; names = ldap_next_attribute( mLdap, msg, track ) ) {
219 values = ldap_get_values( mLdap, msg, names ); 226 values = ldap_get_values( mLdap, msg, names );
220 for ( int i = 0; i < ldap_count_values( values ); ++i ) { 227 for ( int i = 0; i < ldap_count_values( values ); ++i ) {
221 QString name = QString::fromUtf8( names ).lower(); 228 QString name = QString::fromUtf8( names ).lower();
222 QString value = QString::fromUtf8( values[ i ] ); 229 QString value = QString::fromUtf8( values[ i ] );
223 230
224 if ( name == mAttributes[ "commonName" ].lower() ) { 231 if ( name == mAttributes[ "commonName" ].lower() ) {
225 if ( !addr.formattedName().isEmpty() ) { 232 if ( !addr.formattedName().isEmpty() ) {
226 QString fn = addr.formattedName(); 233 QString fn = addr.formattedName();
227 addr.setNameFromString( value ); 234 addr.setNameFromString( value );
228 addr.setFormattedName( fn ); 235 addr.setFormattedName( fn );
229 } else 236 } else
230 addr.setNameFromString( value ); 237 addr.setNameFromString( value );
231 } else if ( name == mAttributes[ "formattedName" ].lower() ) { 238 } else if ( name == mAttributes[ "formattedName" ].lower() ) {
232 addr.setFormattedName( value ); 239 addr.setFormattedName( value );
233 } else if ( name == mAttributes[ "givenName" ].lower() ) { 240 } else if ( name == mAttributes[ "givenName" ].lower() ) {
234 addr.setGivenName( value ); 241 addr.setGivenName( value );
235 } else if ( name == mAttributes[ "mail" ].lower() ) { 242 } else if ( name == mAttributes[ "mail" ].lower() ) {
236 addr.insertEmail( value, true ); 243 addr.insertEmail( value, true );
237 } else if ( name == mAttributes[ "mailAlias" ].lower() ) { 244 } else if ( name == mAttributes[ "mailAlias" ].lower() ) {
238 addr.insertEmail( value, false ); 245 addr.insertEmail( value, false );
239 } else if ( name == mAttributes[ "phoneNumber" ].lower() ) { 246 } else if ( name == mAttributes[ "phoneNumber" ].lower() ) {
240 PhoneNumber phone; 247 PhoneNumber phone;
241 phone.setNumber( value ); 248 phone.setNumber( value );
242 addr.insertPhoneNumber( phone ); 249 addr.insertPhoneNumber( phone );
243 break; // read only the home number 250 break; // read only the home number
244 } else if ( name == mAttributes[ "familyName" ].lower() ) { 251 } else if ( name == mAttributes[ "familyName" ].lower() ) {
245 addr.setFamilyName( value ); 252 addr.setFamilyName( value );
246 } else if ( name == mAttributes[ "uid" ].lower() ) { 253 } else if ( name == mAttributes[ "uid" ].lower() ) {
247 addr.setUid( value ); 254 addr.setUid( value );
248 } 255 }
249 } 256 }
250 ldap_value_free( values ); 257 ldap_value_free( values );
251 } 258 }
252 ber_free( track, 0 ); 259 ber_free( track, 0 );
253 260
254 addressBook()->insertAddressee( addr ); 261 addressBook()->insertAddressee( addr );
255 } 262 }
256 263
257 ldap_msgfree( res ); 264 ldap_msgfree( res );
258 265
259 for ( i = 0; LdapSearchAttr[ i ]; ++i ) 266 for ( i = 0; LdapSearchAttr[ i ]; ++i )
260 delete [] LdapSearchAttr[ i ]; 267 delete [] LdapSearchAttr[ i ];
261 delete [] LdapSearchAttr; 268 delete [] LdapSearchAttr;
262 269
263 return true; 270 return true;
264} 271}
265 272
266bool ResourceLDAP::save( Ticket * ) 273bool ResourceLDAP::save( Ticket * )
267{ 274{
268 AddressBook::Iterator it; 275 AddressBook::Iterator it;
269 for ( it = addressBook()->begin(); it != addressBook()->end(); ++it ) { 276 for ( it = addressBook()->begin(); it != addressBook()->end(); ++it ) {
270 if ( (*it).resource() == this && (*it).changed() ) { 277 if ( (*it).resource() == this && (*it).changed() ) {
271 LDAPMod **mods = NULL; 278 LDAPMod **mods = NULL;
272 279
273 addModOp( &mods, "objectClass", "organizationalPerson" ); 280 addModOp( &mods, "objectClass", "organizationalPerson" );
274 addModOp( &mods, "objectClass", "person" ); 281 addModOp( &mods, "objectClass", "person" );
275 addModOp( &mods, "objectClass", "Top" ); 282 addModOp( &mods, "objectClass", "Top" );
276 addModOp( &mods, mAttributes[ "commonName" ].utf8(), (*it).assembledName() ); 283 addModOp( &mods, mAttributes[ "commonName" ].utf8(), (*it).assembledName() );
277 addModOp( &mods, mAttributes[ "formattedName" ].utf8(), (*it).formattedName() ); 284 addModOp( &mods, mAttributes[ "formattedName" ].utf8(), (*it).formattedName() );
278 addModOp( &mods, mAttributes[ "givenName" ].utf8(), (*it).givenName() ); 285 addModOp( &mods, mAttributes[ "givenName" ].utf8(), (*it).givenName() );
279 addModOp( &mods, mAttributes[ "familyName" ].utf8(), (*it).familyName() ); 286 addModOp( &mods, mAttributes[ "familyName" ].utf8(), (*it).familyName() );
280 addModOp( &mods, mAttributes[ "uid" ].utf8(), (*it).uid() ); 287 addModOp( &mods, mAttributes[ "uid" ].utf8(), (*it).uid() );
281 288
282 QStringList emails = (*it).emails(); 289 QStringList emails = (*it).emails();
283 QStringList::ConstIterator mailIt; 290 QStringList::ConstIterator mailIt;
284 bool first = true; 291 bool first = true;
285 for ( mailIt = emails.begin(); mailIt != emails.end(); ++mailIt ) { 292 for ( mailIt = emails.begin(); mailIt != emails.end(); ++mailIt ) {
286 if ( first ) { 293 if ( first ) {
287 addModOp( &mods, mAttributes[ "mail" ].utf8(), (*mailIt) ); 294 addModOp( &mods, mAttributes[ "mail" ].utf8(), (*mailIt) );
288 first = false; 295 first = false;
289 } else 296 } else
290 addModOp( &mods, mAttributes[ "mailAlias" ].utf8(), (*mailIt) ); 297 addModOp( &mods, mAttributes[ "mailAlias" ].utf8(), (*mailIt) );
291 } 298 }
292 299
293 PhoneNumber number = (*it).phoneNumber( PhoneNumber::Home ); 300 PhoneNumber number = (*it).phoneNumber( PhoneNumber::Home );
294 addModOp( &mods, mAttributes[ "phoneNumber" ].utf8(), number.number() ); 301 addModOp( &mods, mAttributes[ "phoneNumber" ].utf8(), number.number() );
295 302
296 QString dn = "cn=" + (*it).assembledName() + "," + mDn; 303 QString dn = "cn=" + (*it).assembledName() + "," + mDn;
297 304
298 int retval; 305 int retval;
299 if ( (retval = ldap_add_s( mLdap, dn.local8Bit(), mods )) != LDAP_SUCCESS ) 306 if ( (retval = ldap_add_s( mLdap, dn.local8Bit(), mods )) != LDAP_SUCCESS )
300 addressBook()->error( i18n( "Unable to modify '%1' on server '%2'" ).arg( (*it).uid() ).arg( mHost ) ); 307 addressBook()->error( i18n( "Unable to modify '%1' on server '%2'" ).arg( (*it).uid() ).arg( mHost ) );
301 308
302 ldap_mods_free( mods, 1 ); 309 ldap_mods_free( mods, 1 );
303 310
304 // mark as unchanged 311 // mark as unchanged
305 (*it).setChanged( false ); 312 (*it).setChanged( false );
306 } 313 }
307 } 314 }
308 315
309 return true; 316 return true;
310} 317}
311 318
312void ResourceLDAP::removeAddressee( const Addressee &addr ) 319void ResourceLDAP::removeAddressee( const Addressee &addr )
313{ 320{
314 LDAPMessage *res; 321 LDAPMessage *res;
315 LDAPMessage *msg; 322 LDAPMessage *msg;
316 323
317 QString filter = QString( "(&(uid=%1)(%2))" ).arg( addr.uid() ).arg( mFilter ); 324 QString filter = QString( "(&(uid=%1)(%2))" ).arg( addr.uid() ).arg( mFilter );
318 325
319 kdDebug(5700) << "ldap:removeAddressee" << filter << endl; 326 kdDebug(5700) << "ldap:removeAddressee" << filter << endl;
320 327
321 ldap_search_s( mLdap, mDn.local8Bit(), LDAP_SCOPE_SUBTREE, filter.local8Bit(), 328 ldap_search_s( mLdap, mDn.local8Bit(), LDAP_SCOPE_SUBTREE, filter.local8Bit(),
322 0, 0, &res ); 329 0, 0, &res );
323 330
324 for ( msg = ldap_first_entry( mLdap, res ); msg; msg = ldap_next_entry( mLdap, msg ) ) { 331 for ( msg = ldap_first_entry( mLdap, res ); msg; msg = ldap_next_entry( mLdap, msg ) ) {
325 char *dn = ldap_get_dn( mLdap, msg ); 332 char *dn = ldap_get_dn( mLdap, msg );
326 kdDebug(5700) << "found " << dn << endl; 333 kdDebug(5700) << "found " << dn << endl;
327 if ( ldap_delete_s( mLdap, dn ) != LDAP_SUCCESS ) 334 if ( ldap_delete_s( mLdap, dn ) != LDAP_SUCCESS )
328 addressBook()->error( i18n( "Unable to delete '%1' on server '%2'" ).arg( dn ).arg( mHost ) ); 335 addressBook()->error( i18n( "Unable to delete '%1' on server '%2'" ).arg( dn ).arg( mHost ) );
329 ldap_memfree( dn ); 336 ldap_memfree( dn );
330 } 337 }
331 338
332 ldap_msgfree( res ); 339 ldap_msgfree( res );
333} 340}
334 341
335void ResourceLDAP::setUser( const QString &user ) 342void ResourceLDAP::setUser( const QString &user )
336{ 343{
337 mUser = user; 344 mUser = user;
338} 345}
339 346
340QString ResourceLDAP::user() const 347QString ResourceLDAP::user() const
341{ 348{
342 return mUser; 349 return mUser;
343} 350}
344 351
345void ResourceLDAP::setPassword( const QString &password ) 352void ResourceLDAP::setPassword( const QString &password )
346{ 353{
347 mPassword = password; 354 mPassword = password;
348} 355}
349 356
350QString ResourceLDAP::password() const 357QString ResourceLDAP::password() const
351{ 358{
352 return mPassword; 359 return mPassword;
353} 360}
354 361
355void ResourceLDAP::setDn( const QString &dn ) 362void ResourceLDAP::setDn( const QString &dn )
356{ 363{
357 mDn = dn; 364 mDn = dn;
358} 365}
359 366
360QString ResourceLDAP::dn() const 367QString ResourceLDAP::dn() const
361{ 368{
362 return mDn; 369 return mDn;
363} 370}
364 371
365void ResourceLDAP::setHost( const QString &host ) 372void ResourceLDAP::setHost( const QString &host )
366{ 373{
367 mHost = host; 374 mHost = host;
368} 375}
369 376
370QString ResourceLDAP::host() const 377QString ResourceLDAP::host() const
371{ 378{
372 return mHost; 379 return mHost;
373} 380}
374 381
375void ResourceLDAP::setPort( int port ) 382void ResourceLDAP::setPort( int port )
376{ 383{
377 mPort = port; 384 mPort = port;
378} 385}
379 386
380int ResourceLDAP::port() const 387int ResourceLDAP::port() const
381{ 388{
382 return mPort; 389 return mPort;
383} 390}
384 391
385void ResourceLDAP::setFilter( const QString &filter ) 392void ResourceLDAP::setFilter( const QString &filter )
386{ 393{
387 mFilter = filter; 394 mFilter = filter;
388} 395}
389 396
390QString ResourceLDAP::filter() const 397QString ResourceLDAP::filter() const
391{ 398{
392 return mFilter; 399 return mFilter;
393} 400}
394 401
395void ResourceLDAP::setIsAnonymous( bool value ) 402void ResourceLDAP::setIsAnonymous( bool value )
396{ 403{
397 mAnonymous = value; 404 mAnonymous = value;
398} 405}
399 406
400bool ResourceLDAP::isAnonymous() const 407bool ResourceLDAP::isAnonymous() const
401{ 408{
402 return mAnonymous; 409 return mAnonymous;
403} 410}
404 411
405void ResourceLDAP::setAttributes( const QMap<QString, QString> &attributes ) 412void ResourceLDAP::setAttributes( const QMap<QString, QString> &attributes )
406{ 413{
407 mAttributes = attributes; 414 mAttributes = attributes;
408} 415}
409 416
410QMap<QString, QString> ResourceLDAP::attributes() const 417QMap<QString, QString> ResourceLDAP::attributes() const
411{ 418{
412 return mAttributes; 419 return mAttributes;
413} 420}
414 421
415void addModOp( LDAPMod ***pmods, const QString &attr, const QString &value ) 422void addModOp( LDAPMod ***pmods, const QString &attr, const QString &value )
416{ 423{
417 if ( value.isNull() ) 424 if ( value.isNull() )
418 return; 425 return;
419 426
420 LDAPMod**mods; 427 LDAPMod**mods;
421 428
422 mods = *pmods; 429 mods = *pmods;
423 430
424 uint i = 0; 431 uint i = 0;
425 if ( mods != 0 ) 432 if ( mods != 0 )
426 for ( ; mods[ i ] != 0; ++i ); 433 for ( ; mods[ i ] != 0; ++i );
427 434
428 if (( mods = (LDAPMod **)realloc( mods, (i + 2) * sizeof( LDAPMod * ))) == 0 ) { 435 if (( mods = (LDAPMod **)realloc( mods, (i + 2) * sizeof( LDAPMod * ))) == 0 ) {
429 kdError() << "ResourceLDAP: realloc" << endl; 436 kdError() << "ResourceLDAP: realloc" << endl;
430 return; 437 return;
431 } 438 }
432 439
433 *pmods = mods; 440 *pmods = mods;
434 mods[ i + 1 ] = 0; 441 mods[ i + 1 ] = 0;
435 442
436 mods[ i ] = new LDAPMod; 443 mods[ i ] = new LDAPMod;
437 444
438 mods[ i ]->mod_op = 0; 445 mods[ i ]->mod_op = 0;
439 mods[ i ]->mod_type = strdup( attr.utf8() ); 446 mods[ i ]->mod_type = strdup( attr.utf8() );
440 mods[ i ]->mod_values = new char*[ 2 ]; 447 mods[ i ]->mod_values = new char*[ 2 ];
441 mods[ i ]->mod_values[ 0 ] = strdup( value.utf8() ); 448 mods[ i ]->mod_values[ 0 ] = strdup( value.utf8() );
442 mods[ i ]->mod_values[ 1 ] = 0; 449 mods[ i ]->mod_values[ 1 ] = 0;