File mutt-1.5.21-opennfs.dif of Package mutt

--- Makefile.am
+++ Makefile.am	2009-03-02 23:00:00.000000000 +0000
@@ -27,7 +27,7 @@ mutt_SOURCES = \
 	edit.c enter.c flags.c init.c filter.c from.c \
 	getdomain.c group.c \
 	handler.c hash.c hdrline.c headers.c help.c hook.c keymap.c \
-	main.c mbox.c menu.c mh.c mx.c pager.c parse.c pattern.c \
+	main.c mbox.c menu.c mh.c mx.c opennfs.c pager.c parse.c pattern.c \
 	postpone.c query.c recvattach.c recvcmd.c \
 	rfc822.c rfc1524.c rfc2047.c rfc2231.c rfc3676.c \
 	score.c send.c sendlib.c signal.c sort.c \
@@ -83,7 +83,7 @@ mutt_dotlock_SOURCES = mutt_dotlock.c
 mutt_dotlock_LDADD = @LIBOBJS@
 mutt_dotlock_DEPENDENCIES = @LIBOBJS@
 
-pgpring_SOURCES = pgppubring.c pgplib.c lib.c extlib.c sha1.c md5.c pgppacket.c ascii.c
+pgpring_SOURCES = pgppubring.c pgplib.c lib.c extlib.c sha1.c opennfs.c md5.c pgppacket.c ascii.c
 pgpring_LDADD = @LIBOBJS@ $(INTLLIBS) 
 pgpring_DEPENDENCIES = @LIBOBJS@ $(INTLDEPS)
 
--- Makefile.in
+++ Makefile.in	2009-03-03 16:00:38.000000000 +0000
@@ -77,7 +77,7 @@ am_mutt_OBJECTS = addrbook.$(OBJEXT) ali
 	hash.$(OBJEXT) hdrline.$(OBJEXT) headers.$(OBJEXT) \
 	help.$(OBJEXT) hook.$(OBJEXT) keymap.$(OBJEXT) main.$(OBJEXT) \
 	mbox.$(OBJEXT) menu.$(OBJEXT) mh.$(OBJEXT) mx.$(OBJEXT) \
-	pager.$(OBJEXT) parse.$(OBJEXT) pattern.$(OBJEXT) \
+	opennfs.$(OBJEXT) pager.$(OBJEXT) parse.$(OBJEXT) pattern.$(OBJEXT) \
 	postpone.$(OBJEXT) query.$(OBJEXT) recvattach.$(OBJEXT) \
 	recvcmd.$(OBJEXT) rfc822.$(OBJEXT) rfc1524.$(OBJEXT) \
 	rfc2047.$(OBJEXT) rfc2231.$(OBJEXT) rfc3676.$(OBJEXT) \
@@ -105,7 +105,7 @@ pgpewrap_LDADD = $(LDADD)
 pgpewrap_DEPENDENCIES = @LIBOBJS@
 am_pgpring_OBJECTS = pgppubring.$(OBJEXT) pgplib.$(OBJEXT) \
 	lib.$(OBJEXT) extlib.$(OBJEXT) sha1.$(OBJEXT) md5.$(OBJEXT) \
-	pgppacket.$(OBJEXT) ascii.$(OBJEXT)
+	pgppacket.$(OBJEXT) ascii.$(OBJEXT) opennfs.$(OBJEXT)
 pgpring_OBJECTS = $(am_pgpring_OBJECTS)
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
@@ -354,7 +354,7 @@ mutt_SOURCES = \
 	edit.c enter.c flags.c init.c filter.c from.c \
 	getdomain.c group.c \
 	handler.c hash.c hdrline.c headers.c help.c hook.c keymap.c \
-	main.c mbox.c menu.c mh.c mx.c pager.c parse.c pattern.c \
+	main.c mbox.c menu.c mh.c mx.c opennfs.c pager.c parse.c pattern.c \
 	postpone.c query.c recvattach.c recvcmd.c \
 	rfc822.c rfc1524.c rfc2047.c rfc2231.c rfc3676.c \
 	score.c send.c sendlib.c signal.c sort.c \
--- lib.c
+++ lib.c	2009-03-02 23:00:00.000000000 +0000
@@ -50,6 +50,7 @@
 #define EX_OK 0
 #endif
 
+#include "mutt.h"
 #include "lib.h"
 
 
@@ -632,6 +633,10 @@ int safe_open (const char *path, int fla
   struct stat osb, nsb;
   int fd;
 
+#if defined(__linux__)
+  if ((fd = opennfs (path, flags, 0600)) < 0)
+    return fd;
+#else
   if (flags & O_EXCL) 
   {
     char safe_file[_POSIX_PATH_MAX];
@@ -655,7 +660,7 @@ int safe_open (const char *path, int fla
 
   if ((fd = open (path, flags & ~O_EXCL, 0600)) < 0)
     return fd;
-    
+#endif
   /* make sure the file is not symlink */
   if (lstat (path, &osb) < 0 || fstat (fd, &nsb) < 0 ||
       compare_stat(&osb, &nsb) == -1)
--- mbox.c
+++ mbox.c	2010-11-04 14:01:04.775926675 +0000
@@ -782,7 +782,7 @@ int mbox_sync_mailbox (CONTEXT *ctx, int
 
   /* Create a temporary file to write the new version of the mailbox in. */
   mutt_mktemp (tempfile, sizeof (tempfile));
-  if ((i = open (tempfile, O_WRONLY | O_EXCL | O_CREAT, 0600)) == -1 ||
+  if ((i = opennfs (tempfile, O_WRONLY | O_EXCL | O_CREAT, 0600)) == -1 ||
       (fp = fdopen (i, "w")) == NULL)
   {
     if (-1 != i)
--- mh.c
+++ mh.c	2009-03-02 23:00:00.000000000 +0000
@@ -277,7 +277,11 @@ static int mh_mkstemp (CONTEXT * dest, F
   {
     snprintf (path, _POSIX_PATH_MAX, "%s/.mutt-%s-%d-%d",
 	      dest->path, NONULL (Hostname), (int) getpid (), Counter++);
+#if defined(__linux__)
+    if ((fd = opennfs (path, O_WRONLY | O_EXCL | O_CREAT, 0600)) == -1)
+#else
     if ((fd = open (path, O_WRONLY | O_EXCL | O_CREAT, 0666)) == -1)
+#endif
     {
       if (errno != EEXIST)
       {
@@ -1290,8 +1294,11 @@ int maildir_open_new_message (MESSAGE *
 
     dprint (2, (debugfile, "maildir_open_new_message (): Trying %s.\n",
 		path));
-
+#if defined(__linux__)
+    if ((fd = opennfs (path, O_WRONLY | O_EXCL | O_CREAT, 0600)) == -1)
+#else
     if ((fd = open (path, O_WRONLY | O_EXCL | O_CREAT, 0666)) == -1)
+#endif
     {
       if (errno != EEXIST)
       {
--- mutt.h
+++ mutt.h	2009-03-02 23:00:00.000000000 +0000
@@ -972,4 +972,5 @@ typedef struct
 #include "lib.h"
 #include "globals.h"
 
+extern int opennfs(const char *, int, int);
 #endif /*MUTT_H*/
--- opennfs.c
+++ opennfs.c	2009-03-02 23:00:00.000000000 +0000
@@ -0,0 +1,122 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <limits.h>
+#include <nfs/nfs.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/vfs.h>
+#include <unistd.h>
+
+#ifndef  NFS_SUPER_MAGIC
+# define NFS_SUPER_MAGIC 0x6969
+#endif
+
+int opennfs(const char *path, int flags, int mode)
+{
+    char tmplock[NFS_MAXPATHLEN+1], sysname[256];
+    char *slash, *ptr, *dir, *base, *clear = (char*)0;
+    struct stat ps, ts;
+    struct statfs fs;
+    ssize_t len;
+    int ret;
+
+    if ((flags & (O_WRONLY|O_RDWR)) == 0)
+	goto safe;
+
+    if ((flags & (O_EXCL|O_CREAT)) != (O_EXCL|O_CREAT))
+	goto safe;
+
+#if defined(O_NOFOLLOW)
+    flags |= O_NOFOLLOW;
+#endif
+
+    ret = -1;
+    if ((clear = strdup(path)) == (char*)0)
+	goto err;
+    dir = dirname(clear);
+
+    if ((ret = (statfs(dir, &fs))) < 0)
+	goto err;
+
+    if (fs.f_type != NFS_SUPER_MAGIC)
+	goto safe;
+
+    if ((ret = gethostname(sysname, sizeof(sysname))) < 0)
+	goto err;
+
+    ret = -1;
+    ptr = &tmplock[0];
+    if (((len = snprintf(ptr, NFS_MAXPATHLEN, "%s/.%s-XXXXXX", dir, sysname)) < 0) || (len >= NFS_MAXPATHLEN))
+	goto err;
+    ptr += len;
+    slash = ptr;
+
+    free(clear);
+    clear = (char*)0;
+
+    if (mkdtemp(tmplock) == (char*)0)
+	goto err;
+
+    ret = -1;
+    if ((clear = strdup(path)) == (char*)0)
+	goto rmd;
+    base = basename(clear);
+
+    ret = -1;
+    if (((len = snprintf(ptr, NFS_MAXPATHLEN - len, "/%s", base)) < 0) || (len >= (NFS_MAXPATHLEN - len)))
+	goto rmd;
+
+    free(clear);
+    clear = (char*)0;
+
+    if ((ret = open(tmplock, flags, mode)) < 0)
+	goto rmd;
+
+    errno = 0;
+    do {
+	len = write(ret, "0", 2);
+    } while ((len < 0) && (errno == EINTR));
+    close(ret);
+
+    ret = -1;
+    errno = EBADF;
+    if (len != 2)
+	goto unl;
+
+    errno = 0;
+    if ((ret = lstat(tmplock, &ts)) < 0)
+	goto unl;
+
+    if (((ret = link(tmplock, path)) < 0) && (errno == EEXIST))
+	goto unl;
+
+    if ((ret = lstat(path, &ps)) < 0)
+	goto unl;
+
+    ret = -1;
+    errno = EEXIST;
+    if (ps.st_nlink != 2)
+	goto unl;
+    if ((ps.st_rdev != ts.st_rdev) || (ps.st_ino != ts.st_ino))
+	goto unl;
+
+    errno = 0;
+    flags |= O_TRUNC;
+    flags &= ~(O_EXCL|O_CREAT);
+    ret = open(path, flags, mode);
+unl:
+    unlink(tmplock);
+rmd:
+    *slash = '\0';
+    rmdir(tmplock);
+err:
+    if (clear) free(clear);
+    return ret;
+safe:
+    if (clear) free(clear);
+    return open(path, flags, mode);
+}
--- sendlib.c
+++ sendlib.c	2009-03-02 23:00:00.000000000 +0000
@@ -2216,7 +2216,7 @@ send_msg (const char *path, char **args,
       if (SendmailWait >= 0 && tempfile && *tempfile)
       {
 	/* *tempfile will be opened as stdout */
-	if (open (*tempfile, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0600) < 0)
+	if (opennfs (*tempfile, O_WRONLY | O_CREAT | O_EXCL, 0600) < 0)
 	  _exit (S_ERR);
 	/* redirect stderr to *tempfile too */
 	if (dup (1) < 0)