-rw-r--r-- | kabc/plugins/file/resourcefile.cpp | 49 | ||||
-rw-r--r-- | kabc/plugins/file/resourcefile.h | 1 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwmdoc.cpp | 45 |
3 files changed, 93 insertions, 2 deletions
diff --git a/kabc/plugins/file/resourcefile.cpp b/kabc/plugins/file/resourcefile.cpp index 2bd9e71..c89939d 100644 --- a/kabc/plugins/file/resourcefile.cpp +++ b/kabc/plugins/file/resourcefile.cpp @@ -1,167 +1,169 @@ /* This file is part of libkabc. Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Enhanced Version of the file for platform independent KDE tools. Copyright (c) 2004 Ulf Schenk $Id$ */ #include <sys/types.h> #include <sys/stat.h> #ifndef _WIN32_ #include <unistd.h> #endif #include <qfile.h> #include <qfileinfo.h> #include <qregexp.h> #include <qtimer.h> #include <kapplication.h> #include <kconfig.h> #include <kdebug.h> #include <klocale.h> //US #include <ksavefile.h> #include <kstandarddirs.h> #include <kmessagebox.h> +#include <kglobalsettings.h> #include "formatfactory.h" #include "resource.h" #include "resourcefileconfig.h" #include "stdaddressbook.h" #define NO_DIRWATCH #include "resourcefile.h" //#define ALLOW_LOCKING using namespace KABC; extern "C" #ifdef _WIN32_ __declspec(dllexport) #else { #endif //US void *init_kabc_file() void *init_microkabc_file() { return new KRES::PluginFactory<ResourceFile,ResourceFileConfig>(); } #ifndef _WIN32_ } #endif ResourceFile::ResourceFile( const KConfig *config ) : Resource( config ) , mFormat( 0 ) { QString fileName, formatName, default_fileName; default_fileName = StdAddressBook::fileName(); - + mLastBackupDate = -1; KConfig *cfg = (KConfig *)config; if ( cfg ) { fileName = cfg->readEntry( "FileName", default_fileName ); formatName = cfg->readEntry( "FileFormat", "vcard" ); mFamily = cfg->readEntry( "ResourceName", "std" ); + mLastBackupDate = cfg->readNumEntry( "LastBackupDate", 0 ); } else { fileName = default_fileName; formatName = "vcard"; } init( fileName, formatName ); } ResourceFile::ResourceFile( const QString &fileName , const QString &formatName ) : Resource( 0 ) { // qDebug("ResourceFile::ResourceFile : 3 %s, %s", fileName.latin1(), formatName.latin1()); - + mLastBackupDate = -1; init( fileName, formatName ); } void ResourceFile::init( const QString &fileName, const QString &formatName ) { mFormatName = formatName; FormatFactory *factory = FormatFactory::self(); mFormat = factory->format( mFormatName ); if ( !mFormat ) { mFormatName = "vcard"; mFormat = factory->format( mFormatName ); } #ifndef NO_DIRWATCH connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( fileChanged() ) ); connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( fileChanged() ) ); connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( fileChanged() ) ); #endif QString localKdeDir; localKdeDir = readEnvPath("LOCALMICROKDEHOME"); if ( ! localKdeDir.isEmpty() ) { qDebug("LOCALMICROKDEHOME is set to: %s",localKdeDir.latin1() ); QFileInfo fi ( fileName ); QString localname = localKdeDir + "/apps/kabc/" + fi.fileName (); QFileInfo fi2 ( localname ); if ( ! fi2.exists() || mFamily == "sync_res" ) { if ( fi.exists() && mFamily == "sync_res") { qDebug("LOCAL mode SYNC mode using absolute file path "); setFileName( fileName ); return; } else { KMessageBox::error(0,i18n("Addressbook resource file not found:\n '%1'.\nIn LOCAL mode only resource files in\n'%2'\nare supported.\n(i.e. in the dir ./apps/kabc/ relative to the kapi(.exe) binary.)\n\nIf you are starting KA/Pi for the very first time\nyou will get this error message as well.\nIt will create the missing file automatically for you.").arg(localname).arg(localKdeDir+"/apps/kabc/") ); setFileName( localname ); return; } } else { qDebug("Local resource file found. Changing filename to: %s",localname.latin1() ); setFileName( localname ); return; } } setFileName( fileName ); } ResourceFile::~ResourceFile() { delete mFormat; mFormat = 0; } void ResourceFile::writeConfig( KConfig *config ) { config->setGroup( "Resource_" + identifier() ); Resource::writeConfig( config ); config->writeEntry( "FileName", fileName() ); config->writeEntry( "FileFormat", mFormatName ); @@ -196,128 +198,171 @@ bool ResourceFile::doOpen() if ( ok ) file.close(); return ok; } else { if ( !file.open( IO_ReadWrite ) ) return false; if ( file.size() < 10 ) { file.close(); return true; } bool ok = mFormat->checkFormat( &file ); file.close(); return ok; } } void ResourceFile::doClose() { } bool ResourceFile::load() { QFile file( fileName() ); if ( !file.open( IO_ReadOnly ) ) { addressBook()->error( i18n( "Unable to open file '%1'." ).arg( fileName() ) ); return false; } // qDebug("ResourceFile::load format %s, %s", mFileName.latin1(), mFormatName.latin1()); return mFormat->loadAll( addressBook(), this, &file ); } bool ResourceFile::save( Ticket *ticket ) { // qDebug("ResourceFile::save format %s, %s", mFileName.latin1(), mFormatName.latin1()); // create backup file QString extension = "_" + QString::number( QDate::currentDate().dayOfWeek() ); /*US we use a simpler method to create a backupfile (void) KSaveFile::backupFile( mFileName, QString::null ,extension ); KSaveFile saveFile( mFileName ); bool ok = false; if ( saveFile.status() == 0 && saveFile.file() ) { mFormat->saveAll( addressBook(), this, saveFile.file() ); ok = saveFile.close(); } */ //US ToDo: write backupfile #ifndef NO_DIRWATCH mDirWatch.stopScan(); #endif + if ( mLastBackupDate >= 0 && mFamily != "sync_res") { + KConfig conf (locateLocal("config","microkdeglobalrc")); + conf.setGroup( "BackupSettings" ); + bool b_enabled = conf.readBoolEntry( "BackupEnabled" ); + if ( b_enabled ) { + int num = conf.readNumEntry( "BackupNumbers" ); + int d_count = conf.readNumEntry( "BackupDayCount" ); + bool stdDir = conf.readBoolEntry( "BackupUseDefaultDir" ); + QString bupDir = conf.readEntry( "BackupDatadir" ); + QDate reference ( 2000,1,1 ); + int daysTo = reference.daysTo ( QDate::currentDate() ); + bool saveDate = false; + if ( daysTo - d_count >= mLastBackupDate ) { + qDebug("KA: Last backup was %d days ago ", daysTo - mLastBackupDate ); + if ( stdDir ) + bupDir = KGlobalSettings::backupDataDir(); + int retval = KApplication::createBackup( fileName(), bupDir, num ); + if ( retval == 0 ) { + qDebug("KO: Backup cancelled. Will try again tomorrow "); + // retval == 0 : backup skipped for today, try again tomorrow + mLastBackupDate = daysTo - d_count+1; + saveDate = true; + } else if ( retval == 1 ){ + qDebug("KO: Backup created."); + // backup ok + mLastBackupDate = daysTo; + saveDate = true; + } else if ( retval == 2 ){ + qDebug("KO: Backup globally cancelled."); + // backup globally cancelled + b_enabled = false; + } + if ( !b_enabled ) { + conf.writeEntry( "mBackupEnabled", false ); + } + if ( saveDate ) { + KConfig config ( locateLocal("config","kabcrc") ); + config.setGroup( "Resource_" + identifier() ); + config.writeEntry( "LastBackupDate", mLastBackupDate ); + } + } + } + } QFile info; info.setName( fileName() ); bool ok = info.open( IO_WriteOnly ); if ( ok ) { mFormat->saveAll( addressBook(), this, &info ); info.close(); ok = true; } else { } if ( !ok ) addressBook()->error( i18n( "Unable to save file '%1'." ).arg( fileName() ) ); #ifndef NO_DIRWATCH mDirWatch.startScan(); #endif delete ticket; #ifdef ALLOW_LOCKING unlock( mFileName ); #endif return ok; } bool ResourceFile::lock( const QString &fileName ) { #ifdef ALLOW_LOCKING QString fn = fileName; //US change the implementation how the lockfilename is getting created //US fn.replace( QRegExp("/"), "_" ); //US QString lockName = locateLocal( "data", "kabc/lock/" + fn + ".lock" ); KURL url(fn); QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" ); if (QFile::exists( lockName )) return false; QString lockUniqueName; lockUniqueName = fn + KApplication::randomString( 8 ); url = lockUniqueName; //US mLockUniqueName = locateLocal( "data", "kabc/lock/" + lockUniqueName ); mLockUniqueName = locateLocal( "data", "kabc/lock/" + url.fileName() ); kdDebug(5700) << "-- lock unique name: " << mLockUniqueName << endl; // Create unique file QFile file( mLockUniqueName ); file.open( IO_WriteOnly ); file.close(); // Create lock file int result = 0; #ifndef _WIN32_ result = ::link( QFile::encodeName( mLockUniqueName ), QFile::encodeName( lockName ) ); #endif if ( result == 0 ) { diff --git a/kabc/plugins/file/resourcefile.h b/kabc/plugins/file/resourcefile.h index 3e9edfc..61da154 100644 --- a/kabc/plugins/file/resourcefile.h +++ b/kabc/plugins/file/resourcefile.h @@ -86,79 +86,80 @@ public: */ virtual void doClose(); /** * Requests a save ticket, that is used by @ref save() */ virtual Ticket *requestSaveTicket(); /** * Loads all addressees from file to the address book. * Returns true if all addressees could be loaded otherwise false. */ virtual bool load(); /** * Saves all addresses from address book to file. * Returns true if all addressees could be saved otherwise false. * * @param ticket The ticket returned by @ref requestSaveTicket() */ virtual bool save( Ticket *ticket ); /** * Set name of file to be used for saving. */ void setFileName( const QString & ); /** * Return name of file used for loading and saving the address book. */ QString fileName() const; /** Sets a new format by name. */ void setFormat( const QString &name ); /** Returns the format name. */ QString format() const; /** * Remove a addressee from its source. * This method is mainly called by KABC::AddressBook. */ virtual void removeAddressee( const Addressee& addr ); /** * This method is called by an error handler if the application * crashed */ virtual void cleanUp(); protected slots: void fileChanged(); protected: void init( const QString &fileName, const QString &format ); bool lock( const QString &fileName ); void unlock( const QString &fileName ); private: + int mLastBackupDate; QString mFamily; QString mFileName2; QString mFormatName; FormatPlugin *mFormat; QString mLockUniqueName; #ifndef NO_DIRWATCH KDirWatch mDirWatch; #endif }; } #endif diff --git a/pwmanager/pwmanager/pwmdoc.cpp b/pwmanager/pwmanager/pwmdoc.cpp index 61f2616..36b0df5 100644 --- a/pwmanager/pwmanager/pwmdoc.cpp +++ b/pwmanager/pwmanager/pwmdoc.cpp @@ -1,101 +1,103 @@ /*************************************************************************** * * * copyright (C) 2003, 2004 by Michael Buesch * * email: mbuesch@freenet.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation. * * * ***************************************************************************/ /*************************************************************************** * copyright (C) 2004 by Ulf Schenk * This file is originaly based on version 1.1 of pwmanager * and was modified to run on embedded devices that run microkde * * $Id$ **************************************************************************/ #include "pwmdoc.h" #include "pwmview.h" #include "blowfish.h" #include "sha1.h" #include "globalstuff.h" #include "gpasmanfile.h" #include "serializer.h" #include "compressgzip.h" //US#include "compressbzip2.h" #include "randomizer.h" #include "pwminit.h" #include "libgcryptif.h" #ifdef PWM_EMBEDDED #include "pwmprefs.h" #include "kglobal.h" #endif #include <kmessagebox.h> +#include <kconfig.h> +#include <kglobalsettings.h> #include <libkcal/syncdefines.h> #ifdef CONFIG_KWALLETIF # include "kwalletemu.h" #endif // CONFIG_KWALLETIF #include <qdatetime.h> #include <qsize.h> #include <qfileinfo.h> #include <qfile.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> //US#include <iostream> #include <algorithm> #include <sys/types.h> #include <sys/stat.h> #ifndef _WIN32_ #include <unistd.h> #include <stdint.h> #endif #ifdef PWM_EMBEDDED #ifndef Q_LONG #define Q_LONG long #endif #ifndef Q_ULONG #define Q_ULONG unsigned long #endif #endif //PWM_EMBEDDED //TODO: reset to its normal value. //LR set to 5 min #define META_CHECK_TIMER_INTERVAL 300 /* 10 300*/ /* sek */ using namespace std; void PwMDocList::add(PwMDoc *doc, const string &id) { #ifdef PWM_DEBUG // check for existance of object in debug mode only. vector<listItem>::iterator begin = docList.begin(), end = docList.end(), i = begin; while (i != end) { if (i->doc == doc) { BUG(); return; } ++i; } #endif listItem newItem; newItem.doc = doc; newItem.docId = id; docList.push_back(newItem); } @@ -366,128 +368,171 @@ PwMerror PwMDoc::saveDoc(char compress, const QString *file) * the old "filename", because deepLock() references it. */ QString newFilename(filename); filename = savedFilename; getDataChangedLock(); e = deepLock(false); putDataChangedLock(); filename = newFilename; switch (e) { case e_success: break; case e_wrongPw: case e_noPw: emitDataChanged(this); return e; default: emitDataChanged(this); return e_openFile; } } if (!isPwAvailable()) { /* password is not available. This means, the * document wasn't saved, yet. */ bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD); QString pw(requestNewMpw(&useChipcard)); if (pw != "") { currentPw = pw; } else { return e_noPw; } if (useChipcard) { setDocStatFlag(DOC_STAT_USE_CHIPCARD); } else { unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); } } int _cryptAlgo = conf()->confGlobCryptAlgo(); int _hashAlgo = conf()->confGlobHashAlgo(); // sanity check for the selected algorithms if (_cryptAlgo < PWM_CRYPT_BLOWFISH || _cryptAlgo > PWM_CRYPT_TWOFISH128) { printWarn("Invalid Crypto-Algorithm selected! " "Config-file seems to be corrupt. " "Falling back to Blowfish."); _cryptAlgo = PWM_CRYPT_BLOWFISH; } if (_hashAlgo < PWM_HASH_SHA1 || _hashAlgo > PWM_HASH_TIGER) { printWarn("Invalid Hash-Algorithm selected! " "Config-file seems to be corrupt. " "Falling back to SHA1."); _hashAlgo = PWM_HASH_SHA1; } char cryptAlgo = static_cast<char>(_cryptAlgo); char hashAlgo = static_cast<char>(_hashAlgo); if (conf()->confGlobMakeFileBackup()) { if (!backupFile(filename)) return e_fileBackup; } + int mLastBackupDate = 0; + KConfig configGlobal (locateLocal("config","pwmanagerbuprc")); + QFileInfo fileInfo ( filename ); + mLastBackupDate = configGlobal.readNumEntry( "LastBackupDate-"+ fileInfo.fileName (), 0 ); + KConfig config (locateLocal("config","microkdeglobalrc")); + config.setGroup( "BackupSettings" ); + bool b_enabled = config.readBoolEntry( "BackupEnabled" ); + if ( b_enabled ) { + int num = config.readNumEntry( "BackupNumbers" ); + int d_count = config.readNumEntry( "BackupDayCount" ); + bool stdDir = config.readBoolEntry( "BackupUseDefaultDir" ); + QString bupDir = config.readEntry( "BackupDatadir" ); + QDate reference ( 2000,1,1 ); + int daysTo = reference.daysTo ( QDate::currentDate() ); + bool saveDate = false; + if ( daysTo - d_count >= mLastBackupDate ) { + qDebug("KA: Last backup was %d days ago ", daysTo - mLastBackupDate ); + if ( stdDir ) + bupDir = KGlobalSettings::backupDataDir(); + int retval = KApplication::createBackup( filename, bupDir, num ); + if ( retval == 0 ) { + qDebug("KO: Backup cancelled. Will try again tomorrow "); + // retval == 0 : backup skipped for today, try again tomorrow + mLastBackupDate = daysTo - d_count+1; + saveDate = true; + } else if ( retval == 1 ){ + qDebug("KO: Backup created."); + // backup ok + mLastBackupDate = daysTo; + saveDate = true; + } else if ( retval == 2 ){ + qDebug("KO: Backup globally cancelled."); + // backup globally cancelled + b_enabled = false; + } + if ( !b_enabled ) { + config.writeEntry( "mBackupEnabled", false ); + } + if ( saveDate ) { + configGlobal.writeEntry( "LastBackupDate-"+ fileInfo.fileName (), mLastBackupDate ); + } + } + } if (QFile::exists(filename)) { /* Move the existing file to some tmp file. * When saving file succeeds, delete tmp file. Otherwise * move tmp file back. See below. */ Randomizer *rnd = Randomizer::obj(); char rnd_buf[5]; sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF); tmpFileMoved = filename + "." + rnd_buf + ".mv"; if (!copyFile(filename, tmpFileMoved)) return e_openFile; if (!QFile::remove(filename)) { printWarn(string("removing orig file ") + filename.latin1() + " failed!"); } } f.setName(filename); if (!f.open(IO_ReadWrite)) { ret = e_openFile; goto out_moveback; } e = writeFileHeader(hashAlgo, hashAlgo, cryptAlgo, compress, ¤tPw, &f); if (e == e_hashNotImpl) { printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl"); f.close(); ret = e_hashNotImpl; goto out_moveback; } else if (e != e_success) { printDebug("PwMDoc::saveDoc(): writeFileHeader() failed"); f.close(); ret = e_writeHeader; goto out_moveback; } if (!serializeDta(&serialized)) { printDebug("PwMDoc::saveDoc(): serializeDta() failed"); f.close(); ret = e_serializeDta; goto out_moveback; } e = writeDataHash(hashAlgo, &serialized, &f); if (e == e_hashNotImpl) { printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl"); f.close(); ret = e_hashNotImpl; goto out_moveback; } else if (e != e_success) { printDebug("PwMDoc::saveDoc(): writeDataHash() failed"); f.close(); ret = e_writeHeader; goto out_moveback; } if (!compressDta(&serialized, compress)) { printDebug("PwMDoc::saveDoc(): compressDta() failed"); f.close(); ret = e_enc; goto out_moveback; } e = encrypt(&serialized, ¤tPw, &f, cryptAlgo, hashAlgo); if (e == e_weakPw) { printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw"); |