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