summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan/generic/maildirdriver_message.c
Unidiff
Diffstat (limited to 'kmicromail/libetpan/generic/maildirdriver_message.c') (more/less context) (show whitespace changes)
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_message.c199
1 files changed, 199 insertions, 0 deletions
diff --git a/kmicromail/libetpan/generic/maildirdriver_message.c b/kmicromail/libetpan/generic/maildirdriver_message.c
new file mode 100644
index 0000000..7cf9dd1
--- a/dev/null
+++ b/kmicromail/libetpan/generic/maildirdriver_message.c
@@ -0,0 +1,199 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "maildirdriver_message.h"
37
38#include "mailmessage_tools.h"
39#include "maildirdriver.h"
40#include "maildir.h"
41#include "generic_cache.h"
42
43#include <unistd.h>
44#include <sys/mman.h>
45#include <sys/types.h>
46#include <sys/stat.h>
47#include <fcntl.h>
48#include <string.h>
49#include <stdlib.h>
50
51static int prefetch(mailmessage * msg_info);
52
53static void prefetch_free(struct generic_message_t * msg);
54
55static int initialize(mailmessage * msg_info);
56
57static void check(mailmessage * msg_info);
58
59static mailmessage_driver local_maildir_message_driver = {
60 .msg_name = "maildir",
61
62 .msg_initialize = initialize,
63 .msg_uninitialize = mailmessage_generic_uninitialize,
64
65 .msg_flush = mailmessage_generic_flush,
66 .msg_check = check,
67
68 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
69
70 .msg_fetch = mailmessage_generic_fetch,
71 .msg_fetch_header = mailmessage_generic_fetch_header,
72 .msg_fetch_body = mailmessage_generic_fetch_header,
73 .msg_fetch_size = NULL,
74 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
75 .msg_fetch_section = mailmessage_generic_fetch_section,
76 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
77 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
78 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
79 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
80
81 .msg_get_flags = NULL,
82};
83
84mailmessage_driver * maildir_message_driver = &local_maildir_message_driver;
85
86struct maildir_msg_data {
87 int fd;
88};
89
90static inline struct maildir_session_state_data *
91get_session_data(mailmessage * msg)
92{
93 return msg->msg_session->sess_data;
94}
95
96static struct maildir * get_maildir_session(mailmessage * msg)
97{
98 return get_session_data(msg)->md_session;
99}
100
101static int prefetch(mailmessage * msg_info)
102{
103 struct generic_message_t * msg;
104 int res;
105 struct maildir_msg_data * data;
106 char * filename;
107 int fd;
108 char * mapping;
109 struct maildir * md;
110
111 md = get_maildir_session(msg_info);
112
113 if (msg_info->msg_uid == NULL) {
114 res = MAIL_ERROR_INVAL;
115 goto err;
116 }
117
118 filename = maildir_message_get(md, msg_info->msg_uid);
119 if (filename == NULL) {
120 res = MAIL_ERROR_MEMORY;
121 goto err;
122 }
123
124 fd = open(filename, O_RDONLY);
125 free(filename);
126 if (fd == -1) {
127 res = MAIL_ERROR_FILE;
128 goto err;
129 }
130
131 mapping = mmap(NULL, msg_info->msg_size, PROT_READ, MAP_PRIVATE, fd, 0);
132 if (mapping == MAP_FAILED) {
133 res = MAIL_ERROR_FILE;
134 goto close;
135 }
136
137 data = malloc(sizeof(* data));
138 if (data == NULL) {
139 res = MAIL_ERROR_MEMORY;
140 goto unmap;
141 }
142
143 data->fd = fd;
144
145 msg = msg_info->msg_data;
146
147 msg->msg_data = data;
148 msg->msg_message = mapping;
149 msg->msg_length = msg_info->msg_size;
150
151 return MAIL_NO_ERROR;
152
153 unmap:
154 munmap(mapping, msg_info->msg_size);
155 close:
156 close(fd);
157 err:
158 return res;
159}
160
161static void prefetch_free(struct generic_message_t * msg)
162{
163 if (msg->msg_message != NULL) {
164 struct maildir_msg_data * data;
165
166 munmap(msg->msg_message, msg->msg_length);
167 msg->msg_message = NULL;
168 data = msg->msg_data;
169 close(data->fd);
170 free(data);
171 }
172}
173
174static int initialize(mailmessage * msg_info)
175{
176 struct generic_message_t * msg;
177 int r;
178
179 r = mailmessage_generic_initialize(msg_info);
180 if (r != MAIL_NO_ERROR)
181 return r;
182
183 msg = msg_info->msg_data;
184 msg->msg_prefetch = prefetch;
185 msg->msg_prefetch_free = prefetch_free;
186
187 return MAIL_NO_ERROR;
188}
189
190static void check(mailmessage * msg_info)
191{
192 int r;
193
194 if (msg_info->msg_flags != NULL) {
195 r = mail_flags_store_set(get_session_data(msg_info)->md_flags_store,
196 msg_info);
197 /* ignore errors */
198 }
199}