]> git.notmuchmail.org Git - notmuch/blobdiff - contrib/notmuch-deliver/src/maildiropen.c
notmuch-deliver: Initial import
[notmuch] / contrib / notmuch-deliver / src / maildiropen.c
diff --git a/contrib/notmuch-deliver/src/maildiropen.c b/contrib/notmuch-deliver/src/maildiropen.c
new file mode 100644 (file)
index 0000000..5071df7
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+** Copyright 2000 Double Precision, Inc.
+** See COPYING for distribution information.
+*/
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include       <sys/types.h>
+#include       <sys/stat.h>
+#include       <string.h>
+#include       <stdlib.h>
+#include       <time.h>
+#if    HAVE_UNISTD_H
+#include       <unistd.h>
+#endif
+#include       <stdio.h>
+#include       <ctype.h>
+#include       <errno.h>
+#include       <fcntl.h>
+
+#include       "maildirmisc.h"
+
+static const char rcsid[]="$Id: maildiropen.c,v 1.8 2003/01/19 16:39:52 mrsam Exp $";
+
+char *maildir_getlink(const char *filename)
+{
+#if     HAVE_READLINK
+size_t bufsiz;
+char   *buf;
+
+       bufsiz=0;
+       buf=0;
+
+       for (;;)
+       {
+       int     n;
+
+               if (buf)        free(buf);
+               bufsiz += 256;
+               if ((buf=malloc(bufsiz)) == 0)
+               {
+                       perror("malloc");
+                       return (0);
+               }
+               if ((n=readlink(filename, buf, bufsiz)) < 0)
+               {
+                       free(buf);
+                       return (0);
+               }
+               if (n < bufsiz)
+               {
+                       buf[n]=0;
+                       break;
+               }
+       }
+       return (buf);
+#else
+       return (0);
+#endif
+}
+
+int maildir_semisafeopen(const char *path, int mode, int perm)
+{
+
+#if    HAVE_READLINK
+
+char   *l=maildir_getlink(path);
+
+       if (l)
+       {
+       int     f;
+
+               if (*l != '/')
+               {
+               char    *q=malloc(strlen(path)+strlen(l)+2);
+               char    *s;
+
+                       if (!q)
+                       {
+                               free(l);
+                               return (-1);
+                       }
+
+                       strcpy(q, path);
+                       if ((s=strchr(q, '/')) != 0)
+                               s[1]=0;
+                       else    *q=0;
+                       strcat(q, l);
+                       free(l);
+                       l=q;
+               }
+
+               f=maildir_safeopen(l, mode, perm);
+
+               free(l);
+               return (f);
+       }
+#endif
+
+       return (maildir_safeopen(path, mode, perm));
+}
+               
+int maildir_safeopen(const char *path, int mode, int perm)
+{
+       struct  stat    stat1;
+
+       return maildir_safeopen_stat(path, mode, perm, &stat1);
+}
+
+int maildir_safeopen_stat(const char *path, int mode, int perm,
+                         struct stat *stat1)
+{
+       struct  stat    stat2;
+
+       int     fd=open(path, mode
+#ifdef O_NONBLOCK
+                       | O_NONBLOCK
+#else
+                       | O_NDELAY
+#endif
+                       , perm);
+
+       if (fd < 0)     return (fd);
+       if (fcntl(fd, F_SETFL, (mode & O_APPEND)) || fstat(fd, stat1)
+           || lstat(path, &stat2))
+       {
+               close(fd);
+               return (-1);
+       }
+
+       if (stat1->st_dev != stat2.st_dev || stat1->st_ino != stat2.st_ino)
+       {
+               close(fd);
+               errno=ENOENT;
+               return (-1);
+       }
+
+       return (fd);
+}