[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kmail-devel
Subject:    Fwd: Re: Local account locking patch Fwd: Re: question about last commit in kmacctlocal.cpp...
From:       Don Sanders <sanders () kde ! org>
Date:       2000-10-15 17:56:55
[Download RAW message or body]

I would like to update the Local Account Locking in KMail readme so that the fcntl option is 
documented.


-There are four different locking options you can use:
+There are five different locking options you can use:
 procmail_lockfile
 mutt_dotlock
 mutt_dotlock_privileged
+fcntl
 none

...

+ fcntl the default option will use the fcntl system call.

..
 where <value> is procmail_lockfile, mutt_dotlock, mutt_dotlock_privileged,
-or none.  So an actual working account group would look like:
+fcntl or none.  So an actual working account group would look like:

I would also like to put this on the KMail website kmail.kde.org, can/should I keep your name and 
employer on it? With or without your email address? (It doesn't matter to me just whatever you 
would like)

Maybe we should recommend a file locking type, how about mutt_dotlock as preferred and then 
mutt_dottlock_privileged as a secondary choice?

BFN,
Don.

<revised>
Local Account Locking in KMail
----------------------------------------------------------

KMail's file locking implementation uses the fcntl system calls by default.
This has problems in situations where your mail account folders are mounted
over nfs. There is a new hidden option where you can change the locking
implementation for local mail accounts.  This will enable you to use a local
mail account which is mounted over nfs.

To avoid the risk of losing mail when using a local account it is necessary
to ensure that KMail uses the same type of locking as your mail delivery
agent.

There are five different locking options you can use:
procmail_lockfile
mutt_dotlock
mutt_dotlock_privileged
fcntl
none

procmail_lockfile will use a small utility that comes with procmail called
lockfile.  You can use this if your mail folder is in a directory where you
have write permissions.  This will not work on your /var/spool/mail/user file
in most cases.  It will create .lock files on your account when kmail is
checking for new mail.  Please note that this will only work if procmail is
installed on your system.

mutt_dotlock and mutt_dotlock_privileged will both use a small utility that
comes with mutt called mutt_dotlock.  mutt_dotlock can be used in the same
way as the procmail_lockfile option, with the same limitation with regards to
the /var/spool/mail/ folders.  However, the mutt_dotlock_privileged option
can create lock files in the /var/spool/mail directory.  mutt_dotlock is a
setgid program and this option will run mutt_dotlock in setgid mode.  Please
note that these options will only work if mutt is installed on your system.

fcntl the default option will use the fcntl system call.

If you don't want to use any locking, the none option is what you want.
However, there are risks of losing mail when no locking is used.

In your kmailrc, there are group sections for each of your mail accounts-
These will typically look like:
[Account 1]
Folder=inbox
Location=/net/ns/home/wynnw/.newmail
Name=Work
Type=local
check-exclude=false
check-interval=10
precommand=

To change the account to use the locking mechanism you want, change it to:
[Account 1]
Folder=inbox
Location=/net/ns/home/wynnw/.newmail
Name=Work
Type=local
check-exclude=false
check-interval=10
precommand=
LockType=<value>

where <value> is procmail_lockfile, mutt_dotlock, mutt_dotlock_privileged,
fcntl or none.  So an actual working account group would look like:
[Account 1]
Folder=inbox
Location=/net/ns/home/wynnw/.newmail
Name=Work
Type=local
check-exclude=false
check-interval=10
precommand=
LockType=mutt_dotlock

Please make the changes exactly as you see them here- case sensitivity is
very important, as is spelling:)

--
Wynn Wilkes
Caldera Systems, Inc.

-------------------------------------------------------
</revised>
["kmail_latest.patch" (text/plain)]

? mykmail.patch
? kmail_latest.patch
Index: kmacctlocal.cpp
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmacctlocal.cpp,v
retrieving revision 1.47
diff -u -p -B -w -r1.47 kmacctlocal.cpp
--- kmacctlocal.cpp	2000/09/26 13:00:25	1.47
+++ kmacctlocal.cpp	2000/10/05 17:47:43
@@ -36,6 +36,7 @@ KMAcctLocal::KMAcctLocal(KMAcctMgr* aOwn
   KMAcctLocalInherited(aOwner, aAccountName)
 {
   initMetaObject();
+  mLock = FCNTL;
 }
 
 
@@ -83,6 +84,7 @@ void KMAcctLocal::processNewMail(bool)
 {
   QTime t;
   KMFolder mailFolder(NULL, location());
+  mailFolder.setLockType( mLock );
   long num = 0;
   long i;
   int rc;
@@ -118,6 +120,7 @@ void KMAcctLocal::processNewMail(bool)
     KMessageBox::sorry(0, aStr);
     perror("cannot open file "+mailFolder.path()+"/"+mailFolder.name());
     emit finishedCheck(hasNewMail);
+    KMBroadcastStatus::instance()->setStatusMsg( i18n( "Transmission completed..." \
));  return;
   }
 
@@ -125,6 +128,7 @@ void KMAcctLocal::processNewMail(bool)
     kdDebug() << "mailFolder could not be locked" << endl;
     mailFolder.close();
     emit finishedCheck(hasNewMail);
+    KMBroadcastStatus::instance()->setStatusMsg( i18n( "Transmission completed..." \
));  return;
   }
 
@@ -171,8 +174,7 @@ void KMAcctLocal::processNewMail(bool)
   rc = mailFolder.expunge();
   if (rc)
     KMessageBox::information( 0, i18n("Cannot remove mail from\nmailbox \
                `%1':\n%2").arg(mailFolder.location().arg(strerror(rc))));
-  KMBroadcastStatus::instance()->setStatusMsg(
-		     i18n( "Transmission completed..." ));
+    KMBroadcastStatus::instance()->setStatusMsg( i18n( "Transmission completed..." \
));  }
   // else warning is written already
 
@@ -195,6 +197,17 @@ void KMAcctLocal::readConfig(KConfig& co
 
   KMAcctLocalInherited::readConfig(config);
   mLocation = config.readEntry("Location", defaultPath);
+  QString locktype = config.readEntry("LockType", "fcntl" );
+
+  if( locktype == "procmail_lockfile" )
+    mLock = procmail_lockfile;
+  else if( locktype == "mutt_dotlock" )
+    mLock = mutt_dotlock;
+  else if( locktype == "mutt_dotlock_privileged" )
+    mLock = mutt_dotlock_privileged;
+  else if( locktype == "none" )
+    mLock = None;
+  else mLock = FCNTL;
 }
 
 
Index: kmacctlocal.h
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmacctlocal.h,v
retrieving revision 1.6
diff -u -p -B -w -r1.6 kmacctlocal.h
--- kmacctlocal.h	2000/07/10 22:54:51	1.6
+++ kmacctlocal.h	2000/10/05 17:47:43
@@ -5,6 +5,7 @@
 #define kmacctlocal_h
 
 #include "kmaccount.h"
+#include "kmglobal.h"
 
 #define KMAcctLocalInherited KMAccount
 
@@ -33,6 +34,7 @@ public:
 protected:
   QString mLocation;
   bool hasNewMail;
+  LockType mLock;
 };
 
 #endif /*kmacctlocal_h*/
Index: kmfolder.cpp
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmfolder.cpp,v
retrieving revision 1.114
diff -u -p -B -w -r1.114 kmfolder.cpp
--- kmfolder.cpp	2000/09/08 11:02:41	1.114
+++ kmfolder.cpp	2000/10/05 17:47:44
@@ -83,6 +83,7 @@ KMFolder :: KMFolder(KMFolderDir* aParen
   mUnreadMsgs      = -1;
   needsCompact    = FALSE;
   mChild          = 0;
+  mLockType       = FCNTL;
 }
 
 
@@ -304,15 +305,20 @@ int KMFolder::lock()
   fl.l_whence=0;
   fl.l_start=0;
   fl.l_len=0;
-
+  fl.l_pid=-1;
+  QString cmd_str; 
   assert(mStream != NULL);
   mFilesLocked = FALSE;
 
-  rc = fcntl(fileno(mStream), F_SETLK, &fl);
+  switch( mLockType )
+  {
+    case FCNTL:
+      rc = fcntl(fileno(mStream), F_SETLKW, &fl);
 
   if (rc < 0)
   {
-    kdDebug() << "Cannot lock folder `" << (const char*)location() << "': " << \
strerror(errno) << " (" << errno << ")" << endl; +        kdDebug() << "Cannot lock \
folder `" << (const char*)location() << "': " +                  << strerror(errno) \
<< " (" << errno << ")" << endl;  return errno;
   }
 
@@ -322,14 +328,88 @@ int KMFolder::lock()
 
     if (rc < 0)
     {
-      kdDebug() << "Cannot lock index of folder `" << (const char*)location() << "': \
" << strerror(errno) << endl; +          kdDebug() << "Cannot lock index of folder `" \
<< (const char*)location() << "': " +                    << strerror(errno) << " (" \
<< errno << ")" << endl;  rc = errno;
       fl.l_type = F_UNLCK;
       rc = fcntl(fileno(mIndexStream), F_SETLK, &fl);
       return rc;
     }
   }
+      break;
+
+    case procmail_lockfile:
+      cmd_str = "lockfile " + location() + ".lock";
+      rc = system( cmd_str.latin1() );
+      if( rc != 0 )
+      {
+        kdDebug() << "Cannot lock folder `" << (const char*)location() << "': "
+                  << strerror(rc) << " (" << rc << ")" << endl;
+        return rc;
+      }
+      if( mIndexStream )
+      {
+        cmd_str = "lockfile " + indexLocation() + ".lock";
+        rc = system( cmd_str.latin1() );
+        if( rc != 0 )
+        {
+          kdDebug() << "Cannot lock index of folder `" << (const char*)location() << \
"': " +                    << strerror(rc) << " (" << rc << ")" << endl;
+          return rc;
+        }
+      }
+      break;
+
+    case mutt_dotlock:
+      cmd_str = "mutt_dotlock " + location();
+      rc = system( cmd_str.latin1() );
+      if( rc != 0 )
+      {
+        kdDebug() << "Cannot lock folder `" << (const char*)location() << "': "
+                  << strerror(rc) << " (" << rc << ")" << endl;
+        return rc;
+      }
+      if( mIndexStream )
+      {
+        cmd_str = "mutt_dotlock " + indexLocation();
+        rc = system( cmd_str.latin1() );
+        if( rc != 0 )
+        {
+          kdDebug() << "Cannot lock index of folder `" << (const char*)location() << \
"': " +                    << strerror(rc) << " (" << rc << ")" << endl;
+          return rc;
+        }
+      }
+      break;
+
+    case mutt_dotlock_privileged:
+      cmd_str = "mutt_dotlock -p " + location();
+      rc = system( cmd_str.latin1() );
+      if( rc != 0 )
+      {
+        kdDebug() << "Cannot lock folder `" << (const char*)location() << "': "
+                  << strerror(rc) << " (" << rc << ")" << endl;
+        return rc;
+      }
+      if( mIndexStream )
+      {
+        cmd_str = "mutt_dotlock -p " + indexLocation();
+        rc = system( cmd_str.latin1() );
+        if( rc != 0 )
+        {
+          kdDebug() << "Cannot lock index of folder `" << (const char*)location() << \
"': " +                    << strerror(rc) << " (" << rc << ")" << endl;
+          return rc;
+        }
+      }
+      break;
 
+    case None:
+    default:
+      break;
+  }
+
+
   mFilesLocked = TRUE;
   return 0;
 }
@@ -344,17 +424,59 @@ int KMFolder::unlock()
   fl.l_whence=0;
   fl.l_start=0;
   fl.l_len=0;
+  QString cmd_str;
 
   assert(mStream != NULL);
   mFilesLocked = FALSE;
 
+  switch( mLockType )
+  {
+    case FCNTL:
   if (mIndexStream) fcntl(fileno(mIndexStream), F_SETLK, &fl);
-  rc = fcntl(fileno(mStream), F_SETLK, F_UNLCK);
+      fcntl(fileno(mStream), F_SETLK, F_UNLCK);
+      rc = errno;
+      break;
 
-  return errno;
+    case procmail_lockfile:
+      cmd_str = "rm -f " + location() + ".lock";
+      rc = system( cmd_str.latin1() );
+      if( mIndexStream )
+      {
+        cmd_str = "rm -f " + indexLocation() + ".lock";
+        rc = system( cmd_str.latin1() );
 }
+      break;
 
+    case mutt_dotlock:
+      cmd_str = "mutt_dotlock -u " + location();
+      rc = system( cmd_str.latin1() );
+      if( mIndexStream )
+      {
+        cmd_str = "mutt_dotlock -u " + indexLocation();
+        rc = system( cmd_str.latin1() );
+      }
+      break;
+
+    case mutt_dotlock_privileged:
+      cmd_str = "mutt_dotlock -p -u " + location();
+      rc = system( cmd_str.latin1() );
+      if( mIndexStream )
+      {
+        cmd_str = "mutt_dotlock -p -u " + indexLocation();
+        rc = system( cmd_str.latin1() );
+      }
+      break;
+
+    case None:
+    default:
+      rc = 0;
+      break;
+  }
+
+  return rc;
+}
 
+
 //-----------------------------------------------------------------------------
 bool KMFolder::isIndexOutdated()
 {
@@ -1385,4 +1507,9 @@ void KMFolder::correctUnreadMsgsCount()
 }
 
 //-----------------------------------------------------------------------------
+void KMFolder::setLockType( LockType ltype )
+{
+  mLockType = ltype;
+}
+
 #include "kmfolder.moc"
Index: kmfolder.h
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmfolder.h,v
retrieving revision 1.30
diff -u -p -B -w -r1.30 kmfolder.h
--- kmfolder.h	2000/08/30 13:32:26	1.30
+++ kmfolder.h	2000/10/05 17:47:44
@@ -21,6 +21,7 @@
 #include "kmfoldernode.h"
 #include "kmmsginfo.h"
 #include "kmmsglist.h"
+#include "kmglobal.h"
 
 #include <stdio.h>
 #include <qvector.h>
@@ -47,6 +49,8 @@ class KMFolder: public KMFolderNode
   friend class KMMessage;
 
 public:
+  
+  
   /** Usually a parent is given. But in some cases there is no
     fitting parent object available. Then the name of the folder
     is used as the absolute path to the folder file. */
@@ -230,6 +234,8 @@ public:
   /* Returns a string that can be used to identify this folder */
   virtual QString idString();
 
+  void setLockType( LockType ltype=FCNTL );
+  
 signals:
   /** Emitted when the status, name, or associated accounts of this
     folder changed. */
@@ -309,6 +315,7 @@ protected:
   int mUnreadMsgs; // number of unread messages, -1 if not yet set
   bool needsCompact; //sven: true if on destruct folder needs to be compacted.
   KMFolderDir* mChild;
+  LockType mLockType;
 };
 
 #endif /*kmfolder_h*/
Index: kmglobal.h
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmglobal.h,v
retrieving revision 1.19
diff -u -p -B -w -r1.19 kmglobal.h
--- kmglobal.h	2000/03/25 14:04:22	1.19
+++ kmglobal.h	2000/10/05 17:47:44
@@ -17,6 +17,15 @@
 
 #include "kmkernel.h"
 
+typedef enum 
+{
+    FCNTL,
+    procmail_lockfile,
+    mutt_dotlock,
+    mutt_dotlock_privileged,
+    None
+} LockType;
+
 /** The "about KMail" text. */
 extern const char* aboutText;
 #endif


_______________________________________________
Kmail Developers mailing list
Kmail@master.kde.org
http://master.kde.org/mailman/listinfo/kmail


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic