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