summaryrefslogtreecommitdiffabout
authorzautrix <zautrix>2005-04-21 22:07:10 (UTC)
committer zautrix <zautrix>2005-04-21 22:07:10 (UTC)
commit6284b1d7d597463347b471ed8ec2770f4e2d449b (patch) (unidiff)
tree5444a13ed788191733fec406791ddf03ec246b59
parentfd38343ef53c9b2a48208f747100579703cc1814 (diff)
downloadkdepimpi-6284b1d7d597463347b471ed8ec2770f4e2d449b.zip
kdepimpi-6284b1d7d597463347b471ed8ec2770f4e2d449b.tar.gz
kdepimpi-6284b1d7d597463347b471ed8ec2770f4e2d449b.tar.bz2
fixes
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,1197 +1,1242 @@
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;