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