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