diff options
| author | manuel <manuel@mausz.at> | 2013-02-04 02:48:34 +0100 |
|---|---|---|
| committer | manuel <manuel@mausz.at> | 2013-02-04 02:48:34 +0100 |
| commit | 5d47a7101a2394c7f7bb288585464fa293a2ad33 (patch) | |
| tree | 0c371687c8791b2278c5b8049bbd64a7de1d0863 /maildiropen.c | |
| parent | 86d5a6ec30ceea44e9459394d2e6403642cdd158 (diff) | |
| download | qmail-5d47a7101a2394c7f7bb288585464fa293a2ad33.tar.gz qmail-5d47a7101a2394c7f7bb288585464fa293a2ad33.tar.bz2 qmail-5d47a7101a2394c7f7bb288585464fa293a2ad33.zip | |
[PATCH] maildir++ for qmail-local and qmail-pop3d
Patch to make qmail-local and qmail-pop3d compatible with the maildir++ quota
system that is used by vpopmail and courier-imap
qmail-maildir++
Diffstat (limited to 'maildiropen.c')
| -rw-r--r-- | maildiropen.c | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/maildiropen.c b/maildiropen.c new file mode 100644 index 0000000..bcaadd4 --- /dev/null +++ b/maildiropen.c | |||
| @@ -0,0 +1,133 @@ | |||
| 1 | /* | ||
| 2 | ** Copyright 2000 Double Precision, Inc. | ||
| 3 | ** See COPYING for distribution information. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #if HAVE_CONFIG_H | ||
| 7 | #include "config.h" | ||
| 8 | #endif | ||
| 9 | |||
| 10 | #include <sys/types.h> | ||
| 11 | #include <sys/stat.h> | ||
| 12 | #include <string.h> | ||
| 13 | #include <stdlib.h> | ||
| 14 | #include <time.h> | ||
| 15 | #if HAVE_UNISTD_H | ||
| 16 | #include <unistd.h> | ||
| 17 | #endif | ||
| 18 | #include <stdio.h> | ||
| 19 | #include <ctype.h> | ||
| 20 | #include <errno.h> | ||
| 21 | #include <fcntl.h> | ||
| 22 | |||
| 23 | #include "maildirmisc.h" | ||
| 24 | |||
| 25 | static const char rcsid[]="$Id: maildiropen.c,v 1.7 2000/12/10 04:43:44 mrsam Exp $"; | ||
| 26 | |||
| 27 | char *maildir_getlink(const char *filename) | ||
| 28 | { | ||
| 29 | #if HAVE_READLINK | ||
| 30 | size_t bufsiz; | ||
| 31 | char *buf; | ||
| 32 | |||
| 33 | bufsiz=0; | ||
| 34 | buf=0; | ||
| 35 | |||
| 36 | for (;;) | ||
| 37 | { | ||
| 38 | int n; | ||
| 39 | |||
| 40 | if (buf) free(buf); | ||
| 41 | bufsiz += 256; | ||
| 42 | if ((buf=malloc(bufsiz)) == 0) | ||
| 43 | { | ||
| 44 | perror("malloc"); | ||
| 45 | return (0); | ||
| 46 | } | ||
| 47 | if ((n=readlink(filename, buf, bufsiz)) < 0) | ||
| 48 | { | ||
| 49 | free(buf); | ||
| 50 | return (0); | ||
| 51 | } | ||
| 52 | if (n < bufsiz) | ||
| 53 | { | ||
| 54 | buf[n]=0; | ||
| 55 | break; | ||
| 56 | } | ||
| 57 | } | ||
| 58 | return (buf); | ||
| 59 | #else | ||
| 60 | return (0); | ||
| 61 | #endif | ||
| 62 | } | ||
| 63 | |||
| 64 | int maildir_semisafeopen(const char *path, int mode, int perm) | ||
| 65 | { | ||
| 66 | |||
| 67 | #if HAVE_READLINK | ||
| 68 | |||
| 69 | char *l=maildir_getlink(path); | ||
| 70 | |||
| 71 | if (l) | ||
| 72 | { | ||
| 73 | int f; | ||
| 74 | |||
| 75 | if (*l != '/') | ||
| 76 | { | ||
| 77 | char *q=malloc(strlen(path)+strlen(l)+2); | ||
| 78 | char *s; | ||
| 79 | |||
| 80 | if (!q) | ||
| 81 | { | ||
| 82 | free(l); | ||
| 83 | return (-1); | ||
| 84 | } | ||
| 85 | |||
| 86 | strcpy(q, path); | ||
| 87 | if ((s=strchr(q, '/')) != 0) | ||
| 88 | s[1]=0; | ||
| 89 | else *q=0; | ||
| 90 | strcat(q, l); | ||
| 91 | free(l); | ||
| 92 | l=q; | ||
| 93 | } | ||
| 94 | |||
| 95 | f=maildir_safeopen(l, mode, perm); | ||
| 96 | |||
| 97 | free(l); | ||
| 98 | return (f); | ||
| 99 | } | ||
| 100 | #endif | ||
| 101 | |||
| 102 | return (maildir_safeopen(path, mode, perm)); | ||
| 103 | } | ||
| 104 | |||
| 105 | int maildir_safeopen(const char *path, int mode, int perm) | ||
| 106 | { | ||
| 107 | struct stat stat1, stat2; | ||
| 108 | |||
| 109 | int fd=open(path, mode | ||
| 110 | #ifdef O_NONBLOCK | ||
| 111 | | O_NONBLOCK | ||
| 112 | #else | ||
| 113 | | O_NDELAY | ||
| 114 | #endif | ||
| 115 | , perm); | ||
| 116 | |||
| 117 | if (fd < 0) return (fd); | ||
| 118 | if (fcntl(fd, F_SETFL, (mode & O_APPEND)) || fstat(fd, &stat1) | ||
| 119 | || lstat(path, &stat2)) | ||
| 120 | { | ||
| 121 | close(fd); | ||
| 122 | return (-1); | ||
| 123 | } | ||
| 124 | |||
| 125 | if (stat1.st_dev != stat2.st_dev || stat1.st_ino != stat2.st_ino) | ||
| 126 | { | ||
| 127 | close(fd); | ||
| 128 | errno=ENOENT; | ||
| 129 | return (-1); | ||
| 130 | } | ||
| 131 | |||
| 132 | return (fd); | ||
| 133 | } | ||
