X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=contrib%2Fnotmuch-deliver%2Fsrc%2Fmaildiropen.c;fp=contrib%2Fnotmuch-deliver%2Fsrc%2Fmaildiropen.c;h=5071df7681ea6c052700337e3ad2ded7acb3ddc2;hp=0000000000000000000000000000000000000000;hb=af863f8c7f1f1571df4f1172ec4e963fa654945e;hpb=6a280088e6769015ade7758b9790384997a21ff3 diff --git a/contrib/notmuch-deliver/src/maildiropen.c b/contrib/notmuch-deliver/src/maildiropen.c new file mode 100644 index 00000000..5071df76 --- /dev/null +++ b/contrib/notmuch-deliver/src/maildiropen.c @@ -0,0 +1,141 @@ +/* +** Copyright 2000 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include + +#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); +}