summaryrefslogtreecommitdiffstats
path: root/maildiropen.c
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2013-02-04 02:48:34 +0100
committermanuel <manuel@mausz.at>2013-02-04 02:48:34 +0100
commit5d47a7101a2394c7f7bb288585464fa293a2ad33 (patch)
tree0c371687c8791b2278c5b8049bbd64a7de1d0863 /maildiropen.c
parent86d5a6ec30ceea44e9459394d2e6403642cdd158 (diff)
downloadqmail-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.c133
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
25static const char rcsid[]="$Id: maildiropen.c,v 1.7 2000/12/10 04:43:44 mrsam Exp $";
26
27char *maildir_getlink(const char *filename)
28{
29#if HAVE_READLINK
30size_t bufsiz;
31char *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
64int maildir_semisafeopen(const char *path, int mode, int perm)
65{
66
67#if HAVE_READLINK
68
69char *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
105int maildir_safeopen(const char *path, int mode, int perm)
106{
107struct stat stat1, stat2;
108
109int 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}