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