summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--kabc/plugins/file/resourcefile.cpp49
-rw-r--r--kabc/plugins/file/resourcefile.h1
-rw-r--r--pwmanager/pwmanager/pwmdoc.cpp45
3 files changed, 93 insertions, 2 deletions
diff --git a/kabc/plugins/file/resourcefile.cpp b/kabc/plugins/file/resourcefile.cpp
index 2bd9e71..c89939d 100644
--- a/kabc/plugins/file/resourcefile.cpp
+++ b/kabc/plugins/file/resourcefile.cpp
@@ -1,433 +1,478 @@
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 47
47#include "formatfactory.h" 48#include "formatfactory.h"
48 49
49#include "resource.h" 50#include "resource.h"
50#include "resourcefileconfig.h" 51#include "resourcefileconfig.h"
51#include "stdaddressbook.h" 52#include "stdaddressbook.h"
52#define NO_DIRWATCH 53#define NO_DIRWATCH
53#include "resourcefile.h" 54#include "resourcefile.h"
54 55
55//#define ALLOW_LOCKING 56//#define ALLOW_LOCKING
56 57
57 58
58using namespace KABC; 59using namespace KABC;
59 60
60extern "C" 61extern "C"
61#ifdef _WIN32_ 62#ifdef _WIN32_
62__declspec(dllexport) 63__declspec(dllexport)
63#else 64#else
64{ 65{
65#endif 66#endif
66 67
67//US void *init_kabc_file() 68//US void *init_kabc_file()
68 void *init_microkabc_file() 69 void *init_microkabc_file()
69 { 70 {
70 return new KRES::PluginFactory<ResourceFile,ResourceFileConfig>(); 71 return new KRES::PluginFactory<ResourceFile,ResourceFileConfig>();
71 } 72 }
72#ifndef _WIN32_ 73#ifndef _WIN32_
73} 74}
74#endif 75#endif
75 76
76ResourceFile::ResourceFile( const KConfig *config ) 77ResourceFile::ResourceFile( const KConfig *config )
77 : Resource( config ) , mFormat( 0 ) 78 : Resource( config ) , mFormat( 0 )
78{ 79{
79 QString fileName, formatName, default_fileName; 80 QString fileName, formatName, default_fileName;
80 81
81 default_fileName = StdAddressBook::fileName(); 82 default_fileName = StdAddressBook::fileName();
82 83 mLastBackupDate = -1;
83 KConfig *cfg = (KConfig *)config; 84 KConfig *cfg = (KConfig *)config;
84 if ( cfg ) { 85 if ( cfg ) {
85 fileName = cfg->readEntry( "FileName", default_fileName ); 86 fileName = cfg->readEntry( "FileName", default_fileName );
86 formatName = cfg->readEntry( "FileFormat", "vcard" ); 87 formatName = cfg->readEntry( "FileFormat", "vcard" );
87 mFamily = cfg->readEntry( "ResourceName", "std" ); 88 mFamily = cfg->readEntry( "ResourceName", "std" );
89 mLastBackupDate = cfg->readNumEntry( "LastBackupDate", 0 );
88 } else { 90 } else {
89 fileName = default_fileName; 91 fileName = default_fileName;
90 formatName = "vcard"; 92 formatName = "vcard";
91 } 93 }
92 94
93 init( fileName, formatName ); 95 init( fileName, formatName );
94} 96}
95 97
96ResourceFile::ResourceFile( const QString &fileName , 98ResourceFile::ResourceFile( const QString &fileName ,
97 const QString &formatName ) 99 const QString &formatName )
98 : Resource( 0 ) 100 : Resource( 0 )
99{ 101{
100// qDebug("ResourceFile::ResourceFile : 3 %s, %s", fileName.latin1(), formatName.latin1()); 102// qDebug("ResourceFile::ResourceFile : 3 %s, %s", fileName.latin1(), formatName.latin1());
101 103
102 104
103 105 mLastBackupDate = -1;
104 init( fileName, formatName ); 106 init( fileName, formatName );
105} 107}
106 108
107void ResourceFile::init( const QString &fileName, const QString &formatName ) 109void ResourceFile::init( const QString &fileName, const QString &formatName )
108{ 110{
109 mFormatName = formatName; 111 mFormatName = formatName;
110 112
111 FormatFactory *factory = FormatFactory::self(); 113 FormatFactory *factory = FormatFactory::self();
112 mFormat = factory->format( mFormatName ); 114 mFormat = factory->format( mFormatName );
113 115
114 if ( !mFormat ) { 116 if ( !mFormat ) {
115 mFormatName = "vcard"; 117 mFormatName = "vcard";
116 mFormat = factory->format( mFormatName ); 118 mFormat = factory->format( mFormatName );
117 } 119 }
118 120
119#ifndef NO_DIRWATCH 121#ifndef NO_DIRWATCH
120 connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( fileChanged() ) ); 122 connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( fileChanged() ) );
121 connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( fileChanged() ) ); 123 connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( fileChanged() ) );
122 connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( fileChanged() ) ); 124 connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( fileChanged() ) );
123#endif 125#endif
124 126
125 QString localKdeDir; 127 QString localKdeDir;
126 localKdeDir = readEnvPath("LOCALMICROKDEHOME"); 128 localKdeDir = readEnvPath("LOCALMICROKDEHOME");
127 if ( ! localKdeDir.isEmpty() ) { 129 if ( ! localKdeDir.isEmpty() ) {
128 qDebug("LOCALMICROKDEHOME is set to: %s",localKdeDir.latin1() ); 130 qDebug("LOCALMICROKDEHOME is set to: %s",localKdeDir.latin1() );
129 QFileInfo fi ( fileName ); 131 QFileInfo fi ( fileName );
130 QString localname = localKdeDir + "/apps/kabc/" + fi.fileName (); 132 QString localname = localKdeDir + "/apps/kabc/" + fi.fileName ();
131 QFileInfo fi2 ( localname ); 133 QFileInfo fi2 ( localname );
132 if ( ! fi2.exists() || mFamily == "sync_res" ) { 134 if ( ! fi2.exists() || mFamily == "sync_res" ) {
133 if ( fi.exists() && mFamily == "sync_res") { 135 if ( fi.exists() && mFamily == "sync_res") {
134 qDebug("LOCAL mode SYNC mode using absolute file path "); 136 qDebug("LOCAL mode SYNC mode using absolute file path ");
135 setFileName( fileName ); 137 setFileName( fileName );
136 return; 138 return;
137 } else { 139 } else {
138 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/") ); 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/") );
139 setFileName( localname ); 141 setFileName( localname );
140 return; 142 return;
141 } 143 }
142 144
143 } else { 145 } else {
144 qDebug("Local resource file found. Changing filename to: %s",localname.latin1() ); 146 qDebug("Local resource file found. Changing filename to: %s",localname.latin1() );
145 setFileName( localname ); 147 setFileName( localname );
146 return; 148 return;
147 } 149 }
148 150
149 } 151 }
150 setFileName( fileName ); 152 setFileName( fileName );
151} 153}
152 154
153ResourceFile::~ResourceFile() 155ResourceFile::~ResourceFile()
154{ 156{
155 delete mFormat; 157 delete mFormat;
156 mFormat = 0; 158 mFormat = 0;
157} 159}
158 160
159void ResourceFile::writeConfig( KConfig *config ) 161void ResourceFile::writeConfig( KConfig *config )
160{ 162{
161 163
162 config->setGroup( "Resource_" + identifier() ); 164 config->setGroup( "Resource_" + identifier() );
163 Resource::writeConfig( config ); 165 Resource::writeConfig( config );
164 166
165 config->writeEntry( "FileName", fileName() ); 167 config->writeEntry( "FileName", fileName() );
166 config->writeEntry( "FileFormat", mFormatName ); 168 config->writeEntry( "FileFormat", mFormatName );
167 169
168// qDebug("ResourceFile::writeConfig format %s, %s", mFileName.latin1(), mFormatName.latin1()); 170// qDebug("ResourceFile::writeConfig format %s, %s", mFileName.latin1(), mFormatName.latin1());
169 171
170} 172}
171 173
172Ticket *ResourceFile::requestSaveTicket() 174Ticket *ResourceFile::requestSaveTicket()
173{ 175{
174 kdDebug(5700) << "ResourceFile::requestSaveTicket()" << endl; 176 kdDebug(5700) << "ResourceFile::requestSaveTicket()" << endl;
175 177
176 if ( !addressBook() ) return 0; 178 if ( !addressBook() ) return 0;
177 179
178#ifdef ALLOW_LOCKING 180#ifdef ALLOW_LOCKING
179 if ( !lock( mFileName ) ) { 181 if ( !lock( mFileName ) ) {
180 qDebug("unablt to lock file "); 182 qDebug("unablt to lock file ");
181 return 0; 183 return 0;
182 } 184 }
183#endif 185#endif
184 return createTicket( this ); 186 return createTicket( this );
185} 187}
186 188
187 189
188bool ResourceFile::doOpen() 190bool ResourceFile::doOpen()
189{ 191{
190 QFile file( fileName() ); 192 QFile file( fileName() );
191 qDebug("ResourceFile::openfile %s ", fileName().latin1()); 193 qDebug("ResourceFile::openfile %s ", fileName().latin1());
192 194
193 if ( !file.exists() ) { 195 if ( !file.exists() ) {
194 // try to create the file 196 // try to create the file
195 bool ok = file.open( IO_WriteOnly ); 197 bool ok = file.open( IO_WriteOnly );
196 if ( ok ) 198 if ( ok )
197 file.close(); 199 file.close();
198 200
199 return ok; 201 return ok;
200 } else { 202 } else {
201 if ( !file.open( IO_ReadWrite ) ) 203 if ( !file.open( IO_ReadWrite ) )
202 return false; 204 return false;
203 205
204 if ( file.size() < 10 ) { 206 if ( file.size() < 10 ) {
205 file.close(); 207 file.close();
206 return true; 208 return true;
207 } 209 }
208 210
209 bool ok = mFormat->checkFormat( &file ); 211 bool ok = mFormat->checkFormat( &file );
210 file.close(); 212 file.close();
211 213
212 return ok; 214 return ok;
213 } 215 }
214} 216}
215 217
216void ResourceFile::doClose() 218void ResourceFile::doClose()
217{ 219{
218} 220}
219 221
220bool ResourceFile::load() 222bool ResourceFile::load()
221{ 223{
222 224
223 QFile file( fileName() ); 225 QFile file( fileName() );
224 if ( !file.open( IO_ReadOnly ) ) { 226 if ( !file.open( IO_ReadOnly ) ) {
225 addressBook()->error( i18n( "Unable to open file '%1'." ).arg( fileName() ) ); 227 addressBook()->error( i18n( "Unable to open file '%1'." ).arg( fileName() ) );
226 return false; 228 return false;
227 } 229 }
228 230
229// qDebug("ResourceFile::load format %s, %s", mFileName.latin1(), mFormatName.latin1()); 231// qDebug("ResourceFile::load format %s, %s", mFileName.latin1(), mFormatName.latin1());
230 232
231 return mFormat->loadAll( addressBook(), this, &file ); 233 return mFormat->loadAll( addressBook(), this, &file );
232} 234}
233 235
234bool ResourceFile::save( Ticket *ticket ) 236bool ResourceFile::save( Ticket *ticket )
235{ 237{
236// qDebug("ResourceFile::save format %s, %s", mFileName.latin1(), mFormatName.latin1()); 238// qDebug("ResourceFile::save format %s, %s", mFileName.latin1(), mFormatName.latin1());
237 239
238 240
239 // create backup file 241 // create backup file
240 QString extension = "_" + QString::number( QDate::currentDate().dayOfWeek() ); 242 QString extension = "_" + QString::number( QDate::currentDate().dayOfWeek() );
241 243
242/*US we use a simpler method to create a backupfile 244/*US we use a simpler method to create a backupfile
243 245
244 (void) KSaveFile::backupFile( mFileName, QString::null 246 (void) KSaveFile::backupFile( mFileName, QString::null
245 ,extension ); 247 ,extension );
246 248
247 KSaveFile saveFile( mFileName ); 249 KSaveFile saveFile( mFileName );
248 bool ok = false; 250 bool ok = false;
249 if ( saveFile.status() == 0 && saveFile.file() ) 251 if ( saveFile.status() == 0 && saveFile.file() )
250 { 252 {
251 mFormat->saveAll( addressBook(), this, saveFile.file() ); 253 mFormat->saveAll( addressBook(), this, saveFile.file() );
252 ok = saveFile.close(); 254 ok = saveFile.close();
253 } 255 }
254*/ 256*/
255 257
256//US ToDo: write backupfile 258//US ToDo: write backupfile
257#ifndef NO_DIRWATCH 259#ifndef NO_DIRWATCH
258 mDirWatch.stopScan(); 260 mDirWatch.stopScan();
259#endif 261#endif
262 if ( mLastBackupDate >= 0 && mFamily != "sync_res") {
263 KConfig conf (locateLocal("config","microkdeglobalrc"));
264 conf.setGroup( "BackupSettings" );
265 bool b_enabled = conf.readBoolEntry( "BackupEnabled" );
266 if ( b_enabled ) {
267 int num = conf.readNumEntry( "BackupNumbers" );
268 int d_count = conf.readNumEntry( "BackupDayCount" );
269 bool stdDir = conf.readBoolEntry( "BackupUseDefaultDir" );
270 QString bupDir = conf.readEntry( "BackupDatadir" );
271 QDate reference ( 2000,1,1 );
272 int daysTo = reference.daysTo ( QDate::currentDate() );
273 bool saveDate = false;
274 if ( daysTo - d_count >= mLastBackupDate ) {
275 qDebug("KA: Last backup was %d days ago ", daysTo - mLastBackupDate );
276 if ( stdDir )
277 bupDir = KGlobalSettings::backupDataDir();
278 int retval = KApplication::createBackup( fileName(), bupDir, num );
279 if ( retval == 0 ) {
280 qDebug("KO: Backup cancelled. Will try again tomorrow ");
281 // retval == 0 : backup skipped for today, try again tomorrow
282 mLastBackupDate = daysTo - d_count+1;
283 saveDate = true;
284 } else if ( retval == 1 ){
285 qDebug("KO: Backup created.");
286 // backup ok
287 mLastBackupDate = daysTo;
288 saveDate = true;
289 } else if ( retval == 2 ){
290 qDebug("KO: Backup globally cancelled.");
291 // backup globally cancelled
292 b_enabled = false;
293 }
294 if ( !b_enabled ) {
295 conf.writeEntry( "mBackupEnabled", false );
296 }
297 if ( saveDate ) {
298 KConfig config ( locateLocal("config","kabcrc") );
299 config.setGroup( "Resource_" + identifier() );
300 config.writeEntry( "LastBackupDate", mLastBackupDate );
301 }
302 }
303 }
304 }
260 QFile info; 305 QFile info;
261 info.setName( fileName() ); 306 info.setName( fileName() );
262 bool ok = info.open( IO_WriteOnly ); 307 bool ok = info.open( IO_WriteOnly );
263 if ( ok ) { 308 if ( ok ) {
264 mFormat->saveAll( addressBook(), this, &info ); 309 mFormat->saveAll( addressBook(), this, &info );
265 310
266 info.close(); 311 info.close();
267 ok = true; 312 ok = true;
268 } 313 }
269 else { 314 else {
270 315
271 } 316 }
272 317
273 if ( !ok ) 318 if ( !ok )
274 addressBook()->error( i18n( "Unable to save file '%1'." ).arg( fileName() ) ); 319 addressBook()->error( i18n( "Unable to save file '%1'." ).arg( fileName() ) );
275#ifndef NO_DIRWATCH 320#ifndef NO_DIRWATCH
276 mDirWatch.startScan(); 321 mDirWatch.startScan();
277#endif 322#endif
278 delete ticket; 323 delete ticket;
279#ifdef ALLOW_LOCKING 324#ifdef ALLOW_LOCKING
280 unlock( mFileName ); 325 unlock( mFileName );
281#endif 326#endif
282 327
283 return ok; 328 return ok;
284} 329}
285 330
286bool ResourceFile::lock( const QString &fileName ) 331bool ResourceFile::lock( const QString &fileName )
287{ 332{
288#ifdef ALLOW_LOCKING 333#ifdef ALLOW_LOCKING
289 334
290 335
291 QString fn = fileName; 336 QString fn = fileName;
292 337
293//US change the implementation how the lockfilename is getting created 338//US change the implementation how the lockfilename is getting created
294//US fn.replace( QRegExp("/"), "_" ); 339//US fn.replace( QRegExp("/"), "_" );
295//US QString lockName = locateLocal( "data", "kabc/lock/" + fn + ".lock" ); 340//US QString lockName = locateLocal( "data", "kabc/lock/" + fn + ".lock" );
296 341
297 KURL url(fn); 342 KURL url(fn);
298 QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" ); 343 QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" );
299 344
300 345
301 346
302 if (QFile::exists( lockName )) return false; 347 if (QFile::exists( lockName )) return false;
303 348
304 QString lockUniqueName; 349 QString lockUniqueName;
305 lockUniqueName = fn + KApplication::randomString( 8 ); 350 lockUniqueName = fn + KApplication::randomString( 8 );
306 351
307 url = lockUniqueName; 352 url = lockUniqueName;
308//US mLockUniqueName = locateLocal( "data", "kabc/lock/" + lockUniqueName ); 353//US mLockUniqueName = locateLocal( "data", "kabc/lock/" + lockUniqueName );
309 mLockUniqueName = locateLocal( "data", "kabc/lock/" + url.fileName() ); 354 mLockUniqueName = locateLocal( "data", "kabc/lock/" + url.fileName() );
310 kdDebug(5700) << "-- lock unique name: " << mLockUniqueName << endl; 355 kdDebug(5700) << "-- lock unique name: " << mLockUniqueName << endl;
311 356
312 // Create unique file 357 // Create unique file
313 QFile file( mLockUniqueName ); 358 QFile file( mLockUniqueName );
314 file.open( IO_WriteOnly ); 359 file.open( IO_WriteOnly );
315 file.close(); 360 file.close();
316 361
317 // Create lock file 362 // Create lock file
318 int result = 0; 363 int result = 0;
319#ifndef _WIN32_ 364#ifndef _WIN32_
320 result = ::link( QFile::encodeName( mLockUniqueName ), 365 result = ::link( QFile::encodeName( mLockUniqueName ),
321 QFile::encodeName( lockName ) ); 366 QFile::encodeName( lockName ) );
322#endif 367#endif
323 if ( result == 0 ) { 368 if ( result == 0 ) {
324 addressBook()->emitAddressBookLocked(); 369 addressBook()->emitAddressBookLocked();
325 return true; 370 return true;
326 } 371 }
327 372
328 // TODO: check stat 373 // TODO: check stat
329 374
330 return false; 375 return false;
331#else 376#else
332 return true; 377 return true;
333#endif 378#endif
334} 379}
335 380
336void ResourceFile::unlock( const QString &fileName ) 381void ResourceFile::unlock( const QString &fileName )
337{ 382{
338#ifdef ALLOW_LOCKING 383#ifdef ALLOW_LOCKING
339 QString fn = fileName; 384 QString fn = fileName;
340//US change the implementation how the lockfilename is getting created 385//US change the implementation how the lockfilename is getting created
341//US fn.replace( QRegExp( "/" ), "_" ); 386//US fn.replace( QRegExp( "/" ), "_" );
342//US QString lockName = locateLocal( "data", "kabc/lock/" + fn + ".lock" ); 387//US QString lockName = locateLocal( "data", "kabc/lock/" + fn + ".lock" );
343//US QString lockName = fn + ".lock"; 388//US QString lockName = fn + ".lock";
344 KURL url(fn); 389 KURL url(fn);
345 QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" ); 390 QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" );
346 391
347 QFile::remove( lockName ); 392 QFile::remove( lockName );
348 QFile::remove( mLockUniqueName ); 393 QFile::remove( mLockUniqueName );
349 addressBook()->emitAddressBookUnlocked(); 394 addressBook()->emitAddressBookUnlocked();
350#else 395#else
351 return; 396 return;
352#endif 397#endif
353} 398}
354 399
355void ResourceFile::setFileName( const QString &fileName ) 400void ResourceFile::setFileName( const QString &fileName )
356{ 401{
357#ifndef NO_DIRWATCH 402#ifndef NO_DIRWATCH
358 mDirWatch.stopScan(); 403 mDirWatch.stopScan();
359 mDirWatch.removeFile( mFileName ); 404 mDirWatch.removeFile( mFileName );
360 mFileName = fileName; 405 mFileName = fileName;
361 406
362 407
363 mDirWatch.addFile( mFileName ); 408 mDirWatch.addFile( mFileName );
364 mDirWatch.startScan(); 409 mDirWatch.startScan();
365#else 410#else
366 mFileName2 = fileName; 411 mFileName2 = fileName;
367#endif 412#endif
368 413
369//US simulate KDirWatch event 414//US simulate KDirWatch event
370//US fileChanged(); 415//US fileChanged();
371} 416}
372 417
373QString ResourceFile::fileName() const 418QString ResourceFile::fileName() const
374{ 419{
375 return mFileName2; 420 return mFileName2;
376} 421}
377 422
378void ResourceFile::setFormat( const QString &format ) 423void ResourceFile::setFormat( const QString &format )
379{ 424{
380 mFormatName = format; 425 mFormatName = format;
381 delete mFormat; 426 delete mFormat;
382 427
383 FormatFactory *factory = FormatFactory::self(); 428 FormatFactory *factory = FormatFactory::self();
384 mFormat = factory->format( mFormatName ); 429 mFormat = factory->format( mFormatName );
385/*US 430/*US
386//qDebug("ResourceFile::setFormat initialized with format %s ", format.latin1()); 431//qDebug("ResourceFile::setFormat initialized with format %s ", format.latin1());
387 if (mFormatName == "vcard") { 432 if (mFormatName == "vcard") {
388 mFormat = new VCardFormatPlugin2(); 433 mFormat = new VCardFormatPlugin2();
389// qDebug("ResourceFile::setFormat format %s", mFormatName.latin1()); 434// qDebug("ResourceFile::setFormat format %s", mFormatName.latin1());
390 } 435 }
391 else if (mFormatName == "binary") { 436 else if (mFormatName == "binary") {
392 mFormat = new BinaryFormat(); 437 mFormat = new BinaryFormat();
393// qDebug("ResourceFile::setFormat format %s", mFormatName.latin1()); 438// qDebug("ResourceFile::setFormat format %s", mFormatName.latin1());
394 } 439 }
395 else 440 else
396 qDebug("ResourceFile::setFormat format unknown !!! %s ", format.latin1()); 441 qDebug("ResourceFile::setFormat format unknown !!! %s ", format.latin1());
397*/ 442*/
398 443
399} 444}
400 445
401QString ResourceFile::format() const 446QString ResourceFile::format() const
402{ 447{
403 return mFormatName; 448 return mFormatName;
404} 449}
405 450
406void ResourceFile::fileChanged() 451void ResourceFile::fileChanged()
407{ 452{
408 // There is a small theoretical chance that KDirWatch calls us before 453 // There is a small theoretical chance that KDirWatch calls us before
409 // we are fully constructed 454 // we are fully constructed
410 if (!addressBook()) 455 if (!addressBook())
411 return; 456 return;
412 457
413 458
414 QString text( i18n( "File resource '%1'<br> has been changed by third party.<br>Do you want to reload?").arg( fileName() ) ); 459 QString text( i18n( "File resource '%1'<br> has been changed by third party.<br>Do you want to reload?").arg( fileName() ) );
415 if ( readOnly() || KMessageBox::questionYesNo( 0, text ) == KMessageBox::Yes ) { 460 if ( readOnly() || KMessageBox::questionYesNo( 0, text ) == KMessageBox::Yes ) {
416 load(); 461 load();
417 addressBook()->emitAddressBookChanged(); 462 addressBook()->emitAddressBookChanged();
418 } 463 }
419} 464}
420 465
421void ResourceFile::removeAddressee( const Addressee &addr ) 466void ResourceFile::removeAddressee( const Addressee &addr )
422{ 467{
423 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/photos/" ) + addr.uid() ) ); 468 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/photos/" ) + addr.uid() ) );
424 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/logos/" ) + addr.uid() ) ); 469 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/logos/" ) + addr.uid() ) );
425 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/sounds/" ) + addr.uid() ) ); 470 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/sounds/" ) + addr.uid() ) );
426} 471}
427 472
428void ResourceFile::cleanUp() 473void ResourceFile::cleanUp()
429{ 474{
430 unlock( fileName() ); 475 unlock( fileName() );
431} 476}
432 477
433//US #include "resourcefile.moc" 478//US #include "resourcefile.moc"
diff --git a/kabc/plugins/file/resourcefile.h b/kabc/plugins/file/resourcefile.h
index 3e9edfc..61da154 100644
--- a/kabc/plugins/file/resourcefile.h
+++ b/kabc/plugins/file/resourcefile.h
@@ -1,164 +1,165 @@
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 28
29#ifndef KABC_RESOURCEFILE_H 29#ifndef KABC_RESOURCEFILE_H
30#define KABC_RESOURCEFILE_H 30#define KABC_RESOURCEFILE_H
31 31
32#include <kconfig.h> 32#include <kconfig.h>
33#include <kdirwatch.h> 33#include <kdirwatch.h>
34 34
35#include <sys/types.h> 35#include <sys/types.h>
36 36
37#include <resource.h> 37#include <resource.h>
38 38
39class QTimer; 39class QTimer;
40class FormatPlugin; 40class FormatPlugin;
41 41
42namespace KABC { 42namespace KABC {
43 43
44//US class FormatPlugin; 44//US class FormatPlugin;
45class ResourceConfigWidget; 45class ResourceConfigWidget;
46 46
47/** 47/**
48 @internal 48 @internal
49*/ 49*/
50class ResourceFile : public Resource 50class ResourceFile : public Resource
51{ 51{
52 Q_OBJECT 52 Q_OBJECT
53 53
54public: 54public:
55 55
56 /** 56 /**
57 Constructor. 57 Constructor.
58 58
59 @param cfg The config object where custom resource settings are stored. 59 @param cfg The config object where custom resource settings are stored.
60 */ 60 */
61 ResourceFile( const KConfig *cfg ); 61 ResourceFile( const KConfig *cfg );
62 62
63 /** 63 /**
64 Construct file resource on file @arg fileName using format @arg formatName. 64 Construct file resource on file @arg fileName using format @arg formatName.
65 */ 65 */
66 ResourceFile( const QString &fileName , const QString &formatName = "vcard" ); 66 ResourceFile( const QString &fileName , const QString &formatName = "vcard" );
67 67
68 /** 68 /**
69 * Destructor. 69 * Destructor.
70 */ 70 */
71 ~ResourceFile(); 71 ~ResourceFile();
72 72
73 /** 73 /**
74 Writes the config back. 74 Writes the config back.
75 */ 75 */
76 virtual void writeConfig( KConfig *cfg ); 76 virtual void writeConfig( KConfig *cfg );
77 77
78 /** 78 /**
79 * Tries to open the file and checks for the proper format. 79 * Tries to open the file and checks for the proper format.
80 * This method should be called before @ref load(). 80 * This method should be called before @ref load().
81 */ 81 */
82 virtual bool doOpen(); 82 virtual bool doOpen();
83 83
84 /** 84 /**
85 * Closes the file again. 85 * Closes the file again.
86 */ 86 */
87 virtual void doClose(); 87 virtual void doClose();
88 88
89 /** 89 /**
90 * Requests a save ticket, that is used by @ref save() 90 * Requests a save ticket, that is used by @ref save()
91 */ 91 */
92 virtual Ticket *requestSaveTicket(); 92 virtual Ticket *requestSaveTicket();
93 93
94 /** 94 /**
95 * Loads all addressees from file to the address book. 95 * Loads all addressees from file to the address book.
96 * Returns true if all addressees could be loaded otherwise false. 96 * Returns true if all addressees could be loaded otherwise false.
97 */ 97 */
98 virtual bool load(); 98 virtual bool load();
99 99
100 /** 100 /**
101 * Saves all addresses from address book to file. 101 * Saves all addresses from address book to file.
102 * Returns true if all addressees could be saved otherwise false. 102 * Returns true if all addressees could be saved otherwise false.
103 * 103 *
104 * @param ticket The ticket returned by @ref requestSaveTicket() 104 * @param ticket The ticket returned by @ref requestSaveTicket()
105 */ 105 */
106 virtual bool save( Ticket *ticket ); 106 virtual bool save( Ticket *ticket );
107 107
108 /** 108 /**
109 * Set name of file to be used for saving. 109 * Set name of file to be used for saving.
110 */ 110 */
111 void setFileName( const QString & ); 111 void setFileName( const QString & );
112 112
113 /** 113 /**
114 * Return name of file used for loading and saving the address book. 114 * Return name of file used for loading and saving the address book.
115 */ 115 */
116 QString fileName() const; 116 QString fileName() const;
117 117
118 /** 118 /**
119 Sets a new format by name. 119 Sets a new format by name.
120 */ 120 */
121 void setFormat( const QString &name ); 121 void setFormat( const QString &name );
122 122
123 /** 123 /**
124 Returns the format name. 124 Returns the format name.
125 */ 125 */
126 QString format() const; 126 QString format() const;
127 127
128 /** 128 /**
129 * Remove a addressee from its source. 129 * Remove a addressee from its source.
130 * This method is mainly called by KABC::AddressBook. 130 * This method is mainly called by KABC::AddressBook.
131 */ 131 */
132 virtual void removeAddressee( const Addressee& addr ); 132 virtual void removeAddressee( const Addressee& addr );
133 133
134 /** 134 /**
135 * This method is called by an error handler if the application 135 * This method is called by an error handler if the application
136 * crashed 136 * crashed
137 */ 137 */
138 virtual void cleanUp(); 138 virtual void cleanUp();
139 139
140protected slots: 140protected slots:
141 void fileChanged(); 141 void fileChanged();
142 142
143protected: 143protected:
144 void init( const QString &fileName, const QString &format ); 144 void init( const QString &fileName, const QString &format );
145 145
146 bool lock( const QString &fileName ); 146 bool lock( const QString &fileName );
147 void unlock( const QString &fileName ); 147 void unlock( const QString &fileName );
148 148
149private: 149private:
150 int mLastBackupDate;
150 QString mFamily; 151 QString mFamily;
151 QString mFileName2; 152 QString mFileName2;
152 QString mFormatName; 153 QString mFormatName;
153 154
154 FormatPlugin *mFormat; 155 FormatPlugin *mFormat;
155 156
156 QString mLockUniqueName; 157 QString mLockUniqueName;
157#ifndef NO_DIRWATCH 158#ifndef NO_DIRWATCH
158 KDirWatch mDirWatch; 159 KDirWatch mDirWatch;
159#endif 160#endif
160}; 161};
161 162
162} 163}
163 164
164#endif 165#endif
diff --git a/pwmanager/pwmanager/pwmdoc.cpp b/pwmanager/pwmanager/pwmdoc.cpp
index 61f2616..36b0df5 100644
--- a/pwmanager/pwmanager/pwmdoc.cpp
+++ b/pwmanager/pwmanager/pwmdoc.cpp
@@ -1,3589 +1,3634 @@
1/*************************************************************************** 1/***************************************************************************
2 * * 2 * *
3 * copyright (C) 2003, 2004 by Michael Buesch * 3 * copyright (C) 2003, 2004 by Michael Buesch *
4 * email: mbuesch@freenet.de * 4 * email: mbuesch@freenet.de *
5 * * 5 * *
6 * This program is free software; you can redistribute it and/or modify * 6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License version 2 * 7 * it under the terms of the GNU General Public License version 2 *
8 * as published by the Free Software Foundation. * 8 * as published by the Free Software Foundation. *
9 * * 9 * *
10 ***************************************************************************/ 10 ***************************************************************************/
11 11
12/*************************************************************************** 12/***************************************************************************
13 * copyright (C) 2004 by Ulf Schenk 13 * copyright (C) 2004 by Ulf Schenk
14 * This file is originaly based on version 1.1 of pwmanager 14 * This file is originaly based on version 1.1 of pwmanager
15 * and was modified to run on embedded devices that run microkde 15 * and was modified to run on embedded devices that run microkde
16 * 16 *
17 * $Id$ 17 * $Id$
18 **************************************************************************/ 18 **************************************************************************/
19 19
20#include "pwmdoc.h" 20#include "pwmdoc.h"
21#include "pwmview.h" 21#include "pwmview.h"
22#include "blowfish.h" 22#include "blowfish.h"
23#include "sha1.h" 23#include "sha1.h"
24#include "globalstuff.h" 24#include "globalstuff.h"
25#include "gpasmanfile.h" 25#include "gpasmanfile.h"
26#include "serializer.h" 26#include "serializer.h"
27#include "compressgzip.h" 27#include "compressgzip.h"
28//US#include "compressbzip2.h" 28//US#include "compressbzip2.h"
29#include "randomizer.h" 29#include "randomizer.h"
30#include "pwminit.h" 30#include "pwminit.h"
31#include "libgcryptif.h" 31#include "libgcryptif.h"
32#ifdef PWM_EMBEDDED 32#ifdef PWM_EMBEDDED
33#include "pwmprefs.h" 33#include "pwmprefs.h"
34#include "kglobal.h" 34#include "kglobal.h"
35#endif 35#endif
36 36
37#include <kmessagebox.h> 37#include <kmessagebox.h>
38#include <kconfig.h>
39#include <kglobalsettings.h>
38#include <libkcal/syncdefines.h> 40#include <libkcal/syncdefines.h>
39 41
40 42
41#ifdef CONFIG_KWALLETIF 43#ifdef CONFIG_KWALLETIF
42# include "kwalletemu.h" 44# include "kwalletemu.h"
43#endif // CONFIG_KWALLETIF 45#endif // CONFIG_KWALLETIF
44 46
45#include <qdatetime.h> 47#include <qdatetime.h>
46#include <qsize.h> 48#include <qsize.h>
47#include <qfileinfo.h> 49#include <qfileinfo.h>
48#include <qfile.h> 50#include <qfile.h>
49 51
50#include <stdio.h> 52#include <stdio.h>
51#include <stdlib.h> 53#include <stdlib.h>
52#include <errno.h> 54#include <errno.h>
53#include <string.h> 55#include <string.h>
54//US#include <iostream> 56//US#include <iostream>
55#include <algorithm> 57#include <algorithm>
56#include <sys/types.h> 58#include <sys/types.h>
57#include <sys/stat.h> 59#include <sys/stat.h>
58#ifndef _WIN32_ 60#ifndef _WIN32_
59#include <unistd.h> 61#include <unistd.h>
60#include <stdint.h> 62#include <stdint.h>
61#endif 63#endif
62 64
63#ifdef PWM_EMBEDDED 65#ifdef PWM_EMBEDDED
64#ifndef Q_LONG 66#ifndef Q_LONG
65#define Q_LONG long 67#define Q_LONG long
66#endif 68#endif
67 69
68#ifndef Q_ULONG 70#ifndef Q_ULONG
69#define Q_ULONG unsigned long 71#define Q_ULONG unsigned long
70#endif 72#endif
71#endif //PWM_EMBEDDED 73#endif //PWM_EMBEDDED
72 74
73 75
74//TODO: reset to its normal value. 76//TODO: reset to its normal value.
75//LR set to 5 min 77//LR set to 5 min
76 #define META_CHECK_TIMER_INTERVAL300 /* 10 300*/ /* sek */ 78 #define META_CHECK_TIMER_INTERVAL300 /* 10 300*/ /* sek */
77 79
78using namespace std; 80using namespace std;
79 81
80 82
81void PwMDocList::add(PwMDoc *doc, const string &id) 83void PwMDocList::add(PwMDoc *doc, const string &id)
82{ 84{
83#ifdef PWM_DEBUG 85#ifdef PWM_DEBUG
84 // check for existance of object in debug mode only. 86 // check for existance of object in debug mode only.
85 vector<listItem>::iterator begin = docList.begin(), 87 vector<listItem>::iterator begin = docList.begin(),
86 end = docList.end(), 88 end = docList.end(),
87 i = begin; 89 i = begin;
88 while (i != end) { 90 while (i != end) {
89 if (i->doc == doc) { 91 if (i->doc == doc) {
90 BUG(); 92 BUG();
91 return; 93 return;
92 } 94 }
93 ++i; 95 ++i;
94 } 96 }
95#endif 97#endif
96 listItem newItem; 98 listItem newItem;
97 newItem.doc = doc; 99 newItem.doc = doc;
98 newItem.docId = id; 100 newItem.docId = id;
99 docList.push_back(newItem); 101 docList.push_back(newItem);
100} 102}
101 103
102void PwMDocList::edit(PwMDoc *doc, const string &newId) 104void PwMDocList::edit(PwMDoc *doc, const string &newId)
103{ 105{
104 vector<listItem>::iterator begin = docList.begin(), 106 vector<listItem>::iterator begin = docList.begin(),
105 end = docList.end(), 107 end = docList.end(),
106 i = begin; 108 i = begin;
107 while (i != end) { 109 while (i != end) {
108 if (i->doc == doc) { 110 if (i->doc == doc) {
109 i->docId = newId; 111 i->docId = newId;
110 return; 112 return;
111 } 113 }
112 ++i; 114 ++i;
113 } 115 }
114} 116}
115 117
116void PwMDocList::del(PwMDoc *doc) 118void PwMDocList::del(PwMDoc *doc)
117{ 119{
118 vector<listItem>::iterator begin = docList.begin(), 120 vector<listItem>::iterator begin = docList.begin(),
119 end = docList.end(), 121 end = docList.end(),
120 i = begin; 122 i = begin;
121 while (i != end) { 123 while (i != end) {
122 if (i->doc == doc) { 124 if (i->doc == doc) {
123 docList.erase(i); 125 docList.erase(i);
124 return; 126 return;
125 } 127 }
126 ++i; 128 ++i;
127 } 129 }
128} 130}
129 131
130bool PwMDocList::find(const string &id, listItem *ret) 132bool PwMDocList::find(const string &id, listItem *ret)
131{ 133{
132 vector<listItem>::iterator begin = docList.begin(), 134 vector<listItem>::iterator begin = docList.begin(),
133 end = docList.end(), 135 end = docList.end(),
134 i = begin; 136 i = begin;
135 while (i != end) { 137 while (i != end) {
136 if (i->docId == id) { 138 if (i->docId == id) {
137 if (ret) 139 if (ret)
138 *ret = *i; 140 *ret = *i;
139 return true; 141 return true;
140 } 142 }
141 ++i; 143 ++i;
142 } 144 }
143 return false; 145 return false;
144} 146}
145 147
146 148
147 149
148DocTimer::DocTimer(PwMDoc *_doc) 150DocTimer::DocTimer(PwMDoc *_doc)
149 : doc (_doc) 151 : doc (_doc)
150 , mpwLock (0) 152 , mpwLock (0)
151 , autoLockLock (0) 153 , autoLockLock (0)
152 , metaCheckLock (0) 154 , metaCheckLock (0)
153{ 155{
154 mpwTimer = new QTimer; 156 mpwTimer = new QTimer;
155 autoLockTimer = new QTimer; 157 autoLockTimer = new QTimer;
156 metaCheckTimer = new QTimer; 158 metaCheckTimer = new QTimer;
157 connect(mpwTimer, SIGNAL(timeout()), 159 connect(mpwTimer, SIGNAL(timeout()),
158 this, SLOT(mpwTimeout())); 160 this, SLOT(mpwTimeout()));
159 connect(autoLockTimer, SIGNAL(timeout()), 161 connect(autoLockTimer, SIGNAL(timeout()),
160 this, SLOT(autoLockTimeout())); 162 this, SLOT(autoLockTimeout()));
161 connect(metaCheckTimer, SIGNAL(timeout()), 163 connect(metaCheckTimer, SIGNAL(timeout()),
162 this, SLOT(metaCheckTimeout())); 164 this, SLOT(metaCheckTimeout()));
163} 165}
164 166
165DocTimer::~DocTimer() 167DocTimer::~DocTimer()
166{ 168{
167 delete mpwTimer; 169 delete mpwTimer;
168 delete autoLockTimer; 170 delete autoLockTimer;
169 delete metaCheckTimer; 171 delete metaCheckTimer;
170} 172}
171 173
172void DocTimer::start(TimerIDs timer) 174void DocTimer::start(TimerIDs timer)
173{ 175{
174 switch (timer) { 176 switch (timer) {
175 case id_mpwTimer: 177 case id_mpwTimer:
176 if (mpwTimer->isActive()) 178 if (mpwTimer->isActive())
177 mpwTimer->stop(); 179 mpwTimer->stop();
178 doc->setDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); 180 doc->setDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW);
179 mpwTimer->start(conf()->confGlobPwTimeout() * 1000, true); 181 mpwTimer->start(conf()->confGlobPwTimeout() * 1000, true);
180 break; 182 break;
181 case id_autoLockTimer: 183 case id_autoLockTimer:
182 if (autoLockTimer->isActive()) 184 if (autoLockTimer->isActive())
183 autoLockTimer->stop(); 185 autoLockTimer->stop();
184 if (conf()->confGlobLockTimeout() > 0) 186 if (conf()->confGlobLockTimeout() > 0)
185 autoLockTimer->start(conf()->confGlobLockTimeout() * 1000, true); 187 autoLockTimer->start(conf()->confGlobLockTimeout() * 1000, true);
186 break; 188 break;
187 case id_metaCheckTimer: 189 case id_metaCheckTimer:
188 if (metaCheckTimer->isActive()) 190 if (metaCheckTimer->isActive())
189 metaCheckTimer->stop(); 191 metaCheckTimer->stop();
190 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 192 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
191 break; 193 break;
192 } 194 }
193} 195}
194 196
195void DocTimer::stop(TimerIDs timer) 197void DocTimer::stop(TimerIDs timer)
196{ 198{
197 switch (timer) { 199 switch (timer) {
198 case id_mpwTimer: 200 case id_mpwTimer:
199 mpwTimer->stop(); 201 mpwTimer->stop();
200 break; 202 break;
201 case id_autoLockTimer: 203 case id_autoLockTimer:
202 autoLockTimer->stop(); 204 autoLockTimer->stop();
203 break; 205 break;
204 case id_metaCheckTimer: 206 case id_metaCheckTimer:
205 metaCheckTimer->stop(); 207 metaCheckTimer->stop();
206 break; 208 break;
207 } 209 }
208} 210}
209 211
210void DocTimer::getLock(TimerIDs timer) 212void DocTimer::getLock(TimerIDs timer)
211{ 213{
212 switch (timer) { 214 switch (timer) {
213 case id_mpwTimer: 215 case id_mpwTimer:
214 ++mpwLock; 216 ++mpwLock;
215 break; 217 break;
216 case id_autoLockTimer: 218 case id_autoLockTimer:
217 ++autoLockLock; 219 ++autoLockLock;
218 break; 220 break;
219 case id_metaCheckTimer: 221 case id_metaCheckTimer:
220 ++metaCheckLock; 222 ++metaCheckLock;
221 break; 223 break;
222 } 224 }
223} 225}
224 226
225void DocTimer::putLock(TimerIDs timer) 227void DocTimer::putLock(TimerIDs timer)
226{ 228{
227 switch (timer) { 229 switch (timer) {
228 case id_mpwTimer: 230 case id_mpwTimer:
229 if (mpwLock) 231 if (mpwLock)
230 --mpwLock; 232 --mpwLock;
231 break; 233 break;
232 case id_autoLockTimer: 234 case id_autoLockTimer:
233 if (autoLockLock) 235 if (autoLockLock)
234 --autoLockLock; 236 --autoLockLock;
235 break; 237 break;
236 case id_metaCheckTimer: 238 case id_metaCheckTimer:
237 if (metaCheckLock) 239 if (metaCheckLock)
238 --metaCheckLock; 240 --metaCheckLock;
239 break; 241 break;
240 } 242 }
241} 243}
242 244
243void DocTimer::mpwTimeout() 245void DocTimer::mpwTimeout()
244{ 246{
245 if (mpwLock) { 247 if (mpwLock) {
246 mpwTimer->start(1000, true); 248 mpwTimer->start(1000, true);
247 return; 249 return;
248 } 250 }
249 doc->unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); 251 doc->unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW);
250} 252}
251 253
252void DocTimer::autoLockTimeout() 254void DocTimer::autoLockTimeout()
253{ 255{
254 if (autoLockLock) { 256 if (autoLockLock) {
255 autoLockTimer->start(1000, true); 257 autoLockTimer->start(1000, true);
256 return; 258 return;
257 } 259 }
258 if (conf()->confGlobAutoDeepLock() && 260 if (conf()->confGlobAutoDeepLock() &&
259 doc->filename != QString::null && 261 doc->filename != QString::null &&
260 doc->filename != "") { 262 doc->filename != "") {
261 doc->deepLock(true); 263 doc->deepLock(true);
262 } else { 264 } else {
263 doc->lockAll(true); 265 doc->lockAll(true);
264 } 266 }
265} 267}
266 268
267void DocTimer::metaCheckTimeout() 269void DocTimer::metaCheckTimeout()
268{ 270{
269 if (metaCheckLock) { 271 if (metaCheckLock) {
270 // check again in one second. 272 // check again in one second.
271 metaCheckTimer->start(1000, true); 273 metaCheckTimer->start(1000, true);
272 return; 274 return;
273 } 275 }
274 if (doc->isDeepLocked()) { 276 if (doc->isDeepLocked()) {
275 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 277 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
276 return; 278 return;
277 } 279 }
278 if (doc->isDocEmpty()) { 280 if (doc->isDocEmpty()) {
279 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 281 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
280 return; 282 return;
281 } 283 }
282#ifdef CONFIG_KWALLETIF 284#ifdef CONFIG_KWALLETIF
283 KWalletEmu *kwlEmu = doc->init->kwalletEmu(); 285 KWalletEmu *kwlEmu = doc->init->kwalletEmu();
284 if (kwlEmu) 286 if (kwlEmu)
285 kwlEmu->suspendDocSignals(); 287 kwlEmu->suspendDocSignals();
286#endif // CONFIG_KWALLETIF 288#endif // CONFIG_KWALLETIF
287 /* We simply trigger all views to update their 289 /* We simply trigger all views to update their
288 * displayed values. This way they have a chance 290 * displayed values. This way they have a chance
289 * to get notified when some meta changes over time. 291 * to get notified when some meta changes over time.
290 * (for example an entry expired). 292 * (for example an entry expired).
291 * The _view_ is responsive for not updating its 293 * The _view_ is responsive for not updating its
292 * contents if nothing really changed! 294 * contents if nothing really changed!
293 */ 295 */
294 emit doc->dataChanged(doc); 296 emit doc->dataChanged(doc);
295#ifdef CONFIG_KWALLETIF 297#ifdef CONFIG_KWALLETIF
296 if (kwlEmu) 298 if (kwlEmu)
297 kwlEmu->resumeDocSignals(); 299 kwlEmu->resumeDocSignals();
298#endif // CONFIG_KWALLETIF 300#endif // CONFIG_KWALLETIF
299 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true); 301 metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
300} 302}
301 303
302 304
303 305
304PwMDocList PwMDoc::openDocList; 306PwMDocList PwMDoc::openDocList;
305unsigned int PwMDocList::unnamedDocCnt = 1; 307unsigned int PwMDocList::unnamedDocCnt = 1;
306 308
307PwMDoc::PwMDoc(QObject *parent, const char *name) 309PwMDoc::PwMDoc(QObject *parent, const char *name)
308 : PwMDocUi(parent, name) 310 : PwMDocUi(parent, name)
309 , dataChangedLock (0) 311 , dataChangedLock (0)
310{ 312{
311 deleted = false; 313 deleted = false;
312 unnamedNum = 0; 314 unnamedNum = 0;
313 getOpenDocList()->add(this, getTitle().latin1()); 315 getOpenDocList()->add(this, getTitle().latin1());
314 curDocStat = 0; 316 curDocStat = 0;
315 setMaxNumEntries(); 317 setMaxNumEntries();
316 _timer = new DocTimer(this); 318 _timer = new DocTimer(this);
317 timer()->start(DocTimer::id_mpwTimer); 319 timer()->start(DocTimer::id_mpwTimer);
318 timer()->start(DocTimer::id_autoLockTimer); 320 timer()->start(DocTimer::id_autoLockTimer);
319 timer()->start(DocTimer::id_metaCheckTimer); 321 timer()->start(DocTimer::id_metaCheckTimer);
320 addCategory(DEFAULT_CATEGORY, 0, false); 322 addCategory(DEFAULT_CATEGORY, 0, false);
321 listView = 0; 323 listView = 0;
322 emit docCreated(this); 324 emit docCreated(this);
323} 325}
324 326
325PwMDoc::~PwMDoc() 327PwMDoc::~PwMDoc()
326{ 328{
327 emit docClosed(this); 329 emit docClosed(this);
328 getOpenDocList()->del(this); 330 getOpenDocList()->del(this);
329 delete _timer; 331 delete _timer;
330} 332}
331 333
332PwMerror PwMDoc::saveDoc(char compress, const QString *file) 334PwMerror PwMDoc::saveDoc(char compress, const QString *file)
333{ 335{
334 PwMerror ret, e; 336 PwMerror ret, e;
335 string serialized; 337 string serialized;
336 QFile f; 338 QFile f;
337 QString tmpFileMoved(QString::null); 339 QString tmpFileMoved(QString::null);
338 bool wasDeepLocked; 340 bool wasDeepLocked;
339 QString savedFilename(filename); 341 QString savedFilename(filename);
340 342
341 if (!file) { 343 if (!file) {
342 if (filename == "") 344 if (filename == "")
343 return e_filename; 345 return e_filename;
344 if (isDeepLocked()) { 346 if (isDeepLocked()) {
345 /* We don't need to save any data. 347 /* We don't need to save any data.
346 * It's already all on disk, because 348 * It's already all on disk, because
347 * we are deeplocked. 349 * we are deeplocked.
348 */ 350 */
349 unsetDocStatFlag(DOC_STAT_DISK_DIRTY); 351 unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
350 ret = e_success; 352 ret = e_success;
351 return ret; 353 return ret;
352 } 354 }
353 } else { 355 } else {
354 if (*file == "" && filename == "") 356 if (*file == "" && filename == "")
355 return e_filename; 357 return e_filename;
356 if (*file != "") 358 if (*file != "")
357 filename = *file; 359 filename = *file;
358 } 360 }
359 361
360 wasDeepLocked = isDeepLocked(); 362 wasDeepLocked = isDeepLocked();
361 if (wasDeepLocked) { 363 if (wasDeepLocked) {
362 /* We are deeplocked. That means all data is already 364 /* We are deeplocked. That means all data is already
363 * on disk. BUT we need to do saving procedure, 365 * on disk. BUT we need to do saving procedure,
364 * because *file != savedFilename. 366 * because *file != savedFilename.
365 * Additionally we need to tempoarly restore 367 * Additionally we need to tempoarly restore
366 * the old "filename", because deepLock() references it. 368 * the old "filename", because deepLock() references it.
367 */ 369 */
368 QString newFilename(filename); 370 QString newFilename(filename);
369 filename = savedFilename; 371 filename = savedFilename;
370 getDataChangedLock(); 372 getDataChangedLock();
371 e = deepLock(false); 373 e = deepLock(false);
372 putDataChangedLock(); 374 putDataChangedLock();
373 filename = newFilename; 375 filename = newFilename;
374 switch (e) { 376 switch (e) {
375 case e_success: 377 case e_success:
376 break; 378 break;
377 case e_wrongPw: 379 case e_wrongPw:
378 case e_noPw: 380 case e_noPw:
379 emitDataChanged(this); 381 emitDataChanged(this);
380 return e; 382 return e;
381 default: 383 default:
382 emitDataChanged(this); 384 emitDataChanged(this);
383 return e_openFile; 385 return e_openFile;
384 } 386 }
385 } 387 }
386 388
387 if (!isPwAvailable()) { 389 if (!isPwAvailable()) {
388 /* password is not available. This means, the 390 /* password is not available. This means, the
389 * document wasn't saved, yet. 391 * document wasn't saved, yet.
390 */ 392 */
391 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD); 393 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD);
392 QString pw(requestNewMpw(&useChipcard)); 394 QString pw(requestNewMpw(&useChipcard));
393 if (pw != "") { 395 if (pw != "") {
394 currentPw = pw; 396 currentPw = pw;
395 } else { 397 } else {
396 return e_noPw; 398 return e_noPw;
397 } 399 }
398 if (useChipcard) { 400 if (useChipcard) {
399 setDocStatFlag(DOC_STAT_USE_CHIPCARD); 401 setDocStatFlag(DOC_STAT_USE_CHIPCARD);
400 } else { 402 } else {
401 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); 403 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
402 } 404 }
403 } 405 }
404 406
405 int _cryptAlgo = conf()->confGlobCryptAlgo(); 407 int _cryptAlgo = conf()->confGlobCryptAlgo();
406 int _hashAlgo = conf()->confGlobHashAlgo(); 408 int _hashAlgo = conf()->confGlobHashAlgo();
407 409
408 // sanity check for the selected algorithms 410 // sanity check for the selected algorithms
409 if (_cryptAlgo < PWM_CRYPT_BLOWFISH || 411 if (_cryptAlgo < PWM_CRYPT_BLOWFISH ||
410 _cryptAlgo > PWM_CRYPT_TWOFISH128) { 412 _cryptAlgo > PWM_CRYPT_TWOFISH128) {
411 printWarn("Invalid Crypto-Algorithm selected! " 413 printWarn("Invalid Crypto-Algorithm selected! "
412 "Config-file seems to be corrupt. " 414 "Config-file seems to be corrupt. "
413 "Falling back to Blowfish."); 415 "Falling back to Blowfish.");
414 _cryptAlgo = PWM_CRYPT_BLOWFISH; 416 _cryptAlgo = PWM_CRYPT_BLOWFISH;
415 } 417 }
416 if (_hashAlgo < PWM_HASH_SHA1 || 418 if (_hashAlgo < PWM_HASH_SHA1 ||
417 _hashAlgo > PWM_HASH_TIGER) { 419 _hashAlgo > PWM_HASH_TIGER) {
418 printWarn("Invalid Hash-Algorithm selected! " 420 printWarn("Invalid Hash-Algorithm selected! "
419 "Config-file seems to be corrupt. " 421 "Config-file seems to be corrupt. "
420 "Falling back to SHA1."); 422 "Falling back to SHA1.");
421 _hashAlgo = PWM_HASH_SHA1; 423 _hashAlgo = PWM_HASH_SHA1;
422 } 424 }
423 char cryptAlgo = static_cast<char>(_cryptAlgo); 425 char cryptAlgo = static_cast<char>(_cryptAlgo);
424 char hashAlgo = static_cast<char>(_hashAlgo); 426 char hashAlgo = static_cast<char>(_hashAlgo);
425 427
426 if (conf()->confGlobMakeFileBackup()) { 428 if (conf()->confGlobMakeFileBackup()) {
427 if (!backupFile(filename)) 429 if (!backupFile(filename))
428 return e_fileBackup; 430 return e_fileBackup;
429 } 431 }
432 int mLastBackupDate = 0;
433 KConfig configGlobal (locateLocal("config","pwmanagerbuprc"));
434 QFileInfo fileInfo ( filename );
435 mLastBackupDate = configGlobal.readNumEntry( "LastBackupDate-"+ fileInfo.fileName (), 0 );
436 KConfig config (locateLocal("config","microkdeglobalrc"));
437 config.setGroup( "BackupSettings" );
438 bool b_enabled = config.readBoolEntry( "BackupEnabled" );
439 if ( b_enabled ) {
440 int num = config.readNumEntry( "BackupNumbers" );
441 int d_count = config.readNumEntry( "BackupDayCount" );
442 bool stdDir = config.readBoolEntry( "BackupUseDefaultDir" );
443 QString bupDir = config.readEntry( "BackupDatadir" );
444 QDate reference ( 2000,1,1 );
445 int daysTo = reference.daysTo ( QDate::currentDate() );
446 bool saveDate = false;
447 if ( daysTo - d_count >= mLastBackupDate ) {
448 qDebug("KA: Last backup was %d days ago ", daysTo - mLastBackupDate );
449 if ( stdDir )
450 bupDir = KGlobalSettings::backupDataDir();
451 int retval = KApplication::createBackup( filename, bupDir, num );
452 if ( retval == 0 ) {
453 qDebug("KO: Backup cancelled. Will try again tomorrow ");
454 // retval == 0 : backup skipped for today, try again tomorrow
455 mLastBackupDate = daysTo - d_count+1;
456 saveDate = true;
457 } else if ( retval == 1 ){
458 qDebug("KO: Backup created.");
459 // backup ok
460 mLastBackupDate = daysTo;
461 saveDate = true;
462 } else if ( retval == 2 ){
463 qDebug("KO: Backup globally cancelled.");
464 // backup globally cancelled
465 b_enabled = false;
466 }
467 if ( !b_enabled ) {
468 config.writeEntry( "mBackupEnabled", false );
469 }
470 if ( saveDate ) {
471 configGlobal.writeEntry( "LastBackupDate-"+ fileInfo.fileName (), mLastBackupDate );
472 }
473 }
474 }
430 if (QFile::exists(filename)) { 475 if (QFile::exists(filename)) {
431 /* Move the existing file to some tmp file. 476 /* Move the existing file to some tmp file.
432 * When saving file succeeds, delete tmp file. Otherwise 477 * When saving file succeeds, delete tmp file. Otherwise
433 * move tmp file back. See below. 478 * move tmp file back. See below.
434 */ 479 */
435 Randomizer *rnd = Randomizer::obj(); 480 Randomizer *rnd = Randomizer::obj();
436 char rnd_buf[5]; 481 char rnd_buf[5];
437 sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF, 482 sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF,
438 rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF); 483 rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF);
439 tmpFileMoved = filename + "." + rnd_buf + ".mv"; 484 tmpFileMoved = filename + "." + rnd_buf + ".mv";
440 if (!copyFile(filename, tmpFileMoved)) 485 if (!copyFile(filename, tmpFileMoved))
441 return e_openFile; 486 return e_openFile;
442 if (!QFile::remove(filename)) { 487 if (!QFile::remove(filename)) {
443 printWarn(string("removing orig file ") 488 printWarn(string("removing orig file ")
444 + filename.latin1() 489 + filename.latin1()
445 + " failed!"); 490 + " failed!");
446 } 491 }
447 } 492 }
448 f.setName(filename); 493 f.setName(filename);
449 if (!f.open(IO_ReadWrite)) { 494 if (!f.open(IO_ReadWrite)) {
450 ret = e_openFile; 495 ret = e_openFile;
451 goto out_moveback; 496 goto out_moveback;
452 } 497 }
453 e = writeFileHeader(hashAlgo, hashAlgo, 498 e = writeFileHeader(hashAlgo, hashAlgo,
454 cryptAlgo, compress, 499 cryptAlgo, compress,
455 &currentPw, &f); 500 &currentPw, &f);
456 if (e == e_hashNotImpl) { 501 if (e == e_hashNotImpl) {
457 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl"); 502 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl");
458 f.close(); 503 f.close();
459 ret = e_hashNotImpl; 504 ret = e_hashNotImpl;
460 goto out_moveback; 505 goto out_moveback;
461 } else if (e != e_success) { 506 } else if (e != e_success) {
462 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed"); 507 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed");
463 f.close(); 508 f.close();
464 ret = e_writeHeader; 509 ret = e_writeHeader;
465 goto out_moveback; 510 goto out_moveback;
466 } 511 }
467 if (!serializeDta(&serialized)) { 512 if (!serializeDta(&serialized)) {
468 printDebug("PwMDoc::saveDoc(): serializeDta() failed"); 513 printDebug("PwMDoc::saveDoc(): serializeDta() failed");
469 f.close(); 514 f.close();
470 ret = e_serializeDta; 515 ret = e_serializeDta;
471 goto out_moveback; 516 goto out_moveback;
472 } 517 }
473 e = writeDataHash(hashAlgo, &serialized, &f); 518 e = writeDataHash(hashAlgo, &serialized, &f);
474 if (e == e_hashNotImpl) { 519 if (e == e_hashNotImpl) {
475 printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl"); 520 printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl");
476 f.close(); 521 f.close();
477 ret = e_hashNotImpl; 522 ret = e_hashNotImpl;
478 goto out_moveback; 523 goto out_moveback;
479 } else if (e != e_success) { 524 } else if (e != e_success) {
480 printDebug("PwMDoc::saveDoc(): writeDataHash() failed"); 525 printDebug("PwMDoc::saveDoc(): writeDataHash() failed");
481 f.close(); 526 f.close();
482 ret = e_writeHeader; 527 ret = e_writeHeader;
483 goto out_moveback; 528 goto out_moveback;
484 } 529 }
485 if (!compressDta(&serialized, compress)) { 530 if (!compressDta(&serialized, compress)) {
486 printDebug("PwMDoc::saveDoc(): compressDta() failed"); 531 printDebug("PwMDoc::saveDoc(): compressDta() failed");
487 f.close(); 532 f.close();
488 ret = e_enc; 533 ret = e_enc;
489 goto out_moveback; 534 goto out_moveback;
490 } 535 }
491 e = encrypt(&serialized, &currentPw, &f, cryptAlgo, hashAlgo); 536 e = encrypt(&serialized, &currentPw, &f, cryptAlgo, hashAlgo);
492 if (e == e_weakPw) { 537 if (e == e_weakPw) {
493 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw"); 538 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw");
494 f.close(); 539 f.close();
495 ret = e_weakPw; 540 ret = e_weakPw;
496 goto out_moveback; 541 goto out_moveback;
497 } else if (e == e_cryptNotImpl) { 542 } else if (e == e_cryptNotImpl) {
498 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl"); 543 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl");
499 f.close(); 544 f.close();
500 ret = e_cryptNotImpl; 545 ret = e_cryptNotImpl;
501 goto out_moveback; 546 goto out_moveback;
502 } else if (e != e_success) { 547 } else if (e != e_success) {
503 printDebug("PwMDoc::saveDoc(): encrypt() failed"); 548 printDebug("PwMDoc::saveDoc(): encrypt() failed");
504 f.close(); 549 f.close();
505 ret = e_enc; 550 ret = e_enc;
506 goto out_moveback; 551 goto out_moveback;
507 } 552 }
508 unsetDocStatFlag(DOC_STAT_DISK_DIRTY); 553 unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
509 f.close(); 554 f.close();
510#ifndef _WIN32_ 555#ifndef _WIN32_
511 if (chmod(filename.latin1(), 556 if (chmod(filename.latin1(),
512 conf()->confGlobFilePermissions())) { 557 conf()->confGlobFilePermissions())) {
513 printWarn(string("chmod failed: ") + strerror(errno)); 558 printWarn(string("chmod failed: ") + strerror(errno));
514 } 559 }
515#endif 560#endif
516 openDocList.edit(this, getTitle().latin1()); 561 openDocList.edit(this, getTitle().latin1());
517 if (wasDeepLocked) { 562 if (wasDeepLocked) {
518 /* Do _not_ save the data with the deepLock() 563 /* Do _not_ save the data with the deepLock()
519 * call, because this will recurse 564 * call, because this will recurse
520 * into saveDoc() 565 * into saveDoc()
521 */ 566 */
522 deepLock(true, false); 567 deepLock(true, false);
523 /* We don't check return value here, because 568 /* We don't check return value here, because
524 * it won't fail. See NOTE in deepLock() 569 * it won't fail. See NOTE in deepLock()
525 */ 570 */
526 } 571 }
527 if (tmpFileMoved != QString::null) { 572 if (tmpFileMoved != QString::null) {
528 // now remove the moved file. 573 // now remove the moved file.
529 if (!QFile::remove(tmpFileMoved)) { 574 if (!QFile::remove(tmpFileMoved)) {
530 printWarn(string("removing file ") 575 printWarn(string("removing file ")
531 + tmpFileMoved.latin1() 576 + tmpFileMoved.latin1()
532 + " failed!"); 577 + " failed!");
533 } 578 }
534 } 579 }
535 ret = e_success; 580 ret = e_success;
536 printDebug(string("writing file { name: ") 581 printDebug(string("writing file { name: ")
537 + filename.latin1() + " compress: " 582 + filename.latin1() + " compress: "
538 + tostr(static_cast<int>(compress)) + " cryptAlgo: " 583 + tostr(static_cast<int>(compress)) + " cryptAlgo: "
539 + tostr(static_cast<int>(cryptAlgo)) + " hashAlgo: " 584 + tostr(static_cast<int>(cryptAlgo)) + " hashAlgo: "
540 + tostr(static_cast<int>(hashAlgo)) 585 + tostr(static_cast<int>(hashAlgo))
541 + " }"); 586 + " }");
542 goto out; 587 goto out;
543out_moveback: 588out_moveback:
544 if (tmpFileMoved != QString::null) { 589 if (tmpFileMoved != QString::null) {
545 if (copyFile(tmpFileMoved, filename)) { 590 if (copyFile(tmpFileMoved, filename)) {
546 if (!QFile::remove(tmpFileMoved)) { 591 if (!QFile::remove(tmpFileMoved)) {
547 printWarn(string("removing tmp file ") 592 printWarn(string("removing tmp file ")
548 + filename.latin1() 593 + filename.latin1()
549 + " failed!"); 594 + " failed!");
550 } 595 }
551 } else { 596 } else {
552 printWarn(string("couldn't copy file ") 597 printWarn(string("couldn't copy file ")
553 + tmpFileMoved.latin1() 598 + tmpFileMoved.latin1()
554 + " back to " 599 + " back to "
555 + filename.latin1()); 600 + filename.latin1());
556 } 601 }
557 } 602 }
558out: 603out:
559 return ret; 604 return ret;
560} 605}
561 606
562PwMerror PwMDoc::openDoc(const QString *file, int openLocked) 607PwMerror PwMDoc::openDoc(const QString *file, int openLocked)
563{ 608{
564 PWM_ASSERT(file); 609 PWM_ASSERT(file);
565 PWM_ASSERT(openLocked == 0 || openLocked == 1 || openLocked == 2); 610 PWM_ASSERT(openLocked == 0 || openLocked == 1 || openLocked == 2);
566 string decrypted, dataHash; 611 string decrypted, dataHash;
567 PwMerror ret; 612 PwMerror ret;
568 char cryptAlgo, dataHashType, compress; 613 char cryptAlgo, dataHashType, compress;
569 unsigned int headerLen; 614 unsigned int headerLen;
570 615
571 if (*file == "") 616 if (*file == "")
572 return e_readFile; 617 return e_readFile;
573 filename = *file; 618 filename = *file;
574 /* check if this file is already open. 619 /* check if this file is already open.
575 * This does not catch symlinks! 620 * This does not catch symlinks!
576 */ 621 */
577 if (!isDeepLocked()) { 622 if (!isDeepLocked()) {
578 if (getOpenDocList()->find(filename.latin1())) 623 if (getOpenDocList()->find(filename.latin1()))
579 return e_alreadyOpen; 624 return e_alreadyOpen;
580 } 625 }
581 QFile f(filename); 626 QFile f(filename);
582 627
583 if (openLocked == 2) { 628 if (openLocked == 2) {
584 // open deep-locked 629 // open deep-locked
585 if (!QFile::exists(filename)) 630 if (!QFile::exists(filename))
586 return e_openFile; 631 return e_openFile;
587 if (deepLock(true, false) != e_success) 632 if (deepLock(true, false) != e_success)
588 return e_openFile; 633 return e_openFile;
589 goto out_success; 634 goto out_success;
590 } 635 }
591 636
592 if (!f.open(IO_ReadOnly)) 637 if (!f.open(IO_ReadOnly))
593 return e_openFile; 638 return e_openFile;
594 639
595 ret = checkHeader(&cryptAlgo, &currentPw, &compress, &headerLen, 640 ret = checkHeader(&cryptAlgo, &currentPw, &compress, &headerLen,
596 &dataHashType, &dataHash, &f); 641 &dataHashType, &dataHash, &f);
597 if (ret != e_success) { 642 if (ret != e_success) {
598 printDebug("PwMDoc::openDoc(): checkHeader() failed"); 643 printDebug("PwMDoc::openDoc(): checkHeader() failed");
599 f.close(); 644 f.close();
600 if (ret == e_wrongPw) { 645 if (ret == e_wrongPw) {
601 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 646 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
602 return ret; 647 return ret;
603 } else if (ret == e_noPw || 648 } else if (ret == e_noPw ||
604 ret == e_fileVer || 649 ret == e_fileVer ||
605 ret == e_fileFormat || 650 ret == e_fileFormat ||
606 ret == e_hashNotImpl) { 651 ret == e_hashNotImpl) {
607 return ret; 652 return ret;
608 } else 653 } else
609 return e_readFile; 654 return e_readFile;
610 } 655 }
611 ret = decrypt(&decrypted, headerLen, &currentPw, cryptAlgo, dataHashType, &f); 656 ret = decrypt(&decrypted, headerLen, &currentPw, cryptAlgo, dataHashType, &f);
612 if (ret == e_cryptNotImpl) { 657 if (ret == e_cryptNotImpl) {
613 printDebug("PwMDoc::openDoc(): decrypt() failed: e_cryptNotImpl"); 658 printDebug("PwMDoc::openDoc(): decrypt() failed: e_cryptNotImpl");
614 f.close(); 659 f.close();
615 return e_cryptNotImpl; 660 return e_cryptNotImpl;
616 } else if (ret != e_success) { 661 } else if (ret != e_success) {
617 printDebug("PwMDoc::openDoc(): decrypt() failed"); 662 printDebug("PwMDoc::openDoc(): decrypt() failed");
618 f.close(); 663 f.close();
619 return e_readFile; 664 return e_readFile;
620 } 665 }
621 if (!decompressDta(&decrypted, compress)) { 666 if (!decompressDta(&decrypted, compress)) {
622 printDebug("PwMDoc::openDoc(): decompressDta() failed"); 667 printDebug("PwMDoc::openDoc(): decompressDta() failed");
623 f.close(); 668 f.close();
624 return e_fileCorrupt; 669 return e_fileCorrupt;
625 } 670 }
626 ret = checkDataHash(dataHashType, &dataHash, &decrypted); 671 ret = checkDataHash(dataHashType, &dataHash, &decrypted);
627 if (ret == e_hashNotImpl) { 672 if (ret == e_hashNotImpl) {
628 printDebug("PwMDoc::openDoc(): checkDataHash() failed: e_hashNotImpl"); 673 printDebug("PwMDoc::openDoc(): checkDataHash() failed: e_hashNotImpl");
629 f.close(); 674 f.close();
630 return e_hashNotImpl; 675 return e_hashNotImpl;
631 } else if (ret != e_success) { 676 } else if (ret != e_success) {
632 printDebug("PwMDoc::openDoc(): checkDataHash() failed"); 677 printDebug("PwMDoc::openDoc(): checkDataHash() failed");
633 f.close(); 678 f.close();
634 return e_fileCorrupt; 679 return e_fileCorrupt;
635 } 680 }
636 if (!deSerializeDta(&decrypted, openLocked == 1)) { 681 if (!deSerializeDta(&decrypted, openLocked == 1)) {
637 printDebug("PwMDoc::openDoc(): deSerializeDta() failed"); 682 printDebug("PwMDoc::openDoc(): deSerializeDta() failed");
638 f.close(); 683 f.close();
639 return e_readFile; 684 return e_readFile;
640 } 685 }
641 f.close(); 686 f.close();
642 timer()->start(DocTimer::id_mpwTimer); 687 timer()->start(DocTimer::id_mpwTimer);
643 timer()->start(DocTimer::id_autoLockTimer); 688 timer()->start(DocTimer::id_autoLockTimer);
644out_success: 689out_success:
645 openDocList.edit(this, getTitle().latin1()); 690 openDocList.edit(this, getTitle().latin1());
646 emit docOpened(this); 691 emit docOpened(this);
647 return e_success; 692 return e_success;
648} 693}
649 694
650PwMerror PwMDoc::writeFileHeader(char keyHash, char dataHash, char crypt, char compress, 695PwMerror PwMDoc::writeFileHeader(char keyHash, char dataHash, char crypt, char compress,
651 QString *pw, QFile *f) 696 QString *pw, QFile *f)
652{ 697{
653 PWM_ASSERT(pw); 698 PWM_ASSERT(pw);
654 PWM_ASSERT(f); 699 PWM_ASSERT(f);
655 //US ENH: or maybe a bug: checking here for listView does not make sense because we do not check anywhere else 700 //US ENH: or maybe a bug: checking here for listView does not make sense because we do not check anywhere else
656 //Wenn I sync, I open a doc without a view => listView is 0 => Assertion 701 //Wenn I sync, I open a doc without a view => listView is 0 => Assertion
657 //USPWM_ASSERT(listView); 702 //USPWM_ASSERT(listView);
658 if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) != 703 if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) !=
659 static_cast<Q_LONG>(strlen(FILE_ID_HEADER))) { 704 static_cast<Q_LONG>(strlen(FILE_ID_HEADER))) {
660 return e_writeFile; 705 return e_writeFile;
661 } 706 }
662 if (f->putch(PWM_FILE_VER) == -1 || 707 if (f->putch(PWM_FILE_VER) == -1 ||
663 f->putch(keyHash) == -1 || 708 f->putch(keyHash) == -1 ||
664 f->putch(dataHash) == -1 || 709 f->putch(dataHash) == -1 ||
665 f->putch(crypt) == -1 || 710 f->putch(crypt) == -1 ||
666 f->putch(compress) == -1 || 711 f->putch(compress) == -1 ||
667 f->putch((getDocStatFlag(DOC_STAT_USE_CHIPCARD)) ? 712 f->putch((getDocStatFlag(DOC_STAT_USE_CHIPCARD)) ?
668 (static_cast<char>(0x01)) : (static_cast<char>(0x00))) == -1) { 713 (static_cast<char>(0x01)) : (static_cast<char>(0x00))) == -1) {
669 return e_writeFile; 714 return e_writeFile;
670 } 715 }
671 716
672 // write bytes of NUL-data. These bytes are reserved for future-use. 717 // write bytes of NUL-data. These bytes are reserved for future-use.
673 const int bufSize = 64; 718 const int bufSize = 64;
674 char tmp_buf[bufSize]; 719 char tmp_buf[bufSize];
675 memset(tmp_buf, 0x00, bufSize); 720 memset(tmp_buf, 0x00, bufSize);
676 if (f->writeBlock(tmp_buf, bufSize) != bufSize) 721 if (f->writeBlock(tmp_buf, bufSize) != bufSize)
677 return e_writeFile; 722 return e_writeFile;
678 723
679 switch (keyHash) { 724 switch (keyHash) {
680 case PWM_HASH_SHA1: { 725 case PWM_HASH_SHA1: {
681 const int hashlen = SHA1_HASH_LEN_BYTE; 726 const int hashlen = SHA1_HASH_LEN_BYTE;
682 Sha1 hash; 727 Sha1 hash;
683 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length()); 728 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length());
684 string ret = hash.sha1_read(); 729 string ret = hash.sha1_read();
685 if (f->writeBlock(ret.c_str(), hashlen) != hashlen) 730 if (f->writeBlock(ret.c_str(), hashlen) != hashlen)
686 return e_writeFile; 731 return e_writeFile;
687 break; 732 break;
688 } 733 }
689 case PWM_HASH_SHA256: 734 case PWM_HASH_SHA256:
690 /*... fall through */ 735 /*... fall through */
691 case PWM_HASH_SHA384: 736 case PWM_HASH_SHA384:
692 case PWM_HASH_SHA512: 737 case PWM_HASH_SHA512:
693 case PWM_HASH_MD5: 738 case PWM_HASH_MD5:
694 case PWM_HASH_RMD160: 739 case PWM_HASH_RMD160:
695 case PWM_HASH_TIGER: 740 case PWM_HASH_TIGER:
696 { 741 {
697 if (!LibGCryptIf::available()) 742 if (!LibGCryptIf::available())
698 return e_hashNotImpl; 743 return e_hashNotImpl;
699 LibGCryptIf gc; 744 LibGCryptIf gc;
700 PwMerror err; 745 PwMerror err;
701 unsigned char *buf; 746 unsigned char *buf;
702 size_t hashLen; 747 size_t hashLen;
703 err = gc.hash(&buf, 748 err = gc.hash(&buf,
704 &hashLen, 749 &hashLen,
705 reinterpret_cast<const unsigned char *>(pw->latin1()), 750 reinterpret_cast<const unsigned char *>(pw->latin1()),
706 pw->length(), 751 pw->length(),
707 keyHash); 752 keyHash);
708 if (err != e_success) 753 if (err != e_success)
709 return e_hashNotImpl; 754 return e_hashNotImpl;
710 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen) 755 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen)
711 != static_cast<Q_LONG>(hashLen)) { 756 != static_cast<Q_LONG>(hashLen)) {
712 delete [] buf; 757 delete [] buf;
713 return e_hashNotImpl; 758 return e_hashNotImpl;
714 } 759 }
715 delete [] buf; 760 delete [] buf;
716 break; 761 break;
717 } 762 }
718 default: { 763 default: {
719 return e_hashNotImpl; 764 return e_hashNotImpl;
720 } } 765 } }
721 return e_success; 766 return e_success;
722} 767}
723 768
724PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress, 769PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress,
725 unsigned int *headerLength, char *dataHashType, 770 unsigned int *headerLength, char *dataHashType,
726 string *dataHash, QFile *f) 771 string *dataHash, QFile *f)
727{ 772{
728 PWM_ASSERT(cryptAlgo); 773 PWM_ASSERT(cryptAlgo);
729 PWM_ASSERT(pw); 774 PWM_ASSERT(pw);
730 PWM_ASSERT(headerLength); 775 PWM_ASSERT(headerLength);
731 PWM_ASSERT(dataHashType); 776 PWM_ASSERT(dataHashType);
732 PWM_ASSERT(dataHash); 777 PWM_ASSERT(dataHash);
733 PWM_ASSERT(f); 778 PWM_ASSERT(f);
734 int tmpRet; 779 int tmpRet;
735 // check "magic" header 780 // check "magic" header
736 const char magicHdr[] = FILE_ID_HEADER; 781 const char magicHdr[] = FILE_ID_HEADER;
737 const int hdrLen = array_size(magicHdr) - 1; 782 const int hdrLen = array_size(magicHdr) - 1;
738 char tmp[hdrLen]; 783 char tmp[hdrLen];
739 if (f->readBlock(tmp, hdrLen) != hdrLen) 784 if (f->readBlock(tmp, hdrLen) != hdrLen)
740 return e_readFile; 785 return e_readFile;
741 if (memcmp(tmp, magicHdr, hdrLen) != 0) 786 if (memcmp(tmp, magicHdr, hdrLen) != 0)
742 return e_fileFormat; 787 return e_fileFormat;
743 // read and check file ver 788 // read and check file ver
744 int fileV = f->getch(); 789 int fileV = f->getch();
745 if (fileV == -1) 790 if (fileV == -1)
746 return e_fileFormat; 791 return e_fileFormat;
747 if (fileV != PWM_FILE_VER) 792 if (fileV != PWM_FILE_VER)
748 return e_fileVer; 793 return e_fileVer;
749 // read hash hash type 794 // read hash hash type
750 int keyHash = f->getch(); 795 int keyHash = f->getch();
751 if (keyHash == -1) 796 if (keyHash == -1)
752 return e_fileFormat; 797 return e_fileFormat;
753 // read data hash type 798 // read data hash type
754 tmpRet = f->getch(); 799 tmpRet = f->getch();
755 if (tmpRet == -1) 800 if (tmpRet == -1)
756 return e_fileFormat; 801 return e_fileFormat;
757 *dataHashType = tmpRet; 802 *dataHashType = tmpRet;
758 // read crypt algo 803 // read crypt algo
759 tmpRet = f->getch(); 804 tmpRet = f->getch();
760 if (tmpRet == -1) 805 if (tmpRet == -1)
761 return e_fileFormat; 806 return e_fileFormat;
762 *cryptAlgo = tmpRet; 807 *cryptAlgo = tmpRet;
763 // get compression-algo 808 // get compression-algo
764 tmpRet = f->getch(); 809 tmpRet = f->getch();
765 if (tmpRet == -1) 810 if (tmpRet == -1)
766 return e_fileFormat; 811 return e_fileFormat;
767 *compress = tmpRet; 812 *compress = tmpRet;
768 // get the MPW-flag 813 // get the MPW-flag
769 int mpw_flag = f->getch(); 814 int mpw_flag = f->getch();
770 if (mpw_flag == -1) 815 if (mpw_flag == -1)
771 return e_fileFormat; 816 return e_fileFormat;
772 if (mpw_flag == 0x01) 817 if (mpw_flag == 0x01)
773 setDocStatFlag(DOC_STAT_USE_CHIPCARD); 818 setDocStatFlag(DOC_STAT_USE_CHIPCARD);
774 else 819 else
775 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); 820 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
776 // skip the "RESERVED"-bytes 821 // skip the "RESERVED"-bytes
777 if (!(f->at(f->at() + 64))) 822 if (!(f->at(f->at() + 64)))
778 return e_fileFormat; 823 return e_fileFormat;
779 824
780 *pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 825 *pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
781 if (*pw == "") { 826 if (*pw == "") {
782 /* the user didn't give a master-password 827 /* the user didn't give a master-password
783 * or didn't insert a chipcard 828 * or didn't insert a chipcard
784 */ 829 */
785 return e_noPw; 830 return e_noPw;
786 } 831 }
787 // verify key-hash 832 // verify key-hash
788 switch (keyHash) { 833 switch (keyHash) {
789 case PWM_HASH_SHA1: { 834 case PWM_HASH_SHA1: {
790 // read hash from header 835 // read hash from header
791 const int hashLen = SHA1_HASH_LEN_BYTE; 836 const int hashLen = SHA1_HASH_LEN_BYTE;
792 string readHash; 837 string readHash;
793 int i; 838 int i;
794 for (i = 0; i < hashLen; ++i) 839 for (i = 0; i < hashLen; ++i)
795 readHash.push_back(f->getch()); 840 readHash.push_back(f->getch());
796 Sha1 hash; 841 Sha1 hash;
797 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length()); 842 hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length());
798 string ret = hash.sha1_read(); 843 string ret = hash.sha1_read();
799 if (ret != readHash) 844 if (ret != readHash)
800 return e_wrongPw;// hash doesn't match (wrong key) 845 return e_wrongPw;// hash doesn't match (wrong key)
801 break; 846 break;
802 } 847 }
803 case PWM_HASH_SHA256: 848 case PWM_HASH_SHA256:
804 /*... fall through */ 849 /*... fall through */
805 case PWM_HASH_SHA384: 850 case PWM_HASH_SHA384:
806 case PWM_HASH_SHA512: 851 case PWM_HASH_SHA512:
807 case PWM_HASH_MD5: 852 case PWM_HASH_MD5:
808 case PWM_HASH_RMD160: 853 case PWM_HASH_RMD160:
809 case PWM_HASH_TIGER: { 854 case PWM_HASH_TIGER: {
810 if (!LibGCryptIf::available()) 855 if (!LibGCryptIf::available())
811 return e_hashNotImpl; 856 return e_hashNotImpl;
812 LibGCryptIf gc; 857 LibGCryptIf gc;
813 PwMerror err; 858 PwMerror err;
814 unsigned char *buf; 859 unsigned char *buf;
815 size_t hashLen; 860 size_t hashLen;
816 err = gc.hash(&buf, 861 err = gc.hash(&buf,
817 &hashLen, 862 &hashLen,
818 reinterpret_cast<const unsigned char *>(pw->latin1()), 863 reinterpret_cast<const unsigned char *>(pw->latin1()),
819 pw->length(), 864 pw->length(),
820 keyHash); 865 keyHash);
821 if (err != e_success) 866 if (err != e_success)
822 return e_hashNotImpl; 867 return e_hashNotImpl;
823 string calcHash(reinterpret_cast<const char *>(buf), 868 string calcHash(reinterpret_cast<const char *>(buf),
824 static_cast<string::size_type>(hashLen)); 869 static_cast<string::size_type>(hashLen));
825 delete [] buf; 870 delete [] buf;
826 // read hash from header 871 // read hash from header
827 string readHash; 872 string readHash;
828 size_t i; 873 size_t i;
829 for (i = 0; i < hashLen; ++i) 874 for (i = 0; i < hashLen; ++i)
830 readHash.push_back(f->getch()); 875 readHash.push_back(f->getch());
831 if (calcHash != readHash) 876 if (calcHash != readHash)
832 return e_wrongPw;// hash doesn't match (wrong key) 877 return e_wrongPw;// hash doesn't match (wrong key)
833 break; 878 break;
834 } 879 }
835 default: { 880 default: {
836 return e_hashNotImpl; 881 return e_hashNotImpl;
837 } } 882 } }
838 // read the data-hash from the file 883 // read the data-hash from the file
839 unsigned int hashLen, i; 884 unsigned int hashLen, i;
840 switch (*dataHashType) { 885 switch (*dataHashType) {
841 case PWM_HASH_SHA1: 886 case PWM_HASH_SHA1:
842 hashLen = SHA1_HASH_LEN_BYTE; 887 hashLen = SHA1_HASH_LEN_BYTE;
843 break; 888 break;
844 case PWM_HASH_SHA256: 889 case PWM_HASH_SHA256:
845 /*... fall through */ 890 /*... fall through */
846 case PWM_HASH_SHA384: 891 case PWM_HASH_SHA384:
847 case PWM_HASH_SHA512: 892 case PWM_HASH_SHA512:
848 case PWM_HASH_MD5: 893 case PWM_HASH_MD5:
849 case PWM_HASH_RMD160: 894 case PWM_HASH_RMD160:
850 case PWM_HASH_TIGER: { 895 case PWM_HASH_TIGER: {
851 if (!LibGCryptIf::available()) 896 if (!LibGCryptIf::available())
852 return e_hashNotImpl; 897 return e_hashNotImpl;
853 LibGCryptIf gc; 898 LibGCryptIf gc;
854 hashLen = gc.hashLength(*dataHashType); 899 hashLen = gc.hashLength(*dataHashType);
855 if (hashLen == 0) 900 if (hashLen == 0)
856 return e_hashNotImpl; 901 return e_hashNotImpl;
857 break; 902 break;
858 } 903 }
859 default: 904 default:
860 return e_hashNotImpl; 905 return e_hashNotImpl;
861 } 906 }
862 *dataHash = ""; 907 *dataHash = "";
863 for (i = 0; i < hashLen; ++i) { 908 for (i = 0; i < hashLen; ++i) {
864 tmpRet = f->getch(); 909 tmpRet = f->getch();
865 if (tmpRet == -1) 910 if (tmpRet == -1)
866 return e_fileFormat; 911 return e_fileFormat;
867 dataHash->push_back(static_cast<char>(tmpRet)); 912 dataHash->push_back(static_cast<char>(tmpRet));
868 } 913 }
869 *headerLength = f->at(); 914 *headerLength = f->at();
870#ifndef PWM_EMBEDDED 915#ifndef PWM_EMBEDDED
871 printDebug(string("opening file { compress: ") 916 printDebug(string("opening file { compress: ")
872 + tostr(static_cast<int>(*compress)) + " cryptAlgo: " 917 + tostr(static_cast<int>(*compress)) + " cryptAlgo: "
873 + tostr(static_cast<int>(*cryptAlgo)) + " keyHashAlgo: " 918 + tostr(static_cast<int>(*cryptAlgo)) + " keyHashAlgo: "
874 + tostr(static_cast<int>(keyHash)) 919 + tostr(static_cast<int>(keyHash))
875 + " }"); 920 + " }");
876#else 921#else
877 printDebug(string("opening file { compress: ") 922 printDebug(string("opening file { compress: ")
878 + tostr((int)(*compress)) + " cryptAlgo: " 923 + tostr((int)(*compress)) + " cryptAlgo: "
879 + tostr((int)(*cryptAlgo)) + " keyHashAlgo: " 924 + tostr((int)(*cryptAlgo)) + " keyHashAlgo: "
880 + tostr((int)(keyHash)) 925 + tostr((int)(keyHash))
881 + " }"); 926 + " }");
882#endif 927#endif
883 928
884 return e_success; 929 return e_success;
885} 930}
886 931
887PwMerror PwMDoc::writeDataHash(char dataHash, string *d, QFile *f) 932PwMerror PwMDoc::writeDataHash(char dataHash, string *d, QFile *f)
888{ 933{
889 PWM_ASSERT(d); 934 PWM_ASSERT(d);
890 PWM_ASSERT(f); 935 PWM_ASSERT(f);
891 936
892 switch (dataHash) { 937 switch (dataHash) {
893 case PWM_HASH_SHA1: { 938 case PWM_HASH_SHA1: {
894 const int hashLen = SHA1_HASH_LEN_BYTE; 939 const int hashLen = SHA1_HASH_LEN_BYTE;
895 Sha1 h; 940 Sha1 h;
896 h.sha1_write(reinterpret_cast<const byte *>(d->c_str()), d->size()); 941 h.sha1_write(reinterpret_cast<const byte *>(d->c_str()), d->size());
897 string hRet = h.sha1_read(); 942 string hRet = h.sha1_read();
898 if (f->writeBlock(hRet.c_str(), hashLen) != hashLen) 943 if (f->writeBlock(hRet.c_str(), hashLen) != hashLen)
899 return e_writeFile; 944 return e_writeFile;
900 break; 945 break;
901 } 946 }
902 case PWM_HASH_SHA256: 947 case PWM_HASH_SHA256:
903 /*... fall through */ 948 /*... fall through */
904 case PWM_HASH_SHA384: 949 case PWM_HASH_SHA384:
905 case PWM_HASH_SHA512: 950 case PWM_HASH_SHA512:
906 case PWM_HASH_MD5: 951 case PWM_HASH_MD5:
907 case PWM_HASH_RMD160: 952 case PWM_HASH_RMD160:
908 case PWM_HASH_TIGER: { 953 case PWM_HASH_TIGER: {
909 if (!LibGCryptIf::available()) 954 if (!LibGCryptIf::available())
910 return e_hashNotImpl; 955 return e_hashNotImpl;
911 LibGCryptIf gc; 956 LibGCryptIf gc;
912 PwMerror err; 957 PwMerror err;
913 unsigned char *buf; 958 unsigned char *buf;
914 size_t hashLen; 959 size_t hashLen;
915 err = gc.hash(&buf, 960 err = gc.hash(&buf,
916 &hashLen, 961 &hashLen,
917 reinterpret_cast<const unsigned char *>(d->c_str()), 962 reinterpret_cast<const unsigned char *>(d->c_str()),
918 d->size(), 963 d->size(),
919 dataHash); 964 dataHash);
920 if (err != e_success) 965 if (err != e_success)
921 return e_hashNotImpl; 966 return e_hashNotImpl;
922 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen) 967 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen)
923 != static_cast<Q_LONG>(hashLen)) { 968 != static_cast<Q_LONG>(hashLen)) {
924 delete [] buf; 969 delete [] buf;
925 return e_hashNotImpl; 970 return e_hashNotImpl;
926 } 971 }
927 delete [] buf; 972 delete [] buf;
928 break; 973 break;
929 } 974 }
930 default: { 975 default: {
931 return e_hashNotImpl; 976 return e_hashNotImpl;
932 } } 977 } }
933 978
934 return e_success; 979 return e_success;
935} 980}
936 981
937bool PwMDoc::backupFile(const QString &filePath) 982bool PwMDoc::backupFile(const QString &filePath)
938{ 983{
939 QFileInfo fi(filePath); 984 QFileInfo fi(filePath);
940 if (!fi.exists()) 985 if (!fi.exists())
941 return true; // Yes, true is correct. 986 return true; // Yes, true is correct.
942 QString pathOnly(fi.dirPath(true)); 987 QString pathOnly(fi.dirPath(true));
943 QString nameOnly(fi.fileName()); 988 QString nameOnly(fi.fileName());
944 QString backupPath = pathOnly 989 QString backupPath = pathOnly
945 + "/~" 990 + "/~"
946 + nameOnly 991 + nameOnly
947 + ".backup"; 992 + ".backup";
948 return copyFile(filePath, backupPath); 993 return copyFile(filePath, backupPath);
949} 994}
950 995
951bool PwMDoc::copyFile(const QString &src, const QString &dst) 996bool PwMDoc::copyFile(const QString &src, const QString &dst)
952{ 997{
953 QFileInfo fi(src); 998 QFileInfo fi(src);
954 if (!fi.exists()) 999 if (!fi.exists())
955 return false; 1000 return false;
956 if (QFile::exists(dst)) { 1001 if (QFile::exists(dst)) {
957 if (!QFile::remove(dst)) 1002 if (!QFile::remove(dst))
958 return false; 1003 return false;
959 } 1004 }
960 QFile srcFd(src); 1005 QFile srcFd(src);
961 if (!srcFd.open(IO_ReadOnly)) 1006 if (!srcFd.open(IO_ReadOnly))
962 return false; 1007 return false;
963 QFile dstFd(dst); 1008 QFile dstFd(dst);
964 if (!dstFd.open(IO_ReadWrite)) { 1009 if (!dstFd.open(IO_ReadWrite)) {
965 srcFd.close(); 1010 srcFd.close();
966 return false; 1011 return false;
967 } 1012 }
968 const int tmpBuf_size = 512; 1013 const int tmpBuf_size = 512;
969 char tmpBuf[tmpBuf_size]; 1014 char tmpBuf[tmpBuf_size];
970 Q_LONG bytesRead, bytesWritten; 1015 Q_LONG bytesRead, bytesWritten;
971 1016
972 while (!srcFd.atEnd()) { 1017 while (!srcFd.atEnd()) {
973 bytesRead = srcFd.readBlock(tmpBuf, 1018 bytesRead = srcFd.readBlock(tmpBuf,
974 static_cast<Q_ULONG>(tmpBuf_size)); 1019 static_cast<Q_ULONG>(tmpBuf_size));
975 if (bytesRead == -1) { 1020 if (bytesRead == -1) {
976 srcFd.close(); 1021 srcFd.close();
977 dstFd.close(); 1022 dstFd.close();
978 return false; 1023 return false;
979 } 1024 }
980 bytesWritten = dstFd.writeBlock(tmpBuf, 1025 bytesWritten = dstFd.writeBlock(tmpBuf,
981 static_cast<Q_ULONG>(bytesRead)); 1026 static_cast<Q_ULONG>(bytesRead));
982 if (bytesWritten != bytesRead) { 1027 if (bytesWritten != bytesRead) {
983 srcFd.close(); 1028 srcFd.close();
984 dstFd.close(); 1029 dstFd.close();
985 return false; 1030 return false;
986 } 1031 }
987 } 1032 }
988 srcFd.close(); 1033 srcFd.close();
989 dstFd.close(); 1034 dstFd.close();
990 return true; 1035 return true;
991} 1036}
992 1037
993PwMerror PwMDoc::addEntry(const QString &category, PwMDataItem *d, 1038PwMerror PwMDoc::addEntry(const QString &category, PwMDataItem *d,
994 bool dontFlagDirty, bool updateMeta) 1039 bool dontFlagDirty, bool updateMeta)
995{ 1040{
996 PWM_ASSERT(d); 1041 PWM_ASSERT(d);
997 unsigned int cat = 0; 1042 unsigned int cat = 0;
998 1043
999 if (isDeepLocked()) { 1044 if (isDeepLocked()) {
1000 PwMerror ret; 1045 PwMerror ret;
1001 ret = deepLock(false); 1046 ret = deepLock(false);
1002 if (ret != e_success) 1047 if (ret != e_success)
1003 return e_lock; 1048 return e_lock;
1004 } 1049 }
1005 1050
1006 addCategory(category, &cat); 1051 addCategory(category, &cat);
1007 1052
1008 if (numEntries(category) >= maxEntries) 1053 if (numEntries(category) >= maxEntries)
1009 return e_maxAllowedEntr; 1054 return e_maxAllowedEntr;
1010 1055
1011 vector<unsigned int> foundPositions; 1056 vector<unsigned int> foundPositions;
1012 /* historically this was: 1057 /* historically this was:
1013 *const int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME | 1058 *const int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME |
1014 * SEARCH_IN_URL | SEARCH_IN_LAUNCHER; 1059 * SEARCH_IN_URL | SEARCH_IN_LAUNCHER;
1015 * But for now we only search in desc. 1060 * But for now we only search in desc.
1016 * That's a tweak to be KWallet compatible. But it should not add 1061 * That's a tweak to be KWallet compatible. But it should not add
1017 * usability-drop onto PwManager, does it? 1062 * usability-drop onto PwManager, does it?
1018 * (And yes, "int" was a bug. Correct is "unsigned int") 1063 * (And yes, "int" was a bug. Correct is "unsigned int")
1019 */ 1064 */
1020 const unsigned int searchIn = SEARCH_IN_DESC; 1065 const unsigned int searchIn = SEARCH_IN_DESC;
1021 findEntry(cat, *d, searchIn, &foundPositions, true); 1066 findEntry(cat, *d, searchIn, &foundPositions, true);
1022 if (foundPositions.size()) { 1067 if (foundPositions.size()) {
1023 // DOH! We found this entry. 1068 // DOH! We found this entry.
1024 return e_entryExists; 1069 return e_entryExists;
1025 } 1070 }
1026 1071
1027 d->listViewPos = -1; 1072 d->listViewPos = -1;
1028 d->lockStat = conf()->confGlobNewEntrLockStat(); 1073 d->lockStat = conf()->confGlobNewEntrLockStat();
1029 if (updateMeta) { 1074 if (updateMeta) {
1030 d->meta.create = QDateTime::currentDateTime(); 1075 d->meta.create = QDateTime::currentDateTime();
1031 d->meta.update = d->meta.create; 1076 d->meta.update = d->meta.create;
1032 } 1077 }
1033 dti.dta[cat].d.push_back(*d); 1078 dti.dta[cat].d.push_back(*d);
1034 1079
1035 delAllEmptyCat(true); 1080 delAllEmptyCat(true);
1036 1081
1037 if (!dontFlagDirty) 1082 if (!dontFlagDirty)
1038 flagDirty(); 1083 flagDirty();
1039 return e_success; 1084 return e_success;
1040} 1085}
1041 1086
1042PwMerror PwMDoc::addCategory(const QString &category, unsigned int *categoryIndex, 1087PwMerror PwMDoc::addCategory(const QString &category, unsigned int *categoryIndex,
1043 bool checkIfExist) 1088 bool checkIfExist)
1044{ 1089{
1045 if (isDeepLocked()) { 1090 if (isDeepLocked()) {
1046 PwMerror ret; 1091 PwMerror ret;
1047 ret = deepLock(false); 1092 ret = deepLock(false);
1048 if (ret != e_success) 1093 if (ret != e_success)
1049 return e_lock; 1094 return e_lock;
1050 } 1095 }
1051 if (checkIfExist) { 1096 if (checkIfExist) {
1052 if (findCategory(category, categoryIndex)) 1097 if (findCategory(category, categoryIndex))
1053 return e_categoryExists; 1098 return e_categoryExists;
1054 } 1099 }
1055 PwMCategoryItem item; 1100 PwMCategoryItem item;
1056 //US ENH: clear item to initialize with default values, or create a constructor 1101 //US ENH: clear item to initialize with default values, or create a constructor
1057 item.clear(); 1102 item.clear();
1058 1103
1059 item.name = category.latin1(); 1104 item.name = category.latin1();
1060 dti.dta.push_back(item); 1105 dti.dta.push_back(item);
1061 if (categoryIndex) 1106 if (categoryIndex)
1062 *categoryIndex = dti.dta.size() - 1; 1107 *categoryIndex = dti.dta.size() - 1;
1063 return e_success; 1108 return e_success;
1064} 1109}
1065 1110
1066bool PwMDoc::delEntry(const QString &category, unsigned int index, bool dontFlagDirty) 1111bool PwMDoc::delEntry(const QString &category, unsigned int index, bool dontFlagDirty)
1067{ 1112{
1068 unsigned int cat = 0; 1113 unsigned int cat = 0;
1069 1114
1070 if (!findCategory(category, &cat)) { 1115 if (!findCategory(category, &cat)) {
1071 BUG(); 1116 BUG();
1072 return false; 1117 return false;
1073 } 1118 }
1074 1119
1075 return delEntry(cat, index, dontFlagDirty); 1120 return delEntry(cat, index, dontFlagDirty);
1076} 1121}
1077 1122
1078bool PwMDoc::delEntry(unsigned int category, unsigned int index, bool dontFlagDirty) 1123bool PwMDoc::delEntry(unsigned int category, unsigned int index, bool dontFlagDirty)
1079{ 1124{
1080 if (isDeepLocked()) 1125 if (isDeepLocked())
1081 return false; 1126 return false;
1082 if (index > dti.dta[category].d.size() - 1) 1127 if (index > dti.dta[category].d.size() - 1)
1083 return false; 1128 return false;
1084 getDataChangedLock(); 1129 getDataChangedLock();
1085 if (!lockAt(category, index, false)) { 1130 if (!lockAt(category, index, false)) {
1086 putDataChangedLock(); 1131 putDataChangedLock();
1087 return false; 1132 return false;
1088 } 1133 }
1089 putDataChangedLock(); 1134 putDataChangedLock();
1090 int lvPos = dti.dta[category].d[index].listViewPos; 1135 int lvPos = dti.dta[category].d[index].listViewPos;
1091 1136
1092 // delete entry 1137 // delete entry
1093 dti.dta[category].d.erase(dti.dta[category].d.begin() + index); 1138 dti.dta[category].d.erase(dti.dta[category].d.begin() + index);
1094 1139
1095 unsigned int i, entries = numEntries(category); 1140 unsigned int i, entries = numEntries(category);
1096 if (!entries) { 1141 if (!entries) {
1097 // no more entries in this category, so 1142 // no more entries in this category, so
1098 // we can delete it, too. 1143 // we can delete it, too.
1099 BUG_ON(!delCategory(category)); 1144 BUG_ON(!delCategory(category));
1100 // delCategory() flags it dirty, so we need not to do so. 1145 // delCategory() flags it dirty, so we need not to do so.
1101 return true; 1146 return true;
1102 } 1147 }
1103 for (i = 0; i < entries; ++i) { 1148 for (i = 0; i < entries; ++i) {
1104 // decrement all listViewPositions that are greater than the deleted. 1149 // decrement all listViewPositions that are greater than the deleted.
1105 if (dti.dta[category].d[i].listViewPos > lvPos) 1150 if (dti.dta[category].d[i].listViewPos > lvPos)
1106 --dti.dta[category].d[i].listViewPos; 1151 --dti.dta[category].d[i].listViewPos;
1107 } 1152 }
1108 1153
1109 if (!dontFlagDirty) 1154 if (!dontFlagDirty)
1110 flagDirty(); 1155 flagDirty();
1111 return true; 1156 return true;
1112} 1157}
1113 1158
1114bool PwMDoc::editEntry(const QString &oldCategory, const QString &newCategory, 1159bool PwMDoc::editEntry(const QString &oldCategory, const QString &newCategory,
1115 unsigned int index, PwMDataItem *d, bool updateMeta) 1160 unsigned int index, PwMDataItem *d, bool updateMeta)
1116{ 1161{
1117 PWM_ASSERT(d); 1162 PWM_ASSERT(d);
1118 unsigned int oldCat = 0; 1163 unsigned int oldCat = 0;
1119 1164
1120 if (!findCategory(oldCategory, &oldCat)) { 1165 if (!findCategory(oldCategory, &oldCat)) {
1121 BUG(); 1166 BUG();
1122 return false; 1167 return false;
1123 } 1168 }
1124 1169
1125 return editEntry(oldCat, newCategory, index, d, updateMeta); 1170 return editEntry(oldCat, newCategory, index, d, updateMeta);
1126} 1171}
1127 1172
1128bool PwMDoc::editEntry(unsigned int oldCategory, const QString &newCategory, 1173bool PwMDoc::editEntry(unsigned int oldCategory, const QString &newCategory,
1129 unsigned int index, PwMDataItem *d, bool updateMeta) 1174 unsigned int index, PwMDataItem *d, bool updateMeta)
1130{ 1175{
1131 if (isDeepLocked()) 1176 if (isDeepLocked())
1132 return false; 1177 return false;
1133 if (updateMeta) { 1178 if (updateMeta) {
1134 d->meta.update = QDateTime::currentDateTime(); 1179 d->meta.update = QDateTime::currentDateTime();
1135 if (d->meta.create.isNull()) { 1180 if (d->meta.create.isNull()) {
1136 d->meta.create = d->meta.update; 1181 d->meta.create = d->meta.update;
1137 } 1182 }
1138 } 1183 }
1139 if (dti.dta[oldCategory].name != newCategory.latin1()) { 1184 if (dti.dta[oldCategory].name != newCategory.latin1()) {
1140 // the user changed the category. 1185 // the user changed the category.
1141 PwMerror ret; 1186 PwMerror ret;
1142 d->rev = 0; 1187 d->rev = 0;
1143 ret = addEntry(newCategory, d, true, false); 1188 ret = addEntry(newCategory, d, true, false);
1144 if (ret != e_success) 1189 if (ret != e_success)
1145 return false; 1190 return false;
1146 if (!delEntry(oldCategory, index, true)) 1191 if (!delEntry(oldCategory, index, true))
1147 return false; 1192 return false;
1148 } else { 1193 } else {
1149 d->rev = dti.dta[oldCategory].d[index].rev + 1; // increment revision counter. 1194 d->rev = dti.dta[oldCategory].d[index].rev + 1; // increment revision counter.
1150 dti.dta[oldCategory].d[index] = *d; 1195 dti.dta[oldCategory].d[index] = *d;
1151 } 1196 }
1152 flagDirty(); 1197 flagDirty();
1153 return true; 1198 return true;
1154} 1199}
1155 1200
1156unsigned int PwMDoc::numEntries(const QString &category) 1201unsigned int PwMDoc::numEntries(const QString &category)
1157{ 1202{
1158 unsigned int cat = 0; 1203 unsigned int cat = 0;
1159 1204
1160 if (!findCategory(category, &cat)) { 1205 if (!findCategory(category, &cat)) {
1161 BUG(); 1206 BUG();
1162 return 0; 1207 return 0;
1163 } 1208 }
1164 1209
1165 return numEntries(cat); 1210 return numEntries(cat);
1166} 1211}
1167 1212
1168bool PwMDoc::serializeDta(string *d) 1213bool PwMDoc::serializeDta(string *d)
1169{ 1214{
1170 PWM_ASSERT(d); 1215 PWM_ASSERT(d);
1171 Serializer ser; 1216 Serializer ser;
1172 if (!ser.serialize(dti)) 1217 if (!ser.serialize(dti))
1173 return false; 1218 return false;
1174 d->assign(ser.getXml()); 1219 d->assign(ser.getXml());
1175 if (!d->size()) 1220 if (!d->size())
1176 return false; 1221 return false;
1177 return true; 1222 return true;
1178} 1223}
1179 1224
1180bool PwMDoc::deSerializeDta(const string *d, bool entriesLocked) 1225bool PwMDoc::deSerializeDta(const string *d, bool entriesLocked)
1181{ 1226{
1182 PWM_ASSERT(d); 1227 PWM_ASSERT(d);
1183#ifndef PWM_EMBEDDED 1228#ifndef PWM_EMBEDDED
1184 try { 1229 try {
1185 1230
1186 Serializer ser(d->c_str()); 1231 Serializer ser(d->c_str());
1187 ser.setDefaultLockStat(entriesLocked); 1232 ser.setDefaultLockStat(entriesLocked);
1188 if (!ser.deSerialize(&dti)) 1233 if (!ser.deSerialize(&dti))
1189 return false; 1234 return false;
1190 } catch (PwMException) { 1235 } catch (PwMException) {
1191 return false; 1236 return false;
1192 } 1237 }
1193#else 1238#else
1194 Serializer ser(d->c_str()); 1239 Serializer ser(d->c_str());
1195 ser.setDefaultLockStat(entriesLocked); 1240 ser.setDefaultLockStat(entriesLocked);
1196 if (!ser.deSerialize(&dti)) 1241 if (!ser.deSerialize(&dti))
1197 return false; 1242 return false;
1198#endif 1243#endif
1199 1244
1200 emitDataChanged(this); 1245 emitDataChanged(this);
1201 return true; 1246 return true;
1202} 1247}
1203 1248
1204bool PwMDoc::getEntry(const QString &category, unsigned int index, 1249bool PwMDoc::getEntry(const QString &category, unsigned int index,
1205 PwMDataItem * d, bool unlockIfLocked) 1250 PwMDataItem * d, bool unlockIfLocked)
1206{ 1251{
1207 PWM_ASSERT(d); 1252 PWM_ASSERT(d);
1208 unsigned int cat = 0; 1253 unsigned int cat = 0;
1209 1254
1210 if (!findCategory(category, &cat)) { 1255 if (!findCategory(category, &cat)) {
1211 BUG(); 1256 BUG();
1212 return false; 1257 return false;
1213 } 1258 }
1214 1259
1215 return getEntry(cat, index, d, unlockIfLocked); 1260 return getEntry(cat, index, d, unlockIfLocked);
1216} 1261}
1217 1262
1218bool PwMDoc::getEntry(unsigned int category, unsigned int index, 1263bool PwMDoc::getEntry(unsigned int category, unsigned int index,
1219 PwMDataItem *d, bool unlockIfLocked) 1264 PwMDataItem *d, bool unlockIfLocked)
1220{ 1265{
1221 if (index > dti.dta[category].d.size() - 1) 1266 if (index > dti.dta[category].d.size() - 1)
1222 return false; 1267 return false;
1223 1268
1224 bool locked = isLocked(category, index); 1269 bool locked = isLocked(category, index);
1225 if (locked) { 1270 if (locked) {
1226 /* this entry is locked. We don't return a password, 1271 /* this entry is locked. We don't return a password,
1227 * until it's unlocked by the user by inserting 1272 * until it's unlocked by the user by inserting
1228 * chipcard or entering the mpw 1273 * chipcard or entering the mpw
1229 */ 1274 */
1230 if (unlockIfLocked) { 1275 if (unlockIfLocked) {
1231 if (!lockAt(category, index, false)) { 1276 if (!lockAt(category, index, false)) {
1232 return false; 1277 return false;
1233 } 1278 }
1234 locked = false; 1279 locked = false;
1235 } 1280 }
1236 } 1281 }
1237 1282
1238 *d = dti.dta[category].d[index]; 1283 *d = dti.dta[category].d[index];
1239 if (locked) 1284 if (locked)
1240 d->pw = LOCKED_STRING.latin1(); 1285 d->pw = LOCKED_STRING.latin1();
1241 1286
1242 return true; 1287 return true;
1243} 1288}
1244PwMerror PwMDoc::getCommentByLvp(const QString &category, int listViewPos, 1289PwMerror PwMDoc::getCommentByLvp(const QString &category, int listViewPos,
1245 string *foundComment) 1290 string *foundComment)
1246{ 1291{
1247 PWM_ASSERT(foundComment); 1292 PWM_ASSERT(foundComment);
1248 unsigned int cat = 0; 1293 unsigned int cat = 0;
1249 1294
1250 if (!findCategory(category, &cat)) 1295 if (!findCategory(category, &cat))
1251 return e_invalidArg; 1296 return e_invalidArg;
1252 1297
1253 unsigned int i, entries = numEntries(cat); 1298 unsigned int i, entries = numEntries(cat);
1254 for (i = 0; i < entries; ++i) { 1299 for (i = 0; i < entries; ++i) {
1255 if (dti.dta[cat].d[i].listViewPos == listViewPos) { 1300 if (dti.dta[cat].d[i].listViewPos == listViewPos) {
1256 *foundComment = dti.dta[cat].d[i].comment; 1301 *foundComment = dti.dta[cat].d[i].comment;
1257 if (dti.dta[cat].d[i].binary) 1302 if (dti.dta[cat].d[i].binary)
1258 return e_binEntry; 1303 return e_binEntry;
1259 return e_normalEntry; 1304 return e_normalEntry;
1260 } 1305 }
1261 } 1306 }
1262 BUG(); 1307 BUG();
1263 return e_generic; 1308 return e_generic;
1264} 1309}
1265 1310
1266PwMerror PwMDoc::getCommentByLvp_long(const QString &category, int listViewPos, 1311PwMerror PwMDoc::getCommentByLvp_long(const QString &category, int listViewPos,
1267 string *foundComment) 1312 string *foundComment)
1268{ 1313{
1269 PWM_ASSERT(foundComment); 1314 PWM_ASSERT(foundComment);
1270 unsigned int cat = 0; 1315 unsigned int cat = 0;
1271 1316
1272 if (!findCategory(category, &cat)) 1317 if (!findCategory(category, &cat))
1273 return e_invalidArg; 1318 return e_invalidArg;
1274 1319
1275 unsigned int i, entries = numEntries(cat); 1320 unsigned int i, entries = numEntries(cat);
1276 for (i = 0; i < entries; ++i) { 1321 for (i = 0; i < entries; ++i) {
1277 if (dti.dta[cat].d[i].listViewPos == listViewPos) { 1322 if (dti.dta[cat].d[i].listViewPos == listViewPos) {
1278 if (dti.dta[cat].d[i].binary) 1323 if (dti.dta[cat].d[i].binary)
1279 return e_binEntry; 1324 return e_binEntry;
1280 PwMCategoryItem* catItem = getCategoryEntry(cat); 1325 PwMCategoryItem* catItem = getCategoryEntry(cat);
1281 QString retval; 1326 QString retval;
1282 QString tempval = QString (dti.dta[cat].d[i].desc.c_str()); 1327 QString tempval = QString (dti.dta[cat].d[i].desc.c_str());
1283 if ( !tempval.isEmpty() ) { 1328 if ( !tempval.isEmpty() ) {
1284 retval += "<b>" +QString ( catItem->desc_text.c_str() )+ ":</b> "+ tempval+"<br>" ; 1329 retval += "<b>" +QString ( catItem->desc_text.c_str() )+ ":</b> "+ tempval+"<br>" ;
1285 } 1330 }
1286 tempval = QString (dti.dta[cat].d[i].name.c_str()); 1331 tempval = QString (dti.dta[cat].d[i].name.c_str());
1287 if ( !tempval.isEmpty() ) { 1332 if ( !tempval.isEmpty() ) {
1288 retval += "<b>" +QString ( catItem->name_text.c_str() ) + ":</b> "+ tempval+"<br>" ; 1333 retval += "<b>" +QString ( catItem->name_text.c_str() ) + ":</b> "+ tempval+"<br>" ;
1289 } 1334 }
1290 tempval = QString (dti.dta[cat].d[i].pw.c_str()); 1335 tempval = QString (dti.dta[cat].d[i].pw.c_str());
1291 if ( !tempval.isEmpty() ) { 1336 if ( !tempval.isEmpty() ) {
1292 if ( dti.dta[cat].d[i].lockStat ) 1337 if ( dti.dta[cat].d[i].lockStat )
1293 retval += "<b>" +QString ( catItem->pw_text.c_str() )+ ": " + i18n("LOCKED") +"</b><br>" ; 1338 retval += "<b>" +QString ( catItem->pw_text.c_str() )+ ": " + i18n("LOCKED") +"</b><br>" ;
1294 else 1339 else
1295 retval += "<b>" +QString ( catItem->pw_text.c_str() )+ ":</b> " + tempval+"<br>" ; 1340 retval += "<b>" +QString ( catItem->pw_text.c_str() )+ ":</b> " + tempval+"<br>" ;
1296 } 1341 }
1297 tempval = QString (dti.dta[cat].d[i].url.c_str()); 1342 tempval = QString (dti.dta[cat].d[i].url.c_str());
1298 if ( !tempval.isEmpty() ) { 1343 if ( !tempval.isEmpty() ) {
1299 retval += "<b>" +i18n("URL:")+ "</b> " + tempval+"<br>" ; 1344 retval += "<b>" +i18n("URL:")+ "</b> " + tempval+"<br>" ;
1300 } 1345 }
1301 tempval = QString (dti.dta[cat].d[i].launcher.c_str()); 1346 tempval = QString (dti.dta[cat].d[i].launcher.c_str());
1302 if ( !tempval.isEmpty() ) { 1347 if ( !tempval.isEmpty() ) {
1303 retval += "<b>" +i18n("Launcher:")+ "</b> " + tempval+"<br>" ; 1348 retval += "<b>" +i18n("Launcher:")+ "</b> " + tempval+"<br>" ;
1304 } 1349 }
1305 tempval = QString (dti.dta[cat].d[i].comment.c_str()); 1350 tempval = QString (dti.dta[cat].d[i].comment.c_str());
1306 if ( !tempval.isEmpty() ) { 1351 if ( !tempval.isEmpty() ) {
1307 tempval.replace(QRegExp ( "\n" ), "<br>" ); 1352 tempval.replace(QRegExp ( "\n" ), "<br>" );
1308 retval += "<b>" +i18n("Comment:")+ "</b><br>" + tempval+"<br>" ; 1353 retval += "<b>" +i18n("Comment:")+ "</b><br>" + tempval+"<br>" ;
1309 } 1354 }
1310 1355
1311 string ret ( retval.latin1() ); 1356 string ret ( retval.latin1() );
1312 1357
1313 1358
1314 // *foundComment = dti.dta[cat].d[i].comment; 1359 // *foundComment = dti.dta[cat].d[i].comment;
1315 *foundComment = ret; 1360 *foundComment = ret;
1316 return e_normalEntry; 1361 return e_normalEntry;
1317 } 1362 }
1318 } 1363 }
1319 BUG(); 1364 BUG();
1320 return e_generic; 1365 return e_generic;
1321} 1366}
1322 1367
1323bool PwMDoc::compressDta(string *d, char algo) 1368bool PwMDoc::compressDta(string *d, char algo)
1324{ 1369{
1325 PWM_ASSERT(d); 1370 PWM_ASSERT(d);
1326 switch (algo) { 1371 switch (algo) {
1327 case PWM_COMPRESS_GZIP: { 1372 case PWM_COMPRESS_GZIP: {
1328 CompressGzip comp; 1373 CompressGzip comp;
1329 return comp.compress(d); 1374 return comp.compress(d);
1330 } 1375 }
1331#ifndef PWM_EMBEDDED 1376#ifndef PWM_EMBEDDED
1332 case PWM_COMPRESS_BZIP2: { 1377 case PWM_COMPRESS_BZIP2: {
1333 CompressBzip2 comp; 1378 CompressBzip2 comp;
1334 return comp.compress(d); 1379 return comp.compress(d);
1335 } 1380 }
1336#endif 1381#endif
1337 case PWM_COMPRESS_NONE: { 1382 case PWM_COMPRESS_NONE: {
1338 return true; 1383 return true;
1339 } default: { 1384 } default: {
1340 BUG(); 1385 BUG();
1341 } 1386 }
1342 } 1387 }
1343 return false; 1388 return false;
1344} 1389}
1345 1390
1346bool PwMDoc::decompressDta(string *d, char algo) 1391bool PwMDoc::decompressDta(string *d, char algo)
1347{ 1392{
1348 PWM_ASSERT(d); 1393 PWM_ASSERT(d);
1349 switch (algo) { 1394 switch (algo) {
1350 case PWM_COMPRESS_GZIP: { 1395 case PWM_COMPRESS_GZIP: {
1351 CompressGzip comp; 1396 CompressGzip comp;
1352 return comp.decompress(d); 1397 return comp.decompress(d);
1353 } 1398 }
1354#ifndef PWM_EMBEDDED 1399#ifndef PWM_EMBEDDED
1355 case PWM_COMPRESS_BZIP2: { 1400 case PWM_COMPRESS_BZIP2: {
1356 CompressBzip2 comp; 1401 CompressBzip2 comp;
1357 return comp.decompress(d); 1402 return comp.decompress(d);
1358 } 1403 }
1359#endif 1404#endif
1360 case PWM_COMPRESS_NONE: { 1405 case PWM_COMPRESS_NONE: {
1361 return true; 1406 return true;
1362 } 1407 }
1363 } 1408 }
1364 return false; 1409 return false;
1365} 1410}
1366 1411
1367PwMerror PwMDoc::encrypt(string *d, const QString *pw, QFile *f, char algo, 1412PwMerror PwMDoc::encrypt(string *d, const QString *pw, QFile *f, char algo,
1368 char hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase 1413 char hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
1369) 1414)
1370{ 1415{
1371 PWM_ASSERT(d); 1416 PWM_ASSERT(d);
1372 PWM_ASSERT(pw); 1417 PWM_ASSERT(pw);
1373 PWM_ASSERT(f); 1418 PWM_ASSERT(f);
1374 1419
1375 size_t encSize; 1420 size_t encSize;
1376 byte *encrypted = 0; 1421 byte *encrypted = 0;
1377 1422
1378 switch (algo) { 1423 switch (algo) {
1379 case PWM_CRYPT_BLOWFISH: { 1424 case PWM_CRYPT_BLOWFISH: {
1380 Blowfish::padNull(d); 1425 Blowfish::padNull(d);
1381 encSize = d->length(); 1426 encSize = d->length();
1382 encrypted = new byte[encSize]; 1427 encrypted = new byte[encSize];
1383 Blowfish bf; 1428 Blowfish bf;
1384 if (bf.bf_setkey((byte *) pw->latin1(), pw->length())) { 1429 if (bf.bf_setkey((byte *) pw->latin1(), pw->length())) {
1385 delete [] encrypted; 1430 delete [] encrypted;
1386 return e_weakPw; 1431 return e_weakPw;
1387 } 1432 }
1388 bf.bf_encrypt((byte *) encrypted, (byte *) d->c_str(), encSize); 1433 bf.bf_encrypt((byte *) encrypted, (byte *) d->c_str(), encSize);
1389 break; 1434 break;
1390 } 1435 }
1391 case PWM_CRYPT_AES128: 1436 case PWM_CRYPT_AES128:
1392 /*... fall through */ 1437 /*... fall through */
1393 case PWM_CRYPT_AES192: 1438 case PWM_CRYPT_AES192:
1394 case PWM_CRYPT_AES256: 1439 case PWM_CRYPT_AES256:
1395 case PWM_CRYPT_3DES: 1440 case PWM_CRYPT_3DES:
1396 case PWM_CRYPT_TWOFISH: 1441 case PWM_CRYPT_TWOFISH:
1397 case PWM_CRYPT_TWOFISH128: { 1442 case PWM_CRYPT_TWOFISH128: {
1398 if (!LibGCryptIf::available()) 1443 if (!LibGCryptIf::available())
1399 return e_cryptNotImpl; 1444 return e_cryptNotImpl;
1400 LibGCryptIf gc; 1445 LibGCryptIf gc;
1401 PwMerror err; 1446 PwMerror err;
1402 unsigned char *plain = new unsigned char[d->length() + 1024]; 1447 unsigned char *plain = new unsigned char[d->length() + 1024];
1403 memcpy(plain, d->c_str(), d->length()); 1448 memcpy(plain, d->c_str(), d->length());
1404 err = gc.encrypt(&encrypted, 1449 err = gc.encrypt(&encrypted,
1405 &encSize, 1450 &encSize,
1406 plain, 1451 plain,
1407 d->length(), 1452 d->length(),
1408 reinterpret_cast<const unsigned char *>(pw->latin1()), 1453 reinterpret_cast<const unsigned char *>(pw->latin1()),
1409 pw->length(), 1454 pw->length(),
1410 algo, 1455 algo,
1411 hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase 1456 hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
1412 ); 1457 );
1413 delete [] plain; 1458 delete [] plain;
1414 if (err != e_success) 1459 if (err != e_success)
1415 return e_cryptNotImpl; 1460 return e_cryptNotImpl;
1416 break; 1461 break;
1417 } 1462 }
1418 default: { 1463 default: {
1419 delete_ifnot_null_array(encrypted); 1464 delete_ifnot_null_array(encrypted);
1420 return e_cryptNotImpl; 1465 return e_cryptNotImpl;
1421 } } 1466 } }
1422 1467
1423 // write encrypted data to file 1468 // write encrypted data to file
1424 if (f->writeBlock(reinterpret_cast<const char *>(encrypted), 1469 if (f->writeBlock(reinterpret_cast<const char *>(encrypted),
1425 static_cast<Q_ULONG>(encSize)) 1470 static_cast<Q_ULONG>(encSize))
1426 != static_cast<Q_LONG>(encSize)) { 1471 != static_cast<Q_LONG>(encSize)) {
1427 delete_ifnot_null_array(encrypted); 1472 delete_ifnot_null_array(encrypted);
1428 return e_writeFile; 1473 return e_writeFile;
1429 } 1474 }
1430 delete_ifnot_null_array(encrypted); 1475 delete_ifnot_null_array(encrypted);
1431 return e_success; 1476 return e_success;
1432} 1477}
1433 1478
1434PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw, 1479PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw,
1435 char algo, 1480 char algo,
1436 char hashalgo, //US BUG: pass _hashalgo because we need it in hashPassphrase 1481 char hashalgo, //US BUG: pass _hashalgo because we need it in hashPassphrase
1437 QFile *f) 1482 QFile *f)
1438{ 1483{
1439 PWM_ASSERT(d); 1484 PWM_ASSERT(d);
1440 PWM_ASSERT(pw); 1485 PWM_ASSERT(pw);
1441 PWM_ASSERT(f); 1486 PWM_ASSERT(f);
1442 1487
1443 unsigned int cryptLen = f->size() - pos; 1488 unsigned int cryptLen = f->size() - pos;
1444 byte *encrypted = new byte[cryptLen]; 1489 byte *encrypted = new byte[cryptLen];
1445 byte *decrypted = new byte[cryptLen]; 1490 byte *decrypted = new byte[cryptLen];
1446 1491
1447 f->at(pos); 1492 f->at(pos);
1448#ifndef PWM_EMBEDDED 1493#ifndef PWM_EMBEDDED
1449 if (f->readBlock(reinterpret_cast<char *>(encrypted), 1494 if (f->readBlock(reinterpret_cast<char *>(encrypted),
1450 static_cast<Q_ULONG>(cryptLen)) 1495 static_cast<Q_ULONG>(cryptLen))
1451 != static_cast<Q_LONG>(cryptLen)) { 1496 != static_cast<Q_LONG>(cryptLen)) {
1452 delete [] encrypted; 1497 delete [] encrypted;
1453 delete [] decrypted; 1498 delete [] decrypted;
1454 return e_readFile; 1499 return e_readFile;
1455 } 1500 }
1456#else 1501#else
1457 if (f->readBlock((char *)(encrypted), 1502 if (f->readBlock((char *)(encrypted),
1458 (unsigned long)(cryptLen)) 1503 (unsigned long)(cryptLen))
1459 != (long)(cryptLen)) { 1504 != (long)(cryptLen)) {
1460 delete [] encrypted; 1505 delete [] encrypted;
1461 delete [] decrypted; 1506 delete [] decrypted;
1462 return e_readFile; 1507 return e_readFile;
1463 } 1508 }
1464#endif 1509#endif
1465 switch (algo) { 1510 switch (algo) {
1466 case PWM_CRYPT_BLOWFISH: { 1511 case PWM_CRYPT_BLOWFISH: {
1467 Blowfish bf; 1512 Blowfish bf;
1468 bf.bf_setkey((byte *) pw->latin1(), pw->length()); 1513 bf.bf_setkey((byte *) pw->latin1(), pw->length());
1469 bf.bf_decrypt(decrypted, encrypted, cryptLen); 1514 bf.bf_decrypt(decrypted, encrypted, cryptLen);
1470 break; 1515 break;
1471 } 1516 }
1472 case PWM_CRYPT_AES128: 1517 case PWM_CRYPT_AES128:
1473 /*... fall through */ 1518 /*... fall through */
1474 case PWM_CRYPT_AES192: 1519 case PWM_CRYPT_AES192:
1475 case PWM_CRYPT_AES256: 1520 case PWM_CRYPT_AES256:
1476 case PWM_CRYPT_3DES: 1521 case PWM_CRYPT_3DES:
1477 case PWM_CRYPT_TWOFISH: 1522 case PWM_CRYPT_TWOFISH:
1478 case PWM_CRYPT_TWOFISH128: { 1523 case PWM_CRYPT_TWOFISH128: {
1479 if (!LibGCryptIf::available()) 1524 if (!LibGCryptIf::available())
1480 return e_cryptNotImpl; 1525 return e_cryptNotImpl;
1481 LibGCryptIf gc; 1526 LibGCryptIf gc;
1482 PwMerror err; 1527 PwMerror err;
1483 err = gc.decrypt(&decrypted, 1528 err = gc.decrypt(&decrypted,
1484 &cryptLen, 1529 &cryptLen,
1485 encrypted, 1530 encrypted,
1486 cryptLen, 1531 cryptLen,
1487 reinterpret_cast<const unsigned char *>(pw->latin1()), 1532 reinterpret_cast<const unsigned char *>(pw->latin1()),
1488 pw->length(), 1533 pw->length(),
1489 algo, 1534 algo,
1490 hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase 1535 hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
1491); 1536);
1492 if (err != e_success) { 1537 if (err != e_success) {
1493 delete [] encrypted; 1538 delete [] encrypted;
1494 delete [] decrypted; 1539 delete [] decrypted;
1495 return e_cryptNotImpl; 1540 return e_cryptNotImpl;
1496 } 1541 }
1497 break; 1542 break;
1498 } 1543 }
1499 default: { 1544 default: {
1500 delete [] encrypted; 1545 delete [] encrypted;
1501 delete [] decrypted; 1546 delete [] decrypted;
1502 return e_cryptNotImpl; 1547 return e_cryptNotImpl;
1503 } } 1548 } }
1504 delete [] encrypted; 1549 delete [] encrypted;
1505#ifndef PWM_EMBEDDED 1550#ifndef PWM_EMBEDDED
1506 d->assign(reinterpret_cast<const char *>(decrypted), 1551 d->assign(reinterpret_cast<const char *>(decrypted),
1507 static_cast<string::size_type>(cryptLen)); 1552 static_cast<string::size_type>(cryptLen));
1508#else 1553#else
1509 d->assign((const char *)(decrypted), 1554 d->assign((const char *)(decrypted),
1510 (string::size_type)(cryptLen)); 1555 (string::size_type)(cryptLen));
1511#endif 1556#endif
1512 delete [] decrypted; 1557 delete [] decrypted;
1513 if (algo == PWM_CRYPT_BLOWFISH) { 1558 if (algo == PWM_CRYPT_BLOWFISH) {
1514 if (!Blowfish::unpadNull(d)) { 1559 if (!Blowfish::unpadNull(d)) {
1515 BUG(); 1560 BUG();
1516 return e_readFile; 1561 return e_readFile;
1517 } 1562 }
1518 } 1563 }
1519 return e_success; 1564 return e_success;
1520} 1565}
1521 1566
1522PwMerror PwMDoc::checkDataHash(char dataHashType, const string *dataHash, 1567PwMerror PwMDoc::checkDataHash(char dataHashType, const string *dataHash,
1523 const string *dataStream) 1568 const string *dataStream)
1524{ 1569{
1525 PWM_ASSERT(dataHash); 1570 PWM_ASSERT(dataHash);
1526 PWM_ASSERT(dataStream); 1571 PWM_ASSERT(dataStream);
1527 switch(dataHashType) { 1572 switch(dataHashType) {
1528 case PWM_HASH_SHA1: { 1573 case PWM_HASH_SHA1: {
1529 Sha1 hash; 1574 Sha1 hash;
1530 hash.sha1_write((byte*)dataStream->c_str(), dataStream->length()); 1575 hash.sha1_write((byte*)dataStream->c_str(), dataStream->length());
1531 string ret = hash.sha1_read(); 1576 string ret = hash.sha1_read();
1532 if (ret != *dataHash) 1577 if (ret != *dataHash)
1533 return e_fileCorrupt; 1578 return e_fileCorrupt;
1534 break; 1579 break;
1535 } 1580 }
1536 case PWM_HASH_SHA256: 1581 case PWM_HASH_SHA256:
1537 /*... fall through */ 1582 /*... fall through */
1538 case PWM_HASH_SHA384: 1583 case PWM_HASH_SHA384:
1539 case PWM_HASH_SHA512: 1584 case PWM_HASH_SHA512:
1540 case PWM_HASH_MD5: 1585 case PWM_HASH_MD5:
1541 case PWM_HASH_RMD160: 1586 case PWM_HASH_RMD160:
1542 case PWM_HASH_TIGER: { 1587 case PWM_HASH_TIGER: {
1543 if (!LibGCryptIf::available()) 1588 if (!LibGCryptIf::available())
1544 return e_hashNotImpl; 1589 return e_hashNotImpl;
1545 LibGCryptIf gc; 1590 LibGCryptIf gc;
1546 PwMerror err; 1591 PwMerror err;
1547 unsigned char *buf; 1592 unsigned char *buf;
1548 size_t hashLen; 1593 size_t hashLen;
1549 err = gc.hash(&buf, 1594 err = gc.hash(&buf,
1550 &hashLen, 1595 &hashLen,
1551 reinterpret_cast<const unsigned char *>(dataStream->c_str()), 1596 reinterpret_cast<const unsigned char *>(dataStream->c_str()),
1552 dataStream->length(), 1597 dataStream->length(),
1553 dataHashType); 1598 dataHashType);
1554 if (err != e_success) 1599 if (err != e_success)
1555 return e_hashNotImpl; 1600 return e_hashNotImpl;
1556 string calcHash(reinterpret_cast<const char *>(buf), 1601 string calcHash(reinterpret_cast<const char *>(buf),
1557 static_cast<string::size_type>(hashLen)); 1602 static_cast<string::size_type>(hashLen));
1558 delete [] buf; 1603 delete [] buf;
1559 if (calcHash != *dataHash) 1604 if (calcHash != *dataHash)
1560 return e_fileCorrupt; 1605 return e_fileCorrupt;
1561 break; 1606 break;
1562 } 1607 }
1563 default: 1608 default:
1564 return e_hashNotImpl; 1609 return e_hashNotImpl;
1565 } 1610 }
1566 return e_success; 1611 return e_success;
1567} 1612}
1568 1613
1569bool PwMDoc::lockAt(unsigned int category, unsigned int index, 1614bool PwMDoc::lockAt(unsigned int category, unsigned int index,
1570 bool lock) 1615 bool lock)
1571{ 1616{
1572 if (index >= numEntries(category)) { 1617 if (index >= numEntries(category)) {
1573 BUG(); 1618 BUG();
1574 return false; 1619 return false;
1575 } 1620 }
1576 if (lock == dti.dta[category].d[index].lockStat) 1621 if (lock == dti.dta[category].d[index].lockStat)
1577 return true; 1622 return true;
1578 1623
1579 if (!lock && currentPw != "") { 1624 if (!lock && currentPw != "") {
1580 // "unlocking" and "password is already set" 1625 // "unlocking" and "password is already set"
1581 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) { 1626 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) {
1582 // unlocking without pw not allowed 1627 // unlocking without pw not allowed
1583 QString pw; 1628 QString pw;
1584 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1629 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1585 if (pw != "") { 1630 if (pw != "") {
1586 if (pw != currentPw) { 1631 if (pw != currentPw) {
1587 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1632 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1588 return false; 1633 return false;
1589 } else { 1634 } else {
1590 timer()->start(DocTimer::id_mpwTimer); 1635 timer()->start(DocTimer::id_mpwTimer);
1591 } 1636 }
1592 } else { 1637 } else {
1593 return false; 1638 return false;
1594 } 1639 }
1595 } else { 1640 } else {
1596 timer()->start(DocTimer::id_mpwTimer); 1641 timer()->start(DocTimer::id_mpwTimer);
1597 } 1642 }
1598 } 1643 }
1599 1644
1600 dti.dta[category].d[index].lockStat = lock; 1645 dti.dta[category].d[index].lockStat = lock;
1601 dti.dta[category].d[index].rev++; // increment revision counter. 1646 dti.dta[category].d[index].rev++; // increment revision counter.
1602 1647
1603 emitDataChanged(this); 1648 emitDataChanged(this);
1604 if (!lock) 1649 if (!lock)
1605 timer()->start(DocTimer::id_autoLockTimer); 1650 timer()->start(DocTimer::id_autoLockTimer);
1606 1651
1607 return true; 1652 return true;
1608 1653
1609} 1654}
1610 1655
1611bool PwMDoc::lockAt(const QString &category,unsigned int index, 1656bool PwMDoc::lockAt(const QString &category,unsigned int index,
1612 bool lock) 1657 bool lock)
1613{ 1658{
1614 unsigned int cat = 0; 1659 unsigned int cat = 0;
1615 1660
1616 if (!findCategory(category, &cat)) { 1661 if (!findCategory(category, &cat)) {
1617 BUG(); 1662 BUG();
1618 return false; 1663 return false;
1619 } 1664 }
1620 1665
1621 return lockAt(cat, index, lock); 1666 return lockAt(cat, index, lock);
1622} 1667}
1623 1668
1624bool PwMDoc::lockAll(bool lock) 1669bool PwMDoc::lockAll(bool lock)
1625{ 1670{
1626 if (!lock && isDeepLocked()) { 1671 if (!lock && isDeepLocked()) {
1627 PwMerror ret; 1672 PwMerror ret;
1628 ret = deepLock(false); 1673 ret = deepLock(false);
1629 if (ret != e_success) 1674 if (ret != e_success)
1630 return false; 1675 return false;
1631 return true; 1676 return true;
1632 } 1677 }
1633 if (isDocEmpty()) { 1678 if (isDocEmpty()) {
1634 return true; 1679 return true;
1635 } 1680 }
1636 if (!lock && currentPw != "") { 1681 if (!lock && currentPw != "") {
1637 // unlocking and password is already set 1682 // unlocking and password is already set
1638 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) { 1683 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) {
1639 // unlocking without pw not allowed 1684 // unlocking without pw not allowed
1640 QString pw; 1685 QString pw;
1641 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1686 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1642 if (pw != "") { 1687 if (pw != "") {
1643 if (pw != currentPw) { 1688 if (pw != currentPw) {
1644 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1689 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1645 return false; 1690 return false;
1646 } else { 1691 } else {
1647 timer()->start(DocTimer::id_mpwTimer); 1692 timer()->start(DocTimer::id_mpwTimer);
1648 } 1693 }
1649 } else { 1694 } else {
1650 return false; 1695 return false;
1651 } 1696 }
1652 } else { 1697 } else {
1653 timer()->start(DocTimer::id_mpwTimer); 1698 timer()->start(DocTimer::id_mpwTimer);
1654 } 1699 }
1655 } 1700 }
1656 1701
1657 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1702 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1658 catEnd = dti.dta.end(), 1703 catEnd = dti.dta.end(),
1659 catI = catBegin; 1704 catI = catBegin;
1660 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1705 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1661 while (catI != catEnd) { 1706 while (catI != catEnd) {
1662 entrBegin = catI->d.begin(); 1707 entrBegin = catI->d.begin();
1663 entrEnd = catI->d.end(); 1708 entrEnd = catI->d.end();
1664 entrI = entrBegin; 1709 entrI = entrBegin;
1665 while (entrI != entrEnd) { 1710 while (entrI != entrEnd) {
1666 entrI->lockStat = lock; 1711 entrI->lockStat = lock;
1667 entrI->rev++; // increment revision counter. 1712 entrI->rev++; // increment revision counter.
1668 ++entrI; 1713 ++entrI;
1669 } 1714 }
1670 ++catI; 1715 ++catI;
1671 } 1716 }
1672 1717
1673 emitDataChanged(this); 1718 emitDataChanged(this);
1674 if (lock) 1719 if (lock)
1675 timer()->stop(DocTimer::id_autoLockTimer); 1720 timer()->stop(DocTimer::id_autoLockTimer);
1676 else 1721 else
1677 timer()->start(DocTimer::id_autoLockTimer); 1722 timer()->start(DocTimer::id_autoLockTimer);
1678 1723
1679 return true; 1724 return true;
1680} 1725}
1681 1726
1682bool PwMDoc::isLocked(const QString &category, unsigned int index) 1727bool PwMDoc::isLocked(const QString &category, unsigned int index)
1683{ 1728{
1684 unsigned int cat = 0; 1729 unsigned int cat = 0;
1685 1730
1686 if (!findCategory(category, &cat)) { 1731 if (!findCategory(category, &cat)) {
1687 BUG(); 1732 BUG();
1688 return false; 1733 return false;
1689 } 1734 }
1690 1735
1691 return isLocked(cat, index); 1736 return isLocked(cat, index);
1692} 1737}
1693 1738
1694bool PwMDoc::unlockAll_tempoary(bool revert) 1739bool PwMDoc::unlockAll_tempoary(bool revert)
1695{ 1740{
1696 static vector< vector<bool> > *oldLockStates = 0; 1741 static vector< vector<bool> > *oldLockStates = 0;
1697 static bool wasDeepLocked; 1742 static bool wasDeepLocked;
1698 1743
1699 if (revert) {// revert the unlocking 1744 if (revert) {// revert the unlocking
1700 if (oldLockStates) { 1745 if (oldLockStates) {
1701 /* we actually _have_ unlocked something, because 1746 /* we actually _have_ unlocked something, because
1702 * we have allocated space for the oldLockStates. 1747 * we have allocated space for the oldLockStates.
1703 * So, go on and revert them! 1748 * So, go on and revert them!
1704 */ 1749 */
1705 if (wasDeepLocked) { 1750 if (wasDeepLocked) {
1706 PwMerror ret = deepLock(true); 1751 PwMerror ret = deepLock(true);
1707 if (ret == e_success) { 1752 if (ret == e_success) {
1708 /* deep-lock succeed. We are save. 1753 /* deep-lock succeed. We are save.
1709 * (but if it failed, just go on 1754 * (but if it failed, just go on
1710 * lock them normally) 1755 * lock them normally)
1711 */ 1756 */
1712 delete_and_null(oldLockStates); 1757 delete_and_null(oldLockStates);
1713 timer()->start(DocTimer::id_autoLockTimer); 1758 timer()->start(DocTimer::id_autoLockTimer);
1714 printDebug("tempoary unlocking of dta " 1759 printDebug("tempoary unlocking of dta "
1715 "reverted by deep-locking."); 1760 "reverted by deep-locking.");
1716 return true; 1761 return true;
1717 } 1762 }
1718 printDebug("deep-lock failed while reverting! " 1763 printDebug("deep-lock failed while reverting! "
1719 "Falling back to normal-lock."); 1764 "Falling back to normal-lock.");
1720 } 1765 }
1721 if (unlikely(!wasDeepLocked && 1766 if (unlikely(!wasDeepLocked &&
1722 numCategories() != oldLockStates->size())) { 1767 numCategories() != oldLockStates->size())) {
1723 /* DOH! We have modified "dta" while 1768 /* DOH! We have modified "dta" while
1724 * it was unlocked tempoary. DON'T DO THIS! 1769 * it was unlocked tempoary. DON'T DO THIS!
1725 */ 1770 */
1726 BUG(); 1771 BUG();
1727 delete_and_null(oldLockStates); 1772 delete_and_null(oldLockStates);
1728 timer()->start(DocTimer::id_autoLockTimer); 1773 timer()->start(DocTimer::id_autoLockTimer);
1729 return false; 1774 return false;
1730 } 1775 }
1731 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1776 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1732 catEnd = dti.dta.end(), 1777 catEnd = dti.dta.end(),
1733 catI = catBegin; 1778 catI = catBegin;
1734 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1779 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1735 vector< vector<bool> >::iterator oldCatStatI = oldLockStates->begin(); 1780 vector< vector<bool> >::iterator oldCatStatI = oldLockStates->begin();
1736 vector<bool>::iterator oldEntrStatBegin, 1781 vector<bool>::iterator oldEntrStatBegin,
1737 oldEntrStatEnd, 1782 oldEntrStatEnd,
1738 oldEntrStatI; 1783 oldEntrStatI;
1739 while (catI != catEnd) { 1784 while (catI != catEnd) {
1740 entrBegin = catI->d.begin(); 1785 entrBegin = catI->d.begin();
1741 entrEnd = catI->d.end(); 1786 entrEnd = catI->d.end();
1742 entrI = entrBegin; 1787 entrI = entrBegin;
1743 if (likely(!wasDeepLocked)) { 1788 if (likely(!wasDeepLocked)) {
1744 oldEntrStatBegin = oldCatStatI->begin(); 1789 oldEntrStatBegin = oldCatStatI->begin();
1745 oldEntrStatEnd = oldCatStatI->end(); 1790 oldEntrStatEnd = oldCatStatI->end();
1746 oldEntrStatI = oldEntrStatBegin; 1791 oldEntrStatI = oldEntrStatBegin;
1747 if (unlikely(catI->d.size() != oldCatStatI->size())) { 1792 if (unlikely(catI->d.size() != oldCatStatI->size())) {
1748 /* DOH! We have modified "dta" while 1793 /* DOH! We have modified "dta" while
1749 * it was unlocked tempoary. DON'T DO THIS! 1794 * it was unlocked tempoary. DON'T DO THIS!
1750 */ 1795 */
1751 BUG(); 1796 BUG();
1752 delete_and_null(oldLockStates); 1797 delete_and_null(oldLockStates);
1753 timer()->start(DocTimer::id_autoLockTimer); 1798 timer()->start(DocTimer::id_autoLockTimer);
1754 return false; 1799 return false;
1755 } 1800 }
1756 } 1801 }
1757 while (entrI != entrEnd) { 1802 while (entrI != entrEnd) {
1758 if (wasDeepLocked) { 1803 if (wasDeepLocked) {
1759 /* this is an error-fallback if 1804 /* this is an error-fallback if
1760 * deeplock didn't succeed 1805 * deeplock didn't succeed
1761 */ 1806 */
1762 entrI->lockStat = true; 1807 entrI->lockStat = true;
1763 } else { 1808 } else {
1764 entrI->lockStat = *oldEntrStatI; 1809 entrI->lockStat = *oldEntrStatI;
1765 } 1810 }
1766 ++entrI; 1811 ++entrI;
1767 if (likely(!wasDeepLocked)) 1812 if (likely(!wasDeepLocked))
1768 ++oldEntrStatI; 1813 ++oldEntrStatI;
1769 } 1814 }
1770 ++catI; 1815 ++catI;
1771 if (likely(!wasDeepLocked)) 1816 if (likely(!wasDeepLocked))
1772 ++oldCatStatI; 1817 ++oldCatStatI;
1773 } 1818 }
1774 delete_and_null(oldLockStates); 1819 delete_and_null(oldLockStates);
1775 if (unlikely(wasDeepLocked)) { 1820 if (unlikely(wasDeepLocked)) {
1776 /* error fallback... */ 1821 /* error fallback... */
1777 unsetDocStatFlag(DOC_STAT_DEEPLOCKED); 1822 unsetDocStatFlag(DOC_STAT_DEEPLOCKED);
1778 emitDataChanged(this); 1823 emitDataChanged(this);
1779 printDebug("WARNING: unlockAll_tempoary(true) " 1824 printDebug("WARNING: unlockAll_tempoary(true) "
1780 "deeplock fallback!"); 1825 "deeplock fallback!");
1781 } 1826 }
1782 printDebug("tempoary unlocking of dta reverted."); 1827 printDebug("tempoary unlocking of dta reverted.");
1783 } else { 1828 } else {
1784 printDebug("unlockAll_tempoary(true): nothing to do."); 1829 printDebug("unlockAll_tempoary(true): nothing to do.");
1785 } 1830 }
1786 timer()->start(DocTimer::id_autoLockTimer); 1831 timer()->start(DocTimer::id_autoLockTimer);
1787 } else {// unlock all data tempoary 1832 } else {// unlock all data tempoary
1788 if (unlikely(oldLockStates != 0)) { 1833 if (unlikely(oldLockStates != 0)) {
1789 /* DOH! We have already unlocked the data tempoarly. 1834 /* DOH! We have already unlocked the data tempoarly.
1790 * No need to do it twice. ;) 1835 * No need to do it twice. ;)
1791 */ 1836 */
1792 BUG(); 1837 BUG();
1793 return false; 1838 return false;
1794 } 1839 }
1795 wasDeepLocked = false; 1840 wasDeepLocked = false;
1796 bool mustUnlock = false; 1841 bool mustUnlock = false;
1797 if (isDeepLocked()) { 1842 if (isDeepLocked()) {
1798 PwMerror ret; 1843 PwMerror ret;
1799 while (1) { 1844 while (1) {
1800 ret = deepLock(false); 1845 ret = deepLock(false);
1801 if (ret == e_success) { 1846 if (ret == e_success) {
1802 break; 1847 break;
1803 } else if (ret == e_wrongPw) { 1848 } else if (ret == e_wrongPw) {
1804 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1849 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1805 } else { 1850 } else {
1806 printDebug("deep-unlocking failed while " 1851 printDebug("deep-unlocking failed while "
1807 "tempoary unlocking!"); 1852 "tempoary unlocking!");
1808 return false; 1853 return false;
1809 } 1854 }
1810 } 1855 }
1811 wasDeepLocked = true; 1856 wasDeepLocked = true;
1812 mustUnlock = true; 1857 mustUnlock = true;
1813 } else { 1858 } else {
1814 // first check if it's needed to unlock some entries 1859 // first check if it's needed to unlock some entries
1815 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1860 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1816 catEnd = dti.dta.end(), 1861 catEnd = dti.dta.end(),
1817 catI = catBegin; 1862 catI = catBegin;
1818 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1863 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1819 while (catI != catEnd) { 1864 while (catI != catEnd) {
1820 entrBegin = catI->d.begin(); 1865 entrBegin = catI->d.begin();
1821 entrEnd = catI->d.end(); 1866 entrEnd = catI->d.end();
1822 entrI = entrBegin; 1867 entrI = entrBegin;
1823 while (entrI != entrEnd) { 1868 while (entrI != entrEnd) {
1824 if (entrI->lockStat == true) { 1869 if (entrI->lockStat == true) {
1825 mustUnlock = true; 1870 mustUnlock = true;
1826 break; 1871 break;
1827 } 1872 }
1828 ++entrI; 1873 ++entrI;
1829 } 1874 }
1830 if (mustUnlock) 1875 if (mustUnlock)
1831 break; 1876 break;
1832 ++catI; 1877 ++catI;
1833 } 1878 }
1834 } 1879 }
1835 if (!mustUnlock) { 1880 if (!mustUnlock) {
1836 // nothing to do. 1881 // nothing to do.
1837 timer()->stop(DocTimer::id_autoLockTimer); 1882 timer()->stop(DocTimer::id_autoLockTimer);
1838 printDebug("unlockAll_tempoary(): nothing to do."); 1883 printDebug("unlockAll_tempoary(): nothing to do.");
1839 return true; 1884 return true;
1840 } else if (!wasDeepLocked) { 1885 } else if (!wasDeepLocked) {
1841 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW) && 1886 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW) &&
1842 currentPw != "") { 1887 currentPw != "") {
1843 /* we can't unlock without mpw, so 1888 /* we can't unlock without mpw, so
1844 * we need to ask for it. 1889 * we need to ask for it.
1845 */ 1890 */
1846 QString pw; 1891 QString pw;
1847 while (1) { 1892 while (1) {
1848 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1893 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1849 if (pw == "") { 1894 if (pw == "") {
1850 return false; 1895 return false;
1851 } else if (pw == currentPw) { 1896 } else if (pw == currentPw) {
1852 break; 1897 break;
1853 } 1898 }
1854 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1899 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1855 } 1900 }
1856 } 1901 }
1857 } 1902 }
1858 timer()->stop(DocTimer::id_autoLockTimer); 1903 timer()->stop(DocTimer::id_autoLockTimer);
1859 oldLockStates = new vector< vector<bool> >; 1904 oldLockStates = new vector< vector<bool> >;
1860 vector<bool> tmp_vec; 1905 vector<bool> tmp_vec;
1861 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1906 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1862 catEnd = dti.dta.end(), 1907 catEnd = dti.dta.end(),
1863 catI = catBegin; 1908 catI = catBegin;
1864 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1909 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1865 while (catI != catEnd) { 1910 while (catI != catEnd) {
1866 entrBegin = catI->d.begin(); 1911 entrBegin = catI->d.begin();
1867 entrEnd = catI->d.end(); 1912 entrEnd = catI->d.end();
1868 entrI = entrBegin; 1913 entrI = entrBegin;
1869 while (entrI != entrEnd) { 1914 while (entrI != entrEnd) {
1870 if (!wasDeepLocked) { 1915 if (!wasDeepLocked) {
1871 tmp_vec.push_back(entrI->lockStat); 1916 tmp_vec.push_back(entrI->lockStat);
1872 } 1917 }
1873 entrI->lockStat = false; 1918 entrI->lockStat = false;
1874 ++entrI; 1919 ++entrI;
1875 } 1920 }
1876 if (!wasDeepLocked) { 1921 if (!wasDeepLocked) {
1877 oldLockStates->push_back(tmp_vec); 1922 oldLockStates->push_back(tmp_vec);
1878 tmp_vec.clear(); 1923 tmp_vec.clear();
1879 } 1924 }
1880 ++catI; 1925 ++catI;
1881 } 1926 }
1882 printDebug("tempoary unlocked dta."); 1927 printDebug("tempoary unlocked dta.");
1883 } 1928 }
1884 1929
1885 return true; 1930 return true;
1886} 1931}
1887 1932
1888PwMerror PwMDoc::deepLock(bool lock, bool saveToFile) 1933PwMerror PwMDoc::deepLock(bool lock, bool saveToFile)
1889{ 1934{
1890 PwMerror ret; 1935 PwMerror ret;
1891 /* NOTE: saveDoc() depends on this function to return 1936 /* NOTE: saveDoc() depends on this function to return
1892 * e_success if saveToFile == false 1937 * e_success if saveToFile == false
1893 */ 1938 */
1894 1939
1895 if (lock) { 1940 if (lock) {
1896 if (isDeepLocked()) 1941 if (isDeepLocked())
1897 return e_lock; 1942 return e_lock;
1898 if (saveToFile) { 1943 if (saveToFile) {
1899 if (isDocEmpty()) 1944 if (isDocEmpty())
1900 return e_docIsEmpty; 1945 return e_docIsEmpty;
1901 ret = saveDoc(conf()->confGlobCompression()); 1946 ret = saveDoc(conf()->confGlobCompression());
1902 if (ret == e_filename) { 1947 if (ret == e_filename) {
1903 /* the doc wasn't saved to a file 1948 /* the doc wasn't saved to a file
1904 * by the user, yet. 1949 * by the user, yet.
1905 */ 1950 */
1906 cantDeeplock_notSavedMsgBox(); 1951 cantDeeplock_notSavedMsgBox();
1907 return e_docNotSaved; 1952 return e_docNotSaved;
1908 } else if (ret != e_success) { 1953 } else if (ret != e_success) {
1909 return e_lock; 1954 return e_lock;
1910 } 1955 }
1911 } 1956 }
1912 timer()->stop(DocTimer::id_autoLockTimer); 1957 timer()->stop(DocTimer::id_autoLockTimer);
1913 clearDoc(); 1958 clearDoc();
1914 PwMDataItem d; 1959 PwMDataItem d;
1915 d.desc = IS_DEEPLOCKED_SHORTMSG.latin1(); 1960 d.desc = IS_DEEPLOCKED_SHORTMSG.latin1();
1916 d.comment = IS_DEEPLOCKED_MSG.latin1(); 1961 d.comment = IS_DEEPLOCKED_MSG.latin1();
1917 d.listViewPos = 0; 1962 d.listViewPos = 0;
1918 addEntry(DEFAULT_CATEGORY, &d, true); 1963 addEntry(DEFAULT_CATEGORY, &d, true);
1919 lockAt(DEFAULT_CATEGORY, 0, true); 1964 lockAt(DEFAULT_CATEGORY, 0, true);
1920 unsetDocStatFlag(DOC_STAT_DISK_DIRTY); 1965 unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
1921 setDocStatFlag(DOC_STAT_DEEPLOCKED); 1966 setDocStatFlag(DOC_STAT_DEEPLOCKED);
1922 } else { 1967 } else {
1923 if (!isDeepLocked()) 1968 if (!isDeepLocked())
1924 return e_lock; 1969 return e_lock;
1925 ret = openDoc(&filename, (conf()->confGlobUnlockOnOpen()) 1970 ret = openDoc(&filename, (conf()->confGlobUnlockOnOpen())
1926 ? 0 : 1); 1971 ? 0 : 1);
1927 if (ret == e_wrongPw) { 1972 if (ret == e_wrongPw) {
1928 return e_wrongPw; 1973 return e_wrongPw;
1929 } else if (ret != e_success) { 1974 } else if (ret != e_success) {
1930 printDebug(string("PwMDoc::deepLock(false): ERR! openDoc() == ") 1975 printDebug(string("PwMDoc::deepLock(false): ERR! openDoc() == ")
1931 + tostr(static_cast<int>(ret))); 1976 + tostr(static_cast<int>(ret)));
1932 return e_lock; 1977 return e_lock;
1933 } 1978 }
1934 unsetDocStatFlag(DOC_STAT_DEEPLOCKED); 1979 unsetDocStatFlag(DOC_STAT_DEEPLOCKED);
1935 timer()->start(DocTimer::id_autoLockTimer); 1980 timer()->start(DocTimer::id_autoLockTimer);
1936 } 1981 }
1937 1982
1938 emitDataChanged(this); 1983 emitDataChanged(this);
1939 return e_success; 1984 return e_success;
1940} 1985}
1941 1986
1942void PwMDoc::_deepUnlock() 1987void PwMDoc::_deepUnlock()
1943{ 1988{
1944 deepLock(false); 1989 deepLock(false);
1945} 1990}
1946 1991
1947void PwMDoc::clearDoc() 1992void PwMDoc::clearDoc()
1948{ 1993{
1949 dti.clear(); 1994 dti.clear();
1950 PwMCategoryItem d; 1995 PwMCategoryItem d;
1951 //US ENH: to initialize all members with meaningfull data. 1996 //US ENH: to initialize all members with meaningfull data.
1952 d.clear(); 1997 d.clear();
1953 d.name = DEFAULT_CATEGORY.latin1(); 1998 d.name = DEFAULT_CATEGORY.latin1();
1954 dti.dta.push_back(d); 1999 dti.dta.push_back(d);
1955 currentPw = ""; 2000 currentPw = "";
1956 unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); 2001 unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW);
1957} 2002}
1958 2003
1959void PwMDoc::changeCurrentPw() 2004void PwMDoc::changeCurrentPw()
1960{ 2005{
1961 if (currentPw == "") 2006 if (currentPw == "")
1962 return; // doc hasn't been saved. No mpw available. 2007 return; // doc hasn't been saved. No mpw available.
1963 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD); 2008 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD);
1964 QString pw = requestMpwChange(&currentPw, &useChipcard); 2009 QString pw = requestMpwChange(&currentPw, &useChipcard);
1965 if (pw == "") 2010 if (pw == "")
1966 return; 2011 return;
1967 if (useChipcard) 2012 if (useChipcard)
1968 setDocStatFlag(DOC_STAT_USE_CHIPCARD); 2013 setDocStatFlag(DOC_STAT_USE_CHIPCARD);
1969 else 2014 else
1970 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); 2015 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
1971 setCurrentPw(pw); 2016 setCurrentPw(pw);
1972} 2017}
1973 2018
1974void PwMDoc::setListViewPos(const QString &category, unsigned int index, 2019void PwMDoc::setListViewPos(const QString &category, unsigned int index,
1975 int pos) 2020 int pos)
1976{ 2021{
1977 unsigned int cat = 0; 2022 unsigned int cat = 0;
1978 2023
1979 if (!findCategory(category, &cat)) { 2024 if (!findCategory(category, &cat)) {
1980 BUG(); 2025 BUG();
1981 return; 2026 return;
1982 } 2027 }
1983 setListViewPos(cat, index, pos); 2028 setListViewPos(cat, index, pos);
1984} 2029}
1985 2030
1986void PwMDoc::setListViewPos(unsigned int category, unsigned int index, 2031void PwMDoc::setListViewPos(unsigned int category, unsigned int index,
1987 int pos) 2032 int pos)
1988{ 2033{
1989 dti.dta[category].d[index].listViewPos = pos; 2034 dti.dta[category].d[index].listViewPos = pos;
1990 2035
1991/* FIXME workaround: don't flag dirty, because this function sometimes 2036/* FIXME workaround: don't flag dirty, because this function sometimes
1992 * get's called when it shouldn't. It's because PwMView assumes 2037 * get's called when it shouldn't. It's because PwMView assumes
1993 * the user resorted the UI on behalf of signal layoutChanged(). 2038 * the user resorted the UI on behalf of signal layoutChanged().
1994 * This is somewhat broken and incorrect, but I've no other 2039 * This is somewhat broken and incorrect, but I've no other
1995 * solution for now. 2040 * solution for now.
1996 */ 2041 */
1997 //setDocStatFlag(DOC_STAT_DISK_DIRTY); 2042 //setDocStatFlag(DOC_STAT_DISK_DIRTY);
1998} 2043}
1999 2044
2000int PwMDoc::getListViewPos(const QString &category, unsigned int index) 2045int PwMDoc::getListViewPos(const QString &category, unsigned int index)
2001{ 2046{
2002 unsigned int cat = 0; 2047 unsigned int cat = 0;
2003 2048
2004 if (!findCategory(category, &cat)) { 2049 if (!findCategory(category, &cat)) {
2005 BUG(); 2050 BUG();
2006 return -1; 2051 return -1;
2007 } 2052 }
2008 2053
2009 return dti.dta[cat].d[index].listViewPos; 2054 return dti.dta[cat].d[index].listViewPos;
2010} 2055}
2011 2056
2012void PwMDoc::findEntry(unsigned int category, PwMDataItem find, unsigned int searchIn, 2057void PwMDoc::findEntry(unsigned int category, PwMDataItem find, unsigned int searchIn,
2013 vector<unsigned int> *foundPositions, bool breakAfterFound, 2058 vector<unsigned int> *foundPositions, bool breakAfterFound,
2014 bool caseSensitive, bool exactWordMatch, bool sortByLvp) 2059 bool caseSensitive, bool exactWordMatch, bool sortByLvp)
2015{ 2060{
2016 PWM_ASSERT(foundPositions); 2061 PWM_ASSERT(foundPositions);
2017 PWM_ASSERT(searchIn); 2062 PWM_ASSERT(searchIn);
2018 foundPositions->clear(); 2063 foundPositions->clear();
2019 2064
2020 unsigned int i, entries = numEntries(category); 2065 unsigned int i, entries = numEntries(category);
2021 for (i = 0; i < entries; ++i) { 2066 for (i = 0; i < entries; ++i) {
2022 if (searchIn & SEARCH_IN_DESC) { 2067 if (searchIn & SEARCH_IN_DESC) {
2023 if (!compareString(find.desc, dti.dta[category].d[i].desc, 2068 if (!compareString(find.desc, dti.dta[category].d[i].desc,
2024 caseSensitive, exactWordMatch)) { 2069 caseSensitive, exactWordMatch)) {
2025 continue; 2070 continue;
2026 } 2071 }
2027 } 2072 }
2028 if (searchIn & SEARCH_IN_NAME) { 2073 if (searchIn & SEARCH_IN_NAME) {
2029 if (!compareString(find.name, dti.dta[category].d[i].name, 2074 if (!compareString(find.name, dti.dta[category].d[i].name,
2030 caseSensitive, exactWordMatch)) { 2075 caseSensitive, exactWordMatch)) {
2031 continue; 2076 continue;
2032 } 2077 }
2033 } 2078 }
2034 if (searchIn & SEARCH_IN_PW) { 2079 if (searchIn & SEARCH_IN_PW) {
2035 bool wasLocked = isLocked(category, i); 2080 bool wasLocked = isLocked(category, i);
2036 getDataChangedLock(); 2081 getDataChangedLock();
2037 lockAt(category, i, false); 2082 lockAt(category, i, false);
2038 if (!compareString(find.pw, dti.dta[category].d[i].pw, 2083 if (!compareString(find.pw, dti.dta[category].d[i].pw,
2039 caseSensitive, exactWordMatch)) { 2084 caseSensitive, exactWordMatch)) {
2040 lockAt(category, i, wasLocked); 2085 lockAt(category, i, wasLocked);
2041 putDataChangedLock(); 2086 putDataChangedLock();
2042 continue; 2087 continue;
2043 } 2088 }
2044 lockAt(category, i, wasLocked); 2089 lockAt(category, i, wasLocked);
2045 putDataChangedLock(); 2090 putDataChangedLock();
2046 } 2091 }
2047 if (searchIn & SEARCH_IN_COMMENT) { 2092 if (searchIn & SEARCH_IN_COMMENT) {
2048 if (!compareString(find.comment, dti.dta[category].d[i].comment, 2093 if (!compareString(find.comment, dti.dta[category].d[i].comment,
2049 caseSensitive, exactWordMatch)) { 2094 caseSensitive, exactWordMatch)) {
2050 continue; 2095 continue;
2051 } 2096 }
2052 } 2097 }
2053 if (searchIn & SEARCH_IN_URL) { 2098 if (searchIn & SEARCH_IN_URL) {
2054 if (!compareString(find.url, dti.dta[category].d[i].url, 2099 if (!compareString(find.url, dti.dta[category].d[i].url,
2055 caseSensitive, exactWordMatch)) { 2100 caseSensitive, exactWordMatch)) {
2056 continue; 2101 continue;
2057 } 2102 }
2058 } 2103 }
2059 if (searchIn & SEARCH_IN_LAUNCHER) { 2104 if (searchIn & SEARCH_IN_LAUNCHER) {
2060 if (!compareString(find.launcher, dti.dta[category].d[i].launcher, 2105 if (!compareString(find.launcher, dti.dta[category].d[i].launcher,
2061 caseSensitive, exactWordMatch)) { 2106 caseSensitive, exactWordMatch)) {
2062 continue; 2107 continue;
2063 } 2108 }
2064 } 2109 }
2065 2110
2066 // all selected "searchIn" matched. 2111 // all selected "searchIn" matched.
2067 foundPositions->push_back(i); 2112 foundPositions->push_back(i);
2068 if (breakAfterFound) 2113 if (breakAfterFound)
2069 break; 2114 break;
2070 } 2115 }
2071 2116
2072 if (sortByLvp && foundPositions->size() > 1) { 2117 if (sortByLvp && foundPositions->size() > 1) {
2073 vector< pair<unsigned int /* foundPosition (real doc pos) */, 2118 vector< pair<unsigned int /* foundPosition (real doc pos) */,
2074 unsigned int /* lvp-pos */> > tmp_vec; 2119 unsigned int /* lvp-pos */> > tmp_vec;
2075 2120
2076 unsigned int i, items = foundPositions->size(); 2121 unsigned int i, items = foundPositions->size();
2077 pair<unsigned int, unsigned int> tmp_pair; 2122 pair<unsigned int, unsigned int> tmp_pair;
2078 for (i = 0; i < items; ++i) { 2123 for (i = 0; i < items; ++i) {
2079 tmp_pair.first = (*foundPositions)[i]; 2124 tmp_pair.first = (*foundPositions)[i];
2080 tmp_pair.second = dti.dta[category].d[(*foundPositions)[i]].listViewPos; 2125 tmp_pair.second = dti.dta[category].d[(*foundPositions)[i]].listViewPos;
2081 tmp_vec.push_back(tmp_pair); 2126 tmp_vec.push_back(tmp_pair);
2082 } 2127 }
2083 sort(tmp_vec.begin(), tmp_vec.end(), dta_lvp_greater()); 2128 sort(tmp_vec.begin(), tmp_vec.end(), dta_lvp_greater());
2084 foundPositions->clear(); 2129 foundPositions->clear();
2085 for (i = 0; i < items; ++i) { 2130 for (i = 0; i < items; ++i) {
2086 foundPositions->push_back(tmp_vec[i].first); 2131 foundPositions->push_back(tmp_vec[i].first);
2087 } 2132 }
2088 } 2133 }
2089} 2134}
2090 2135
2091void PwMDoc::findEntry(const QString &category, PwMDataItem find, unsigned int searchIn, 2136void PwMDoc::findEntry(const QString &category, PwMDataItem find, unsigned int searchIn,
2092 vector<unsigned int> *foundPositions, bool breakAfterFound, 2137 vector<unsigned int> *foundPositions, bool breakAfterFound,
2093 bool caseSensitive, bool exactWordMatch, bool sortByLvp) 2138 bool caseSensitive, bool exactWordMatch, bool sortByLvp)
2094{ 2139{
2095 PWM_ASSERT(foundPositions); 2140 PWM_ASSERT(foundPositions);
2096 unsigned int cat = 0; 2141 unsigned int cat = 0;
2097 2142
2098 if (!findCategory(category, &cat)) { 2143 if (!findCategory(category, &cat)) {
2099 foundPositions->clear(); 2144 foundPositions->clear();
2100 return; 2145 return;
2101 } 2146 }
2102 2147
2103 findEntry(cat, find, searchIn, foundPositions, breakAfterFound, 2148 findEntry(cat, find, searchIn, foundPositions, breakAfterFound,
2104 caseSensitive, exactWordMatch, sortByLvp); 2149 caseSensitive, exactWordMatch, sortByLvp);
2105} 2150}
2106 2151
2107bool PwMDoc::compareString(const string &s1, const string &s2, bool caseSensitive, 2152bool PwMDoc::compareString(const string &s1, const string &s2, bool caseSensitive,
2108 bool exactWordMatch) 2153 bool exactWordMatch)
2109{ 2154{
2110 QString _s1(s1.c_str()); 2155 QString _s1(s1.c_str());
2111 QString _s2(s2.c_str()); 2156 QString _s2(s2.c_str());
2112 if (!caseSensitive) { 2157 if (!caseSensitive) {
2113 _s1 = _s1.lower(); 2158 _s1 = _s1.lower();
2114 _s2 = _s2.lower(); 2159 _s2 = _s2.lower();
2115 } 2160 }
2116 if (exactWordMatch ? (_s1 == _s2) : (_s2.find(_s1) != -1)) 2161 if (exactWordMatch ? (_s1 == _s2) : (_s2.find(_s1) != -1))
2117 return true; 2162 return true;
2118 return false; 2163 return false;
2119} 2164}
2120 2165
2121bool PwMDoc::findCategory(const QString &name, unsigned int *index) 2166bool PwMDoc::findCategory(const QString &name, unsigned int *index)
2122{ 2167{
2123 vector<PwMCategoryItem>::iterator i = dti.dta.begin(), 2168 vector<PwMCategoryItem>::iterator i = dti.dta.begin(),
2124 end = dti.dta.end(); 2169 end = dti.dta.end();
2125 while (i != end) { 2170 while (i != end) {
2126 if ((*i).name == name.latin1()) { 2171 if ((*i).name == name.latin1()) {
2127 if (index) { 2172 if (index) {
2128 *index = i - dti.dta.begin(); 2173 *index = i - dti.dta.begin();
2129 } 2174 }
2130 return true; 2175 return true;
2131 } 2176 }
2132 ++i; 2177 ++i;
2133 } 2178 }
2134 return false; 2179 return false;
2135} 2180}
2136 2181
2137bool PwMDoc::renameCategory(const QString &category, const QString &newName) 2182bool PwMDoc::renameCategory(const QString &category, const QString &newName)
2138{ 2183{
2139 unsigned int cat = 0; 2184 unsigned int cat = 0;
2140 2185
2141 if (!findCategory(category, &cat)) 2186 if (!findCategory(category, &cat))
2142 return false; 2187 return false;
2143 2188
2144 return renameCategory(cat, newName); 2189 return renameCategory(cat, newName);
2145} 2190}
2146 2191
2147bool PwMDoc::renameCategory(unsigned int category, const QString &newName, 2192bool PwMDoc::renameCategory(unsigned int category, const QString &newName,
2148 bool dontFlagDirty) 2193 bool dontFlagDirty)
2149{ 2194{
2150 if (category > numCategories() - 1) 2195 if (category > numCategories() - 1)
2151 return false; 2196 return false;
2152 2197
2153 dti.dta[category].name = newName.latin1(); 2198 dti.dta[category].name = newName.latin1();
2154 if (!dontFlagDirty) 2199 if (!dontFlagDirty)
2155 flagDirty(); 2200 flagDirty();
2156 2201
2157 return true; 2202 return true;
2158} 2203}
2159 2204
2160bool PwMDoc::delCategory(const QString &category) 2205bool PwMDoc::delCategory(const QString &category)
2161{ 2206{
2162 unsigned int cat = 0; 2207 unsigned int cat = 0;
2163 2208
2164 if (!findCategory(category, &cat)) 2209 if (!findCategory(category, &cat))
2165 return false; 2210 return false;
2166 2211
2167 return delCategory(cat); 2212 return delCategory(cat);
2168} 2213}
2169 2214
2170bool PwMDoc::delCategory(unsigned int category, bool dontFlagDirty) 2215bool PwMDoc::delCategory(unsigned int category, bool dontFlagDirty)
2171{ 2216{
2172 if (category > numCategories() - 1) 2217 if (category > numCategories() - 1)
2173 return false; 2218 return false;
2174 2219
2175 // We don't delete it, if it is the last existing 2220 // We don't delete it, if it is the last existing
2176 // category! Instead we rename it to "Default". 2221 // category! Instead we rename it to "Default".
2177 if (numCategories() > 1) { 2222 if (numCategories() > 1) {
2178 dti.dta.erase(dti.dta.begin() + category); 2223 dti.dta.erase(dti.dta.begin() + category);
2179 } else { 2224 } else {
2180 renameCategory(category, DEFAULT_CATEGORY, dontFlagDirty); 2225 renameCategory(category, DEFAULT_CATEGORY, dontFlagDirty);
2181 return true; 2226 return true;
2182 } 2227 }
2183 if (!dontFlagDirty) 2228 if (!dontFlagDirty)
2184 flagDirty(); 2229 flagDirty();
2185 2230
2186 return true; 2231 return true;
2187} 2232}
2188 2233
2189void PwMDoc::delAllEmptyCat(bool dontFlagDirty) 2234void PwMDoc::delAllEmptyCat(bool dontFlagDirty)
2190{ 2235{
2191 vector<PwMCategoryItem>::iterator begin = dti.dta.begin(), 2236 vector<PwMCategoryItem>::iterator begin = dti.dta.begin(),
2192 end = dti.dta.end(), 2237 end = dti.dta.end(),
2193 i = begin; 2238 i = begin;
2194 while (i != end) { 2239 while (i != end) {
2195 if (i->d.empty()) { 2240 if (i->d.empty()) {
2196 delCategory(begin - i, dontFlagDirty); 2241 delCategory(begin - i, dontFlagDirty);
2197 } 2242 }
2198 ++i; 2243 ++i;
2199 } 2244 }
2200} 2245}
2201 2246
2202void PwMDoc::getCategoryList(vector<string> *list) 2247void PwMDoc::getCategoryList(vector<string> *list)
2203{ 2248{
2204 PWM_ASSERT(list); 2249 PWM_ASSERT(list);
2205 list->clear(); 2250 list->clear();
2206 vector<PwMCategoryItem>::iterator i = dti.dta.begin(), 2251 vector<PwMCategoryItem>::iterator i = dti.dta.begin(),
2207 end = dti.dta.end(); 2252 end = dti.dta.end();
2208 while (i != end) { 2253 while (i != end) {
2209 list->push_back(i->name); 2254 list->push_back(i->name);
2210 ++i; 2255 ++i;
2211 } 2256 }
2212} 2257}
2213 2258
2214void PwMDoc::getCategoryList(QStringList *list) 2259void PwMDoc::getCategoryList(QStringList *list)
2215{ 2260{
2216 PWM_ASSERT(list); 2261 PWM_ASSERT(list);
2217 list->clear(); 2262 list->clear();
2218 vector<PwMCategoryItem>::iterator i = dti.dta.begin(), 2263 vector<PwMCategoryItem>::iterator i = dti.dta.begin(),
2219 end = dti.dta.end(); 2264 end = dti.dta.end();
2220 while (i != end) { 2265 while (i != end) {
2221#ifndef PWM_EMBEDDED 2266#ifndef PWM_EMBEDDED
2222 list->push_back(i->name.c_str()); 2267 list->push_back(i->name.c_str());
2223#else 2268#else
2224 list->append(i->name.c_str()); 2269 list->append(i->name.c_str());
2225#endif 2270#endif
2226 ++i; 2271 ++i;
2227 } 2272 }
2228} 2273}
2229 2274
2230void PwMDoc::getEntryList(const QString &category, QStringList *list) 2275void PwMDoc::getEntryList(const QString &category, QStringList *list)
2231{ 2276{
2232 PWM_ASSERT(list); 2277 PWM_ASSERT(list);
2233 unsigned int cat = 0; 2278 unsigned int cat = 0;
2234 if (!findCategory(category, &cat)) { 2279 if (!findCategory(category, &cat)) {
2235 list->clear(); 2280 list->clear();
2236 return; 2281 return;
2237 } 2282 }
2238 getEntryList(cat, list); 2283 getEntryList(cat, list);
2239} 2284}
2240 2285
2241void PwMDoc::getEntryList(const QString &category, vector<string> *list) 2286void PwMDoc::getEntryList(const QString &category, vector<string> *list)
2242{ 2287{
2243 PWM_ASSERT(list); 2288 PWM_ASSERT(list);
2244 unsigned int cat = 0; 2289 unsigned int cat = 0;
2245 if (!findCategory(category, &cat)) { 2290 if (!findCategory(category, &cat)) {
2246 list->clear(); 2291 list->clear();
2247 return; 2292 return;
2248 } 2293 }
2249 getEntryList(cat, list); 2294 getEntryList(cat, list);
2250} 2295}
2251 2296
2252void PwMDoc::getEntryList(unsigned int category, vector<string> *list) 2297void PwMDoc::getEntryList(unsigned int category, vector<string> *list)
2253{ 2298{
2254 PWM_ASSERT(list); 2299 PWM_ASSERT(list);
2255 list->clear(); 2300 list->clear();
2256 vector<PwMDataItem>::iterator begin = dti.dta[category].d.begin(), 2301 vector<PwMDataItem>::iterator begin = dti.dta[category].d.begin(),
2257 end = dti.dta[category].d.end(), 2302 end = dti.dta[category].d.end(),
2258 i = begin; 2303 i = begin;
2259 while (i != end) { 2304 while (i != end) {
2260 list->push_back(i->desc); 2305 list->push_back(i->desc);
2261 ++i; 2306 ++i;
2262 } 2307 }
2263} 2308}
2264 2309
2265void PwMDoc::getEntryList(unsigned int category, QStringList *list) 2310void PwMDoc::getEntryList(unsigned int category, QStringList *list)
2266{ 2311{
2267 PWM_ASSERT(list); 2312 PWM_ASSERT(list);
2268 list->clear(); 2313 list->clear();
2269 vector<PwMDataItem>::iterator begin = dti.dta[category].d.begin(), 2314 vector<PwMDataItem>::iterator begin = dti.dta[category].d.begin(),
2270 end = dti.dta[category].d.end(), 2315 end = dti.dta[category].d.end(),
2271 i = begin; 2316 i = begin;
2272 while (i != end) { 2317 while (i != end) {
2273#ifndef PWM_EMBEDDED 2318#ifndef PWM_EMBEDDED
2274 list->push_back(i->desc.c_str()); 2319 list->push_back(i->desc.c_str());
2275#else 2320#else
2276 list->append(i->desc.c_str()); 2321 list->append(i->desc.c_str());
2277#endif 2322#endif
2278 ++i; 2323 ++i;
2279 } 2324 }
2280} 2325}
2281 2326
2282bool PwMDoc::execLauncher(const QString &category, unsigned int entryIndex) 2327bool PwMDoc::execLauncher(const QString &category, unsigned int entryIndex)
2283{ 2328{
2284 unsigned int cat = 0; 2329 unsigned int cat = 0;
2285 2330
2286 if (!findCategory(category, &cat)) 2331 if (!findCategory(category, &cat))
2287 return false; 2332 return false;
2288 2333
2289 return execLauncher(cat, entryIndex); 2334 return execLauncher(cat, entryIndex);
2290} 2335}
2291 2336
2292bool PwMDoc::execLauncher(unsigned int category, unsigned int entryIndex) 2337bool PwMDoc::execLauncher(unsigned int category, unsigned int entryIndex)
2293{ 2338{
2294#ifndef _WIN32_ 2339#ifndef _WIN32_
2295 if (geteuid() == 0) { 2340 if (geteuid() == 0) {
2296 rootAlertMsgBox(); 2341 rootAlertMsgBox();
2297 return false; 2342 return false;
2298 } 2343 }
2299#endif 2344#endif
2300 QString command(dti.dta[category].d[entryIndex].launcher.c_str()); 2345 QString command(dti.dta[category].d[entryIndex].launcher.c_str());
2301 bool wasLocked = isLocked(category, entryIndex); 2346 bool wasLocked = isLocked(category, entryIndex);
2302 2347
2303 if (command.find("$p") != -1) { 2348 if (command.find("$p") != -1) {
2304 /* the user requested the password to be included 2349 /* the user requested the password to be included
2305 * into the command. We have to ask for the password, 2350 * into the command. We have to ask for the password,
2306 * if it's locked. We do that by unlocking the entry 2351 * if it's locked. We do that by unlocking the entry
2307 */ 2352 */
2308 if (!lockAt(category, entryIndex, false)) 2353 if (!lockAt(category, entryIndex, false))
2309 return false; 2354 return false;
2310 } 2355 }
2311#ifndef PWM_EMBEDDED 2356#ifndef PWM_EMBEDDED
2312 command.replace("$d", dti.dta[category].d[entryIndex].desc.c_str()); 2357 command.replace("$d", dti.dta[category].d[entryIndex].desc.c_str());
2313 command.replace("$n", dti.dta[category].d[entryIndex].name.c_str()); 2358 command.replace("$n", dti.dta[category].d[entryIndex].name.c_str());
2314 command.replace("$p", dti.dta[category].d[entryIndex].pw.c_str()); 2359 command.replace("$p", dti.dta[category].d[entryIndex].pw.c_str());
2315 command.replace("$u", dti.dta[category].d[entryIndex].url.c_str()); 2360 command.replace("$u", dti.dta[category].d[entryIndex].url.c_str());
2316 command.replace("$c", dti.dta[category].d[entryIndex].comment.c_str()); 2361 command.replace("$c", dti.dta[category].d[entryIndex].comment.c_str());
2317#else 2362#else
2318 command.replace(QRegExp("$d"), dti.dta[category].d[entryIndex].desc.c_str()); 2363 command.replace(QRegExp("$d"), dti.dta[category].d[entryIndex].desc.c_str());
2319 command.replace(QRegExp("$n"), dti.dta[category].d[entryIndex].name.c_str()); 2364 command.replace(QRegExp("$n"), dti.dta[category].d[entryIndex].name.c_str());
2320 command.replace(QRegExp("$p"), dti.dta[category].d[entryIndex].pw.c_str()); 2365 command.replace(QRegExp("$p"), dti.dta[category].d[entryIndex].pw.c_str());
2321 command.replace(QRegExp("$u"), dti.dta[category].d[entryIndex].url.c_str()); 2366 command.replace(QRegExp("$u"), dti.dta[category].d[entryIndex].url.c_str());
2322 command.replace(QRegExp("$c"), dti.dta[category].d[entryIndex].comment.c_str()); 2367 command.replace(QRegExp("$c"), dti.dta[category].d[entryIndex].comment.c_str());
2323#endif 2368#endif
2324 command.append(" &"); 2369 command.append(" &");
2325 2370
2326 QString customXterm(conf()->confGlobXtermCommand()); 2371 QString customXterm(conf()->confGlobXtermCommand());
2327 if (!customXterm.isEmpty()) 2372 if (!customXterm.isEmpty())
2328 command = customXterm + " " + command; 2373 command = customXterm + " " + command;
2329 2374
2330 system(command.latin1()); 2375 system(command.latin1());
2331 2376
2332 lockAt(category, entryIndex, wasLocked); 2377 lockAt(category, entryIndex, wasLocked);
2333 return true; 2378 return true;
2334} 2379}
2335 2380
2336bool PwMDoc::goToURL(const QString &category, unsigned int entryIndex) 2381bool PwMDoc::goToURL(const QString &category, unsigned int entryIndex)
2337{ 2382{
2338 unsigned int cat = 0; 2383 unsigned int cat = 0;
2339 2384
2340 if (!findCategory(category, &cat)) 2385 if (!findCategory(category, &cat))
2341 return false; 2386 return false;
2342 2387
2343 return goToURL(cat, entryIndex); 2388 return goToURL(cat, entryIndex);
2344} 2389}
2345 2390
2346bool PwMDoc::goToURL(unsigned int category, unsigned int entryIndex) 2391bool PwMDoc::goToURL(unsigned int category, unsigned int entryIndex)
2347{ 2392{
2348#ifndef _WIN32_ 2393#ifndef _WIN32_
2349 if (geteuid() == 0) { 2394 if (geteuid() == 0) {
2350 rootAlertMsgBox(); 2395 rootAlertMsgBox();
2351 return false; 2396 return false;
2352 } 2397 }
2353#endif 2398#endif
2354 QString url(dti.dta[category].d[entryIndex].url.c_str()); 2399 QString url(dti.dta[category].d[entryIndex].url.c_str());
2355 if (url.isEmpty()) 2400 if (url.isEmpty())
2356 return false; 2401 return false;
2357 2402
2358 QString customBrowser(conf()->confGlobBrowserCommand()); 2403 QString customBrowser(conf()->confGlobBrowserCommand());
2359 if (!customBrowser.isEmpty()) { 2404 if (!customBrowser.isEmpty()) {
2360 browserProc.clearArguments(); 2405 browserProc.clearArguments();
2361 browserProc << customBrowser << url; 2406 browserProc << customBrowser << url;
2362 if (browserProc.start(KProcess::DontCare)) 2407 if (browserProc.start(KProcess::DontCare))
2363 return true; 2408 return true;
2364 } 2409 }
2365 2410
2366 browserProc.clearArguments(); 2411 browserProc.clearArguments();
2367 browserProc << "konqueror" << url; 2412 browserProc << "konqueror" << url;
2368 if (browserProc.start(KProcess::DontCare)) 2413 if (browserProc.start(KProcess::DontCare))
2369 return true; 2414 return true;
2370 2415
2371 browserProc.clearArguments(); 2416 browserProc.clearArguments();
2372 browserProc << "mozilla" << url; 2417 browserProc << "mozilla" << url;
2373 if (browserProc.start(KProcess::DontCare)) 2418 if (browserProc.start(KProcess::DontCare))
2374 return true; 2419 return true;
2375 2420
2376 browserProc.clearArguments(); 2421 browserProc.clearArguments();
2377 browserProc << "opera" << url; 2422 browserProc << "opera" << url;
2378 if (browserProc.start(KProcess::DontCare)) 2423 if (browserProc.start(KProcess::DontCare))
2379 return true; 2424 return true;
2380 return false; 2425 return false;
2381} 2426}
2382 2427
2383PwMerror PwMDoc::exportToText(const QString *file) 2428PwMerror PwMDoc::exportToText(const QString *file)
2384{ 2429{
2385 PWM_ASSERT(file); 2430 PWM_ASSERT(file);
2386 if (QFile::exists(*file)) { 2431 if (QFile::exists(*file)) {
2387 if (!QFile::remove(*file)) 2432 if (!QFile::remove(*file))
2388 return e_accessFile; 2433 return e_accessFile;
2389 } 2434 }
2390 QFile f(*file); 2435 QFile f(*file);
2391 if (!f.open(IO_ReadWrite)) 2436 if (!f.open(IO_ReadWrite))
2392 return e_openFile; 2437 return e_openFile;
2393 2438
2394 if (!unlockAll_tempoary()) { 2439 if (!unlockAll_tempoary()) {
2395 f.close(); 2440 f.close();
2396 return e_lock; 2441 return e_lock;
2397 } 2442 }
2398 2443
2399 // write header 2444 // write header
2400 string header = i18n("Password table generated by\nPwM v").latin1(); 2445 string header = i18n("Password table generated by\nPwM v").latin1();
2401 header += PACKAGE_VER; 2446 header += PACKAGE_VER;
2402 header += i18n("\non ").latin1(); 2447 header += i18n("\non ").latin1();
2403 QDate currDate = QDate::currentDate(); 2448 QDate currDate = QDate::currentDate();
2404 QTime currTime = QTime::currentTime(); 2449 QTime currTime = QTime::currentTime();
2405 2450
2406#ifndef PWM_EMBEDDED 2451#ifndef PWM_EMBEDDED
2407 header += currDate.toString("ddd MMMM d ").latin1(); 2452 header += currDate.toString("ddd MMMM d ").latin1();
2408 header += currTime.toString("hh:mm:ss ").latin1(); 2453 header += currTime.toString("hh:mm:ss ").latin1();
2409#else 2454#else
2410 QString dfs = KGlobal::locale()->dateFormatShort(); 2455 QString dfs = KGlobal::locale()->dateFormatShort();
2411 bool ampm = KGlobal::locale()->use12Clock(); 2456 bool ampm = KGlobal::locale()->use12Clock();
2412 KGlobal::locale()->setDateFormatShort("%A %B %d"); 2457 KGlobal::locale()->setDateFormatShort("%A %B %d");
2413 KGlobal::locale()->setHore24Format(true); 2458 KGlobal::locale()->setHore24Format(true);
2414 2459
2415 header += KGlobal::locale()->formatDate(currDate, true, KLocale::Userdefined).latin1(); 2460 header += KGlobal::locale()->formatDate(currDate, true, KLocale::Userdefined).latin1();
2416 header += KGlobal::locale()->formatTime(currTime, true).latin1(); 2461 header += KGlobal::locale()->formatTime(currTime, true).latin1();
2417 KGlobal::locale()->setDateFormatShort(dfs); 2462 KGlobal::locale()->setDateFormatShort(dfs);
2418 KGlobal::locale()->setHore24Format(!ampm); 2463 KGlobal::locale()->setHore24Format(!ampm);
2419 2464
2420#endif 2465#endif
2421 header += tostr(currDate.year()); 2466 header += tostr(currDate.year());
2422 header += "\n==============================\n\n"; 2467 header += "\n==============================\n\n";
2423 2468
2424 2469
2425#ifndef PWM_EMBEDDED 2470#ifndef PWM_EMBEDDED
2426 if (f.writeBlock(header.c_str(), header.length()) != (Q_LONG)header.length()) { 2471 if (f.writeBlock(header.c_str(), header.length()) != (Q_LONG)header.length()) {
2427 unlockAll_tempoary(true); 2472 unlockAll_tempoary(true);
2428 f.close(); 2473 f.close();
2429 return e_writeFile; 2474 return e_writeFile;
2430 } 2475 }
2431#else 2476#else
2432 if (f.writeBlock(header.c_str(), header.length()) != (long)header.length()) { 2477 if (f.writeBlock(header.c_str(), header.length()) != (long)header.length()) {
2433 unlockAll_tempoary(true); 2478 unlockAll_tempoary(true);
2434 f.close(); 2479 f.close();
2435 return e_writeFile; 2480 return e_writeFile;
2436 } 2481 }
2437#endif 2482#endif
2438 unsigned int i, numCat = numCategories(); 2483 unsigned int i, numCat = numCategories();
2439 unsigned int j, numEnt; 2484 unsigned int j, numEnt;
2440 string exp; 2485 string exp;
2441 for (i = 0; i < numCat; ++i) { 2486 for (i = 0; i < numCat; ++i) {
2442 numEnt = numEntries(i); 2487 numEnt = numEntries(i);
2443 2488
2444 exp = "\n== Category: "; 2489 exp = "\n== Category: ";
2445 exp += dti.dta[i].name; 2490 exp += dti.dta[i].name;
2446 exp += " ==\n"; 2491 exp += " ==\n";
2447#ifndef PWM_EMBEDDED 2492#ifndef PWM_EMBEDDED
2448 if (f.writeBlock(exp.c_str(), exp.length()) != (Q_LONG)exp.length()) { 2493 if (f.writeBlock(exp.c_str(), exp.length()) != (Q_LONG)exp.length()) {
2449 unlockAll_tempoary(true); 2494 unlockAll_tempoary(true);
2450 f.close(); 2495 f.close();
2451 return e_writeFile; 2496 return e_writeFile;
2452 } 2497 }
2453#else 2498#else
2454 if (f.writeBlock(exp.c_str(), exp.length()) != (long)exp.length()) { 2499 if (f.writeBlock(exp.c_str(), exp.length()) != (long)exp.length()) {
2455 unlockAll_tempoary(true); 2500 unlockAll_tempoary(true);
2456 f.close(); 2501 f.close();
2457 return e_writeFile; 2502 return e_writeFile;
2458 } 2503 }
2459#endif 2504#endif
2460 for (j = 0; j < numEnt; ++j) { 2505 for (j = 0; j < numEnt; ++j) {
2461 exp = "\n-- "; 2506 exp = "\n-- ";
2462 exp += dti.dta[i].d[j].desc; 2507 exp += dti.dta[i].d[j].desc;
2463 exp += " --\n"; 2508 exp += " --\n";
2464 2509
2465 exp += i18n("Username: ").latin1(); 2510 exp += i18n("Username: ").latin1();
2466 exp += dti.dta[i].d[j].name; 2511 exp += dti.dta[i].d[j].name;
2467 exp += "\n"; 2512 exp += "\n";
2468 2513
2469 exp += i18n("Password: ").latin1(); 2514 exp += i18n("Password: ").latin1();
2470 exp += dti.dta[i].d[j].pw; 2515 exp += dti.dta[i].d[j].pw;
2471 exp += "\n"; 2516 exp += "\n";
2472 2517
2473 exp += i18n("Comment: ").latin1(); 2518 exp += i18n("Comment: ").latin1();
2474 exp += dti.dta[i].d[j].comment; 2519 exp += dti.dta[i].d[j].comment;
2475 exp += "\n"; 2520 exp += "\n";
2476 2521
2477 exp += i18n("URL: ").latin1(); 2522 exp += i18n("URL: ").latin1();
2478 exp += dti.dta[i].d[j].url; 2523 exp += dti.dta[i].d[j].url;
2479 exp += "\n"; 2524 exp += "\n";
2480 2525
2481 exp += i18n("Launcher: ").latin1(); 2526 exp += i18n("Launcher: ").latin1();
2482 exp += dti.dta[i].d[j].launcher; 2527 exp += dti.dta[i].d[j].launcher;
2483 exp += "\n"; 2528 exp += "\n";
2484 2529
2485#ifndef PWM_EMBEDDED 2530#ifndef PWM_EMBEDDED
2486 if (f.writeBlock(exp.c_str(), exp.length()) != (Q_LONG)exp.length()) { 2531 if (f.writeBlock(exp.c_str(), exp.length()) != (Q_LONG)exp.length()) {
2487 unlockAll_tempoary(true); 2532 unlockAll_tempoary(true);
2488 f.close(); 2533 f.close();
2489 return e_writeFile; 2534 return e_writeFile;
2490 } 2535 }
2491#else 2536#else
2492 if (f.writeBlock(exp.c_str(), exp.length()) != (long)exp.length()) { 2537 if (f.writeBlock(exp.c_str(), exp.length()) != (long)exp.length()) {
2493 unlockAll_tempoary(true); 2538 unlockAll_tempoary(true);
2494 f.close(); 2539 f.close();
2495 return e_writeFile; 2540 return e_writeFile;
2496 } 2541 }
2497#endif 2542#endif
2498 } 2543 }
2499 } 2544 }
2500 unlockAll_tempoary(true); 2545 unlockAll_tempoary(true);
2501 f.close(); 2546 f.close();
2502 2547
2503 return e_success; 2548 return e_success;
2504} 2549}
2505 2550
2506PwMerror PwMDoc::importFromText(const QString *file, int format) 2551PwMerror PwMDoc::importFromText(const QString *file, int format)
2507{ 2552{
2508 PWM_ASSERT(file); 2553 PWM_ASSERT(file);
2509 if (format == 0) 2554 if (format == 0)
2510 return importText_PwM(file); 2555 return importText_PwM(file);
2511 else if (format == -1) { 2556 else if (format == -1) {
2512 // probe for all formats 2557 // probe for all formats
2513 if (importText_PwM(file) == e_success) 2558 if (importText_PwM(file) == e_success)
2514 return e_success; 2559 return e_success;
2515 dti.clear(); 2560 dti.clear();
2516 emitDataChanged(this); 2561 emitDataChanged(this);
2517 // add next format here... 2562 // add next format here...
2518 return e_fileFormat; 2563 return e_fileFormat;
2519 } 2564 }
2520 return e_invalidArg; 2565 return e_invalidArg;
2521} 2566}
2522 2567
2523PwMerror PwMDoc::importText_PwM(const QString *file) 2568PwMerror PwMDoc::importText_PwM(const QString *file)
2524{ 2569{
2525#ifndef PWM_EMBEDDED 2570#ifndef PWM_EMBEDDED
2526 PWM_ASSERT(file); 2571 PWM_ASSERT(file);
2527 FILE *f; 2572 FILE *f;
2528 int tmp; 2573 int tmp;
2529 ssize_t ret; 2574 ssize_t ret;
2530 string curCat; 2575 string curCat;
2531 unsigned int entriesRead = 0; 2576 unsigned int entriesRead = 0;
2532 PwMDataItem currItem; 2577 PwMDataItem currItem;
2533 f = fopen(file->latin1(), "r"); 2578 f = fopen(file->latin1(), "r");
2534 if (!f) 2579 if (!f)
2535 return e_openFile; 2580 return e_openFile;
2536 size_t ch_tmp_size = 1024; 2581 size_t ch_tmp_size = 1024;
2537 char *ch_tmp = (char*)malloc(ch_tmp_size); 2582 char *ch_tmp = (char*)malloc(ch_tmp_size);
2538 if (!ch_tmp) { 2583 if (!ch_tmp) {
2539 fclose(f); 2584 fclose(f);
2540 return e_outOfMem; 2585 return e_outOfMem;
2541 } 2586 }
2542 2587
2543 // - check header 2588 // - check header
2544 if (getline(&ch_tmp, &ch_tmp_size, f) == -1) // skip first line. 2589 if (getline(&ch_tmp, &ch_tmp_size, f) == -1) // skip first line.
2545 goto formatError; 2590 goto formatError;
2546 // check version-string and return version in "ch_tmp". 2591 // check version-string and return version in "ch_tmp".
2547 if (fscanf(f, "PwM v%s", ch_tmp) != 1) { 2592 if (fscanf(f, "PwM v%s", ch_tmp) != 1) {
2548 // header not recognized as PwM generated header 2593 // header not recognized as PwM generated header
2549 goto formatError; 2594 goto formatError;
2550 } 2595 }
2551 // set filepointer behind version-string-line previously checked 2596 // set filepointer behind version-string-line previously checked
2552 if (getline(&ch_tmp, &ch_tmp_size, f) == -1) 2597 if (getline(&ch_tmp, &ch_tmp_size, f) == -1)
2553 goto formatError; 2598 goto formatError;
2554 // skip next line containing the build-date 2599 // skip next line containing the build-date
2555 if (getline(&ch_tmp, &ch_tmp_size, f) == -1) 2600 if (getline(&ch_tmp, &ch_tmp_size, f) == -1)
2556 goto formatError; 2601 goto formatError;
2557 // read header termination line 2602 // read header termination line
2558 if (getline(&ch_tmp, &ch_tmp_size, f) == -1) 2603 if (getline(&ch_tmp, &ch_tmp_size, f) == -1)
2559 goto formatError; 2604 goto formatError;
2560 if (strcmp(ch_tmp, "==============================\n")) 2605 if (strcmp(ch_tmp, "==============================\n"))
2561 goto formatError; 2606 goto formatError;
2562 2607
2563 // - read entries 2608 // - read entries
2564 do { 2609 do {
2565 // find beginning of next category 2610 // find beginning of next category
2566 do { 2611 do {
2567 tmp = fgetc(f); 2612 tmp = fgetc(f);
2568 } while (tmp == '\n' && tmp != EOF); 2613 } while (tmp == '\n' && tmp != EOF);
2569 if (tmp == EOF) 2614 if (tmp == EOF)
2570 break; 2615 break;
2571 2616
2572 // decrement filepos by one 2617 // decrement filepos by one
2573 fseek(f, -1, SEEK_CUR); 2618 fseek(f, -1, SEEK_CUR);
2574 // read cat-name 2619 // read cat-name
2575 if (getline(&ch_tmp, &ch_tmp_size, f) == -1) 2620 if (getline(&ch_tmp, &ch_tmp_size, f) == -1)
2576 goto formatError; 2621 goto formatError;
2577 // check cat-name format 2622 // check cat-name format
2578 if (memcmp(ch_tmp, "== Category: ", 13) != 0) 2623 if (memcmp(ch_tmp, "== Category: ", 13) != 0)
2579 goto formatError; 2624 goto formatError;
2580 if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " ==", 3) != 0) 2625 if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " ==", 3) != 0)
2581 goto formatError; 2626 goto formatError;
2582 // copy cat-name 2627 // copy cat-name
2583 curCat.assign(ch_tmp + 13, strlen(ch_tmp) - 1 - 16); 2628 curCat.assign(ch_tmp + 13, strlen(ch_tmp) - 1 - 16);
2584 2629
2585 do { 2630 do {
2586 // find beginning of next entry 2631 // find beginning of next entry
2587 do { 2632 do {
2588 tmp = fgetc(f); 2633 tmp = fgetc(f);
2589 } while (tmp == '\n' && tmp != EOF && tmp != '='); 2634 } while (tmp == '\n' && tmp != EOF && tmp != '=');
2590 if (tmp == EOF) 2635 if (tmp == EOF)
2591 break; 2636 break;
2592 if (tmp == '=') { 2637 if (tmp == '=') {
2593 fseek(f, -1, SEEK_CUR); 2638 fseek(f, -1, SEEK_CUR);
2594 break; 2639 break;
2595 } 2640 }
2596 // decrement filepos by one 2641 // decrement filepos by one
2597 fseek(f, -1, SEEK_CUR); 2642 fseek(f, -1, SEEK_CUR);
2598 // read desc-line 2643 // read desc-line
2599 if (getline(&ch_tmp, &ch_tmp_size, f) == -1) 2644 if (getline(&ch_tmp, &ch_tmp_size, f) == -1)
2600 goto formatError; 2645 goto formatError;
2601 // check desc-line format 2646 // check desc-line format
2602 if (memcmp(ch_tmp, "-- ", 3) != 0) 2647 if (memcmp(ch_tmp, "-- ", 3) != 0)
2603 goto formatError; 2648 goto formatError;
2604 if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " --", 3) != 0) 2649 if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " --", 3) != 0)
2605 goto formatError; 2650 goto formatError;
2606 // add desc-line 2651 // add desc-line
2607 currItem.desc.assign(ch_tmp + 3, strlen(ch_tmp) - 1 - 6); 2652 currItem.desc.assign(ch_tmp + 3, strlen(ch_tmp) - 1 - 6);
2608 2653
2609 // read username-line 2654 // read username-line
2610 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1) 2655 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1)
2611 goto formatError; 2656 goto formatError;
2612 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.name)) 2657 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.name))
2613 goto formatError; 2658 goto formatError;
2614 2659
2615 // read pw-line 2660 // read pw-line
2616 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1) 2661 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1)
2617 goto formatError; 2662 goto formatError;
2618 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.pw)) 2663 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.pw))
2619 goto formatError; 2664 goto formatError;
2620 2665
2621 // read comment-line 2666 // read comment-line
2622 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1) 2667 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1)
2623 goto formatError; 2668 goto formatError;
2624 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.comment)) 2669 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.comment))
2625 goto formatError; 2670 goto formatError;
2626 2671
2627 // read URL-line 2672 // read URL-line
2628 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1) 2673 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1)
2629 goto formatError; 2674 goto formatError;
2630 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.url)) 2675 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.url))
2631 goto formatError; 2676 goto formatError;
2632 2677
2633 // read launcher-line 2678 // read launcher-line
2634 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1) 2679 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1)
2635 goto formatError; 2680 goto formatError;
2636 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.launcher)) 2681 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.launcher))
2637 goto formatError; 2682 goto formatError;
2638 2683
2639 currItem.lockStat = true; 2684 currItem.lockStat = true;
2640 currItem.listViewPos = -1; 2685 currItem.listViewPos = -1;
2641 addEntry(curCat.c_str(), &currItem, true); 2686 addEntry(curCat.c_str(), &currItem, true);
2642 ++entriesRead; 2687 ++entriesRead;
2643 } while (1); 2688 } while (1);
2644 } while (1); 2689 } while (1);
2645 if (!entriesRead) 2690 if (!entriesRead)
2646 goto formatError; 2691 goto formatError;
2647 2692
2648 free(ch_tmp); 2693 free(ch_tmp);
2649 fclose(f); 2694 fclose(f);
2650 flagDirty(); 2695 flagDirty();
2651 return e_success; 2696 return e_success;
2652 2697
2653 formatError: 2698 formatError:
2654 free(ch_tmp); 2699 free(ch_tmp);
2655 fclose(f); 2700 fclose(f);
2656 return e_fileFormat; 2701 return e_fileFormat;
2657#else 2702#else
2658 PWM_ASSERT(file); 2703 PWM_ASSERT(file);
2659 QFile f(file->latin1()); 2704 QFile f(file->latin1());
2660 int tmp; 2705 int tmp;
2661 ssize_t ret; 2706 ssize_t ret;
2662 string curCat; 2707 string curCat;
2663 unsigned int entriesRead = 0; 2708 unsigned int entriesRead = 0;
2664 PwMDataItem currItem; 2709 PwMDataItem currItem;
2665 bool res = f.open(IO_ReadOnly); 2710 bool res = f.open(IO_ReadOnly);
2666 if (res == false) 2711 if (res == false)
2667 return e_openFile; 2712 return e_openFile;
2668 2713
2669 unsigned int ch_tmp_size = 1024; 2714 unsigned int ch_tmp_size = 1024;
2670 char *ch_tmp = (char*)malloc(ch_tmp_size); 2715 char *ch_tmp = (char*)malloc(ch_tmp_size);
2671 if (!ch_tmp) { 2716 if (!ch_tmp) {
2672 f.close(); 2717 f.close();
2673 return e_outOfMem; 2718 return e_outOfMem;
2674 } 2719 }
2675 2720
2676 // - check header 2721 // - check header
2677 if (f.readLine(ch_tmp, ch_tmp_size) == -1) // skip first line. 2722 if (f.readLine(ch_tmp, ch_tmp_size) == -1) // skip first line.
2678 goto formatError; 2723 goto formatError;
2679 2724
2680 //US read fileversion first, then check if ok. 2725 //US read fileversion first, then check if ok.
2681 if (f.readLine(ch_tmp, ch_tmp_size) == -1) 2726 if (f.readLine(ch_tmp, ch_tmp_size) == -1)
2682 goto formatError; 2727 goto formatError;
2683 2728
2684 // check version-string and return version in "ch_tmp". 2729 // check version-string and return version in "ch_tmp".
2685 //US if (fscanf(f, "PwM v%s", ch_tmp) != 1) { 2730 //US if (fscanf(f, "PwM v%s", ch_tmp) != 1) {
2686 //US // header not recognized as PwM generated header 2731 //US // header not recognized as PwM generated header
2687 //US goto formatError; 2732 //US goto formatError;
2688 //US} 2733 //US}
2689 //US set filepointer behind version-string-line previously checked 2734 //US set filepointer behind version-string-line previously checked
2690 //US if (f.readLine(ch_tmp, ch_tmp_size) == -1) 2735 //US if (f.readLine(ch_tmp, ch_tmp_size) == -1)
2691 //US goto formatError; 2736 //US goto formatError;
2692 // skip next line containing the build-date 2737 // skip next line containing the build-date
2693 if (f.readLine(ch_tmp, ch_tmp_size) == -1) 2738 if (f.readLine(ch_tmp, ch_tmp_size) == -1)
2694 goto formatError; 2739 goto formatError;
2695 // read header termination line 2740 // read header termination line
2696 if (f.readLine(ch_tmp, ch_tmp_size) == -1) 2741 if (f.readLine(ch_tmp, ch_tmp_size) == -1)
2697 goto formatError; 2742 goto formatError;
2698 if (strcmp(ch_tmp, "==============================\n")) 2743 if (strcmp(ch_tmp, "==============================\n"))
2699 goto formatError; 2744 goto formatError;
2700 2745
2701 // - read entries 2746 // - read entries
2702 do { 2747 do {
2703 // find beginning of next category 2748 // find beginning of next category
2704 do { 2749 do {
2705 tmp = f.getch(); 2750 tmp = f.getch();
2706 } while (tmp == '\n' && tmp != EOF); 2751 } while (tmp == '\n' && tmp != EOF);
2707 if (tmp == EOF) 2752 if (tmp == EOF)
2708 break; 2753 break;
2709 2754
2710 // decrement filepos by one 2755 // decrement filepos by one
2711 f.at(f.at()-1); 2756 f.at(f.at()-1);
2712 // read cat-name 2757 // read cat-name
2713 if (f.readLine(ch_tmp, ch_tmp_size) == -1) 2758 if (f.readLine(ch_tmp, ch_tmp_size) == -1)
2714 goto formatError; 2759 goto formatError;
2715 // check cat-name format 2760 // check cat-name format
2716 if (memcmp(ch_tmp, "== Category: ", 13) != 0) 2761 if (memcmp(ch_tmp, "== Category: ", 13) != 0)
2717 goto formatError; 2762 goto formatError;
2718 if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " ==", 3) != 0) 2763 if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " ==", 3) != 0)
2719 goto formatError; 2764 goto formatError;
2720 // copy cat-name 2765 // copy cat-name
2721 curCat.assign(ch_tmp + 13, strlen(ch_tmp) - 1 - 16); 2766 curCat.assign(ch_tmp + 13, strlen(ch_tmp) - 1 - 16);
2722 2767
2723 do { 2768 do {
2724 // find beginning of next entry 2769 // find beginning of next entry
2725 do { 2770 do {
2726 tmp = f.getch(); 2771 tmp = f.getch();
2727 } while (tmp == '\n' && tmp != EOF && tmp != '='); 2772 } while (tmp == '\n' && tmp != EOF && tmp != '=');
2728 if (tmp == EOF) 2773 if (tmp == EOF)
2729 break; 2774 break;
2730 if (tmp == '=') { 2775 if (tmp == '=') {
2731 f.at(f.at()-1); 2776 f.at(f.at()-1);
2732 break; 2777 break;
2733 } 2778 }
2734 // decrement filepos by one 2779 // decrement filepos by one
2735 f.at(f.at()-1); 2780 f.at(f.at()-1);
2736 // read desc-line 2781 // read desc-line
2737 if (f.readLine(ch_tmp, ch_tmp_size) == -1) 2782 if (f.readLine(ch_tmp, ch_tmp_size) == -1)
2738 goto formatError; 2783 goto formatError;
2739 // check desc-line format 2784 // check desc-line format
2740 if (memcmp(ch_tmp, "-- ", 3) != 0) 2785 if (memcmp(ch_tmp, "-- ", 3) != 0)
2741 goto formatError; 2786 goto formatError;
2742 if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " --", 3) != 0) 2787 if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " --", 3) != 0)
2743 goto formatError; 2788 goto formatError;
2744 // add desc-line 2789 // add desc-line
2745 currItem.desc.assign(ch_tmp + 3, strlen(ch_tmp) - 1 - 6); 2790 currItem.desc.assign(ch_tmp + 3, strlen(ch_tmp) - 1 - 6);
2746 2791
2747 // read username-line 2792 // read username-line
2748 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1) 2793 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1)
2749 goto formatError; 2794 goto formatError;
2750 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.name)) 2795 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.name))
2751 goto formatError; 2796 goto formatError;
2752 2797
2753 // read pw-line 2798 // read pw-line
2754 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1) 2799 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1)
2755 goto formatError; 2800 goto formatError;
2756 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.pw)) 2801 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.pw))
2757 goto formatError; 2802 goto formatError;
2758 2803
2759 // read comment-line 2804 // read comment-line
2760 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1) 2805 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1)
2761 goto formatError; 2806 goto formatError;
2762 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.comment)) 2807 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.comment))
2763 goto formatError; 2808 goto formatError;
2764 2809
2765 // read URL-line 2810 // read URL-line
2766 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1) 2811 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1)
2767 goto formatError; 2812 goto formatError;
2768 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.url)) 2813 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.url))
2769 goto formatError; 2814 goto formatError;
2770 2815
2771 // read launcher-line 2816 // read launcher-line
2772 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1) 2817 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1)
2773 goto formatError; 2818 goto formatError;
2774 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.launcher)) 2819 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.launcher))
2775 goto formatError; 2820 goto formatError;
2776 2821
2777 currItem.lockStat = true; 2822 currItem.lockStat = true;
2778 currItem.listViewPos = -1; 2823 currItem.listViewPos = -1;
2779 addEntry(curCat.c_str(), &currItem, true); 2824 addEntry(curCat.c_str(), &currItem, true);
2780 ++entriesRead; 2825 ++entriesRead;
2781 } while (1); 2826 } while (1);
2782 } while (1); 2827 } while (1);
2783 if (!entriesRead) 2828 if (!entriesRead)
2784 goto formatError; 2829 goto formatError;
2785 2830
2786 free(ch_tmp); 2831 free(ch_tmp);
2787 f.close(); 2832 f.close();
2788 flagDirty(); 2833 flagDirty();
2789 return e_success; 2834 return e_success;
2790 2835
2791 formatError: 2836 formatError:
2792 free(ch_tmp); 2837 free(ch_tmp);
2793 f.close(); 2838 f.close();
2794 return e_fileFormat; 2839 return e_fileFormat;
2795 2840
2796#endif 2841#endif
2797 2842
2798} 2843}
2799 2844
2800bool PwMDoc::textExtractEntry_PwM(const char *in, ssize_t in_size, string *out) 2845bool PwMDoc::textExtractEntry_PwM(const char *in, ssize_t in_size, string *out)
2801{ 2846{
2802 PWM_ASSERT(in && out); 2847 PWM_ASSERT(in && out);
2803 ssize_t i = 0, len = in_size - 1; 2848 ssize_t i = 0, len = in_size - 1;
2804 while (i < len) { 2849 while (i < len) {
2805 if (in[i] == ':') 2850 if (in[i] == ':')
2806 break; 2851 break;
2807 ++i; 2852 ++i;
2808 } 2853 }
2809 i += 2; 2854 i += 2;
2810 *out = ""; 2855 *out = "";
2811 out->append(in + i, in_size - i - 1); 2856 out->append(in + i, in_size - i - 1);
2812 return true; 2857 return true;
2813} 2858}
2814 2859
2815PwMerror PwMDoc::exportToGpasman(const QString *file) 2860PwMerror PwMDoc::exportToGpasman(const QString *file)
2816{ 2861{
2817 PWM_ASSERT(file); 2862 PWM_ASSERT(file);
2818 GpasmanFile gp; 2863 GpasmanFile gp;
2819 int ret; 2864 int ret;
2820 2865
2821 if (!unlockAll_tempoary()) 2866 if (!unlockAll_tempoary())
2822 return e_lock; 2867 return e_lock;
2823 2868
2824 QString gpmPassword; 2869 QString gpmPassword;
2825 while (1) { 2870 while (1) {
2826 gpmPassword = requestNewMpw(0); 2871 gpmPassword = requestNewMpw(0);
2827 if (gpmPassword == "") { 2872 if (gpmPassword == "") {
2828 unlockAll_tempoary(true); 2873 unlockAll_tempoary(true);
2829 return e_noPw; 2874 return e_noPw;
2830 } 2875 }
2831 if (gpmPassword.length() < 4) { 2876 if (gpmPassword.length() < 4) {
2832 gpmPwLenErrMsgBox(); 2877 gpmPwLenErrMsgBox();
2833 } else { 2878 } else {
2834 break; 2879 break;
2835 } 2880 }
2836 } 2881 }
2837 2882
2838 ret = gp.save_init(file->latin1(), gpmPassword.latin1()); 2883 ret = gp.save_init(file->latin1(), gpmPassword.latin1());
2839 if (ret != 1) { 2884 if (ret != 1) {
2840 unlockAll_tempoary(true); 2885 unlockAll_tempoary(true);
2841 return e_accessFile; 2886 return e_accessFile;
2842 } 2887 }
2843 2888
2844 char *entry[4]; 2889 char *entry[4];
2845 unsigned int numCat = numCategories(), i; 2890 unsigned int numCat = numCategories(), i;
2846 unsigned int numEntr, j; 2891 unsigned int numEntr, j;
2847 int descLen, nameLen, pwLen, commentLen; 2892 int descLen, nameLen, pwLen, commentLen;
2848 for (i = 0; i < numCat; ++i) { 2893 for (i = 0; i < numCat; ++i) {
2849 numEntr = numEntries(i); 2894 numEntr = numEntries(i);
2850 for (j = 0; j < numEntr; ++j) { 2895 for (j = 0; j < numEntr; ++j) {
2851 descLen = dti.dta[i].d[j].desc.length(); 2896 descLen = dti.dta[i].d[j].desc.length();
2852 nameLen = dti.dta[i].d[j].name.length(); 2897 nameLen = dti.dta[i].d[j].name.length();
2853 pwLen = dti.dta[i].d[j].pw.length(); 2898 pwLen = dti.dta[i].d[j].pw.length();
2854 commentLen = dti.dta[i].d[j].comment.length(); 2899 commentLen = dti.dta[i].d[j].comment.length();
2855 entry[0] = new char[descLen + 1]; 2900 entry[0] = new char[descLen + 1];
2856 entry[1] = new char[nameLen + 1]; 2901 entry[1] = new char[nameLen + 1];
2857 entry[2] = new char[pwLen + 1]; 2902 entry[2] = new char[pwLen + 1];
2858 entry[3] = new char[commentLen + 1]; 2903 entry[3] = new char[commentLen + 1];
2859 strcpy(entry[0], descLen == 0 ? " " : dti.dta[i].d[j].desc.c_str()); 2904 strcpy(entry[0], descLen == 0 ? " " : dti.dta[i].d[j].desc.c_str());
2860 strcpy(entry[1], nameLen == 0 ? " " : dti.dta[i].d[j].name.c_str()); 2905 strcpy(entry[1], nameLen == 0 ? " " : dti.dta[i].d[j].name.c_str());
2861 strcpy(entry[2], pwLen == 0 ? " " : dti.dta[i].d[j].pw.c_str()); 2906 strcpy(entry[2], pwLen == 0 ? " " : dti.dta[i].d[j].pw.c_str());
2862 strcpy(entry[3], commentLen == 0 ? " " : dti.dta[i].d[j].comment.c_str()); 2907 strcpy(entry[3], commentLen == 0 ? " " : dti.dta[i].d[j].comment.c_str());
2863 entry[0][descLen == 0 ? descLen + 1 : descLen] = '\0'; 2908 entry[0][descLen == 0 ? descLen + 1 : descLen] = '\0';
2864 entry[1][nameLen == 0 ? nameLen + 1 : nameLen] = '\0'; 2909 entry[1][nameLen == 0 ? nameLen + 1 : nameLen] = '\0';
2865 entry[2][pwLen == 0 ? pwLen + 1 : pwLen] = '\0'; 2910 entry[2][pwLen == 0 ? pwLen + 1 : pwLen] = '\0';
2866 entry[3][commentLen == 0 ? commentLen + 1 : commentLen] = '\0'; 2911 entry[3][commentLen == 0 ? commentLen + 1 : commentLen] = '\0';
2867 2912
2868 ret = gp.save_entry(entry); 2913 ret = gp.save_entry(entry);
2869 if (ret == -1){ 2914 if (ret == -1){
2870 delete [] entry[0]; 2915 delete [] entry[0];
2871 delete [] entry[1]; 2916 delete [] entry[1];
2872 delete [] entry[2]; 2917 delete [] entry[2];
2873 delete [] entry[3]; 2918 delete [] entry[3];
2874 gp.save_finalize(); 2919 gp.save_finalize();
2875 unlockAll_tempoary(true); 2920 unlockAll_tempoary(true);
2876 return e_writeFile; 2921 return e_writeFile;
2877 } 2922 }
2878 2923
2879 delete [] entry[0]; 2924 delete [] entry[0];
2880 delete [] entry[1]; 2925 delete [] entry[1];
2881 delete [] entry[2]; 2926 delete [] entry[2];
2882 delete [] entry[3]; 2927 delete [] entry[3];
2883 } 2928 }
2884 } 2929 }
2885 unlockAll_tempoary(true); 2930 unlockAll_tempoary(true);
2886 if (gp.save_finalize() == -1) 2931 if (gp.save_finalize() == -1)
2887 return e_writeFile; 2932 return e_writeFile;
2888 2933
2889 return e_success; 2934 return e_success;
2890} 2935}
2891 2936
2892PwMerror PwMDoc::importFromGpasman(const QString *file) 2937PwMerror PwMDoc::importFromGpasman(const QString *file)
2893{ 2938{
2894 PWM_ASSERT(file); 2939 PWM_ASSERT(file);
2895 QString pw = requestMpw(false); 2940 QString pw = requestMpw(false);
2896 if (pw == "") 2941 if (pw == "")
2897 return e_noPw; 2942 return e_noPw;
2898 GpasmanFile gp; 2943 GpasmanFile gp;
2899 int ret, i; 2944 int ret, i;
2900 PwMerror ret2; 2945 PwMerror ret2;
2901 char *entry[4]; 2946 char *entry[4];
2902 PwMDataItem tmpData; 2947 PwMDataItem tmpData;
2903 ret = gp.load_init(file->latin1(), pw.latin1()); 2948 ret = gp.load_init(file->latin1(), pw.latin1());
2904 if (ret != 1) 2949 if (ret != 1)
2905 return e_accessFile; 2950 return e_accessFile;
2906 2951
2907 do { 2952 do {
2908 ret = gp.load_entry(entry); 2953 ret = gp.load_entry(entry);
2909 if(ret != 1) 2954 if(ret != 1)
2910 break; 2955 break;
2911 tmpData.desc = entry[0]; 2956 tmpData.desc = entry[0];
2912 tmpData.name = entry[1]; 2957 tmpData.name = entry[1];
2913 tmpData.pw = entry[2]; 2958 tmpData.pw = entry[2];
2914 tmpData.comment = entry[3]; 2959 tmpData.comment = entry[3];
2915 tmpData.lockStat = true; 2960 tmpData.lockStat = true;
2916 tmpData.listViewPos = -1; 2961 tmpData.listViewPos = -1;
2917 ret2 = addEntry(DEFAULT_CATEGORY, &tmpData, true); 2962 ret2 = addEntry(DEFAULT_CATEGORY, &tmpData, true);
2918 for (i = 0; i < 4; ++i) 2963 for (i = 0; i < 4; ++i)
2919 free(entry[i]); 2964 free(entry[i]);
2920 if (ret2 == e_maxAllowedEntr) { 2965 if (ret2 == e_maxAllowedEntr) {
2921 gp.load_finalize(); 2966 gp.load_finalize();
2922 return e_maxAllowedEntr; 2967 return e_maxAllowedEntr;
2923 } 2968 }
2924 } while (1); 2969 } while (1);
2925 gp.load_finalize(); 2970 gp.load_finalize();
2926 if (isDocEmpty()) 2971 if (isDocEmpty())
2927 return e_wrongPw; // we assume this. 2972 return e_wrongPw; // we assume this.
2928 2973
2929 flagDirty(); 2974 flagDirty();
2930 return e_success; 2975 return e_success;
2931} 2976}
2932 2977
2933 2978
2934//US: we use the stl sort algorythm to sort all elements in the order 2979//US: we use the stl sort algorythm to sort all elements in the order
2935//of its listViewPos (in the order 1,2,3,5,...,x,-1, -1, -1 2980//of its listViewPos (in the order 1,2,3,5,...,x,-1, -1, -1
2936struct PwMDataItemListViewPosSort 2981struct PwMDataItemListViewPosSort
2937{ 2982{
2938 bool operator()(PwMDataItem* rpStart, PwMDataItem* rpEnd) 2983 bool operator()(PwMDataItem* rpStart, PwMDataItem* rpEnd)
2939 { 2984 {
2940 //qDebug("pwMDoc::PwMDataItemListViewPosSort()"); 2985 //qDebug("pwMDoc::PwMDataItemListViewPosSort()");
2941 if ((rpEnd)->listViewPos < 0) 2986 if ((rpEnd)->listViewPos < 0)
2942 return false; 2987 return false;
2943 else 2988 else
2944 return (rpStart)->listViewPos < (rpEnd)->listViewPos; 2989 return (rpStart)->listViewPos < (rpEnd)->listViewPos;
2945 } 2990 }
2946}; 2991};
2947 2992
2948void PwMDoc::ensureLvp() 2993void PwMDoc::ensureLvp()
2949{ 2994{
2950 if (isDocEmpty()) 2995 if (isDocEmpty())
2951 return; 2996 return;
2952 2997
2953 //US ENH BUG: when using syncronizing, this way of sorting 2998 //US ENH BUG: when using syncronizing, this way of sorting
2954 //is not sufficient, because there might be empty spaces 2999 //is not sufficient, because there might be empty spaces
2955 // at the beginning. But the old algorythm only can add elements 3000 // at the beginning. But the old algorythm only can add elements
2956 //to the end.The result are crashes because of list overflows 3001 //to the end.The result are crashes because of list overflows
2957 //we need something to fill all gaps. 3002 //we need something to fill all gaps.
2958 vector<PwMDataItem*> sorted; 3003 vector<PwMDataItem*> sorted;
2959 vector< PwMDataItem*>::iterator sortedBegin, 3004 vector< PwMDataItem*>::iterator sortedBegin,
2960 sortedEnd, 3005 sortedEnd,
2961 sortedI; 3006 sortedI;
2962 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 3007 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
2963 catEnd = dti.dta.end(), 3008 catEnd = dti.dta.end(),
2964 catI = catBegin; 3009 catI = catBegin;
2965 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 3010 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
2966 int lvpTop, tmpLvp; 3011 int lvpTop, tmpLvp;
2967 3012
2968 //qDebug("collect:"); 3013 //qDebug("collect:");
2969 3014
2970 while (catI != catEnd) { 3015 while (catI != catEnd) {
2971 lvpTop = -1; 3016 lvpTop = -1;
2972 sorted.clear(); 3017 sorted.clear();
2973 3018
2974 entrBegin = catI->d.begin(); 3019 entrBegin = catI->d.begin();
2975 entrEnd = catI->d.end(); 3020 entrEnd = catI->d.end();
2976 entrI = entrBegin; 3021 entrI = entrBegin;
2977 3022
2978 //US: we use the stl sort algorythm to sort all elements in the order 3023 //US: we use the stl sort algorythm to sort all elements in the order
2979 //of its listViewPos (in the order 1,2,2,3,5,...,x,-1, -1, -1 3024 //of its listViewPos (in the order 1,2,2,3,5,...,x,-1, -1, -1
2980 while (entrI != entrEnd) { 3025 while (entrI != entrEnd) {
2981 //qDebug("found: %s, pos=%i", (*entrI).desc.c_str(), (*entrI).listViewPos); 3026 //qDebug("found: %s, pos=%i", (*entrI).desc.c_str(), (*entrI).listViewPos);
2982 sorted.push_back((PwMDataItem*)&(*entrI)); 3027 sorted.push_back((PwMDataItem*)&(*entrI));
2983 ++entrI; 3028 ++entrI;
2984 } 3029 }
2985 3030
2986 sortedBegin = sorted.begin(); 3031 sortedBegin = sorted.begin();
2987 sortedEnd = sorted.end(); 3032 sortedEnd = sorted.end();
2988 3033
2989 sort(sortedBegin, sortedEnd, PwMDataItemListViewPosSort()); 3034 sort(sortedBegin, sortedEnd, PwMDataItemListViewPosSort());
2990 3035
2991 // qDebug("resort:"); 3036 // qDebug("resort:");
2992 //now we have all sorted in a collection 3037 //now we have all sorted in a collection
2993 //Now start with the sorted and reset listviewpos. 3038 //Now start with the sorted and reset listviewpos.
2994 sortedBegin = sorted.begin(); 3039 sortedBegin = sorted.begin();
2995 sortedEnd = sorted.end(); 3040 sortedEnd = sorted.end();
2996 sortedI = sortedBegin; 3041 sortedI = sortedBegin;
2997 3042
2998 while (sortedI != sortedEnd) { 3043 while (sortedI != sortedEnd) {
2999 // qDebug("reset defined: %s, from pos=%i to pos=%i", (*sortedI)->desc.c_str(), (*sortedI)->listViewPos, lvpTop+1); 3044 // qDebug("reset defined: %s, from pos=%i to pos=%i", (*sortedI)->desc.c_str(), (*sortedI)->listViewPos, lvpTop+1);
3000 (*sortedI)->listViewPos = ++lvpTop; 3045 (*sortedI)->listViewPos = ++lvpTop;
3001 ++sortedI; 3046 ++sortedI;
3002 } 3047 }
3003 3048
3004 /*/debug 3049 /*/debug
3005 entrBegin = catI->d.begin(); 3050 entrBegin = catI->d.begin();
3006 entrEnd = catI->d.end(); 3051 entrEnd = catI->d.end();
3007 entrI = entrBegin; 3052 entrI = entrBegin;
3008 3053
3009 while (entrI != entrEnd) { 3054 while (entrI != entrEnd) {
3010 qDebug("check: %s, pos=%i", (*entrI).desc.c_str(), (*entrI).listViewPos); 3055 qDebug("check: %s, pos=%i", (*entrI).desc.c_str(), (*entrI).listViewPos);
3011 ++entrI; 3056 ++entrI;
3012 } 3057 }
3013 */ 3058 */
3014 3059
3015 ++catI; 3060 ++catI;
3016 } 3061 }
3017} 3062}
3018 3063
3019QString PwMDoc::getTitle() 3064QString PwMDoc::getTitle()
3020{ 3065{
3021 /* NOTE: We have to ensure, that the returned title 3066 /* NOTE: We have to ensure, that the returned title
3022 * is unique and not reused somewhere else while 3067 * is unique and not reused somewhere else while
3023 * this document is valid (open). 3068 * this document is valid (open).
3024 */ 3069 */
3025 QString title(getFilename()); 3070 QString title(getFilename());
3026 3071
3027 //US ENH: The whole filename on PDAs is too long. So use only the last characters 3072 //US ENH: The whole filename on PDAs is too long. So use only the last characters
3028 if (QApplication::desktop()->width() < 640) 3073 if (QApplication::desktop()->width() < 640)
3029 { 3074 {
3030 if (title.length() > 30) 3075 if (title.length() > 30)
3031 title = "..." + title.right(30); 3076 title = "..." + title.right(30);
3032 3077
3033 } 3078 }
3034 3079
3035 3080
3036 if (title.isEmpty()) { 3081 if (title.isEmpty()) {
3037 if (unnamedNum == 0) { 3082 if (unnamedNum == 0) {
3038 unnamedNum = PwMDocList::getNewUnnamedNumber(); 3083 unnamedNum = PwMDocList::getNewUnnamedNumber();
3039 PWM_ASSERT(unnamedNum != 0); 3084 PWM_ASSERT(unnamedNum != 0);
3040 } 3085 }
3041 title = DEFAULT_TITLE; 3086 title = DEFAULT_TITLE;
3042 title += " "; 3087 title += " ";
3043 title += tostr(unnamedNum).c_str(); 3088 title += tostr(unnamedNum).c_str();
3044 } 3089 }
3045 return title; 3090 return title;
3046} 3091}
3047 3092
3048bool PwMDoc::tryDelete() 3093bool PwMDoc::tryDelete()
3049{ 3094{
3050 3095
3051 if (deleted) 3096 if (deleted)
3052 return true; 3097 return true;
3053 int ret; 3098 int ret;
3054 if (isDirty()) { 3099 if (isDirty()) {
3055 ret = dirtyAskSave(getTitle()); 3100 ret = dirtyAskSave(getTitle());
3056 if (ret == 0) { // save to disk 3101 if (ret == 0) { // save to disk
3057 if (!saveDocUi(this)) 3102 if (!saveDocUi(this))
3058 goto out_ignore; 3103 goto out_ignore;
3059 } else if (ret == 1) { // don't save and delete 3104 } else if (ret == 1) { // don't save and delete
3060 goto out_accept; 3105 goto out_accept;
3061 } else { // cancel operation 3106 } else { // cancel operation
3062 goto out_ignore; 3107 goto out_ignore;
3063 } 3108 }
3064 } 3109 }
3065out_accept: 3110out_accept:
3066 deleted = true; 3111 deleted = true;
3067 delete this; 3112 delete this;
3068 return true; 3113 return true;
3069out_ignore: 3114out_ignore:
3070 return false; 3115 return false;
3071} 3116}
3072 3117
3073 3118
3074 3119
3075#ifdef PWM_EMBEDDED 3120#ifdef PWM_EMBEDDED
3076//US ENH: this is the magic function that syncronizes the this doc with the remote doc 3121//US ENH: this is the magic function that syncronizes the this doc with the remote doc
3077//US it could have been defined as static, but I did not want to. 3122//US it could have been defined as static, but I did not want to.
3078PwMerror PwMDoc::syncronize(KSyncManager* manager, PwMDoc* syncLocal , PwMDoc* syncRemote, int mode ) 3123PwMerror PwMDoc::syncronize(KSyncManager* manager, PwMDoc* syncLocal , PwMDoc* syncRemote, int mode )
3079{ 3124{
3080 int addedPasswordsLocal = 0; 3125 int addedPasswordsLocal = 0;
3081 int addedPasswordsRemote = 0; 3126 int addedPasswordsRemote = 0;
3082 int deletedPasswordsRemote = 0; 3127 int deletedPasswordsRemote = 0;
3083 int deletedPasswordsLocal = 0; 3128 int deletedPasswordsLocal = 0;
3084 int changedLocal = 0; 3129 int changedLocal = 0;
3085 int changedRemote = 0; 3130 int changedRemote = 0;
3086 3131
3087 PwMSyncItem* syncItemLocal; 3132 PwMSyncItem* syncItemLocal;
3088 PwMSyncItem* syncItemRemote; 3133 PwMSyncItem* syncItemRemote;
3089 3134
3090 QString mCurrentSyncName = manager->getCurrentSyncName(); 3135 QString mCurrentSyncName = manager->getCurrentSyncName();
3091 QString mCurrentSyncDevice = manager->getCurrentSyncDevice(); 3136 QString mCurrentSyncDevice = manager->getCurrentSyncDevice();
3092 3137
3093 bool mSyncLauncher = true; 3138 bool mSyncLauncher = true;
3094 3139
3095 bool fullDateRange = false; 3140 bool fullDateRange = false;
3096 int take; 3141 int take;
3097 // local->resetTempSyncStat(); 3142 // local->resetTempSyncStat();
3098 QDateTime mLastSync = QDateTime::currentDateTime(); 3143 QDateTime mLastSync = QDateTime::currentDateTime();
3099 QDateTime modifiedSync = mLastSync; 3144 QDateTime modifiedSync = mLastSync;
3100 3145
3101 unsigned int index; 3146 unsigned int index;
3102 //Step 1. Find syncinfo in Local file and create if not existent. 3147 //Step 1. Find syncinfo in Local file and create if not existent.
3103 bool found = syncLocal->findSyncData(mCurrentSyncDevice, &index); 3148 bool found = syncLocal->findSyncData(mCurrentSyncDevice, &index);
3104 if (found == false) 3149 if (found == false)
3105 { 3150 {
3106 PwMSyncItem newSyncItemLocal; 3151 PwMSyncItem newSyncItemLocal;
3107 newSyncItemLocal.syncName = mCurrentSyncDevice.latin1(); 3152 newSyncItemLocal.syncName = mCurrentSyncDevice.latin1();
3108 newSyncItemLocal.lastSyncDate = mLastSync; 3153 newSyncItemLocal.lastSyncDate = mLastSync;
3109 syncLocal->addSyncDataEntry(&newSyncItemLocal, true); 3154 syncLocal->addSyncDataEntry(&newSyncItemLocal, true);
3110 found = syncLocal->findSyncData(mCurrentSyncDevice, &index); 3155 found = syncLocal->findSyncData(mCurrentSyncDevice, &index);
3111 if (found == false) { 3156 if (found == false) {
3112 qDebug("PwMDoc::syncronize : newly created local sync data could not be found"); 3157 qDebug("PwMDoc::syncronize : newly created local sync data could not be found");
3113 return e_syncError; 3158 return e_syncError;
3114 } 3159 }
3115 } 3160 }
3116 3161
3117 syncItemLocal = syncLocal->getSyncDataEntry(index); 3162 syncItemLocal = syncLocal->getSyncDataEntry(index);
3118 qDebug("Last Sync Local %s ", syncItemLocal->lastSyncDate.toString().latin1()); 3163 qDebug("Last Sync Local %s ", syncItemLocal->lastSyncDate.toString().latin1());
3119 3164
3120 //Step 2. Find syncinfo in remote file and create if not existent. 3165 //Step 2. Find syncinfo in remote file and create if not existent.
3121 found = syncRemote->findSyncData(mCurrentSyncName, &index); 3166 found = syncRemote->findSyncData(mCurrentSyncName, &index);
3122 if (found == false) 3167 if (found == false)
3123 { 3168 {
3124 qDebug("FULLDATE 1"); 3169 qDebug("FULLDATE 1");
3125 fullDateRange = true; 3170 fullDateRange = true;
3126 PwMSyncItem newSyncItemRemote; 3171 PwMSyncItem newSyncItemRemote;
3127 newSyncItemRemote.syncName = mCurrentSyncName.latin1(); 3172 newSyncItemRemote.syncName = mCurrentSyncName.latin1();
3128 newSyncItemRemote.lastSyncDate = mLastSync; 3173 newSyncItemRemote.lastSyncDate = mLastSync;
3129 syncRemote->addSyncDataEntry(&newSyncItemRemote, true); 3174 syncRemote->addSyncDataEntry(&newSyncItemRemote, true);
3130 found = syncRemote->findSyncData(mCurrentSyncName, &index); 3175 found = syncRemote->findSyncData(mCurrentSyncName, &index);
3131 if (found == false) { 3176 if (found == false) {
3132 qDebug("PwMDoc::syncronize : newly created remote sync data could not be found"); 3177 qDebug("PwMDoc::syncronize : newly created remote sync data could not be found");
3133 return e_syncError; 3178 return e_syncError;
3134 } 3179 }
3135 } 3180 }
3136 3181
3137 syncItemRemote = syncRemote->getSyncDataEntry(index); 3182 syncItemRemote = syncRemote->getSyncDataEntry(index);
3138 qDebug("Last Sync Remote %s ", syncItemRemote->lastSyncDate.toString().latin1()); 3183 qDebug("Last Sync Remote %s ", syncItemRemote->lastSyncDate.toString().latin1());
3139 //and remove the found entry here. We will reenter it later again. 3184 //and remove the found entry here. We will reenter it later again.
3140 //US syncRemote->delSyncDataEntry(index, true); 3185 //US syncRemote->delSyncDataEntry(index, true);
3141 3186
3142 3187
3143 if ( syncItemLocal->lastSyncDate == mLastSync ) { 3188 if ( syncItemLocal->lastSyncDate == mLastSync ) {
3144 qDebug("FULLDATE 2"); 3189 qDebug("FULLDATE 2");
3145 fullDateRange = true; 3190 fullDateRange = true;
3146 } 3191 }
3147 3192
3148 if ( ! fullDateRange ) { 3193 if ( ! fullDateRange ) {
3149 if ( syncItemLocal->lastSyncDate != syncItemRemote->lastSyncDate ) { 3194 if ( syncItemLocal->lastSyncDate != syncItemRemote->lastSyncDate ) {
3150 3195
3151 fullDateRange = true; 3196 fullDateRange = true;
3152 qDebug("FULLDATE 3 %s %s", syncItemLocal->lastSyncDate.toString().latin1() , syncItemRemote->lastSyncDate.toString().latin1() ); 3197 qDebug("FULLDATE 3 %s %s", syncItemLocal->lastSyncDate.toString().latin1() , syncItemRemote->lastSyncDate.toString().latin1() );
3153 } 3198 }
3154 } 3199 }
3155 // fullDateRange = true; // debug only! 3200 // fullDateRange = true; // debug only!
3156 if ( fullDateRange ) 3201 if ( fullDateRange )
3157 mLastSync = QDateTime::currentDateTime().addDays( -100*365); 3202 mLastSync = QDateTime::currentDateTime().addDays( -100*365);
3158 else 3203 else
3159 mLastSync = syncItemLocal->lastSyncDate; 3204 mLastSync = syncItemLocal->lastSyncDate;
3160 3205
3161 3206
3162 qDebug("*************************** "); 3207 qDebug("*************************** ");
3163 qDebug("mLastSync %s ",mLastSync.toString().latin1() ); 3208 qDebug("mLastSync %s ",mLastSync.toString().latin1() );
3164 QStringList er = syncRemote->getIDEntryList(); 3209 QStringList er = syncRemote->getIDEntryList();
3165 PwMDataItem* inRemote ;//= er.first(); 3210 PwMDataItem* inRemote ;//= er.first();
3166 PwMDataItem* inLocal; 3211 PwMDataItem* inLocal;
3167 unsigned int catLocal, indexLocal; 3212 unsigned int catLocal, indexLocal;
3168 unsigned int catRemote, indexRemote; 3213 unsigned int catRemote, indexRemote;
3169 3214
3170 QString uid; 3215 QString uid;
3171 manager->showProgressBar(0, i18n("Syncing - close to abort!"), er.count()); 3216 manager->showProgressBar(0, i18n("Syncing - close to abort!"), er.count());
3172 3217
3173 int modulo = (er.count()/10)+1; 3218 int modulo = (er.count()/10)+1;
3174 unsigned int incCounter = 0; 3219 unsigned int incCounter = 0;
3175 while ( incCounter < er.count()) { 3220 while ( incCounter < er.count()) {
3176 if (manager->isProgressBarCanceled()) 3221 if (manager->isProgressBarCanceled())
3177 return e_syncError; 3222 return e_syncError;
3178 if ( incCounter % modulo == 0 ) 3223 if ( incCounter % modulo == 0 )
3179 manager->showProgressBar(incCounter); 3224 manager->showProgressBar(incCounter);
3180 3225
3181 uid = er[ incCounter ]; 3226 uid = er[ incCounter ];
3182 qDebug("sync uid %s from remote file", uid.latin1()); 3227 qDebug("sync uid %s from remote file", uid.latin1());
3183 3228
3184 qApp->processEvents(); 3229 qApp->processEvents();
3185 3230
3186 inLocal = syncLocal->findEntryByID( uid, &catLocal, &indexLocal ); 3231 inLocal = syncLocal->findEntryByID( uid, &catLocal, &indexLocal );
3187 inRemote = syncRemote->findEntryByID( uid, &catRemote, &indexRemote ); 3232 inRemote = syncRemote->findEntryByID( uid, &catRemote, &indexRemote );
3188 PWM_ASSERT(inRemote); 3233 PWM_ASSERT(inRemote);
3189 if ( inLocal != 0 ) { // maybe conflict - same uid in both files 3234 if ( inLocal != 0 ) { // maybe conflict - same uid in both files
3190 if ( (take = takePwMDataItem( inLocal, inRemote, mLastSync, mode, fullDateRange) ) ) { 3235 if ( (take = takePwMDataItem( inLocal, inRemote, mLastSync, mode, fullDateRange) ) ) {
3191 qDebug("take %d %s ", take, inLocal->desc.c_str()); 3236 qDebug("take %d %s ", take, inLocal->desc.c_str());
3192 if ( take == 3 ) 3237 if ( take == 3 )
3193 return e_syncError; 3238 return e_syncError;
3194 if ( take == 1 ) {// take local 3239 if ( take == 1 ) {// take local
3195 inRemote->syncItem(*inLocal, mSyncLauncher); 3240 inRemote->syncItem(*inLocal, mSyncLauncher);
3196 ++changedRemote; 3241 ++changedRemote;
3197 } else { // take == 2 take remote 3242 } else { // take == 2 take remote
3198 inLocal->syncItem(*inRemote, mSyncLauncher); 3243 inLocal->syncItem(*inRemote, mSyncLauncher);
3199 ++changedLocal; 3244 ++changedLocal;
3200 } 3245 }
3201 } 3246 }
3202 } else { // no conflict 3247 } else { // no conflict
3203 if ( inRemote->meta.update > mLastSync || mode == 5 ) { 3248 if ( inRemote->meta.update > mLastSync || mode == 5 ) {
3204 inRemote->meta.update = modifiedSync; 3249 inRemote->meta.update = modifiedSync;
3205 3250
3206 //first check if we have a matching category in the local file 3251 //first check if we have a matching category in the local file
3207 const string* remotecat = syncRemote->getCategory(catRemote); 3252 const string* remotecat = syncRemote->getCategory(catRemote);
3208 syncLocal->addEntry(remotecat->c_str(), inRemote, true, false); 3253 syncLocal->addEntry(remotecat->c_str(), inRemote, true, false);
3209 3254
3210 ++addedPasswordsLocal; 3255 ++addedPasswordsLocal;
3211 } else { 3256 } else {
3212 // pending checkExternSyncAddressee(addresseeRSyncSharp, inR); 3257 // pending checkExternSyncAddressee(addresseeRSyncSharp, inR);
3213 syncRemote->delEntry(catRemote, indexRemote, true); 3258 syncRemote->delEntry(catRemote, indexRemote, true);
3214 ++deletedPasswordsRemote; 3259 ++deletedPasswordsRemote;
3215 } 3260 }
3216 } 3261 }
3217 3262
3218 ++incCounter; 3263 ++incCounter;
3219 } 3264 }
3220 3265
3221 3266
3222 er.clear(); 3267 er.clear();
3223 QStringList el = syncLocal->getIDEntryList(); 3268 QStringList el = syncLocal->getIDEntryList();
3224 modulo = (el.count()/10)+1; 3269 modulo = (el.count()/10)+1;
3225 3270
3226 manager->showProgressBar(0, i18n("Add / remove addressees"), el.count()); 3271 manager->showProgressBar(0, i18n("Add / remove addressees"), el.count());
3227 incCounter = 0; 3272 incCounter = 0;
3228 while ( incCounter < el.count()) { 3273 while ( incCounter < el.count()) {
3229 qApp->processEvents(); 3274 qApp->processEvents();
3230 if (manager->isProgressBarCanceled()) 3275 if (manager->isProgressBarCanceled())
3231 return e_syncError; 3276 return e_syncError;
3232 if ( incCounter % modulo == 0 ) 3277 if ( incCounter % modulo == 0 )
3233 manager->showProgressBar(incCounter); 3278 manager->showProgressBar(incCounter);
3234 uid = el[ incCounter ]; 3279 uid = el[ incCounter ];
3235 qDebug("sync uid %s from local file", uid.latin1()); 3280 qDebug("sync uid %s from local file", uid.latin1());
3236 3281
3237 inLocal = syncLocal->findEntryByID( uid, &catLocal, &indexLocal ); 3282 inLocal = syncLocal->findEntryByID( uid, &catLocal, &indexLocal );
3238 inRemote = syncRemote->findEntryByID( uid, &catRemote, &indexRemote ); 3283 inRemote = syncRemote->findEntryByID( uid, &catRemote, &indexRemote );
3239 PWM_ASSERT(inLocal); 3284 PWM_ASSERT(inLocal);
3240 3285
3241 if ( inRemote == 0 ) { 3286 if ( inRemote == 0 ) {
3242 if ( inLocal->meta.update < mLastSync && mode != 4 ) { 3287 if ( inLocal->meta.update < mLastSync && mode != 4 ) {
3243 // pending checkExternSyncAddressee(addresseeLSyncSharp, inL); 3288 // pending checkExternSyncAddressee(addresseeLSyncSharp, inL);
3244 syncLocal->delEntry(catLocal, indexLocal, true); 3289 syncLocal->delEntry(catLocal, indexLocal, true);
3245 ++deletedPasswordsLocal; 3290 ++deletedPasswordsLocal;
3246 } else { 3291 } else {
3247 if ( ! manager->mWriteBackExistingOnly ) { 3292 if ( ! manager->mWriteBackExistingOnly ) {
3248 ++addedPasswordsRemote; 3293 ++addedPasswordsRemote;
3249 inLocal->meta.update = modifiedSync; 3294 inLocal->meta.update = modifiedSync;
3250 3295
3251 //first check if we have a matching category in the remote file 3296 //first check if we have a matching category in the remote file
3252 const string* localcat = syncLocal->getCategory(catLocal); 3297 const string* localcat = syncLocal->getCategory(catLocal);
3253 3298
3254 PwMDataItem newEntry; 3299 PwMDataItem newEntry;
3255 newEntry = *inLocal; 3300 newEntry = *inLocal;
3256 inRemote = &newEntry; 3301 inRemote = &newEntry;
3257 3302
3258 //USsyncRemote->insertAddressee( inRemote, false ); 3303 //USsyncRemote->insertAddressee( inRemote, false );
3259 syncRemote->addEntry(localcat->c_str(), inRemote, true, false); 3304 syncRemote->addEntry(localcat->c_str(), inRemote, true, false);
3260 3305
3261 } 3306 }
3262 } 3307 }
3263 3308
3264 } 3309 }
3265 ++incCounter; 3310 ++incCounter;
3266 } 3311 }
3267 el.clear(); 3312 el.clear();
3268 manager->hideProgressBar(); 3313 manager->hideProgressBar();
3269 3314
3270 // Now write the info back into the sync data space of the files 3315 // Now write the info back into the sync data space of the files
3271 3316
3272 mLastSync = QDateTime::currentDateTime().addSecs( 1 ); 3317 mLastSync = QDateTime::currentDateTime().addSecs( 1 );
3273 // get rid of micro seconds 3318 // get rid of micro seconds
3274 QTime t = mLastSync.time(); 3319 QTime t = mLastSync.time();
3275 mLastSync.setTime( QTime (t.hour (), t.minute (), t.second () ) ); 3320 mLastSync.setTime( QTime (t.hour (), t.minute (), t.second () ) );
3276 3321
3277 3322
3278 syncItemLocal->lastSyncDate = mLastSync; 3323 syncItemLocal->lastSyncDate = mLastSync;
3279 syncItemRemote->lastSyncDate = mLastSync; 3324 syncItemRemote->lastSyncDate = mLastSync;
3280 3325
3281 QString mes; 3326 QString mes;
3282 mes .sprintf( i18n("Synchronization summary:\n\n %d items added to local\n %d items added to remote\n %d items updated on local\n %d items updated on remote\n %d items deleted on local\n %d items deleted on remote\n"),addedPasswordsLocal, addedPasswordsRemote, changedLocal, changedRemote, deletedPasswordsLocal, deletedPasswordsRemote ); 3327 mes .sprintf( i18n("Synchronization summary:\n\n %d items added to local\n %d items added to remote\n %d items updated on local\n %d items updated on remote\n %d items deleted on local\n %d items deleted on remote\n"),addedPasswordsLocal, addedPasswordsRemote, changedLocal, changedRemote, deletedPasswordsLocal, deletedPasswordsRemote );
3283 if ( manager->mShowSyncSummary ) { 3328 if ( manager->mShowSyncSummary ) {
3284 KMessageBox::information(0, mes, i18n("PWM/Pi Synchronization") ); 3329 KMessageBox::information(0, mes, i18n("PWM/Pi Synchronization") );
3285 } 3330 }
3286 qDebug( mes ); 3331 qDebug( mes );
3287 return e_success; 3332 return e_success;
3288} 3333}
3289 3334
3290 3335
3291int PwMDoc::takePwMDataItem( PwMDataItem* local, PwMDataItem* remote, QDateTime lastSync, int mode , bool full ) 3336int PwMDoc::takePwMDataItem( PwMDataItem* local, PwMDataItem* remote, QDateTime lastSync, int mode , bool full )
3292{ 3337{
3293 // 0 equal 3338 // 0 equal
3294 // 1 take local 3339 // 1 take local
3295 // 2 take remote 3340 // 2 take remote
3296 // 3 cancel 3341 // 3 cancel
3297 QDateTime localMod = local->meta.update; 3342 QDateTime localMod = local->meta.update;
3298 QDateTime remoteMod = remote->meta.update; 3343 QDateTime remoteMod = remote->meta.update;
3299 3344
3300 if ( localMod == remoteMod ) 3345 if ( localMod == remoteMod )
3301 return 0; 3346 return 0;
3302 3347
3303 qDebug(" %d %d conflict on %s %s ", mode, full, local->desc.c_str(), remote->desc.c_str() ); 3348 qDebug(" %d %d conflict on %s %s ", mode, full, local->desc.c_str(), remote->desc.c_str() );
3304 3349
3305 //qDebug("%s %d %s %d", local->lastModified().toString().latin1() , localMod, remote->lastModified().toString().latin1(), remoteMod); 3350 //qDebug("%s %d %s %d", local->lastModified().toString().latin1() , localMod, remote->lastModified().toString().latin1(), remoteMod);
3306 //qDebug("%d %d %d %d ", local->lastModified().time().second(), local->lastModified().time().msec(), remote->lastModified().time().second(), remote->lastModified().time().msec() ); 3351 //qDebug("%d %d %d %d ", local->lastModified().time().second(), local->lastModified().time().msec(), remote->lastModified().time().second(), remote->lastModified().time().msec() );
3307 //full = true; //debug only 3352 //full = true; //debug only
3308 if ( full ) { 3353 if ( full ) {
3309 bool equ = ( (*local) == (*remote) ); 3354 bool equ = ( (*local) == (*remote) );
3310 if ( equ ) { 3355 if ( equ ) {
3311 //qDebug("equal "); 3356 //qDebug("equal ");
3312 if ( mode < SYNC_PREF_FORCE_LOCAL ) 3357 if ( mode < SYNC_PREF_FORCE_LOCAL )
3313 return 0; 3358 return 0;
3314 3359
3315 }//else //debug only 3360 }//else //debug only
3316 //qDebug("not equal %s %s ", local->desc.c_str(), remote->desc.c_str()); 3361 //qDebug("not equal %s %s ", local->desc.c_str(), remote->desc.c_str());
3317 } 3362 }
3318 3363
3319 int result; 3364 int result;
3320 bool localIsNew; 3365 bool localIsNew;
3321 //qDebug("%s -- %s mLastCalendarSync %s lastsync %s --- local %s remote %s ",local->summary().latin1(), remote->summary().latin1(),mLastCalendarSync.toString().latin1() ,lastSync.toString().latin1() , local->lastModified().toString().latin1() , remote->lastModified().toString().latin1() ); 3366 //qDebug("%s -- %s mLastCalendarSync %s lastsync %s --- local %s remote %s ",local->summary().latin1(), remote->summary().latin1(),mLastCalendarSync.toString().latin1() ,lastSync.toString().latin1() , local->lastModified().toString().latin1() , remote->lastModified().toString().latin1() );
3322 3367
3323 if ( full && mode < SYNC_PREF_NEWEST ) 3368 if ( full && mode < SYNC_PREF_NEWEST )
3324 mode = SYNC_PREF_ASK; 3369 mode = SYNC_PREF_ASK;
3325 3370
3326 switch( mode ) { 3371 switch( mode ) {
3327 case SYNC_PREF_LOCAL: 3372 case SYNC_PREF_LOCAL:
3328 if ( lastSync > remoteMod ) 3373 if ( lastSync > remoteMod )
3329 return 1; 3374 return 1;
3330 if ( lastSync > localMod ) 3375 if ( lastSync > localMod )
3331 return 2; 3376 return 2;
3332 return 1; 3377 return 1;
3333 break; 3378 break;
3334 case SYNC_PREF_REMOTE: 3379 case SYNC_PREF_REMOTE:
3335 if ( lastSync > remoteMod ) 3380 if ( lastSync > remoteMod )
3336 return 1; 3381 return 1;
3337 if ( lastSync > localMod ) 3382 if ( lastSync > localMod )
3338 return 2; 3383 return 2;
3339 return 2; 3384 return 2;
3340 break; 3385 break;
3341 case SYNC_PREF_NEWEST: 3386 case SYNC_PREF_NEWEST:
3342 if ( localMod > remoteMod ) 3387 if ( localMod > remoteMod )
3343 return 1; 3388 return 1;
3344 else 3389 else
3345 return 2; 3390 return 2;
3346 break; 3391 break;
3347 case SYNC_PREF_ASK: 3392 case SYNC_PREF_ASK:
3348 //qDebug("lsy %s --- lo %s --- re %s ", lastSync.toString().latin1(), localMod.toString().latin1(), remoteMod.toString().latin1() ); 3393 //qDebug("lsy %s --- lo %s --- re %s ", lastSync.toString().latin1(), localMod.toString().latin1(), remoteMod.toString().latin1() );
3349 if ( lastSync > remoteMod ) 3394 if ( lastSync > remoteMod )
3350 return 1; 3395 return 1;
3351 if ( lastSync > localMod ) 3396 if ( lastSync > localMod )
3352 return 2; 3397 return 2;
3353 localIsNew = localMod >= remoteMod; 3398 localIsNew = localMod >= remoteMod;
3354 //qDebug("conflict! ************************************** "); 3399 //qDebug("conflict! ************************************** ");
3355 { 3400 {
3356 PwMDataItemChooser acd ( *local,*remote, localIsNew , 0/*this*/ ); 3401 PwMDataItemChooser acd ( *local,*remote, localIsNew , 0/*this*/ );
3357 result = acd.executeD(localIsNew); 3402 result = acd.executeD(localIsNew);
3358 return result; 3403 return result;
3359 } 3404 }
3360 break; 3405 break;
3361 case SYNC_PREF_FORCE_LOCAL: 3406 case SYNC_PREF_FORCE_LOCAL:
3362 return 1; 3407 return 1;
3363 break; 3408 break;
3364 case SYNC_PREF_FORCE_REMOTE: 3409 case SYNC_PREF_FORCE_REMOTE:
3365 return 2; 3410 return 2;
3366 break; 3411 break;
3367 3412
3368 default: 3413 default:
3369 // SYNC_PREF_TAKE_BOTH not implemented 3414 // SYNC_PREF_TAKE_BOTH not implemented
3370 break; 3415 break;
3371 } 3416 }
3372 return 0; 3417 return 0;
3373} 3418}
3374 3419
3375void PwMDoc::removeSyncInfo( QString syncProfile) 3420void PwMDoc::removeSyncInfo( QString syncProfile)
3376{ 3421{
3377 bool res, found; 3422 bool res, found;
3378 unsigned int count, i; 3423 unsigned int count, i;
3379 if ( syncProfile.isEmpty() ) { 3424 if ( syncProfile.isEmpty() ) {
3380 count = numSyncDataEntries(); 3425 count = numSyncDataEntries();
3381 for (i = count; count > 0; count-- ) { 3426 for (i = count; count > 0; count-- ) {
3382 res = delSyncDataEntry(i-1, false); 3427 res = delSyncDataEntry(i-1, false);
3383 if (res == false) { 3428 if (res == false) {
3384 qDebug("PwMDoc::removeSyncInfo: could not remove syncprofile"); 3429 qDebug("PwMDoc::removeSyncInfo: could not remove syncprofile");
3385 } 3430 }
3386 } 3431 }
3387 } else { 3432 } else {
3388 found = findSyncData(syncProfile, &count); 3433 found = findSyncData(syncProfile, &count);
3389 if (found == true) 3434 if (found == true)
3390 { 3435 {
3391 res = delSyncDataEntry(count, false); 3436 res = delSyncDataEntry(count, false);
3392 if (res == false) { 3437 if (res == false) {
3393 qDebug("PwMDoc::removeSyncInfo: could not remove %s", syncProfile.latin1()); 3438 qDebug("PwMDoc::removeSyncInfo: could not remove %s", syncProfile.latin1());
3394 3439
3395 } 3440 }
3396 } 3441 }
3397 } 3442 }
3398} 3443}
3399 3444
3400 3445
3401//this are the overwritten callbackmethods from the syncinterface 3446//this are the overwritten callbackmethods from the syncinterface
3402bool PwMDoc::sync(KSyncManager* manager, QString filename, int mode) 3447bool PwMDoc::sync(KSyncManager* manager, QString filename, int mode)
3403{ 3448{
3404 QString mCurrentSyncDevice = manager->getCurrentSyncDevice(); 3449 QString mCurrentSyncDevice = manager->getCurrentSyncDevice();
3405 3450
3406 //1) unlock local file first if necessary (ask for password) 3451 //1) unlock local file first if necessary (ask for password)
3407 if (this->isDeepLocked()) { 3452 if (this->isDeepLocked()) {
3408 PwMerror ret = this->deepLock(false); 3453 PwMerror ret = this->deepLock(false);
3409 if (ret != e_success) 3454 if (ret != e_success)
3410 return false; 3455 return false;
3411 } 3456 }
3412 3457
3413 //2) construct and open a new doc on the stack(automatic cleanup of remote file). 3458 //2) construct and open a new doc on the stack(automatic cleanup of remote file).
3414 PwMDoc syncTarget(this, "synctarget"); 3459 PwMDoc syncTarget(this, "synctarget");
3415 PwMDoc* pSyncTarget = &syncTarget; 3460 PwMDoc* pSyncTarget = &syncTarget;
3416 3461
3417 3462
3418 PwMerror err = pSyncTarget->openDoc(&filename, 1 /*== open with all entries locked*/); 3463 PwMerror err = pSyncTarget->openDoc(&filename, 1 /*== open with all entries locked*/);
3419 3464
3420 if (err == e_alreadyOpen) { 3465 if (err == e_alreadyOpen) {
3421 PwMDocList::listItem li; 3466 PwMDocList::listItem li;
3422 if (getOpenDocList()->find(filename.latin1(), &li)) 3467 if (getOpenDocList()->find(filename.latin1(), &li))
3423 pSyncTarget = li.doc; 3468 pSyncTarget = li.doc;
3424 else { 3469 else {
3425 qDebug("PwmDoc::sync: sync failed. Error %i while opening file %s",err, filename.latin1()); 3470 qDebug("PwmDoc::sync: sync failed. Error %i while opening file %s",err, filename.latin1());
3426 return false; 3471 return false;
3427 } 3472 }
3428 } 3473 }
3429 else if (err != e_success) { 3474 else if (err != e_success) {
3430 qDebug("PwmDoc::sync: sync failed. Error %i while opening file %s",err, filename.latin1()); 3475 qDebug("PwmDoc::sync: sync failed. Error %i while opening file %s",err, filename.latin1());
3431 return false; 3476 return false;
3432 } 3477 }
3433 3478
3434 qDebug("PWM file loaded %s,sync mode %d",filename.latin1(), mode ); 3479 qDebug("PWM file loaded %s,sync mode %d",filename.latin1(), mode );
3435 3480
3436 3481
3437 //3) unlock remote file first if necessary (ask for password) 3482 //3) unlock remote file first if necessary (ask for password)
3438 if (pSyncTarget->isDeepLocked()) { 3483 if (pSyncTarget->isDeepLocked()) {
3439 PwMerror ret = pSyncTarget->deepLock(false); 3484 PwMerror ret = pSyncTarget->deepLock(false);
3440 if (ret != e_success) 3485 if (ret != e_success)
3441 return false; 3486 return false;
3442 } 3487 }
3443 3488
3444 3489
3445 err = syncronize(manager, this, pSyncTarget, mode ); 3490 err = syncronize(manager, this, pSyncTarget, mode );
3446 3491
3447 if (err == e_success) { 3492 if (err == e_success) {
3448 if ( manager->mWriteBackFile ){ 3493 if ( manager->mWriteBackFile ){
3449 qDebug("Saving remote PWManager file"); 3494 qDebug("Saving remote PWManager file");
3450 err = pSyncTarget->saveDoc(conf()->confGlobCompression()); 3495 err = pSyncTarget->saveDoc(conf()->confGlobCompression());
3451 if (err != e_success) { 3496 if (err != e_success) {
3452 qDebug("PwmDoc::sync: Sync failed. Error %i while storing file %s",err, filename.latin1()); 3497 qDebug("PwmDoc::sync: Sync failed. Error %i while storing file %s",err, filename.latin1());
3453 return false; 3498 return false;
3454 } 3499 }
3455 } 3500 }
3456 3501
3457 flagDirty(); 3502 flagDirty();
3458 return true; 3503 return true;
3459 } 3504 }
3460 else { 3505 else {
3461 return false; 3506 return false;
3462 } 3507 }
3463} 3508}
3464 3509
3465#endif 3510#endif
3466 3511
3467 3512
3468bool PwMDoc::findSyncData(const QString &syncname, unsigned int *index) 3513bool PwMDoc::findSyncData(const QString &syncname, unsigned int *index)
3469{ 3514{
3470 vector<PwMSyncItem>::iterator i = dti.syncDta.begin(), 3515 vector<PwMSyncItem>::iterator i = dti.syncDta.begin(),
3471 end = dti.syncDta.end(); 3516 end = dti.syncDta.end();
3472 3517
3473 while (i != end) { 3518 while (i != end) {
3474 if ((*i).syncName == syncname.latin1()) { 3519 if ((*i).syncName == syncname.latin1()) {
3475 if (index) { 3520 if (index) {
3476 *index = i - dti.syncDta.begin(); 3521 *index = i - dti.syncDta.begin();
3477 } 3522 }
3478 return true; 3523 return true;
3479 } 3524 }
3480 ++i; 3525 ++i;
3481 } 3526 }
3482 return false; 3527 return false;
3483}; 3528};
3484 3529
3485/** add new syncdataentry */ 3530/** add new syncdataentry */
3486PwMerror PwMDoc::addSyncDataEntry(PwMSyncItem *d, bool dontFlagDirty) 3531PwMerror PwMDoc::addSyncDataEntry(PwMSyncItem *d, bool dontFlagDirty)
3487{ 3532{
3488 PWM_ASSERT(d); 3533 PWM_ASSERT(d);
3489 3534
3490 if (isDeepLocked()) { 3535 if (isDeepLocked()) {
3491 PwMerror ret; 3536 PwMerror ret;
3492 ret = deepLock(false); 3537 ret = deepLock(false);
3493 if (ret != e_success) 3538 if (ret != e_success)
3494 return e_lock; 3539 return e_lock;
3495 } 3540 }
3496 unsigned int index; 3541 unsigned int index;
3497 3542
3498 const QString tmp = d->syncName.c_str(); 3543 const QString tmp = d->syncName.c_str();
3499 bool exists = findSyncData(d->syncName.c_str(), &index); 3544 bool exists = findSyncData(d->syncName.c_str(), &index);
3500 3545
3501 if (exists == true) { 3546 if (exists == true) {
3502 // DOH! We found this entry. 3547 // DOH! We found this entry.
3503 return e_entryExists; 3548 return e_entryExists;
3504 } 3549 }
3505 3550
3506 dti.syncDta.push_back(*d); 3551 dti.syncDta.push_back(*d);
3507 3552
3508 if (!dontFlagDirty) 3553 if (!dontFlagDirty)
3509 flagDirty(); 3554 flagDirty();
3510 return e_success; 3555 return e_success;
3511} 3556}
3512 3557
3513 3558
3514 3559
3515/** delete syncdata entry */ 3560/** delete syncdata entry */
3516bool PwMDoc::delSyncDataEntry(unsigned int index, bool dontFlagDirty) 3561bool PwMDoc::delSyncDataEntry(unsigned int index, bool dontFlagDirty)
3517{ 3562{
3518 if (isDeepLocked()) 3563 if (isDeepLocked())
3519 return false; 3564 return false;
3520 if (index > dti.syncDta.size() - 1) 3565 if (index > dti.syncDta.size() - 1)
3521 return false; 3566 return false;
3522 3567
3523 // delete entry 3568 // delete entry
3524 dti.syncDta.erase(dti.syncDta.begin() + index); 3569 dti.syncDta.erase(dti.syncDta.begin() + index);
3525 3570
3526 if (!dontFlagDirty) 3571 if (!dontFlagDirty)
3527 flagDirty(); 3572 flagDirty();
3528 return true; 3573 return true;
3529} 3574}
3530 3575
3531 3576
3532PwMDataItem* PwMDoc::findEntryByID(const QString &uid, unsigned int *category, unsigned int *index) 3577PwMDataItem* PwMDoc::findEntryByID(const QString &uid, unsigned int *category, unsigned int *index)
3533{ 3578{
3534 vector<PwMCategoryItem>::iterator catcounter = dti.dta.begin(), 3579 vector<PwMCategoryItem>::iterator catcounter = dti.dta.begin(),
3535 catend = dti.dta.end(); 3580 catend = dti.dta.end();
3536 3581
3537 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 3582 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
3538 3583
3539 while (catcounter != catend) { 3584 while (catcounter != catend) {
3540 entrBegin = catcounter->d.begin(); 3585 entrBegin = catcounter->d.begin();
3541 entrEnd = catcounter->d.end(); 3586 entrEnd = catcounter->d.end();
3542 entrI = entrBegin; 3587 entrI = entrBegin;
3543 while (entrI != entrEnd) { 3588 while (entrI != entrEnd) {
3544 if ((*entrI).meta.uniqueid == uid.latin1()) { 3589 if ((*entrI).meta.uniqueid == uid.latin1()) {
3545 if (category) 3590 if (category)
3546 *category = catcounter - dti.dta.begin(); 3591 *category = catcounter - dti.dta.begin();
3547 if (index) 3592 if (index)
3548 *index = entrI - entrBegin; 3593 *index = entrI - entrBegin;
3549 3594
3550 return &(*entrI); 3595 return &(*entrI);
3551 } 3596 }
3552 ++entrI; 3597 ++entrI;
3553 } 3598 }
3554 ++catcounter; 3599 ++catcounter;
3555 } 3600 }
3556 3601
3557 return 0; 3602 return 0;
3558} 3603}
3559 3604
3560QStringList PwMDoc::getIDEntryList() 3605QStringList PwMDoc::getIDEntryList()
3561{ 3606{
3562 QStringList results; 3607 QStringList results;
3563 3608
3564 vector<PwMCategoryItem>::iterator catcounter = dti.dta.begin(), 3609 vector<PwMCategoryItem>::iterator catcounter = dti.dta.begin(),
3565 catend = dti.dta.end(); 3610 catend = dti.dta.end();
3566 3611
3567 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 3612 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
3568 3613
3569 while (catcounter != catend) { 3614 while (catcounter != catend) {
3570 entrBegin = catcounter->d.begin(); 3615 entrBegin = catcounter->d.begin();
3571 entrEnd = catcounter->d.end(); 3616 entrEnd = catcounter->d.end();
3572 entrI = entrBegin; 3617 entrI = entrBegin;
3573 while (entrI != entrEnd) { 3618 while (entrI != entrEnd) {
3574 results.append( (*entrI).meta.uniqueid.c_str() ); 3619 results.append( (*entrI).meta.uniqueid.c_str() );
3575 ++entrI; 3620 ++entrI;
3576 } 3621 }
3577 ++catcounter; 3622 ++catcounter;
3578 } 3623 }
3579 3624
3580 return results; 3625 return results;
3581} 3626}
3582 3627
3583 3628
3584 3629
3585 3630
3586 3631
3587#ifndef PWM_EMBEDDED 3632#ifndef PWM_EMBEDDED
3588#include "pwmdoc.moc" 3633#include "pwmdoc.moc"
3589#endif 3634#endif