File mutt-1.6.1-opennfs.dif of Package mutt

---
 Makefile.am |    4 -
 lib/file.c  |    7 ++-
 mbox.c      |    5 ++
 mh.c        |    8 +++
 mutt.h      |    3 +
 opennfs.c   |  122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sendlib.c   |    4 +
 7 files changed, 150 insertions(+), 3 deletions(-)

--- Makefile.am
+++ Makefile.am	2017-09-11 11:47:43.214350183 +0000
@@ -52,7 +52,7 @@ mutt_SOURCES = account.c addrbook.c addr
 	handler.c hdrline.c header.h headers.c help.c history.c hook.c \
 	init.c keymap.c list.h main.c mbox.c mbyte.c mbtable.h \
 	menu.c mh.c muttlib.c mutt_idna.c mutt_sasl_plain.c mutt_socket.c \
-	mutt_tunnel.c mx.c newsrc.c nntp.c options.h pager.c parameter.c parameter.h \
+	mutt_tunnel.c mx.c newsrc.c nntp.c opennfs.c options.h pager.c parameter.c parameter.h \
 	parse.c pattern.c pattern.h pop.c pop_auth.c pop_lib.c postpone.c \
 	query.c recvattach.c recvcmd.c rfc1524.c rfc2047.c rfc2231.c rfc3676.c \
 	rfc822.c safe_asprintf.c score.c send.c sendlib.c sidebar.c signal.c \
@@ -96,7 +96,7 @@ EXTRA_DIST = account.h attach.h bcache.h
 
 EXTRA_SCRIPTS =
 
-pgpring_SOURCES = pgppubring.c
+pgpring_SOURCES = opennfs.c pgppubring.c
 pgpring_LDADD = $(LIBOBJS) $(NCRYPT_LIBS) $(INTLLIBS) $(LIBMUTT)
 pgpring_DEPENDENCIES = $(LIBOBJS) $(NCRYPT_DEPS) $(INTLDEPS) $(LIBMUTTDEPS)
 
--- lib/file.c
+++ lib/file.c	2017-09-11 11:45:32.960743565 +0000
@@ -71,6 +71,7 @@
 #include "debug.h"
 #include "memory.h"
 #include "message.h"
+#include "mutt.h"
 #include "string2.h"
 
 /* these characters must be escaped in regular expressions */
@@ -502,6 +503,10 @@ int safe_open(const char *path, int flag
   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];
@@ -526,7 +531,7 @@ int safe_open(const char *path, int flag
   fd = open(path, flags & ~O_EXCL, 0600);
   if (fd < 0)
     return fd;
-
+#endif
   /* make sure the file is not symlink */
   if ((lstat(path, &osb) < 0 || fstat(fd, &nsb) < 0) || !compare_stat(&osb, &nsb))
   {
--- mbox.c
+++ mbox.c	2017-09-11 11:40:15.902567799 +0000
@@ -1075,8 +1075,13 @@ static int mbox_sync_mailbox(struct Cont
 
   /* Create a temporary file to write the new version of the mailbox in. */
   mutt_mktemp(tempfile, sizeof(tempfile));
+#if defined(__linux__)
+  if ((i = opennfs(tempfile, O_WRONLY | O_EXCL | O_CREAT, 0600)) == -1 ||
+      (fp = fdopen(i, "w")) == NULL)
+#else
   if ((i = open(tempfile, O_WRONLY | O_EXCL | O_CREAT, 0600)) == -1 ||
       (fp = fdopen(i, "w")) == NULL)
+#endif
   {
     if (-1 != i)
     {
--- mh.c
+++ mh.c	2017-09-11 11:49:25.892463230 +0000
@@ -383,7 +383,11 @@ static int mh_mkstemp(struct Context *de
   {
     snprintf(path, _POSIX_PATH_MAX, "%s/.mutt-%s-%d-%" PRIu64, dest->path,
              NONULL(ShortHostname), (int) getpid(), mutt_rand64());
+#if defined(__linux__)
+    if ((fd = opennfs(path, O_WRONLY | O_EXCL | O_CREAT, 0666)) == -1)
+#else
     if ((fd = open(path, O_WRONLY | O_EXCL | O_CREAT, 0666)) == -1)
+#endif
     {
       if (errno != EEXIST)
       {
@@ -1518,7 +1522,11 @@ static int maildir_open_new_message(stru
 
     mutt_debug(2, "maildir_open_new_message (): Trying %s.\n", path);
 
+#if defined(__linux__)
+    if ((fd = opennfs(path, O_WRONLY | O_EXCL | O_CREAT, 0666)) == -1)
+#else
     if ((fd = open(path, O_WRONLY | O_EXCL | O_CREAT, 0666)) == -1)
+#endif
     {
       if (errno != EEXIST)
       {
--- mutt.h
+++ mutt.h	2017-09-11 11:50:18.979487541 +0000
@@ -367,4 +367,7 @@ extern char *debugfile_cmdline;
 extern int debuglevel_cmdline;
 #endif
 
+#if defined(__linux__)
+extern int opennfs(const char *, int, int);
+#endif
 #endif /* _MUTT_H */
--- opennfs.c
+++ opennfs.c	2017-09-11 11:40:15.906567726 +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	2017-09-11 11:40:15.906567726 +0000
@@ -2354,7 +2354,11 @@ static int send_msg(const char *path, ch
       if (SendmailWait >= 0 && tempfile && *tempfile)
       {
         /* *tempfile will be opened as stdout */
+#if defined(__linux__)
+        if (opennfs(*tempfile, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0600) < 0)
+#else
         if (open(*tempfile, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0600) < 0)
+#endif
           _exit(S_ERR);
         /* redirect stderr to *tempfile too */
         if (dup(1) < 0)
openSUSE Build Service is sponsored by