diff --git a/kabc/Makefile.am b/kabc/Makefile.am index 8b64753a5..d04629465 100644 --- a/kabc/Makefile.am +++ b/kabc/Makefile.am @@ -1,115 +1,121 @@ SUBDIRS = scripts vcard vcardparser . formats plugins # FIXME: doesn't work with final for now KDE_OPTIONS = nofinal # Make sure $(all_includes) remains last! INCLUDES = -I$(top_builddir)/kabc -I$(top_srcdir)/kabc -I$(top_srcdir)/kab \ -I$(srcdir)/vcardparser/ -I$(srcdir)/vcard/include \ -I$(srcdir)/vcard/include/generated \ -I$(srcdir)/vcardparser $(all_includes) addressee.h addressee.cpp field.cpp: \ $(srcdir)/scripts/makeaddressee \ $(srcdir)/scripts/addressee.src.cpp \ $(srcdir)/scripts/addressee.src.h \ $(srcdir)/scripts/entrylist \ $(srcdir)/scripts/field.src.cpp ( cd scripts && $(MAKE) ) CLEANFILES = addressee.h addressee.cpp field.cpp COMPILE_FIRST = addressee.h lib_LTLIBRARIES = libkabc.la libkabc_la_COMPILE_FIRST = addressee.h libkabc_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) -version-info 3:0:2 -no-undefined libkabc_la_LIBADD = vcard/libvcard.la vcardparser/libvcards.la $(LIB_KIO) \ $(top_builddir)/kresources/libkresources.la libkabc_la_SOURCES = \ address.cpp addressbook.cpp addressee.cpp addresseedialog.cpp agent.cpp \ distributionlist.cpp distributionlistdialog.cpp distributionlisteditor.cpp \ errorhandler.cpp field.cpp formatfactory.cpp geo.cpp key.cpp \ phonenumber.cpp picture.cpp plugin.cpp resource.cpp \ resourceselectdialog.cpp secrecy.cpp sound.cpp stdaddressbook.cpp \ timezone.cpp vcard21parser.cpp vcardconverter.cpp vcardformat.cpp \ vcardformatimpl.cpp vcardformatplugin.cpp ldifconverter.cpp addresslineedit.cpp \ ldapclient.cpp addresseelist.cpp vcardtool.cpp addresseehelper.cpp \ - addresseehelper.skel + addresseehelper.skel lock.cpp kabcincludedir = $(includedir)/kabc kabcinclude_HEADERS = address.h addressbook.h addressee.h addresseedialog.h \ agent.h distributionlist.h distributionlistdialog.h distributionlisteditor.h \ errorhandler.h field.h format.h formatfactory.h formatplugin.h geo.h key.h \ phonenumber.h picture.h plugin.h resource.h \ resourceselectdialog.h secrecy.h sound.h stdaddressbook.h timezone.h \ vcardconverter.h vcardformat.h vcardformatplugin.h ldifconverter.h \ - addresslineedit.h ldapclient.h addresseelist.h vcardtool.h + addresslineedit.h ldapclient.h addresseelist.h vcardtool.h lock.h METASOURCES = AUTO bin_PROGRAMS = kab2kabc kab2kabc_LDFLAGS = $(all_libraries) $(KDE_RPATH) kab2kabc_LDADD = libkabc.la ../kab/libkab.la kab2kabc_SOURCES = kab2kabc.cpp +check_PROGRAMS = testlock + +testlock_LDFPLAGS = $(all_libraries) +testlock_LDADD = libkabc.la +testlock_SOURCES = testlock.cpp + EXTRA_PROGRAMS = testkabc testkabcdlg testdistlist bigread bigwrite testdb \ testaddressee testaddresseelist testaddressfmt kabcargl testaddresslineedit testkabc_LDFLAGS = $(all_libraries) $(KDE_RPATH) testkabc_LDADD = libkabc.la testkabc_SOURCES = testkabc.cpp testaddressee_LDFLAGS = $(all_libraries) $(KDE_RPATH) testaddressee_LDADD = libkabc.la testaddressee_SOURCES = testaddressee.cpp testaddresseelist_LDFLAGS = $(all_libraries) $(KDE_RPATH) testaddresseelist_LDADD = libkabc.la testaddresseelist_SOURCES = testaddresseelist.cpp testaddressfmt_LDFLAGS = $(all_libraries) $(KDE_RPATH) testaddressfmt_LDADD = libkabc.la testaddressfmt_SOURCES = testaddressfmt.cpp testkabcdlg_LDFLAGS = $(all_libraries) $(KDE_RPATH) testkabcdlg_LDADD = libkabc.la testkabcdlg_SOURCES = testkabcdlg.cpp testdistlist_LDFLAGS = $(all_libraries) $(KDE_RPATH) testdistlist_LDADD = libkabc.la testdistlist_SOURCES = testdistlist.cpp testaddresslineedit_LDFLAGS = $(all_libraries) $(KDE_RPATH) testaddresslineedit_LDADD = libkabc.la testaddresslineedit_SOURCES = testaddresslineedit.cpp bigread_LDFLAGS = $(all_libraries) $(KDE_RPATH) bigread_LDADD = libkabc.la $(top_builddir)/kabc/plugins/file/libkabc_file.la bigread_SOURCES = bigread.cpp bigwrite_LDFLAGS = $(all_libraries) $(KDE_RPATH) bigwrite_LDADD = libkabc.la $(top_builddir)/kabc/plugins/file/libkabc_file.la bigwrite_SOURCES = bigwrite.cpp testdb_LDFLAGS = $(all_libraries) $(KDE_RPATH) testdb_LDADD = libkabc.la testdb_SOURCES = testdb.cpp kabcargl_LDFLAGS = $(all_libraries) $(KDE_RPATH) kabcargl_LDADD = libkabc.la kabcargl_SOURCES = kabcargl.cpp autostart_DATA = kab2kabc.desktop autostartdir = $(prefix)/share/autostart DOXYGEN_REFERENCES = kdecore kdeui map_DATA = countrytransl.map mapdir = $(kde_datadir)/kabc EXTRA_DIST = $(map_DATA) include ../admin/Doxyfile.am diff --git a/kabc/lock.cpp b/kabc/lock.cpp new file mode 100644 index 000000000..3fef923fd --- /dev/null +++ b/kabc/lock.cpp @@ -0,0 +1,120 @@ +/* + This file is part of libkabc. + Copyright (c) 2001 Cornelius Schumacher + + 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. +*/ + +#include "lock.h" + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +using namespace KABC; + +Lock::Lock( const QString &identifier ) + : mIdentifier( identifier ) +{ + mIdentifier.replace( "/", "_" ); +} + +bool Lock::lock() +{ + kdDebug(5700) << "Lock::lock()" << endl; + + QString lockName = locateLocal( "data", "kabc/lock/" + mIdentifier + ".lock" ); + kdDebug(5700) << "-- lock name: " << lockName << endl; + + if ( QFile::exists( lockName ) ) { // check if it is a stale lock file + QFile file( lockName ); + if ( !file.open( IO_ReadOnly ) ) { + mError = i18n("Unable to open lock file."); + return false; + } + + QDataStream t( &file ); + + QString app; int pid; + t >> pid >> app; + + int retval = ::kill( pid, 0 ); + if ( retval == -1 && errno == ESRCH ) { // process doesn't exists anymore + QFile::remove( lockName ); + kdError(5700) << "detect stale lock file from process '" << app << "'" << endl; + file.close(); + } else { + mError = i18n("The resource '%1' is locked by application '%2'.") + .arg( mIdentifier ).arg( app ); + return false; + } + } + + QString lockUniqueName; + lockUniqueName = mIdentifier + kapp->randomString( 8 ); + mLockUniqueName = locateLocal( "data", "kabc/lock/" + lockUniqueName ); + kdDebug(5700) << "-- lock unique name: " << mLockUniqueName << endl; + + // Create unique file + QFile file( mLockUniqueName ); + file.open( IO_WriteOnly ); + QDataStream t( &file ); + t << ::getpid() << QString( KGlobal::instance()->instanceName() ); + file.close(); + + // Create lock file + int result = ::link( QFile::encodeName( mLockUniqueName ), + QFile::encodeName( lockName ) ); + + if ( result == 0 ) { + mError = ""; + emit locked(); + return true; + } + + // TODO: check stat + + mError = i18n("Error"); + return false; +} + +bool Lock::unlock() +{ + QString lockName = locateLocal( "data", + "kabc/lock/" + mIdentifier + ".lock" ); + QFile::remove( lockName ); + QFile::remove( mLockUniqueName ); + emit unlocked(); + + mError = ""; + return true; +} + +QString Lock::error() const +{ + return mError; +} + +#include "lock.moc" diff --git a/kabc/lock.h b/kabc/lock.h new file mode 100644 index 000000000..0d9f7be17 --- /dev/null +++ b/kabc/lock.h @@ -0,0 +1,71 @@ +/* + This file is part of libkabc. + + Copyright (c) 2001,2003 Cornelius Schumacher + + 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. +*/ +#ifndef KABC_LOCK_H +#define KABC_LOCK_H + +#include +#include + +namespace KABC { + +/** + This class provides locking functionality for a file, directory or an + arbitrary string-represented resource. +*/ +class Lock : public QObject +{ + Q_OBJECT + public: + /** + Constructor. + + @param identifier An identifier for the resource to be locked, e.g. a file + name. + */ + Lock( const QString &identifier ); + + /** + Lock resource. + */ + bool lock(); + + /** + Unlock resource. + */ + bool unlock(); + + QString error() const; + + signals: + void locked(); + void unlocked(); + + private: + QString mIdentifier; + + QString mLockUniqueName; + + QString mError; +}; + +} + +#endif diff --git a/kabc/testlock.cpp b/kabc/testlock.cpp new file mode 100644 index 000000000..e950a2286 --- /dev/null +++ b/kabc/testlock.cpp @@ -0,0 +1,127 @@ +#include "testlock.h" + +#include +#include +#include +#include +#include +/* + This file is part of libkabc. + + Copyright (c) 2003 Cornelius Schumacher + + 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. +*/ + +#include +#include + +#include +#include +#include +#include + +#include + +using namespace KABC; + +LockWidget::LockWidget( const QString &identifier ) +{ + mLock = new Lock( identifier ); + + QVBoxLayout *topLayout = new QVBoxLayout( this ); + topLayout->setMargin( KDialog::marginHint() ); + topLayout->setSpacing( KDialog::spacingHint() ); + + QHBoxLayout *identifierLayout = new QHBoxLayout( topLayout ); + + QLabel *resourceLabel = new QLabel( "Identifier:", this ); + identifierLayout->addWidget( resourceLabel ); + + QLabel *resourceIdentifier = new QLabel( identifier, this ); + identifierLayout->addWidget( resourceIdentifier ); + + mStatus = new QLabel( "Status: Unlocked", this ); + topLayout->addWidget( mStatus ); + + QPushButton *button = new QPushButton( "Lock", this ); + topLayout->addWidget( button ); + connect( button, SIGNAL( clicked() ), SLOT( lock() ) ); + + button = new QPushButton( "Unlock", this ); + topLayout->addWidget( button ); + connect( button, SIGNAL( clicked() ), SLOT( unlock() ) ); + + button = new QPushButton( "Quit", this ); + topLayout->addWidget( button ); + connect( button, SIGNAL( clicked() ), SLOT( close() ) ); +} + +LockWidget::~LockWidget() +{ + delete mLock; +} + +void LockWidget::lock() +{ + if ( !mLock->lock() ) { + KMessageBox::sorry( this, mLock->error() ); + } else { + mStatus->setText( "Status: Locked" ); + } +} + +void LockWidget::unlock() +{ + if ( !mLock->unlock() ) { + KMessageBox::sorry( this, mLock->error() ); + } else { + mStatus->setText( "Status: Unlocked" ); + } +} + + +static const KCmdLineOptions options[] = +{ + {"+identifier","Identifier of resource to be locked, e.g. filename", 0 }, + {0,0,0} +}; + +int main(int argc,char **argv) +{ + KAboutData aboutData("testlock",I18N_NOOP("Test libkabc Lock"),"0.1"); + KCmdLineArgs::init(argc,argv,&aboutData); + KCmdLineArgs::addCmdLineOptions( options ); + + KApplication app; + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + if ( args->count() != 1 ) { + cerr << "Usage: testlock " << endl; + return 1; + } + + QString identifier = args->arg( 0 ); + + LockWidget mainWidget( identifier ); + + kapp->setMainWidget( &mainWidget ); + mainWidget.show(); + + return app.exec(); +} + +#include "testlock.moc" diff --git a/kabc/testlock.h b/kabc/testlock.h new file mode 100644 index 000000000..6bc17426a --- /dev/null +++ b/kabc/testlock.h @@ -0,0 +1,47 @@ +/* + This file is part of libkabc. + + Copyright (c) 2003 Cornelius Schumacher + + 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. +*/ +#ifndef KABC_TESTLOCK_H +#define KABC_TESTLOCK_H + +#include "lock.h" + +#include + +class QLabel; + +class LockWidget : public QWidget +{ + Q_OBJECT + public: + LockWidget( const QString &identifier ); + ~LockWidget(); + + protected slots: + void lock(); + void unlock(); + + private: + KABC::Lock *mLock; + + QLabel *mStatus; +}; + +#endif