header.c header.h header0.h mailbox.c mailbox.h mailbox0.h
mbx_imap.c mbx_mbox.c mbx_mdir.c mbx_mh.c mbx_mmdf.c mbx_pop.c mbx_unix.c cleaning and pruning.
Showing
13 changed files
with
1015 additions
and
1877 deletions
... | @@ -25,299 +25,44 @@ | ... | @@ -25,299 +25,44 @@ |
25 | #include <stdlib.h> | 25 | #include <stdlib.h> |
26 | #include <errno.h> | 26 | #include <errno.h> |
27 | 27 | ||
28 | static int rfc822_parse (header_t h, const char *blurb, size_t len); | ||
29 | static int rfc822_set_value (header_t h, const char *fn, const char *fb, | ||
30 | size_t n, int replace); | ||
31 | static int rfc822_get_value (header_t h, const char *fn, | ||
32 | char *fb, size_t len, size_t *n); | ||
33 | static int rfc822_get_mvalue (header_t h, const char *fn, | ||
34 | char **fb, size_t *n); | ||
35 | |||
36 | struct _hdr | ||
37 | { | ||
38 | char *fn; | ||
39 | char *fb; | ||
40 | }; | ||
41 | typedef struct _hdr *hdr_t; | ||
42 | |||
43 | struct _rfc822_data | ||
44 | { | ||
45 | char *blurb; | ||
46 | struct _hdr unixfrom; /* stupid hack for unix from */ | ||
47 | size_t hdr_count; | ||
48 | struct _hdr *hdr; | ||
49 | }; | ||
50 | typedef struct _rfc822_data *rfc822_t; | ||
51 | |||
52 | |||
53 | int | 28 | int |
54 | header_init (header_t *ph, const char *blurb, size_t len, int flag) | 29 | header_init (header_t *ph, const char *blurb, size_t len, int flag) |
55 | { | 30 | { |
56 | header_t h; | 31 | if (flag != MU_HEADER_RFC822) |
57 | if (flag != MU_HDR_RFC822) | 32 | return ENOTSUP; |
58 | { | 33 | return rfc822_init (ph, blurb, len); |
59 | return ENOTSUP; | ||
60 | } | ||
61 | h = calloc (1, sizeof (*h)); | ||
62 | if (h == NULL) | ||
63 | { | ||
64 | return ENOMEM; | ||
65 | } | ||
66 | h->_parse = rfc822_parse; | ||
67 | h->_get_value = rfc822_get_value; | ||
68 | h->_get_mvalue = rfc822_get_mvalue; | ||
69 | h->_set_value = rfc822_set_value; | ||
70 | |||
71 | h->_parse (h, blurb, len); | ||
72 | *ph = h; | ||
73 | return 0; | ||
74 | } | 34 | } |
75 | 35 | ||
76 | void | 36 | void |
77 | header_destroy (header_t *ph) | 37 | header_destroy (header_t *ph) |
78 | { | 38 | { |
79 | if (ph && *ph) | 39 | if (ph && *ph) |
80 | { | 40 | (*ph)->_destroy (ph); |
81 | header_t h = *ph; | ||
82 | if (h->data) | ||
83 | { | ||
84 | rfc822_t rfc = (rfc822_t)h->data; | ||
85 | if (rfc->hdr) | ||
86 | free (rfc->hdr); | ||
87 | if (rfc->blurb) | ||
88 | free (rfc->blurb); | ||
89 | free (rfc); | ||
90 | } | ||
91 | free (h); | ||
92 | *ph = NULL; | ||
93 | } | ||
94 | } | 41 | } |
95 | 42 | ||
43 | /* stub functions */ | ||
96 | int | 44 | int |
97 | header_gvalue (const char *blurb, size_t blurb_len, const char *fn, char *fb, | 45 | header_set_value (header_t h, const char *fn, const char *fb, size_t n, |
98 | size_t len, size_t *n) | 46 | int replace) |
99 | { | 47 | { |
100 | const char *header_end; | 48 | if (h == NULL) |
101 | const char *header_start; | 49 | return EINVAL; |
102 | const char *colon; | 50 | return h->_set_value (h, fn, fb, n, replace); |
103 | size_t i = 0; | ||
104 | size_t j = 0; | ||
105 | size_t fn_len; | ||
106 | int status = EINVAL; | ||
107 | |||
108 | if (blurb == NULL || blurb_len < 5 || fn == NULL || len == 0) | ||
109 | { | ||
110 | return status; | ||
111 | } | ||
112 | |||
113 | *fb = '\0'; /* if we did find something, return empty */ | ||
114 | for (fn_len = strlen (fn), header_start = blurb;;header_start = header_end) | ||
115 | { | ||
116 | header_end = memchr (header_start, '\n', blurb_len); | ||
117 | if (header_end == NULL) | ||
118 | { | ||
119 | break; | ||
120 | } | ||
121 | header_end++; | ||
122 | blurb_len -= header_end - header_start; | ||
123 | colon = memchr (header_start, ':', header_end - header_start); | ||
124 | if (colon == NULL) | ||
125 | { | ||
126 | continue; | ||
127 | } | ||
128 | /* check if is the header field name */ | ||
129 | j = colon - header_start; | ||
130 | if (fn_len == j) | ||
131 | { | ||
132 | if (memcmp (fn, header_start, fn_len) == 0) | ||
133 | { | ||
134 | i = header_end - colon -1; | ||
135 | if (fb) | ||
136 | { | ||
137 | i = (len < i) ? len : i; | ||
138 | memcpy (fb, colon +1, i); | ||
139 | fb[i - 1] = '\0'; | ||
140 | } | ||
141 | status = 0; | ||
142 | break; | ||
143 | } | ||
144 | } | ||
145 | } | ||
146 | |||
147 | if (n) | ||
148 | *n = i; | ||
149 | return status; | ||
150 | } | 51 | } |
151 | 52 | ||
152 | int | 53 | int |
153 | header_gmvalue (const char *blurb, size_t blurb_ln, const char *fn, | 54 | header_get_value (header_t h, const char *fn, char *fb, |
154 | char **fb, size_t *n) | 55 | size_t len, size_t *n) |
155 | { | ||
156 | size_t i; | ||
157 | if (blurb == NULL || blurb_ln == 0 || fn == NULL || fb == NULL | ||
158 | || header_gvalue (blurb, blurb_ln, fn, NULL, 0, &i) != 0) | ||
159 | { | ||
160 | return EINVAL; | ||
161 | } | ||
162 | *fb = calloc (1, ++i); | ||
163 | if (*fb == NULL) | ||
164 | return ENOMEM; | ||
165 | return header_gvalue (blurb, blurb_ln, fn, *fb, i, n); | ||
166 | } | ||
167 | |||
168 | static int | ||
169 | rfc822_parse (header_t h, const char *blurb, size_t len) | ||
170 | { | 56 | { |
171 | rfc822_t rfc; | 57 | if (h == NULL) |
172 | char *header_end; | 58 | return EINVAL; |
173 | char *header_start; | 59 | return h->_get_value (h, fn, fb, len, n); |
174 | char *header_start2; | ||
175 | char *colon; | ||
176 | struct _hdr *hdr; | ||
177 | |||
178 | if (h == NULL || blurb == NULL || len == 0) | ||
179 | { | ||
180 | return EINVAL; | ||
181 | } | ||
182 | |||
183 | rfc = calloc (1, sizeof (*rfc)); | ||
184 | if (rfc == NULL) | ||
185 | { | ||
186 | return ENOMEM; | ||
187 | } | ||
188 | |||
189 | rfc->blurb = calloc (1, len); | ||
190 | if (rfc->blurb == NULL) | ||
191 | { | ||
192 | free (rfc); | ||
193 | return ENOMEM; | ||
194 | } | ||
195 | memcpy (rfc->blurb, blurb, len); | ||
196 | |||
197 | for (header_start = rfc->blurb;; header_start = ++header_end) | ||
198 | { | ||
199 | /* get a header, a header is : | ||
200 | field-name ':' field-body1 | ||
201 | [ ' ' '\t' field-body2 ] '\r' '\n' | ||
202 | */ | ||
203 | for (header_start2 = header_start;;header_start2 = ++header_end) | ||
204 | { | ||
205 | header_end = memchr (header_start2, '\n', len); | ||
206 | if (header_end == NULL) | ||
207 | { | ||
208 | break; | ||
209 | } | ||
210 | else | ||
211 | { | ||
212 | len -= (header_end - header_start2 + 1); | ||
213 | if (len == 0) | ||
214 | { | ||
215 | header_end = NULL; | ||
216 | break; | ||
217 | } | ||
218 | if (header_end[1] != ' ' | ||
219 | && header_end[1] != '\t') | ||
220 | { | ||
221 | break; /* new header break the inner for */ | ||
222 | } | ||
223 | } | ||
224 | /* *header_end = ' '; smash LF */ | ||
225 | } | ||
226 | |||
227 | if (header_end == NULL) | ||
228 | { | ||
229 | break; /* bail out */ | ||
230 | } | ||
231 | *header_end = '\0'; /* smash LF */ | ||
232 | |||
233 | /* Treats unix "From " specially */ | ||
234 | if ((header_end - header_start >= 5) | ||
235 | && strncmp (header_start, "From ", 5) == 0) | ||
236 | { | ||
237 | rfc->unixfrom.fn = "From "; | ||
238 | rfc->unixfrom.fb = header_start + 6; | ||
239 | } | ||
240 | else | ||
241 | { | ||
242 | colon = memchr (header_start, ':', header_end - header_start); | ||
243 | if (colon == NULL) | ||
244 | { | ||
245 | /* Houston we have a problem */ | ||
246 | free (rfc->blurb); | ||
247 | if (rfc->hdr) | ||
248 | free (rfc->hdr); | ||
249 | free (rfc); | ||
250 | return EINVAL; | ||
251 | } | ||
252 | hdr = realloc (rfc->hdr, (rfc->hdr_count + 1) * sizeof (*hdr)); | ||
253 | if (hdr == NULL) | ||
254 | { | ||
255 | /* Houston we have another problem */ | ||
256 | free (rfc->blurb); | ||
257 | if (rfc->hdr) | ||
258 | free (rfc->hdr); | ||
259 | free (rfc); | ||
260 | return ENOMEM; | ||
261 | } | ||
262 | rfc->hdr = hdr; | ||
263 | rfc->hdr_count++; | ||
264 | *colon = '\0'; /* smash colon */ | ||
265 | rfc->hdr[rfc->hdr_count - 1].fn = header_start; | ||
266 | rfc->hdr[rfc->hdr_count - 1].fb = colon + 1; | ||
267 | } | ||
268 | } | ||
269 | h->data = rfc; | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static int | ||
274 | rfc822_set_value (header_t h, const char *fn, const char *fb, | ||
275 | size_t n, int replace) | ||
276 | { | ||
277 | (void)h; (void)fn; (void)fb; (void)n; (void)replace; | ||
278 | return ENOSYS; | ||
279 | } | ||
280 | |||
281 | static int | ||
282 | rfc822_get_value (header_t h, const char *fn, char *fb, size_t len, size_t *n) | ||
283 | { | ||
284 | size_t i = 0; | ||
285 | size_t j = 0; | ||
286 | rfc822_t rfc = (rfc822_t)h->data; | ||
287 | |||
288 | if (fb) | ||
289 | { | ||
290 | *fb = '\0'; /* if empty */ | ||
291 | } | ||
292 | for (i = 0; i < rfc->hdr_count; i++) | ||
293 | { | ||
294 | if (strcmp (rfc->hdr[i].fn, fn) == 0) | ||
295 | { | ||
296 | j = strlen (rfc->hdr[i].fb); | ||
297 | j = (len < j) ? len : j; | ||
298 | if (fb) | ||
299 | { | ||
300 | memcpy (fb, rfc->hdr[i].fb, j); | ||
301 | } | ||
302 | break; | ||
303 | } | ||
304 | } | ||
305 | if (n) | ||
306 | *n = j; | ||
307 | return 0; | ||
308 | } | 60 | } |
309 | 61 | ||
310 | static int | 62 | ssize_t |
311 | rfc822_get_mvalue (header_t h, const char *fn, char **fb, size_t *n) | 63 | header_get_data (header_t h, char *data, size_t len, off_t off, int *err) |
312 | { | 64 | { |
313 | size_t i; | 65 | if (h == NULL) |
314 | if (h == NULL || fn == NULL || fb == NULL | 66 | return EINVAL; |
315 | || h->_get_value (h, fn, NULL, 0, &i) != 0) | 67 | return h->_get_data (h, data, len, off, err); |
316 | { | ||
317 | return EINVAL; | ||
318 | } | ||
319 | *fb = calloc (1, ++i); | ||
320 | if (*fb == NULL) | ||
321 | return ENOMEM; | ||
322 | return h->_get_value (h, fn, *fb, i, n); | ||
323 | } | 68 | } | ... | ... |
... | @@ -32,34 +32,34 @@ | ... | @@ -32,34 +32,34 @@ |
32 | extern "C" { | 32 | extern "C" { |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | #define MU_HDR_RFC822 0 | 35 | #define MU_HEADER_RFC822 0 |
36 | 36 | ||
37 | #define MU_HDR_UNIX_FROM "From " | 37 | #define MU_HEADER_UNIX_FROM "From " |
38 | #define MU_HDR_RETURN_PATH "Return-Path" | 38 | #define MU_HEADER_RETURN_PATH "Return-Path" |
39 | #define MU_HDR_RECEIVED "Received" | 39 | #define MU_HEADER_RECEIVED "Received" |
40 | #define MU_HDR_DATE "Date" | 40 | #define MU_HEADER_DATE "Date" |
41 | #define MU_HDR_FROM "From" | 41 | #define MU_HEADER_FROM "From" |
42 | #define MU_HDR_RESENT_FROM "Resent-From" | 42 | #define MU_HEADER_RESENT_FROM "Resent-From" |
43 | #define MU_HDR_SUBJECT "Subject" | 43 | #define MU_HEADER_SUBJECT "Subject" |
44 | #define MU_HDR_SENDER "Sender" | 44 | #define MU_HEADER_SENDER "Sender" |
45 | #define MU_HDR_RESENT_SENDER "Resent-SENDER" | 45 | #define MU_HEADER_RESENT_SENDER "Resent-SENDER" |
46 | #define MU_HDR_TO "To" | 46 | #define MU_HEADER_TO "To" |
47 | #define MU_HDR_RESENT_TO "Resent-To" | 47 | #define MU_HEADER_RESENT_TO "Resent-To" |
48 | #define MU_HDR_CC "Cc" | 48 | #define MU_HEADER_CC "Cc" |
49 | #define MU_HDR_RESENT_CC "Resent-Cc" | 49 | #define MU_HEADER_RESENT_CC "Resent-Cc" |
50 | #define MU_HDR_BCC "Bcc" | 50 | #define MU_HEADER_BCC "Bcc" |
51 | #define MU_HDR_RESENT_BCC "Resent-Bcc" | 51 | #define MU_HEADER_RESENT_BCC "Resent-Bcc" |
52 | #define MU_HDR_REPLY_TO "Reply-To" | 52 | #define MU_HEADER_REPLY_TO "Reply-To" |
53 | #define MU_HDR_RESENT_REPLY_TO "Resent-Reply-To" | 53 | #define MU_HEADER_RESENT_REPLY_TO "Resent-Reply-To" |
54 | #define MU_HDR_MESSAGE_ID "Message-ID" | 54 | #define MU_HEADER_MESSAGE_ID "Message-ID" |
55 | #define MU_HDR_RESENT_MESSAGE_ID "Resent-Message-ID" | 55 | #define MU_HEADER_RESENT_MESSAGE_ID "Resent-Message-ID" |
56 | #define MU_HDR_IN_REPLY_TO "In-Reply-To" | 56 | #define MU_HEADER_IN_REPLY_TO "In-Reply-To" |
57 | #define MU_HDR_ENCRYPTED "Encrypted" | 57 | #define MU_HEADER_ENCRYPTED "Encrypted" |
58 | #define MU_HDR_PRECEDENCE "Precedence" | 58 | #define MU_HEADER_PRECEDENCE "Precedence" |
59 | #define MU_HDR_STATUS "Status" | 59 | #define MU_HEADER_STATUS "Status" |
60 | #define MU_HDR_CONTENT_LENGTH "Content-Length" | 60 | #define MU_HEADER_CONTENT_LENGTH "Content-Length" |
61 | #define MU_HDR_CONTENT_TYPE "Content-Type" | 61 | #define MU_HEADER_CONTENT_TYPE "Content-Type" |
62 | #define MU_HDR_MIME_VERSION "MIME-Version" | 62 | #define MU_HEADER_MIME_VERSION "MIME-Version" |
63 | 63 | ||
64 | /* Mime support header attribute */ | 64 | /* Mime support header attribute */ |
65 | 65 | ||
... | @@ -67,30 +67,16 @@ extern "C" { | ... | @@ -67,30 +67,16 @@ extern "C" { |
67 | struct _header; | 67 | struct _header; |
68 | typedef struct _header * header_t; | 68 | typedef struct _header * header_t; |
69 | 69 | ||
70 | extern int header_init __P ((header_t *, const char *blurb, | 70 | extern int header_init __P ((header_t *, const char *blurb, |
71 | size_t ln, int flag)); | 71 | size_t ln, int flag)); |
72 | extern void header_destroy __P ((header_t *)); | 72 | extern void header_destroy __P ((header_t *)); |
73 | |||
74 | extern int header_gvalue __P ((const char *blurb, size_t bl, const char *fn, | ||
75 | char *fv, size_t len, size_t *n)); | ||
76 | extern int header_gmvalue __P ((const char *blurb, size_t bl, const char *fn, | ||
77 | char **fv, size_t *nv)); | ||
78 | |||
79 | #undef INLINE | ||
80 | #ifdef __GNUC__ | ||
81 | #define INLINE __inline__ | ||
82 | #else | ||
83 | #define INLINE | ||
84 | #endif | ||
85 | |||
86 | extern INLINE int header_set_value __P ((header_t, const char *fn, | ||
87 | const char *fv, size_t n, | ||
88 | int replace)); | ||
89 | extern INLINE int header_get_value __P ((header_t, const char *fn, char *fv, | ||
90 | size_t len, size_t *n)); | ||
91 | extern INLINE int header_get_mvalue __P ((header_t, const char *fn, | ||
92 | char **fv, size_t *n)); | ||
93 | 73 | ||
74 | extern int header_set_value __P ((header_t, const char *fn, | ||
75 | const char *fv, size_t n, int replace)); | ||
76 | extern int header_get_value __P ((header_t, const char *fn, char *fv, | ||
77 | size_t len, size_t *n)); | ||
78 | extern ssize_t header_get_data __P ((header_t h, char *data, | ||
79 | size_t len, off_t off, int *err)); | ||
94 | #ifdef _cpluscplus | 80 | #ifdef _cpluscplus |
95 | } | 81 | } |
96 | #endif | 82 | #endif | ... | ... |
... | @@ -33,26 +33,36 @@ | ... | @@ -33,26 +33,36 @@ |
33 | extern "C" { | 33 | extern "C" { |
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | struct _hdr | ||
37 | { | ||
38 | char *fn; | ||
39 | char *fn_end; | ||
40 | char *fv; | ||
41 | char *fv_end; | ||
42 | }; | ||
43 | typedef struct _hdr *hdr_t; | ||
44 | |||
36 | struct _header | 45 | struct _header |
37 | { | 46 | { |
38 | /* Data */ | 47 | /* Data */ |
39 | void *data; | 48 | void *data; |
49 | /* owner ? */ | ||
50 | void *message; | ||
40 | 51 | ||
41 | /* Functions */ | 52 | /* Functions */ |
42 | int (*_set_value) __P ((header_t, const char *fn, const char *fv, | 53 | int (*_init) __P ((header_t *, const char *, size_t)); |
43 | size_t n, int replace)); | 54 | void (*_destroy) __P ((header_t *)); |
44 | int (*_get_value) __P ((header_t, const char *fn, char *fv, | 55 | int (*_set_value) __P ((header_t, const char *fn, const char *fv, |
45 | size_t len, size_t *n)); | 56 | size_t n, int replace)); |
46 | int (*_get_mvalue) __P ((header_t, const char *fn, char **fv, size_t *n)); | 57 | int (*_get_value) __P ((header_t, const char *fn, char *fv, |
47 | int (*_parse) __P ((header_t, const char *blurb, size_t len)); | 58 | size_t len, size_t *n)); |
59 | ssize_t (*_get_data) __P ((header_t h, char *data, | ||
60 | size_t len, off_t off, int *err)); | ||
61 | int (*_parse) __P ((header_t, const char *blurb, size_t len)); | ||
48 | } ; | 62 | } ; |
49 | 63 | ||
50 | #ifdef USE_MACROS | 64 | extern int rfc822_init __P ((header_t *ph, const char *blurb, size_t len)); |
51 | #define header_set_value(h, fn, fv, n, r) h->_set_value (h, fn, fv, n, r) | 65 | extern void rfc822_destroy __P ((header_t *ph)); |
52 | #define header_get_value(h, fn, fv, v, ln, n) h->_get_value (h, fn, fv, ln, n) | ||
53 | #define header_get_mvalue(h, fn, fv, v, n) h->_get_mvalue (h, fn, fv, n) | ||
54 | #endif | ||
55 | |||
56 | #ifdef _cpluscplus | 66 | #ifdef _cpluscplus |
57 | } | 67 | } |
58 | #endif | 68 | #endif | ... | ... |
... | @@ -19,680 +19,236 @@ | ... | @@ -19,680 +19,236 @@ |
19 | #include <config.h> | 19 | #include <config.h> |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #include <mbx_mbox.h> | 22 | #include <mailbox0.h> |
23 | #include <mbx_unix.h> | 23 | #include <message0.h> |
24 | #include <mbx_mdir.h> | 24 | #include <registrar.h> |
25 | #include <mbx_mmdf.h> | 25 | #include <locker.h> |
26 | #include <mbx_pop.h> | ||
27 | #include <mbx_imap.h> | ||
28 | 26 | ||
29 | #include <stdlib.h> | 27 | #include <stdlib.h> |
30 | #include <string.h> | 28 | #include <string.h> |
31 | #include <errno.h> | 29 | #include <errno.h> |
32 | 30 | ||
33 | /* forward prototypes */ | ||
34 | static int mbx_open (mailbox_t, int flag); | ||
35 | static int mbx_close (mailbox_t); | ||
36 | |||
37 | /* name */ | ||
38 | static int mbx_get_name (mailbox_t, int *id, char *name, | ||
39 | size_t len, size_t *n); | ||
40 | static int mbx_get_mname (mailbox_t mbox, int *id, char **name, size_t *n); | ||
41 | |||
42 | /* passwd */ | ||
43 | static int mbx_get_passwd (mailbox_t, char *passwd, size_t, size_t *); | ||
44 | static int mbx_get_mpasswd (mailbox_t, char **passwd, size_t *len); | ||
45 | static int mbx_set_passwd (mailbox_t, const char *passwd, size_t len); | ||
46 | |||
47 | /* deleting */ | ||
48 | static int mbx_delete (mailbox_t, size_t msgno); | ||
49 | static int mbx_undelete (mailbox_t, size_t msgno); | ||
50 | static int mbx_expunge (mailbox_t); | ||
51 | static int mbx_is_deleted (mailbox_t, size_t msgno); | ||
52 | |||
53 | /* appending */ | ||
54 | static int mbx_new_msg (mailbox_t, size_t *msgno); | ||
55 | static int mbx_set_header (mailbox_t, size_t msgno, const char *h, | ||
56 | size_t n, int replace); | ||
57 | static int mbx_set_body (mailbox_t, size_t msgno, const char *b, | ||
58 | size_t n, int replace); | ||
59 | static int mbx_append (mailbox_t, size_t msgno); | ||
60 | static int mbx_destroy_msg (mailbox_t, size_t msgno); | ||
61 | |||
62 | /* reading */ | ||
63 | static int mbx_get_body (mailbox_t, size_t msgno, off_t off, | ||
64 | char *b, size_t len, size_t *n); | ||
65 | static int mbx_get_mbody (mailbox_t, size_t msgno, off_t off, | ||
66 | char **b, size_t *n); | ||
67 | static int mbx_get_header (mailbox_t, size_t msgno, off_t off, | ||
68 | char *h, size_t len, size_t *n); | ||
69 | static int mbx_get_mheader (mailbox_t, size_t msgno, off_t off, | ||
70 | char **h, size_t *n); | ||
71 | |||
72 | /* locking */ | ||
73 | static int mbx_lock (mailbox_t, int flag); | ||
74 | static int mbx_unlock (mailbox_t); | ||
75 | //static int mbx_ilock (mailbox_t, int flag); | ||
76 | //static int mbx_iunlock (mailbox_t); | ||
77 | |||
78 | /* owner and group */ | ||
79 | static int mbx_set_owner (mailbox_t, uid_t uid); | ||
80 | static int mbx_get_owner (mailbox_t, uid_t *uid); | ||
81 | static int mbx_set_group (mailbox_t, uid_t gid); | ||
82 | static int mbx_get_group (mailbox_t, uid_t *gid); | ||
83 | /* misc */ | ||
84 | static int mbx_scan (mailbox_t, size_t *msgs); | ||
85 | static int mbx_is_updated (mailbox_t); | ||
86 | static int mbx_get_timeout (mailbox_t, size_t *timeout); | ||
87 | static int mbx_set_timeout (mailbox_t, size_t timeout); | ||
88 | static int mbx_get_refresh (mailbox_t, size_t *refresh); | ||
89 | static int mbx_set_refresh (mailbox_t, size_t refresh); | ||
90 | static int mbx_get_size (mailbox_t, size_t msgno, size_t *sh, size_t *sb); | ||
91 | static int mbx_set_notification (mailbox_t, | ||
92 | int (*func) (mailbox_t, void *arg)); | ||
93 | |||
94 | /* init all the functions to a default value */ | ||
95 | static void mbx_check_struct (mailbox_t); | ||
96 | |||
97 | /* | 31 | /* |
98 | Builtin mailbox types. | 32 | * Point of entry. |
99 | A circular list is use for the builtin. | 33 | * Simple, first check if they ask for something specific; with the ID. |
100 | Proper locking is not done when accessing the list. | 34 | * Then try to discover the type of mailbox with the url(name). |
101 | FIXME: not thread-safe. */ | 35 | * Then we call the appropriate mailbox_*type*_init() function. |
102 | static struct mailbox_builtin | 36 | */ |
103 | { | ||
104 | struct mailbox_type *mtype; | ||
105 | int is_malloc; | ||
106 | struct mailbox_builtin * next; | ||
107 | } mailbox_builtin [] = { | ||
108 | { NULL, 0, &mailbox_builtin[1] }, /* sentinel, head list */ | ||
109 | { &_mailbox_mbox_type, 0, &mailbox_builtin[2] }, | ||
110 | { &_mailbox_unix_type, 0, &mailbox_builtin[3] }, | ||
111 | { &_mailbox_maildir_type, 0, &mailbox_builtin[4] }, | ||
112 | { &_mailbox_mmdf_type, 0, &mailbox_builtin[5] }, | ||
113 | { &_mailbox_pop_type, 0, &mailbox_builtin[6] }, | ||
114 | { &_mailbox_imap_type, 0, &mailbox_builtin[0] }, | ||
115 | }; | ||
116 | |||
117 | int | ||
118 | mailbox_add_type (struct mailbox_type *mtype) | ||
119 | { | ||
120 | struct mailbox_builtin *current = malloc (sizeof (*current)); | ||
121 | if (current == NULL) | ||
122 | return ENOMEM; | ||
123 | if (mtype->utype) | ||
124 | { | ||
125 | int status = url_add_type (mtype->utype); | ||
126 | if (status != 0) | ||
127 | { | ||
128 | free (current); | ||
129 | return status; | ||
130 | } | ||
131 | mtype->id = mtype->utype->id; /* same ID as the url_type */ | ||
132 | } | ||
133 | else | ||
134 | { | ||
135 | mtype->id = (int)mtype; /* just need to be uniq */ | ||
136 | } | ||
137 | current->mtype = mtype; | ||
138 | current->is_malloc = 1; | ||
139 | current->next = mailbox_builtin->next; | ||
140 | mailbox_builtin->next = current; | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | int | ||
145 | mailbox_remove_type (struct mailbox_type *mtype) | ||
146 | { | ||
147 | struct mailbox_builtin *current, *previous; | ||
148 | for (previous = mailbox_builtin, current = mailbox_builtin->next; | ||
149 | current != mailbox_builtin; | ||
150 | previous = current, current = current->next) | ||
151 | { | ||
152 | if (current->mtype == mtype) | ||
153 | { | ||
154 | previous->next = current->next; | ||
155 | if (current->is_malloc) | ||
156 | free (current); | ||
157 | return 0;; | ||
158 | } | ||
159 | } | ||
160 | return EINVAL; | ||
161 | } | ||
162 | |||
163 | int | ||
164 | mailbox_list_type (struct mailbox_type *list, size_t len, size_t *n) | ||
165 | { | ||
166 | struct mailbox_builtin *current; | ||
167 | size_t i; | ||
168 | for (i = 0, current = mailbox_builtin->next; current != mailbox_builtin; | ||
169 | current = current->next, i++) | ||
170 | { | ||
171 | if (list) | ||
172 | if (i < len) | ||
173 | list[i] = *(current->mtype); | ||
174 | } | ||
175 | if (n) | ||
176 | *n = i; | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | int | ||
181 | mailbox_list_mtype (struct mailbox_type **mlist, size_t *n) | ||
182 | { | ||
183 | struct mailbox_type *mtype; | ||
184 | size_t i = 0; | ||
185 | |||
186 | mailbox_list_type (NULL, 0, &i); | ||
187 | if (i == 0) | ||
188 | { | ||
189 | if (n) | ||
190 | { | ||
191 | *n = i; | ||
192 | } | ||
193 | return 0; | ||
194 | } | ||
195 | mtype = calloc (i, sizeof (*mtype)); | ||
196 | if (mtype == NULL) | ||
197 | { | ||
198 | return ENOMEM; | ||
199 | } | ||
200 | *mlist = mtype; | ||
201 | return *n = mailbox_list_type (mtype, i, n); | ||
202 | } | ||
203 | |||
204 | int | ||
205 | mailbox_get_type (struct mailbox_type **mtype, int id) | ||
206 | { | ||
207 | struct mailbox_builtin *current; | ||
208 | for (current = mailbox_builtin->next; current != mailbox_builtin; | ||
209 | current = current->next) | ||
210 | { | ||
211 | if (current->mtype->id == id) | ||
212 | { | ||
213 | *mtype = current->mtype; | ||
214 | return 0;; | ||
215 | } | ||
216 | } | ||
217 | return EINVAL; | ||
218 | } | ||
219 | |||
220 | |||
221 | int | 37 | int |
222 | mailbox_init (mailbox_t *mbox, const char *name, int id) | 38 | mailbox_init (mailbox_t *pmbox, const char *name, int id) |
223 | { | 39 | { |
224 | int status = EINVAL; | 40 | int status = EINVAL; |
41 | struct mailbox_registrar *mreg; | ||
42 | url_t url = NULL; | ||
43 | |||
44 | url_init (&url, name); | ||
225 | 45 | ||
226 | /* 1st run: if they know what they want, shortcut */ | 46 | /* 1st guest: if an ID is specify, shortcut */ |
227 | if (id) | 47 | if (id) |
228 | { | 48 | { |
229 | struct mailbox_type *mtype; | 49 | status = registrar_get (id, NULL, &mreg); |
230 | status = mailbox_get_type (&mtype, id); | ||
231 | if (status == 0) | 50 | if (status == 0) |
232 | { | 51 | status = mreg->_init (pmbox, name); |
233 | status = mtype->_init (mbox, name); | ||
234 | if (status == 0) | ||
235 | mbx_check_struct (*mbox); | ||
236 | } | ||
237 | } | 52 | } |
238 | 53 | /* 2nd fallback: Use the URL */ | |
239 | /* 2nd run: try heuristic URL discovery */ | 54 | else if (url != NULL) |
240 | if (status != 0) | ||
241 | { | 55 | { |
242 | url_t url; | 56 | url_get_id (url, &id); |
243 | status = url_init (&url, name); | 57 | status = registrar_get (id, NULL, &mreg); |
244 | if (status == 0) | 58 | if (status == 0) |
245 | { | 59 | status = mreg->_init (pmbox, name); |
246 | int id; | ||
247 | struct mailbox_type *mtype; | ||
248 | /* We've found a match get it */ | ||
249 | if (url_get_id (url, &id) == 0 | ||
250 | && (status = mailbox_get_type (&mtype, id)) == 0) | ||
251 | { | ||
252 | status = mtype->_init (mbox, name); | ||
253 | if (status == 0) | ||
254 | mbx_check_struct (*mbox); | ||
255 | } | ||
256 | url_destroy (&url); | ||
257 | } | ||
258 | } | 60 | } |
259 | 61 | ||
260 | /* 3nd run: nothing yet ?? try mbox directly as the last resort. | 62 | /* if things went ok set mreg for mailbox_destroy and the URL */ |
261 | this should take care of the case where the filename is use */ | 63 | if (status == 0) |
262 | if (status != 0 ) | ||
263 | { | 64 | { |
264 | status = mailbox_mbox_init (mbox, name); | 65 | (*pmbox)->url = url; |
265 | if (status == 0) | 66 | (*pmbox)->_init = mreg->_init; |
266 | mbx_check_struct (*mbox); | 67 | (*pmbox)->_destroy = mreg->_destroy; |
267 | } | 68 | } |
268 | return status; | 69 | return status; |
269 | } | 70 | } |
270 | 71 | ||
271 | void | 72 | void |
272 | mailbox_destroy (mailbox_t *mbox) | 73 | mailbox_destroy (mailbox_t *pmbox) |
273 | { | 74 | { |
274 | struct mailbox_type *mtype = (*mbox)->mtype; | 75 | if (pmbox && *pmbox) |
275 | return mtype->_destroy (mbox); | 76 | (*pmbox)->_destroy (pmbox); |
276 | } | 77 | } |
277 | 78 | ||
278 | /* -------------- stub functions ------------------- */ | 79 | /* -------------- stub functions ------------------- */ |
279 | static void | ||
280 | mbx_check_struct (mailbox_t mbox) | ||
281 | { | ||
282 | if (mbox->_open == NULL) | ||
283 | mbox->_open = mbx_open; | ||
284 | |||
285 | if (mbox->_close == NULL) | ||
286 | mbox->_close = mbx_close; | ||
287 | |||
288 | if (mbox->_get_name == NULL) | ||
289 | mbox->_get_name = mbx_get_name; | ||
290 | |||
291 | if (mbox->_get_mname == NULL) | ||
292 | mbox->_get_mname = mbx_get_mname; | ||
293 | |||
294 | if (mbox->_get_passwd == NULL) | ||
295 | mbox->_get_passwd = mbx_get_passwd; | ||
296 | |||
297 | if (mbox->_get_mpasswd == NULL) | ||
298 | mbox->_get_mpasswd = mbx_get_mpasswd; | ||
299 | |||
300 | if (mbox->_set_passwd == NULL) | ||
301 | mbox->_set_passwd = mbx_set_passwd; | ||
302 | |||
303 | if (mbox->_delete == NULL) | ||
304 | mbox->_delete = mbx_delete; | ||
305 | |||
306 | if (mbox->_undelete == NULL) | ||
307 | mbox->_undelete = mbx_undelete; | ||
308 | |||
309 | if (mbox->_expunge == NULL) | ||
310 | mbox->_expunge = mbx_expunge; | ||
311 | |||
312 | if (mbox->_is_deleted == NULL) | ||
313 | mbox->_is_deleted = mbx_is_deleted; | ||
314 | |||
315 | if (mbox->_new_msg == NULL) | ||
316 | mbox->_new_msg = mbx_new_msg; | ||
317 | |||
318 | if (mbox->_set_header == NULL) | ||
319 | mbox->_set_header = mbx_set_header; | ||
320 | |||
321 | if (mbox->_set_body == NULL) | ||
322 | mbox->_set_body = mbx_set_body; | ||
323 | |||
324 | if (mbox->_append == NULL) | ||
325 | mbox->_append = mbx_append; | ||
326 | |||
327 | if (mbox->_destroy_msg == NULL) | ||
328 | mbox->_destroy_msg = mbx_destroy_msg; | ||
329 | |||
330 | if (mbox->_get_body == NULL) | ||
331 | mbox->_get_body = mbx_get_body; | ||
332 | |||
333 | if (mbox->_get_mbody == NULL) | ||
334 | mbox->_get_mbody = mbx_get_mbody; | ||
335 | |||
336 | if (mbox->_get_header == NULL) | ||
337 | mbox->_get_header = mbx_get_header; | ||
338 | |||
339 | if (mbox->_get_mheader == NULL) | ||
340 | mbox->_get_mheader = mbx_get_mheader; | ||
341 | |||
342 | if (mbox->_lock == NULL) | ||
343 | mbox->_lock = mbx_lock; | ||
344 | |||
345 | if (mbox->_unlock == NULL) | ||
346 | mbox->_unlock = mbx_unlock; | ||
347 | |||
348 | if (mbox->_ilock == NULL) | ||
349 | mbox->_ilock = mbx_lock; | ||
350 | |||
351 | if (mbox->_iunlock == NULL) | ||
352 | mbox->_iunlock = mbx_unlock; | ||
353 | |||
354 | if (mbox->_scan == NULL) | ||
355 | mbox->_scan = mbx_scan; | ||
356 | |||
357 | if (mbox->_is_updated == NULL) | ||
358 | mbox->_is_updated = mbx_is_updated; | ||
359 | |||
360 | if (mbox->_set_owner == NULL) | ||
361 | mbox->_set_owner = mbx_set_owner; | ||
362 | |||
363 | if (mbox->_get_owner == NULL) | ||
364 | mbox->_get_owner = mbx_get_owner; | ||
365 | |||
366 | if (mbox->_set_group == NULL) | ||
367 | mbox->_set_group = mbx_set_group; | ||
368 | |||
369 | if (mbox->_get_group == NULL) | ||
370 | mbox->_get_group = mbx_get_group; | ||
371 | |||
372 | if (mbox->_get_timeout == NULL) | ||
373 | mbox->_get_timeout = mbx_get_timeout; | ||
374 | |||
375 | if (mbox->_set_timeout == NULL) | ||
376 | mbox->_set_timeout = mbx_set_timeout; | ||
377 | |||
378 | if (mbox->_get_refresh == NULL) | ||
379 | mbox->_get_refresh = mbx_get_refresh; | ||
380 | |||
381 | if (mbox->_set_refresh == NULL) | ||
382 | mbox->_set_refresh = mbx_set_refresh; | ||
383 | |||
384 | if (mbox->_get_size == NULL) | ||
385 | mbox->_get_size = mbx_get_size; | ||
386 | |||
387 | if (mbox->_set_notification == NULL) | ||
388 | mbox->_set_notification = mbx_set_notification; | ||
389 | |||
390 | } | ||
391 | 80 | ||
392 | 81 | int | |
393 | static int | 82 | mailbox_open (mailbox_t mbox, int flag) |
394 | mbx_open (mailbox_t mbox, int flag) | ||
395 | { | 83 | { |
396 | (void)mbox; (void)flag; | 84 | if (mbox == NULL || mbox->_open == NULL) |
397 | return ENOSYS; | 85 | return ENOSYS; |
86 | return mbox->_open (mbox, flag); | ||
398 | } | 87 | } |
399 | 88 | ||
400 | static int | 89 | int |
401 | mbx_close (mailbox_t mbox) | 90 | mailbox_close (mailbox_t mbox) |
402 | { | 91 | { |
403 | (void)mbox; | 92 | if (mbox == NULL || mbox->_close == NULL) |
404 | return ENOSYS; | 93 | return ENOSYS; |
94 | return mbox->_close (mbox); | ||
405 | } | 95 | } |
406 | 96 | ||
407 | /* name */ | 97 | /* messages */ |
408 | static int | 98 | int |
409 | mbx_get_name (mailbox_t mbox, int *id, char *name, size_t len, size_t *n) | 99 | mailbox_is_deleted (mailbox_t mbox, size_t msgno) |
410 | { | ||
411 | char *s; | ||
412 | size_t i; | ||
413 | |||
414 | if (mbox == NULL || mbox->mtype == NULL) | ||
415 | { | ||
416 | return EINVAL; | ||
417 | } | ||
418 | |||
419 | s = mbox->mtype->name; | ||
420 | i = strlen (s); | ||
421 | |||
422 | if (id) | ||
423 | { | ||
424 | *id = mbox->mtype->id; | ||
425 | } | ||
426 | if (name && len > 0) | ||
427 | { | ||
428 | i = (len < i) ? len : i; | ||
429 | strncpy (name, s, i - 1); | ||
430 | name [i - 1] = 0; | ||
431 | } | ||
432 | if (n) | ||
433 | { | ||
434 | *n = i; | ||
435 | } | ||
436 | return 0; | ||
437 | } | ||
438 | |||
439 | static int | ||
440 | mbx_get_mname (mailbox_t mbox, int *id, char **name, size_t *n) | ||
441 | { | 100 | { |
442 | size_t i = 0; | 101 | if (mbox == NULL || mbox->_is_deleted == NULL) |
443 | mbox->_get_name (mbox, id, 0, 0, &i); | 102 | return 0; |
444 | i++; | 103 | return mbox->_is_deleted (mbox, msgno); |
445 | *name = calloc (i, sizeof (char)); | ||
446 | if (*name == NULL) | ||
447 | { | ||
448 | return ENOMEM; | ||
449 | } | ||
450 | mbox->_get_name (mbox, id, *name, i, n); | ||
451 | return 0; | ||
452 | } | 104 | } |
453 | 105 | ||
454 | /* passwd */ | 106 | int |
455 | static int | 107 | mailbox_append_message (mailbox_t mbox, message_t msg) |
456 | mbx_get_passwd (mailbox_t mbox, char *passwd, size_t len, size_t *n) | ||
457 | { | 108 | { |
458 | (void)mbox; (void)passwd; (void)len; (void)n; | 109 | if (mbox == NULL || mbox->_append_message == NULL) |
459 | return ENOSYS; | 110 | return ENOSYS; |
111 | return mbox->_append_message (mbox, msg); | ||
460 | } | 112 | } |
461 | 113 | ||
462 | static int | 114 | int |
463 | mbx_get_mpasswd (mailbox_t mbox, char **passwd, size_t *n) | 115 | mailbox_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg) |
464 | { | 116 | { |
465 | size_t i = 0; | 117 | int status; |
466 | mbox->_get_passwd (mbox, NULL, 0, &i); | 118 | if (mbox == NULL || pmsg == NULL) |
467 | i++; | 119 | return EINVAL; |
468 | *passwd = calloc (i, sizeof (char)); | 120 | if (mailbox_is_deleted (mbox, msgno)) |
469 | if (*passwd == NULL) | 121 | return EINVAL; |
470 | { | 122 | status = message_init (pmsg); |
471 | return ENOMEM; | 123 | if (status != 0) |
472 | } | 124 | return status; |
473 | mbox->_get_passwd (mbox, *passwd, i, n); | 125 | (*pmsg)->mailbox = mbox; |
126 | (*pmsg)->num = msgno; | ||
474 | return 0; | 127 | return 0; |
475 | } | 128 | } |
476 | 129 | ||
477 | static int | 130 | int |
478 | mbx_set_passwd (mailbox_t mbox, const char *passwd, size_t len) | 131 | mailbox_messages_count (mailbox_t mbox, size_t *num) |
479 | { | ||
480 | (void)mbox; (void)passwd; (void)len; | ||
481 | return ENOSYS; | ||
482 | } | ||
483 | |||
484 | /* deleting */ | ||
485 | static int | ||
486 | mbx_delete (mailbox_t mbox, size_t msgno) | ||
487 | { | ||
488 | (void)mbox; (void)msgno; | ||
489 | return ENOSYS; | ||
490 | } | ||
491 | |||
492 | static int | ||
493 | mbx_undelete (mailbox_t mbox, size_t msgno) | ||
494 | { | ||
495 | (void)mbox; (void)msgno; | ||
496 | return ENOSYS; | ||
497 | } | ||
498 | |||
499 | static int | ||
500 | mbx_expunge (mailbox_t mbox) | ||
501 | { | ||
502 | (void)mbox; | ||
503 | return ENOSYS; | ||
504 | } | ||
505 | |||
506 | static int | ||
507 | mbx_is_deleted (mailbox_t mbox, size_t msgno) | ||
508 | { | ||
509 | (void)mbox; (void)msgno; | ||
510 | return ENOSYS; | ||
511 | } | ||
512 | |||
513 | |||
514 | /* appending */ | ||
515 | static int | ||
516 | mbx_new_msg (mailbox_t mbox, size_t *msgno) | ||
517 | { | ||
518 | (void)mbox; (void)msgno; | ||
519 | return ENOSYS; | ||
520 | } | ||
521 | |||
522 | static int | ||
523 | mbx_set_header (mailbox_t mbox, size_t msgno, const char *h, | ||
524 | size_t len, int replace) | ||
525 | { | ||
526 | (void)mbox; (void)msgno; (void)h; (void)len; (void)replace; | ||
527 | return ENOSYS; | ||
528 | } | ||
529 | |||
530 | static int | ||
531 | mbx_set_body (mailbox_t mbox, size_t msgno, const char *b, | ||
532 | size_t len, int replace) | ||
533 | { | 132 | { |
534 | (void)mbox; (void)msgno; (void)b; (void)len; (void)replace; | 133 | if (mbox == NULL || mbox->_messages_count == NULL) |
535 | return ENOSYS; | 134 | return ENOSYS; |
135 | return mbox->_messages_count (mbox, num); | ||
536 | } | 136 | } |
537 | 137 | ||
538 | static int | 138 | int |
539 | mbx_append (mailbox_t mbox, size_t msgno) | 139 | mailbox_delete (mailbox_t mbox, size_t msgno) |
540 | { | 140 | { |
541 | (void)mbox; (void)msgno; | 141 | if (mbox == NULL || mbox->_delete == NULL) |
542 | return ENOSYS; | 142 | return ENOSYS; |
143 | return mbox->_delete (mbox, msgno); | ||
543 | } | 144 | } |
544 | 145 | ||
545 | static int | 146 | int |
546 | mbx_destroy_msg (mailbox_t mbox, size_t msgno) | 147 | mailbox_undelete (mailbox_t mbox, size_t msgno) |
547 | { | 148 | { |
548 | (void)mbox; (void)msgno; | 149 | if (mbox == NULL || mbox->_undelete == NULL) |
549 | return ENOSYS; | 150 | return ENOSYS; |
151 | return mbox->_undelete (mbox, msgno); | ||
550 | } | 152 | } |
551 | 153 | ||
552 | /* reading */ | 154 | int |
553 | static int | 155 | mailbox_expunge (mailbox_t mbox) |
554 | mbx_get_body (mailbox_t mbox, size_t msgno, off_t off, | ||
555 | char *b, size_t len, size_t *n) | ||
556 | { | 156 | { |
557 | (void)mbox; (void)msgno; (void)off; (void)b; (void)len; (void)n; | 157 | if (mbox == NULL || mbox->_expunge == NULL) |
558 | return ENOSYS; | 158 | return ENOSYS; |
159 | return mbox->_expunge (mbox); | ||
559 | } | 160 | } |
560 | 161 | ||
561 | static int | 162 | int |
562 | mbx_get_mbody (mailbox_t mbox, size_t msgno, off_t off, | 163 | mailbox_num_deleted (mailbox_t mbox, size_t *num) |
563 | char **body, size_t *n) | ||
564 | { | ||
565 | size_t i = 0; | ||
566 | mbox->_get_body (mbox, msgno, off, NULL, 0, &i); | ||
567 | i++; | ||
568 | *body = calloc (i, sizeof (char)); | ||
569 | if (*body == NULL) | ||
570 | { | ||
571 | return ENOMEM; | ||
572 | } | ||
573 | mbox->_get_body (mbox, msgno, off, *body, i, n); | ||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static int | ||
578 | mbx_get_header (mailbox_t mbox, size_t msgno, off_t off, | ||
579 | char *h, size_t len, size_t *n) | ||
580 | { | 164 | { |
581 | (void)mbox; (void)msgno; (void)off; (void)h; (void)len; (void)n; | 165 | if (mbox == NULL || mbox->_num_deleted == NULL) |
582 | return ENOSYS; | 166 | return EINVAL; |
167 | return mbox->_num_deleted (mbox, num); | ||
583 | } | 168 | } |
584 | 169 | ||
585 | static int | 170 | /* hook to allow some sort of "progress bar" .. I don't like it |
586 | mbx_get_mheader (mailbox_t mbox, size_t msgno, off_t off, | 171 | * but can not find any other way yet |
587 | char **header, size_t *n) | 172 | */ |
173 | int | ||
174 | mailbox_progress (mailbox_t mbox, int (*progress) (int, void *arg), void *arg) | ||
588 | { | 175 | { |
589 | size_t i; | 176 | if (mbox == NULL) |
590 | i = mbox->_get_header (mbox, msgno, off, NULL, 0, &i); | 177 | return EINVAL; |
591 | i++; | 178 | mbox->_progress = progress; |
592 | *header = calloc (i, sizeof (char)); | 179 | mbox->progress_arg = arg; |
593 | if (*header == NULL) | ||
594 | { | ||
595 | return ENOMEM; | ||
596 | } | ||
597 | mbox->_get_header (mbox, msgno, off, *header, i, n); | ||
598 | return 0; | 180 | return 0; |
599 | } | 181 | } |
600 | 182 | ||
601 | /* locking */ | 183 | int |
602 | static int | 184 | mailbox_is_updated (mailbox_t mbox) |
603 | mbx_lock (mailbox_t mbox, int flag) | ||
604 | { | ||
605 | (void)mbox; (void)flag; | ||
606 | return ENOSYS; | ||
607 | } | ||
608 | |||
609 | static int | ||
610 | mbx_unlock (mailbox_t mbox) | ||
611 | { | ||
612 | (void)mbox; | ||
613 | return ENOSYS; | ||
614 | } | ||
615 | |||
616 | /* owner and group */ | ||
617 | static int | ||
618 | mbx_set_owner (mailbox_t mbox, uid_t uid) | ||
619 | { | ||
620 | mbox->owner = uid; | ||
621 | return 0; | ||
622 | } | ||
623 | static int | ||
624 | mbx_get_owner (mailbox_t mbox, uid_t *uid) | ||
625 | { | 185 | { |
626 | *uid = mbox->owner; | 186 | if (mbox == NULL || mbox->_is_updated == NULL) |
627 | return 0; | 187 | return 0; |
188 | return mbox->_is_updated (mbox); | ||
628 | } | 189 | } |
629 | 190 | ||
630 | static int | 191 | ssize_t |
631 | mbx_set_group (mailbox_t mbox, uid_t gid) | 192 | mailbox_get_size (mailbox_t mbox, size_t msgno, size_t *h, size_t *b) |
632 | { | ||
633 | mbox->group = gid; | ||
634 | return 0; | ||
635 | } | ||
636 | static int | ||
637 | mbx_get_group (mailbox_t mbox, uid_t *gid) | ||
638 | { | 193 | { |
639 | *gid = mbox->group; | 194 | if (mbox == NULL || mbox->_get_size == NULL) |
640 | return 0; | 195 | return EINVAL; |
196 | return mbox->_get_size (mbox, msgno, h, b); | ||
641 | } | 197 | } |
642 | 198 | ||
643 | /* misc */ | 199 | ssize_t |
644 | static int | 200 | mailbox_get_header (mailbox_t mbox, size_t msgno, char *h, |
645 | mbx_scan (mailbox_t mbox, size_t *msgs) | 201 | size_t len, off_t off, int *err) |
646 | { | 202 | { |
647 | (void)mbox; (void)msgs; | 203 | if (mbox == NULL || mbox->_get_header == NULL) |
648 | return ENOSYS; | 204 | return ENOSYS; |
205 | return mbox->_get_header (mbox, msgno, h, len, off, err); | ||
649 | } | 206 | } |
650 | 207 | ||
651 | static int | 208 | ssize_t |
652 | mbx_is_updated (mailbox_t mbox) | 209 | mailbox_get_body (mailbox_t mbox, size_t msgno, char *b, |
210 | size_t len, off_t off, int *err) | ||
653 | { | 211 | { |
654 | (void)mbox; | 212 | if (mbox == NULL || mbox->_get_body == NULL) |
655 | return ENOSYS; | 213 | return ENOSYS; |
214 | return mbox->_get_body (mbox, msgno, b, len, off, err); | ||
656 | } | 215 | } |
657 | 216 | ||
658 | static int | 217 | /* locking */ |
659 | mbx_get_timeout (mailbox_t mbox, size_t *timeout) | 218 | int |
219 | mailbox_set_locker (mailbox_t mbox, locker_t locker) | ||
660 | { | 220 | { |
661 | *timeout = mbox->timeout; | 221 | if (mbox == NULL) |
222 | return EINVAL; | ||
223 | if (mbox->locker != NULL) | ||
224 | locker_destroy (&mbox->locker); | ||
225 | mbox->locker = locker; | ||
662 | return 0; | 226 | return 0; |
663 | } | 227 | } |
664 | 228 | ||
665 | static int | 229 | int |
666 | mbx_set_timeout (mailbox_t mbox, size_t timeout) | 230 | mailbox_get_locker (mailbox_t mbox, locker_t *locker) |
667 | { | 231 | { |
668 | mbox->timeout = timeout; | 232 | if (mbox == NULL || locker == NULL) |
233 | return EINVAL; | ||
234 | *locker = mbox->locker; | ||
669 | return 0; | 235 | return 0; |
670 | } | 236 | } |
671 | 237 | ||
672 | static int | 238 | int |
673 | mbx_get_refresh (mailbox_t mbox, size_t *refresh) | 239 | mailbox_set_auth (mailbox_t mbox, auth_t auth) |
674 | { | 240 | { |
675 | *refresh = mbox->refresh; | 241 | if (mbox == NULL) |
242 | return EINVAL; | ||
243 | mbox->auth = auth; | ||
676 | return 0; | 244 | return 0; |
677 | } | 245 | } |
678 | 246 | ||
679 | static int | 247 | int |
680 | mbx_set_refresh (mailbox_t mbox, size_t refresh) | 248 | mailbox_get_auth (mailbox_t mbox, auth_t *auth) |
681 | { | 249 | { |
682 | mbox->refresh = refresh; | 250 | if (mbox == NULL || auth == NULL) |
251 | return EINVAL; | ||
252 | *auth = mbox->auth; | ||
683 | return 0; | 253 | return 0; |
684 | } | 254 | } |
685 | |||
686 | static int | ||
687 | mbx_get_size (mailbox_t mbox, size_t msgno, size_t *sh, size_t *sb) | ||
688 | { | ||
689 | (void)mbox; (void)msgno; (void)sh; (void)sb; | ||
690 | return ENOSYS; | ||
691 | } | ||
692 | |||
693 | static int | ||
694 | mbx_set_notification (mailbox_t mbox, int (*func) (mailbox_t, void *arg)) | ||
695 | { | ||
696 | mbox->notification = func; | ||
697 | return ENOSYS; | ||
698 | } | ... | ... |
... | @@ -18,10 +18,12 @@ | ... | @@ -18,10 +18,12 @@ |
18 | #ifndef _MAILBOX_H | 18 | #ifndef _MAILBOX_H |
19 | # define _MAILBOX_H | 19 | # define _MAILBOX_H |
20 | 20 | ||
21 | #include <url.h> | ||
22 | #include <sys/types.h> | 21 | #include <sys/types.h> |
23 | #include <unistd.h> | 22 | |
24 | #include <stdlib.h> | 23 | #include <url.h> |
24 | #include <message.h> | ||
25 | #include <auth.h> | ||
26 | #include <locker.h> | ||
25 | 27 | ||
26 | #ifdef __cplusplus | 28 | #ifdef __cplusplus |
27 | extern "C" { | 29 | extern "C" { |
... | @@ -39,109 +41,44 @@ extern "C" { | ... | @@ -39,109 +41,44 @@ extern "C" { |
39 | struct _mailbox; | 41 | struct _mailbox; |
40 | typedef struct _mailbox *mailbox_t; | 42 | typedef struct _mailbox *mailbox_t; |
41 | 43 | ||
42 | struct mailbox_type | ||
43 | { | ||
44 | char *name; | ||
45 | int id; | ||
46 | struct url_type *utype; | ||
47 | int (*_init) __P ((mailbox_t *, const char *name)); | ||
48 | void (*_destroy) __P ((mailbox_t *)); | ||
49 | }; | ||
50 | |||
51 | |||
52 | /* constructor/destructor and possible types */ | 44 | /* constructor/destructor and possible types */ |
53 | extern int mailbox_init __P ((mailbox_t *, const char *name, int id)); | 45 | extern int mailbox_init __P ((mailbox_t *, const char *, int id)); |
54 | extern void mailbox_destroy __P ((mailbox_t *)); | 46 | extern void mailbox_destroy __P ((mailbox_t *)); |
55 | 47 | ||
56 | /* mailbox registration */ | ||
57 | extern int mailbox_list_type __P ((struct mailbox_type mtype[], | ||
58 | size_t len, size_t *n)); | ||
59 | extern int mailbox_list_mtype __P ((struct mailbox_type **mtype, size_t *n)); | ||
60 | extern int mailbox_add_type __P ((struct mailbox_type *mtype)); | ||
61 | extern int mailbox_remove_type __P ((struct mailbox_type *mtype)); | ||
62 | extern int mailbox_get_type __P ((struct mailbox_type **mtype, int id)); | ||
63 | |||
64 | #ifndef INLINE | ||
65 | # ifdef __GNUC__ | ||
66 | # define INLINE __inline__ | ||
67 | # else | ||
68 | # define INLINE | ||
69 | # endif | ||
70 | #endif | ||
71 | |||
72 | /* flags for mailbox_open () */ | 48 | /* flags for mailbox_open () */ |
73 | #define MU_MB_RDONLY ((int)1) | 49 | #define MU_MAILBOX_RDONLY ((int)1) |
74 | #define MU_MB_WRONLY (MU_MB_RDONLY << 1) | 50 | #define MU_MAILBOX_WRONLY (MU_MAILBOX_RDONLY << 1) |
75 | #define MU_MB_RDWR (MU_MB_WRONLY << 1) | 51 | #define MU_MAILBOX_RDWR (MU_MAILBOX_WRONLY << 1) |
76 | #define MU_MB_APPEND (MU_MB_RDWR << 1) | 52 | #define MU_MAILBOX_APPEND (MU_MAILBOX_RDWR << 1) |
77 | #define MU_MB_CREAT (MU_MB_APPEND << 1) | 53 | #define MU_MAILBOX_CREAT (MU_MAILBOX_APPEND << 1) |
78 | 54 | #define MU_MAILBOX_NONBLOCK (MU_MAILBOX_CREAT << 1) | |
79 | extern INLINE int mailbox_open __P ((mailbox_t, int flag)); | 55 | |
80 | extern INLINE int mailbox_close __P ((mailbox_t)); | 56 | extern int mailbox_open __P ((mailbox_t, int flag)); |
81 | 57 | extern int mailbox_close __P ((mailbox_t)); | |
82 | /* type */ | 58 | |
83 | extern INLINE int mailbox_get_name __P ((mailbox_t, int *id, char *name, | 59 | /* messages */ |
84 | size_t len, size_t *n)); | 60 | extern int mailbox_get_message __P ((mailbox_t, size_t msgno, message_t *msg)); |
85 | extern INLINE int mailbox_get_mname __P ((mailbox_t, int *id, char **name, | 61 | extern int mailbox_append_message __P ((mailbox_t, message_t msg)); |
86 | size_t *n)); | 62 | extern int mailbox_messages_count __P ((mailbox_t, size_t *num)); |
87 | 63 | extern int mailbox_expunge __P ((mailbox_t)); | |
88 | /* passwd */ | ||
89 | extern INLINE int mailbox_get_passwd __P ((mailbox_t, char *passwd, | ||
90 | size_t len, size_t *n)); | ||
91 | extern INLINE int mailbox_get_mpasswd __P ((mailbox_t, char **passwd, | ||
92 | size_t *n)); | ||
93 | extern INLINE int mailbox_set_passwd __P ((mailbox_t, const char *passwd, | ||
94 | size_t len)); | ||
95 | |||
96 | /* deleting */ | ||
97 | extern INLINE int mailbox_delete __P ((mailbox_t, size_t msgno)); | ||
98 | extern INLINE int mailbox_undelete __P ((mailbox_t, size_t msgno)); | ||
99 | extern INLINE int mailbox_expunge __P ((mailbox_t)); | ||
100 | extern INLINE int mailbox_is_deleted __P ((mailbox_t, size_t msgno)); | ||
101 | |||
102 | /* appending */ | ||
103 | extern INLINE int mailbox_new_msg __P ((mailbox_t, size_t * msgno)); | ||
104 | extern INLINE int mailbox_set_header __P ((mailbox_t, size_t msgno, | ||
105 | const char *h, size_t len, | ||
106 | int replace)); | ||
107 | extern INLINE int mailbox_set_body __P ((mailbox_t, size_t msgno, | ||
108 | const char *b, size_t len, | ||
109 | int replace)); | ||
110 | extern INLINE int mailbox_append __P ((mailbox_t, size_t msgno)); | ||
111 | extern INLINE int mailbox_destroy_msg __P ((mailbox_t, size_t msgno)); | ||
112 | |||
113 | /* reading */ | ||
114 | extern INLINE int mailbox_get_body __P ((mailbox_t, size_t msgno, | ||
115 | off_t off, char *b, | ||
116 | size_t len, size_t *n)); | ||
117 | extern INLINE int mailbox_get_mbody __P ((mailbox_t, size_t msgno, off_t off, | ||
118 | char **b, size_t *n)); | ||
119 | extern INLINE int mailbox_get_header __P ((mailbox_t, size_t msgno, off_t off, | ||
120 | char *h, size_t len, size_t *n)); | ||
121 | extern INLINE int mailbox_get_mheader __P ((mailbox_t, size_t msgno, off_t off, | ||
122 | char **h, size_t *n)); | ||
123 | 64 | ||
124 | /* Lock settings */ | 65 | /* Lock settings */ |
125 | typedef enum { MB_RDLOCK, MB_WRLOCK } mailbox_lock_t; | 66 | extern int mailbox_get_locker __P ((mailbox_t, locker_t *locker)); |
126 | extern INLINE int mailbox_lock __P ((mailbox_t, int flag)); | 67 | extern int mailbox_set_locker __P ((mailbox_t, locker_t locker)); |
127 | extern INLINE int mailbox_unlock __P ((mailbox_t)); | 68 | |
128 | 69 | /* Authentication */ | |
129 | /* owner and group */ | 70 | extern int mailbox_get_auth __P ((mailbox_t, auth_t *auth)); |
130 | extern INLINE int mailbox_set_owner __P ((mailbox_t, uid_t uid)); | 71 | extern int mailbox_set_auth __P ((mailbox_t, auth_t auth)); |
131 | extern INLINE int mailbox_set_group __P ((mailbox_t, gid_t gid)); | 72 | |
132 | 73 | /* update and scanning*/ | |
133 | /* miscellany */ | 74 | extern int mailbox_progress __P ((mailbox_t, int (*progress) |
134 | extern INLINE int mailbox_scan __P ((mailbox_t, size_t *msgs)); | 75 | __P ((int, void *)), void *arg)); |
135 | extern INLINE int mailbox_is_updated __P ((mailbox_t)); | 76 | extern int mailbox_is_updated __P ((mailbox_t)); |
136 | extern INLINE int mailbox_get_timeout __P ((mailbox_t, size_t *timeout)); | 77 | |
137 | extern INLINE int mailbox_set_timeout __P ((mailbox_t, size_t timeout)); | 78 | /* mailbox size ? */ |
138 | extern INLINE int mailbox_get_refresh __P ((mailbox_t, size_t *refresh)); | 79 | extern int mailbox_size __P ((mailbox_t, off_t size)); |
139 | extern INLINE int mailbox_set_refresh __P ((mailbox_t, size_t refresh)); | 80 | |
140 | extern INLINE int mailbox_get_size __P ((mailbox_t, size_t msgno, | 81 | extern int mailbox_get_url __P ((mailbox_t, url_t *)); |
141 | size_t *header, size_t *body)); | ||
142 | extern INLINE int mailbox_set_notification __P ((mailbox_t, | ||
143 | int (*notification) | ||
144 | __P ((mailbox_t, void *)))); | ||
145 | 82 | ||
146 | #ifdef __cplusplus | 83 | #ifdef __cplusplus |
147 | } | 84 | } | ... | ... |
... | @@ -16,13 +16,12 @@ | ... | @@ -16,13 +16,12 @@ |
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | 16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
17 | 17 | ||
18 | #ifndef _MAILBOX0_H | 18 | #ifndef _MAILBOX0_H |
19 | # define _MAILBOX0_H | 19 | #define _MAILBOX0_H |
20 | 20 | ||
21 | #include <url.h> | ||
22 | #include <mailbox.h> | 21 | #include <mailbox.h> |
22 | |||
23 | #include <sys/types.h> | 23 | #include <sys/types.h> |
24 | #include <unistd.h> | 24 | #include <stdio.h> |
25 | #include <stdlib.h> | ||
26 | 25 | ||
27 | #ifdef __cplusplus | 26 | #ifdef __cplusplus |
28 | extern "C" { | 27 | extern "C" { |
... | @@ -36,176 +35,78 @@ extern "C" { | ... | @@ -36,176 +35,78 @@ extern "C" { |
36 | # endif | 35 | # endif |
37 | #endif /*__P */ | 36 | #endif /*__P */ |
38 | 37 | ||
39 | /* forward declaration */ | ||
40 | //struct _mailbox; | ||
41 | //typedef struct _mailbox *mailbox_t; | ||
42 | |||
43 | /* Lock settings */ | ||
44 | //typedef enum { MB_ULOCK, MB_RLOCK, MB_WLOCK } mailbox_lock_t; | ||
45 | |||
46 | /* | ||
47 | struct mailbox_type | ||
48 | { | ||
49 | char *name; | ||
50 | int id; | ||
51 | struct url_type *utype; | ||
52 | int (*_init) __P ((mailbox_t *, const char *name)); | ||
53 | void (*_destroy) __P ((mailbox_t *)); | ||
54 | }; | ||
55 | */ | ||
56 | |||
57 | struct _mailbox | 38 | struct _mailbox |
58 | { | 39 | { |
59 | /* Data */ | 40 | /* Data */ |
60 | 41 | ||
61 | char *name; | 42 | char *name; |
62 | uid_t owner; | 43 | FILE *file; |
63 | gid_t group; | 44 | message_t *messages; |
64 | size_t messages; | 45 | size_t messages_num; |
65 | size_t num_deleted; | ||
66 | off_t size; | 46 | off_t size; |
67 | int lock; | ||
68 | size_t timeout; | ||
69 | size_t refresh; | ||
70 | int (*notification) __P ((mailbox_t, void *arg)); | ||
71 | struct mailbox_type *mtype; | ||
72 | 47 | ||
73 | /* back pointer to the specific mailbox */ | 48 | auth_t auth; |
49 | locker_t locker; | ||
50 | url_t url; | ||
51 | |||
52 | int (*_progress) __P ((int, void *arg)); | ||
53 | void *progress_arg; | ||
54 | |||
55 | /* Back pointer to the specific mailbox */ | ||
74 | void *data; | 56 | void *data; |
75 | 57 | ||
76 | /* Functions */ | 58 | /* Public methods */ |
77 | 59 | ||
78 | #define MU_MB_RDONLY ((int)1) | 60 | int (*_init) __P ((mailbox_t *, const char *)); |
79 | #define MU_MB_WRONLY (MU_MB_RDONLY << 1) | 61 | void (*_destroy) __P ((mailbox_t *)); |
80 | #define MU_MB_RDWR (MU_MB_WRONLY << 1) | ||
81 | #define MU_MB_APPEND (MU_MB_RDWR << 1) | ||
82 | #define MU_MB_CREAT (MU_MB_APPEND << 1) | ||
83 | 62 | ||
84 | int (*_open) __P ((mailbox_t, int flag)); | 63 | int (*_open) __P ((mailbox_t, int flag)); |
85 | int (*_close) __P ((mailbox_t)); | 64 | int (*_close) __P ((mailbox_t)); |
86 | 65 | ||
87 | /* type */ | 66 | /* messages */ |
88 | int (*_get_name) __P ((mailbox_t, int *id, char *name, | 67 | int (*_get_message) __P ((mailbox_t, size_t msgno, message_t *msg)); |
89 | size_t len, size_t *n)); | 68 | int (*_append_message) __P ((mailbox_t, message_t msg)); |
90 | int (*_get_mname) __P ((mailbox_t, int *id, char **name, size_t *n)); | 69 | int (*_messages_count) __P ((mailbox_t, size_t *num)); |
91 | |||
92 | /* passwd if needed */ | ||
93 | int (*_get_passwd) __P ((mailbox_t, char *passwd, | ||
94 | size_t len, size_t *n)); | ||
95 | int (*_get_mpasswd) __P ((mailbox_t, char **passwd, size_t *n)); | ||
96 | int (*_set_passwd) __P ((mailbox_t, const char *passwd, size_t len)); | ||
97 | /* deleting mesgs */ | ||
98 | int (*_is_deleted) __P ((mailbox_t, size_t msgno)); | ||
99 | int (*_delete) __P ((mailbox_t, size_t msgno)); | ||
100 | int (*_undelete) __P ((mailbox_t, size_t msgno)); | ||
101 | int (*_expunge) __P ((mailbox_t)); | 70 | int (*_expunge) __P ((mailbox_t)); |
71 | |||
102 | int (*_is_updated) __P ((mailbox_t)); | 72 | int (*_is_updated) __P ((mailbox_t)); |
103 | int (*_scan) __P ((mailbox_t, size_t *msgs)); | ||
104 | |||
105 | /* appending messages */ | ||
106 | int (*_new_msg) __P ((mailbox_t, size_t *msgno)); | ||
107 | int (*_set_header) __P ((mailbox_t, size_t msgno, const char *h, | ||
108 | size_t len, int replace)); | ||
109 | int (*_set_body) __P ((mailbox_t, size_t msgno, const char *b, | ||
110 | size_t len, int replace)); | ||
111 | int (*_append) __P ((mailbox_t, size_t msgno)); | ||
112 | int (*_destroy_msg) __P ((mailbox_t, size_t msgno)); | ||
113 | |||
114 | #define MU_MB_RDLOCK 0 | ||
115 | #define MU_MB_WRLOCK 1 | ||
116 | /* locking */ | ||
117 | int (*_lock) __P ((mailbox_t, int flag)); | ||
118 | int (*_unlock) __P ((mailbox_t)); | ||
119 | int (*_ilock) __P ((mailbox_t, int flag)); | ||
120 | int (*_iunlock) __P ((mailbox_t)); | ||
121 | |||
122 | /* reading mesgs */ | ||
123 | int (*_get_body) __P ((mailbox_t, size_t msgno, off_t off, | ||
124 | char *b, size_t len, size_t *n)); | ||
125 | int (*_get_mbody) __P ((mailbox_t, size_t msgno, off_t off, | ||
126 | char **b, size_t *n)); | ||
127 | int (*_get_header) __P ((mailbox_t, size_t msgno, off_t off, | ||
128 | char *h, size_t len, size_t *n)); | ||
129 | int (*_get_mheader) __P ((mailbox_t, size_t msgno, off_t off, | ||
130 | char **h, size_t *n)); | ||
131 | int (*_get_size) __P ((mailbox_t, size_t msgno, | ||
132 | size_t *h, size_t *b)); | ||
133 | 73 | ||
134 | /* setting flags */ | 74 | int (*_size) __P ((mailbox_t, off_t *size)); |
135 | int (*_is_read) __P ((mailbox_t, size_t msgno)); | ||
136 | int (*_set_read) __P ((mailbox_t, size_t msgno)); | ||
137 | int (*_is_seen) __P ((mailbox_t, size_t msgno)); | ||
138 | int (*_set_seen) __P ((mailbox_t, size_t msgno)); | ||
139 | 75 | ||
140 | /* owner and group */ | 76 | /* private */ |
141 | int (*_set_owner) __P ((mailbox_t, uid_t uid)); | 77 | int (*_delete) __P ((mailbox_t, size_t msgno)); |
142 | int (*_get_owner) __P ((mailbox_t, uid_t *uid)); | 78 | int (*_undelete) __P ((mailbox_t, size_t msgno)); |
143 | int (*_set_group) __P ((mailbox_t, gid_t gid)); | 79 | int (*_is_deleted) __P ((mailbox_t, size_t msgno)); |
144 | int (*_get_group) __P ((mailbox_t, gid_t *gid)); | 80 | int (*_num_deleted) __P ((mailbox_t, size_t *)); |
81 | int (*_get_size) __P ((mailbox_t, size_t msgno, | ||
82 | size_t *h, size_t *b)); | ||
145 | 83 | ||
146 | /* miscellany */ | 84 | ssize_t (*_get_header) __P ((mailbox_t, size_t msgno, char *h, |
147 | int (*_size) __P ((mailbox_t, off_t *size)); | 85 | size_t len, off_t off, int *err)); |
148 | int (*_get_timeout) __P ((mailbox_t, size_t *timeout)); | 86 | ssize_t (*_get_body) __P ((mailbox_t, size_t msgno, char *b, |
149 | int (*_set_timeout) __P ((mailbox_t, size_t timeout)); | 87 | size_t len, off_t off, int *err)); |
150 | int (*_get_refresh) __P ((mailbox_t, size_t *refresh)); | ||
151 | int (*_set_refresh) __P ((mailbox_t, size_t refresh)); | ||
152 | int (*_set_notification) __P ((mailbox_t, | ||
153 | int (*func) __P ((mailbox_t, void * arg)))); | ||
154 | }; | 88 | }; |
155 | 89 | ||
90 | /* private */ | ||
91 | extern int mailbox_delete __P ((mailbox_t, size_t msgno)); | ||
92 | extern int mailbox_undelete __P ((mailbox_t, size_t msgno)); | ||
93 | extern int mailbox_is_deleted __P ((mailbox_t, size_t msgno)); | ||
94 | extern int mailbox_num_deleted __P ((mailbox_t, size_t *)); | ||
95 | extern int mailbox_get_size __P ((mailbox_t, size_t msgno, | ||
96 | size_t *h, size_t *b)); | ||
97 | extern ssize_t mailbox_get_header __P ((mailbox_t, size_t msgno, char *h, | ||
98 | size_t len, off_t off, int *err)); | ||
99 | extern ssize_t mailbox_get_body __P ((mailbox_t, size_t msgno, char *b, | ||
100 | size_t len, off_t off, int *err)); | ||
101 | |||
102 | extern int mailbox_get_auth __P ((mailbox_t mbox, auth_t *auth)); | ||
103 | extern int mailbox_set_auth __P ((mailbox_t mbox, auth_t auth)); | ||
104 | extern int mailbox_get_locker __P ((mailbox_t mbox, locker_t *locker)); | ||
105 | extern int mailbox_set_locker __P ((mailbox_t mbox, locker_t locker)); | ||
106 | extern int mailbox_progress __P ((mailbox_t mbox, | ||
107 | int (*progress) (int, void *arg), | ||
108 | void *arg)); | ||
156 | 109 | ||
157 | #ifdef MU_USE_MACROS | ||
158 | #define mailbox_open(m, f) m->_open (m, f) | ||
159 | #define mailbox_close(m) m->_close (m) | ||
160 | |||
161 | /* type */ | ||
162 | #define mailbox_get_name(m, t, d, l, n) m->_get_name (m, t, d, l, n) | ||
163 | #define mailbox_get_mtype(m, t, d, n) m->_get_mtype (m, t, d, n) | ||
164 | |||
165 | /* passwd */ | ||
166 | #define mailbox_get_passwd(m, p, l, n) m->_get_passwd (m, p, l, n) | ||
167 | #define mailbox_get_mpasswd(m, p, n) m->_get_mpasswd (m, p, n) | ||
168 | #define mailbox_set_passwd(m, p, l) m->_set_passwd (m, p, l) | ||
169 | |||
170 | /* deleting */ | ||
171 | #define mailbox_delete(m, mid) m->_delete (m, mid) | ||
172 | #define mailbox_undelete(m, mid) m->_undelete (m, mid) | ||
173 | #define mailbox_is_deleted(m, mid) m->_is_deleted (m, mid) | ||
174 | #define mailbox_expunge(m) m->_expunge (m) | ||
175 | |||
176 | /* appending */ | ||
177 | #define mailbox_new_msg(m, mid) m->_new_msg (m, mid) | ||
178 | #define mailbox_set_header(m, mid, h, l, r) m->_set_header(m, mid, h, n, r) | ||
179 | #define mailbox_set_body(m, mid, b, l r) m->_set_body (m, mid, b, l, r) | ||
180 | #define mailbox_append(m, mid) m->_append (m, mid) | ||
181 | #define mailbox_destroy_msg(m, mid) m->_destroy_msg (m, mid) | ||
182 | |||
183 | /* locking */ | ||
184 | #define mailbox_lock(m, f) m->_lock (m, f) | ||
185 | #define mailbox_unlock(m) m->_unlock (m) | ||
186 | |||
187 | /* reading */ | ||
188 | #define mailbox_get_header(m, mid, h, l, n) m->_get_header (m, mid, h, o, n) | ||
189 | #define mailbox_get_mheader(m, mid, h, l) m->_get_header (m, mid, h, l) | ||
190 | #define mailbox_get_body(m, mid, b, l, n) m->_get_body (m, mid, b, l, n) | ||
191 | #define mailbox_get_mbody(m, mid, b, n) m->_get_body (m, mid, b, n) | ||
192 | |||
193 | /* owner and group */ | ||
194 | #define mailbox_set_owner(m, uid) m->_set_owner(m, uid) | ||
195 | #define mailbox_get_owner(m, uid) m->_set_owner(m, uid) | ||
196 | #define mailbox_set_group(m, gid) m->_set_group(m, gid) | ||
197 | #define mailbox_get_group(m, gid) m->_set_group(m, gid) | ||
198 | |||
199 | /* miscellany */ | ||
200 | #define mailbox_scan(m, t) m->_scan (m, t) | ||
201 | #define mailbox_is_updated(m) m->_is_updated (m) | ||
202 | #define mailbox_get_timeout(m, t) m->_get_timeout (m, t) | ||
203 | #define mailbox_set_timeout(m, t) m->_set_timeout (m, t) | ||
204 | #define mailbox_get_refresh(m, r) m->_get_refresh (m, r) | ||
205 | #define mailbox_set_refresh(m, r) m->_set_refresh (m, r) | ||
206 | #define mailbox_get_size(m, mid, sh, sb) m->_get_size(m, mid, sh, sb) | ||
207 | #define mailbox_set_notification(m, func) m->_set_notification (m, func) | ||
208 | #endif /* MU_USE_MACROS */ | ||
209 | 110 | ||
210 | #ifdef __cplusplus | 111 | #ifdef __cplusplus |
211 | } | 112 | } | ... | ... |
... | @@ -15,15 +15,17 @@ | ... | @@ -15,15 +15,17 @@ |
15 | along with this program; if not, write to the Free Software | 15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | 16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
17 | 17 | ||
18 | #include <mbx_imap.h> | 18 | #include <mailbox0.h> |
19 | #include <url_imap.h> | 19 | #include <registrar0.h> |
20 | #include <errno.h> | 20 | #include <errno.h> |
21 | 21 | ||
22 | 22 | ||
23 | struct mailbox_type _mailbox_imap_type = | 23 | static int mailbox_imap_init (mailbox_t *mbox, const char *name); |
24 | static void mailbox_imap_destroy (mailbox_t *mbox); | ||
25 | |||
26 | struct mailbox_registrar _mailbox_imap_registrar = | ||
24 | { | 27 | { |
25 | "IMAP4", | 28 | "IMAP4", |
26 | (int)&_url_imap_type, &_url_imap_type, | ||
27 | mailbox_imap_init, mailbox_imap_destroy | 29 | mailbox_imap_init, mailbox_imap_destroy |
28 | }; | 30 | }; |
29 | 31 | ... | ... |
... | @@ -15,24 +15,19 @@ | ... | @@ -15,24 +15,19 @@ |
15 | along with this program; if not, write to the Free Software | 15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | 16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
17 | 17 | ||
18 | #ifdef HAVE_CONFIG_H | 18 | #include <mailbox0.h> |
19 | #include <config.h> | 19 | #include <registrar0.h> |
20 | #endif | ||
21 | |||
22 | 20 | ||
23 | #include <url_mbox.h> | ||
24 | #include <mbx_mbox.h> | ||
25 | #include <mbx_unix.h> | ||
26 | #include <mbx_mdir.h> | ||
27 | #include <string.h> | 21 | #include <string.h> |
28 | |||
29 | #include <errno.h> | 22 | #include <errno.h> |
30 | #include <sys/stat.h> | 23 | #include <sys/stat.h> |
31 | 24 | ||
32 | struct mailbox_type _mailbox_mbox_type = | 25 | static int mailbox_mbox_init (mailbox_t *mbox, const char *name); |
26 | static void mailbox_mbox_destroy (mailbox_t *mbox); | ||
27 | |||
28 | struct mailbox_registrar _mailbox_mbox_registrar = | ||
33 | { | 29 | { |
34 | "UNIX_MBOX/Maildir/MMDF", | 30 | "UNIX_MBOX/Maildir/MMDF", |
35 | (int)&_url_mbox_type, &_url_mbox_type, | ||
36 | mailbox_mbox_init, mailbox_mbox_destroy | 31 | mailbox_mbox_init, mailbox_mbox_destroy |
37 | }; | 32 | }; |
38 | 33 | ||
... | @@ -49,7 +44,7 @@ struct mailbox_type _mailbox_mbox_type = | ... | @@ -49,7 +44,7 @@ struct mailbox_type _mailbox_mbox_type = |
49 | mailbox. | 44 | mailbox. |
50 | */ | 45 | */ |
51 | 46 | ||
52 | int | 47 | static int |
53 | mailbox_mbox_init (mailbox_t *mbox, const char *name) | 48 | mailbox_mbox_init (mailbox_t *mbox, const char *name) |
54 | { | 49 | { |
55 | struct stat st; | 50 | struct stat st; |
... | @@ -65,9 +60,7 @@ mailbox_mbox_init (mailbox_t *mbox, const char *name) | ... | @@ -65,9 +60,7 @@ mailbox_mbox_init (mailbox_t *mbox, const char *name) |
65 | What is the best course of action ?? | 60 | What is the best course of action ?? |
66 | */ | 61 | */ |
67 | if (stat (name, &st) < 0) | 62 | if (stat (name, &st) < 0) |
68 | { | 63 | return _mailbox_unix_registrar._init (mbox, name); |
69 | return errno; /* errno set by stat () */ | ||
70 | } | ||
71 | 64 | ||
72 | if (S_ISREG (st.st_mode)) | 65 | if (S_ISREG (st.st_mode)) |
73 | { | 66 | { |
... | @@ -99,7 +92,7 @@ mailbox_mbox_init (mailbox_t *mbox, const char *name) | ... | @@ -99,7 +92,7 @@ mailbox_mbox_init (mailbox_t *mbox, const char *name) |
99 | if (count == 0) /*empty file*/ | 92 | if (count == 0) /*empty file*/ |
100 | { | 93 | { |
101 | close (fd); | 94 | close (fd); |
102 | return mailbox_unix_init (mbox, name); | 95 | return _mailbox_unix_registrar._init (mbox, name); |
103 | } | 96 | } |
104 | 97 | ||
105 | if (count >= 5) | 98 | if (count >= 5) |
... | @@ -108,27 +101,26 @@ mailbox_mbox_init (mailbox_t *mbox, const char *name) | ... | @@ -108,27 +101,26 @@ mailbox_mbox_init (mailbox_t *mbox, const char *name) |
108 | { | 101 | { |
109 | /* This is Unix Mbox */ | 102 | /* This is Unix Mbox */ |
110 | close (fd); | 103 | close (fd); |
111 | return mailbox_unix_init (mbox, name); | 104 | return _mailbox_unix_registrar._init (mbox, name); |
112 | } | 105 | } |
113 | } | 106 | } |
114 | 107 | ||
115 | /* Try MMDF */ | 108 | /* Try MMDF */ |
116 | close (fd); | 109 | close (fd); |
117 | #endif | 110 | #endif |
118 | return mailbox_unix_init (mbox, name); | 111 | return _mailbox_unix_registrar._init (mbox, name); |
119 | } | 112 | } |
113 | /* Is that true ? Are all directories Maildir ?? */ | ||
120 | else if (S_ISDIR (st.st_mode)) | 114 | else if (S_ISDIR (st.st_mode)) |
121 | { | 115 | return _mailbox_maildir_registrar._init (mbox, name); |
122 | /* Is that true ? Are all directories Maildir ?? */ | ||
123 | return mailbox_maildir_init (mbox, name); | ||
124 | } | ||
125 | 116 | ||
126 | /* Why can't a mailbox be FIFO ? or a DOOR/Portal ? */ | 117 | /* Why can't a mailbox be FIFO ? or a DOOR/Portal ??? */ |
127 | return EINVAL; | 118 | return EINVAL; |
128 | } | 119 | } |
129 | 120 | ||
130 | void | 121 | static void |
131 | mailbox_mbox_destroy (mailbox_t *mbox) | 122 | mailbox_mbox_destroy (mailbox_t *pmbox) |
132 | { | 123 | { |
133 | (*mbox)->mtype->_destroy (mbox); | 124 | if (pmbox && *pmbox) |
125 | _mailbox_unix_registrar._destroy (pmbox); | ||
134 | } | 126 | } | ... | ... |
... | @@ -15,14 +15,16 @@ | ... | @@ -15,14 +15,16 @@ |
15 | along with this program; if not, write to the Free Software | 15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | 16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
17 | 17 | ||
18 | #include <url_mdir.h> | 18 | #include <mailbox0.h> |
19 | #include <mbx_mdir.h> | 19 | #include <registrar0.h> |
20 | #include <errno.h> | 20 | #include <errno.h> |
21 | 21 | ||
22 | struct mailbox_type _mailbox_maildir_type = | 22 | static int mailbox_maildir_init (mailbox_t *mbox, const char *name); |
23 | static void mailbox_maildir_destroy (mailbox_t *mbox); | ||
24 | |||
25 | struct mailbox_registrar _mailbox_maildir_registrar = | ||
23 | { | 26 | { |
24 | "MAILDIR", | 27 | "MAILDIR", |
25 | (int)&_url_maildir_type, &_url_maildir_type, | ||
26 | mailbox_maildir_init, mailbox_maildir_destroy | 28 | mailbox_maildir_init, mailbox_maildir_destroy |
27 | }; | 29 | }; |
28 | 30 | ... | ... |
... | @@ -10,15 +10,13 @@ | ... | @@ -10,15 +10,13 @@ |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU Library General Public License for more details. | 12 | * GNU Library General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU Library General Public License | 14 | * You should have received a copy of the GNU Library General Public License |
15 | * along with this program; if not, write to the Free Software | 15 | * along with this program; if not, write to the Free Software |
16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
17 | */ | 17 | */ |
18 | 18 | #include <mailbox0.h> | |
19 | #ifdef HAVE_CONFIG_H | 19 | #include <registrar0.h> |
20 | #include "config.h" | ||
21 | #endif | ||
22 | 20 | ||
23 | #include <dirent.h> | 21 | #include <dirent.h> |
24 | #include <errno.h> | 22 | #include <errno.h> |
... | @@ -26,13 +24,15 @@ | ... | @@ -26,13 +24,15 @@ |
26 | #include <sys/stat.h> | 24 | #include <sys/stat.h> |
27 | #include <sys/types.h> | 25 | #include <sys/types.h> |
28 | #include <unistd.h> | 26 | #include <unistd.h> |
27 | #include <stdlib.h> | ||
28 | #include <ctype.h> | ||
29 | 29 | ||
30 | typedef int _url_mh_type; | 30 | static int mailbox_mh_init (mailbox_t *pmbox, const char *name); |
31 | static void mailbox_mh_destroy (mailbox_t *pmbox); | ||
31 | 32 | ||
32 | struct mailbox_type _mailbox_mh_type = | 33 | struct mailbox_registrar _mailbox_mh_registrar = |
33 | { | 34 | { |
34 | "MH" | 35 | "MH", |
35 | (int)&_url_mh_type, &_url_mh_type, | ||
36 | mailbox_mh_init, mailbox_mh_destroy | 36 | mailbox_mh_init, mailbox_mh_destroy |
37 | }; | 37 | }; |
38 | 38 | ||
... | @@ -41,9 +41,12 @@ typedef struct _mh_data | ... | @@ -41,9 +41,12 @@ typedef struct _mh_data |
41 | time_t mtime; /* used for checking if mailbox was updated */ | 41 | time_t mtime; /* used for checking if mailbox was updated */ |
42 | } mh_data; | 42 | } mh_data; |
43 | 43 | ||
44 | static int mh_open (mailbox_t mbox, int flags); | ||
45 | static int mh_close (mailbox_t mbox); | ||
46 | static int mh_scan (mailbox_t mbox, size_t *msgs); | ||
44 | static int mh_sequence(const char *name); | 47 | static int mh_sequence(const char *name); |
45 | 48 | ||
46 | int | 49 | static int |
47 | mailbox_mh_init (mailbox_t *pmbox, const char *name) | 50 | mailbox_mh_init (mailbox_t *pmbox, const char *name) |
48 | { | 51 | { |
49 | mailbox_t mbox; | 52 | mailbox_t mbox; |
... | @@ -54,12 +57,16 @@ mailbox_mh_init (mailbox_t *pmbox, const char *name) | ... | @@ -54,12 +57,16 @@ mailbox_mh_init (mailbox_t *pmbox, const char *name) |
54 | mbox->name = malloc(strlen(name) + 1); | 57 | mbox->name = malloc(strlen(name) + 1); |
55 | strcpy(mbox->name, name); | 58 | strcpy(mbox->name, name); |
56 | mbox->data = data; | 59 | mbox->data = data; |
60 | mbox->_init = mailbox_mh_init; | ||
61 | mbox->_destroy = mailbox_mh_destroy; | ||
62 | mbox->_open = mh_open; | ||
63 | mbox->_close = mh_close; | ||
57 | *pmbox = mbox; | 64 | *pmbox = mbox; |
58 | 65 | ||
59 | return 0; | 66 | return 0; |
60 | } | 67 | } |
61 | 68 | ||
62 | void | 69 | static void |
63 | mailbox_mh_destroy (mailbox_t *pmbox) | 70 | mailbox_mh_destroy (mailbox_t *pmbox) |
64 | { | 71 | { |
65 | free((*pmbox)->data); | 72 | free((*pmbox)->data); |
... | @@ -77,6 +84,7 @@ mh_open (mailbox_t mbox, int flags) | ... | @@ -77,6 +84,7 @@ mh_open (mailbox_t mbox, int flags) |
77 | struct stat st; | 84 | struct stat st; |
78 | mh_data *data; | 85 | mh_data *data; |
79 | 86 | ||
87 | (void) flags; | ||
80 | if (stat(mbox->name, &st) == -1) | 88 | if (stat(mbox->name, &st) == -1) |
81 | return errno; | 89 | return errno; |
82 | 90 | ||
... | @@ -141,8 +149,9 @@ mh_scan (mailbox_t mbox, size_t *msgs) | ... | @@ -141,8 +149,9 @@ mh_scan (mailbox_t mbox, size_t *msgs) |
141 | closedir(maildir); | 149 | closedir(maildir); |
142 | 150 | ||
143 | if(parse_sequence_file && count) { | 151 | if(parse_sequence_file && count) { |
152 | FILE *fp; | ||
144 | char *path = malloc(strlen(mbox->name) + strlen(".mh_sequences") + 2); | 153 | char *path = malloc(strlen(mbox->name) + strlen(".mh_sequences") + 2); |
145 | sprintf(path, "%s/.mh_sequences", mbox->name); | 154 | sprintf(path, "%s/.mh_sequences", mbox->name); |
146 | fp = fopen(path, "r"); | 155 | fp = fopen(path, "r"); |
147 | while(!feof(fp)) { | 156 | while(!feof(fp)) { |
148 | /* FIXME: parse the contents */ | 157 | /* FIXME: parse the contents */ |
... | @@ -159,7 +168,7 @@ mh_scan (mailbox_t mbox, size_t *msgs) | ... | @@ -159,7 +168,7 @@ mh_scan (mailbox_t mbox, size_t *msgs) |
159 | return 0; | 168 | return 0; |
160 | } | 169 | } |
161 | 170 | ||
162 | /* | 171 | /* |
163 | * Local atoi() | 172 | * Local atoi() |
164 | * created this to guarantee that name is only digits, normal atoi allows | 173 | * created this to guarantee that name is only digits, normal atoi allows |
165 | * whitespace | 174 | * whitespace |
... | @@ -167,7 +176,7 @@ mh_scan (mailbox_t mbox, size_t *msgs) | ... | @@ -167,7 +176,7 @@ mh_scan (mailbox_t mbox, size_t *msgs) |
167 | static int | 176 | static int |
168 | mh_sequence(const char *name) | 177 | mh_sequence(const char *name) |
169 | { | 178 | { |
170 | char *sequence; | 179 | const char *sequence; |
171 | int i; | 180 | int i; |
172 | 181 | ||
173 | for(i = 0, sequence = name; *sequence; sequence++) { | 182 | for(i = 0, sequence = name; *sequence; sequence++) { | ... | ... |
... | @@ -15,25 +15,28 @@ | ... | @@ -15,25 +15,28 @@ |
15 | along with this program; if not, write to the Free Software | 15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | 16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
17 | 17 | ||
18 | #include <url_mmdf.h> | 18 | #include <mailbox0.h> |
19 | #include <mbx_mmdf.h> | 19 | #include <registrar0.h> |
20 | |||
20 | #include <errno.h> | 21 | #include <errno.h> |
21 | 22 | ||
22 | struct mailbox_type _mailbox_mmdf_type = | 23 | static int mailbox_mmdf_init (mailbox_t *mbox, const char *name); |
24 | static void mailbox_mmdf_destroy (mailbox_t *mbox); | ||
25 | |||
26 | struct mailbox_registrar _mailbox_mmdf_registrar = | ||
23 | { | 27 | { |
24 | "MMDF", | 28 | "MMDF", |
25 | (int)&_url_mmdf_type, &_url_mmdf_type, | ||
26 | mailbox_mmdf_init, mailbox_mmdf_destroy | 29 | mailbox_mmdf_init, mailbox_mmdf_destroy |
27 | }; | 30 | }; |
28 | 31 | ||
29 | int | 32 | static int |
30 | mailbox_mmdf_init (mailbox_t *mbox, const char *name) | 33 | mailbox_mmdf_init (mailbox_t *mbox, const char *name) |
31 | { | 34 | { |
32 | (void)mbox; (void)name; | 35 | (void)mbox; (void)name; |
33 | return ENOSYS; | 36 | return ENOSYS; |
34 | } | 37 | } |
35 | 38 | ||
36 | void | 39 | static void |
37 | mailbox_mmdf_destroy (mailbox_t *mbox) | 40 | mailbox_mmdf_destroy (mailbox_t *mbox) |
38 | { | 41 | { |
39 | (void)mbox; | 42 | (void)mbox; | ... | ... |
... | @@ -15,25 +15,28 @@ | ... | @@ -15,25 +15,28 @@ |
15 | along with this program; if not, write to the Free Software | 15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | 16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
17 | 17 | ||
18 | #include <url_pop.h> | 18 | #include <mailbox0.h> |
19 | #include <mbx_pop.h> | 19 | #include <registrar0.h> |
20 | |||
20 | #include <errno.h> | 21 | #include <errno.h> |
21 | 22 | ||
22 | struct mailbox_type _mailbox_pop_type = | 23 | static int mailbox_pop_init (mailbox_t *mbox, const char *name); |
24 | static void mailbox_pop_destroy (mailbox_t *mbox); | ||
25 | |||
26 | struct mailbox_registrar _mailbox_pop_registrar = | ||
23 | { | 27 | { |
24 | "POP3", | 28 | "POP3", |
25 | (int)&_url_pop_type, &_url_pop_type, | ||
26 | mailbox_pop_init, mailbox_pop_destroy | 29 | mailbox_pop_init, mailbox_pop_destroy |
27 | }; | 30 | }; |
28 | 31 | ||
29 | void | 32 | static void |
30 | mailbox_pop_destroy (mailbox_t *mbox) | 33 | mailbox_pop_destroy (mailbox_t *mbox) |
31 | { | 34 | { |
32 | (void)mbox; | 35 | (void)mbox; |
33 | return; | 36 | return; |
34 | } | 37 | } |
35 | 38 | ||
36 | int | 39 | static int |
37 | mailbox_pop_init (mailbox_t *mbox, const char *name) | 40 | mailbox_pop_init (mailbox_t *mbox, const char *name) |
38 | { | 41 | { |
39 | (void)mbox; (void)name; | 42 | (void)mbox; (void)name; | ... | ... |
... | @@ -15,12 +15,14 @@ | ... | @@ -15,12 +15,14 @@ |
15 | along with this program; if not, write to the Free Software | 15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | 16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
17 | 17 | ||
18 | #include <url_unix.h> | 18 | #include <mailbox0.h> |
19 | #include <mbx_unix.h> | 19 | #include <registrar0.h> |
20 | #include <message0.h> | ||
21 | #include <attribute0.h> | ||
22 | #include <auth.h> | ||
23 | #include <locker.h> | ||
20 | 24 | ||
21 | #ifdef HAVE_CONFIG_H | 25 | #define HAVE_PTHREAD_H |
22 | #include "config.h" | ||
23 | #endif | ||
24 | 26 | ||
25 | #include <stdlib.h> | 27 | #include <stdlib.h> |
26 | #include <stdio.h> | 28 | #include <stdio.h> |
... | @@ -30,226 +32,121 @@ | ... | @@ -30,226 +32,121 @@ |
30 | #include <unistd.h> | 32 | #include <unistd.h> |
31 | #include <signal.h> | 33 | #include <signal.h> |
32 | #include <errno.h> | 34 | #include <errno.h> |
33 | #include <pthread.h> | 35 | #ifdef HAVE_PTHREAD_H |
36 | # include <pthread.h> | ||
37 | #else | ||
38 | # define flockfile(arg) | ||
39 | # define funlockfile(arg) | ||
40 | #endif | ||
34 | #include <string.h> | 41 | #include <string.h> |
35 | #include <ctype.h> | 42 | #include <ctype.h> |
36 | 43 | ||
37 | struct mailbox_type _mailbox_unix_type = | 44 | static int mailbox_unix_init (mailbox_t *pmbox, const char *name); |
45 | static void mailbox_unix_destroy (mailbox_t *pmbox); | ||
46 | |||
47 | struct mailbox_registrar _mailbox_unix_registrar = | ||
38 | { | 48 | { |
39 | "UNIX MBOX", | 49 | "UNIX MBOX", |
40 | (int)&_url_unix_type, &_url_unix_type, | ||
41 | mailbox_unix_init, mailbox_unix_destroy | 50 | mailbox_unix_init, mailbox_unix_destroy |
42 | }; | 51 | }; |
43 | 52 | ||
44 | typedef struct _mailbox_unix_msg | 53 | /* |
54 | * Keep a reference of where the header and body starts | ||
55 | * and end. | ||
56 | */ | ||
57 | typedef struct _mailbox_unix_message | ||
45 | { | 58 | { |
46 | off_t header; | 59 | off_t header; |
60 | off_t header_end; | ||
47 | off_t body; | 61 | off_t body; |
48 | off_t end; | 62 | off_t body_end; |
49 | int deleted; | 63 | attribute_t attribute; |
50 | int is_read; | 64 | } *mailbox_unix_message_t; |
51 | int is_seen; | ||
52 | } *mailbox_unix_msg_t; | ||
53 | 65 | ||
54 | typedef struct _mailbox_unix_data | 66 | typedef struct _mailbox_unix_data |
55 | { | 67 | { |
56 | mailbox_unix_msg_t messages; | 68 | mailbox_unix_message_t messages; |
69 | size_t messages_count; | ||
70 | size_t num_deleted; | ||
57 | FILE *file; | 71 | FILE *file; |
58 | char *dirname; | 72 | char *dirname; |
59 | char *basename; | 73 | char *basename; |
74 | int flags; | ||
60 | #ifdef HAVE_PTHREAD_H | 75 | #ifdef HAVE_PTHREAD_H |
61 | pthread_mutex_t mutex; | 76 | pthread_mutex_t mutex; |
62 | #endif | 77 | #endif |
63 | int lock; | ||
64 | int ilock; | ||
65 | time_t mtime; | 78 | time_t mtime; |
66 | size_t size; | 79 | size_t size; |
67 | } *mailbox_unix_data_t; | 80 | } *mailbox_unix_data_t; |
68 | 81 | ||
69 | |||
70 | /* forward prototypes */ | ||
71 | |||
72 | static int mailbox_unix_open (mailbox_t mbox, int flag); | 82 | static int mailbox_unix_open (mailbox_t mbox, int flag); |
73 | static int mailbox_unix_close (mailbox_t mbox); | 83 | static int mailbox_unix_close (mailbox_t mbox); |
74 | 84 | ||
75 | //static int mailbox_unix_get_name (mailbox_t, int *id, char *name, | 85 | static int mailbox_unix_append_message (mailbox_t, message_t msg); |
76 | // size_t len, size_t *n); | 86 | static int mailbox_unix_messages_count (mailbox_t, size_t *msgno); |
77 | |||
78 | /* passwd */ | ||
79 | |||
80 | /* updating/deleting */ | ||
81 | static int mailbox_unix_is_deleted (mailbox_t, size_t msgno); | ||
82 | static int mailbox_unix_delete (mailbox_t, size_t msgno); | 87 | static int mailbox_unix_delete (mailbox_t, size_t msgno); |
83 | static int mailbox_unix_undelete (mailbox_t, size_t msgno); | 88 | static int mailbox_unix_undelete (mailbox_t, size_t msgno); |
89 | static int mailbox_unix_is_deleted (mailbox_t, size_t msgno); | ||
84 | static int mailbox_unix_expunge (mailbox_t); | 90 | static int mailbox_unix_expunge (mailbox_t); |
85 | static int mailbox_unix_is_updated (mailbox_t); | 91 | static int mailbox_unix_num_deleted (mailbox_t, size_t *); |
86 | static int mailbox_unix_scan (mailbox_t, size_t *msgs); | ||
87 | |||
88 | |||
89 | /* appending */ | ||
90 | static int mailbox_unix_new_msg (mailbox_t, size_t *msgno); | ||
91 | static int mailbox_unix_set_header (mailbox_t, size_t msgno, const char *h, | ||
92 | size_t len, int replace); | ||
93 | static int mailbox_unix_set_body (mailbox_t, size_t msgno, const char *b, | ||
94 | size_t len, int replace); | ||
95 | static int mailbox_unix_append (mailbox_t, size_t msgno); | ||
96 | static int mailbox_unix_destroy_msg (mailbox_t, size_t msgno); | ||
97 | |||
98 | /* reading */ | ||
99 | static int mailbox_unix_get_body (mailbox_t, size_t msgno, off_t off, | ||
100 | char *b, size_t len, size_t *n); | ||
101 | static int mailbox_unix_get_header (mailbox_t, size_t msgno, off_t off, | ||
102 | char *h, size_t len, size_t *n); | ||
103 | static int mailbox_unix_get_size (mailbox_t, size_t msgno, size_t *header, | 92 | static int mailbox_unix_get_size (mailbox_t, size_t msgno, size_t *header, |
104 | size_t *body); | 93 | size_t *body); |
105 | 94 | ||
106 | /* setting flags */ | 95 | static int mailbox_unix_scan (mailbox_t, size_t *msgs); |
107 | static int mailbox_unix_is_read (mailbox_t, size_t msgno); | 96 | static int mailbox_unix_is_updated (mailbox_t); |
108 | static int mailbox_unix_set_read (mailbox_t, size_t msgno); | ||
109 | static int mailbox_unix_is_seen (mailbox_t, size_t msgno); | ||
110 | static int mailbox_unix_set_seen (mailbox_t, size_t msgno); | ||
111 | |||
112 | /* owner and group | ||
113 | static int mailbox_unix_set_owner (mailbox_t mbox, uid_t uid); | ||
114 | static int mailbox_unix_get_owner (mailbox_t mbox, uid_t *uid); | ||
115 | static int mailbox_unix_set_group (mailbox_t mbox, gid_t gid); | ||
116 | static int mailbox_unix_get_group (mailbox_t mbox, gid_t *gid); | ||
117 | */ | ||
118 | |||
119 | /* locking */ | ||
120 | static int mailbox_unix_lock (mailbox_t, int flag); | ||
121 | static int mailbox_unix_unlock (mailbox_t); | ||
122 | static int mailbox_unix_ilock (mailbox_t, int flag); | ||
123 | static int mailbox_unix_iunlock (mailbox_t); | ||
124 | 97 | ||
125 | static int mailbox_unix_size (mailbox_t, off_t *size); | 98 | static int mailbox_unix_size (mailbox_t, off_t *size); |
126 | 99 | ||
100 | static ssize_t mailbox_unix_get_header (mailbox_t, size_t msgno, char *h, | ||
101 | size_t len, off_t off, int *err); | ||
102 | static ssize_t mailbox_unix_get_body (mailbox_t, size_t msgno, char *b, | ||
103 | size_t len, off_t off, int *err); | ||
104 | |||
105 | |||
127 | /* private stuff */ | 106 | /* private stuff */ |
128 | static int mailbox_unix_is_from (const char *); | 107 | static int mailbox_unix_is_from (const char *); |
129 | static int mailbox_unix_readhdr (mailbox_t mbox, char *buf, size_t len, | 108 | static int mailbox_unix_readhdr (mailbox_t mbox, char *buf, size_t len, |
130 | off_t *content_length); | 109 | off_t *content_length, attribute_t attr); |
131 | //static int mailbox_unix_sigblock (); | 110 | static int mailbox_unix_lock (mailbox_t mbox, int flag); |
132 | //static int mailbox_unix_sigunblock (); | 111 | static int mailbox_unix_unlock (mailbox_t mbox); |
133 | 112 | static int mailbox_unix_ilock (mailbox_t mbox, int flag); | |
134 | /* Having a structure initialize at compiletime instead of runtime | 113 | static int mailbox_unix_iunlock (mailbox_t mbox); |
135 | may speed thing a bit, but it is a real pain to maintain with | ||
136 | the changing API */ | ||
137 | static struct _mailbox unixmbox = | ||
138 | { | ||
139 | /* Data */ | ||
140 | |||
141 | (char *)NULL, /* char *name ; */ | ||
142 | (uid_t)-1, /* uid_t owner; */ | ||
143 | (gid_t)-1, /* gid_t group; */ | ||
144 | 0, /* messages */ | ||
145 | 0, /* num_deleted */ | ||
146 | (off_t)0, /* size */ | ||
147 | 0, /* lock */ | ||
148 | 0, /* timeout; */ | ||
149 | 0, /* refresh; */ | ||
150 | (int (*)())NULL, /* (*func) __P ((mailbox_t, void *arg)) */ | ||
151 | |||
152 | /* type of mailbox */ | ||
153 | &_mailbox_unix_type, /*struct mailbox_type *mtype; */ | ||
154 | |||
155 | /* back pointer to the specific mailbox */ | ||
156 | (void *)NULL, /* void *data; */ | ||
157 | |||
158 | /* Functions */ | ||
159 | |||
160 | mailbox_unix_open, /* (*_open) */ | ||
161 | mailbox_unix_close, /* (*_close) */ | ||
162 | |||
163 | /* type */ | ||
164 | NULL, /* (*_get_name) */ | ||
165 | NULL, /* (*_get_mname) */ | ||
166 | |||
167 | /* passwd if needed */ | ||
168 | NULL, /* (*_get_passwd) */ | ||
169 | NULL, /* (*_get_mpasswd) */ | ||
170 | NULL, /* (*_set_passwd) */ | ||
171 | |||
172 | /* updating/deleting mesgs */ | ||
173 | mailbox_unix_is_deleted, /* (*_is_deleted) */ | ||
174 | mailbox_unix_delete, /* (*_delete) */ | ||
175 | mailbox_unix_undelete, /* (*_undelete) */ | ||
176 | mailbox_unix_expunge, /* (*_expunge) */ | ||
177 | mailbox_unix_is_updated, /* (*_is_updated) */ | ||
178 | mailbox_unix_scan, /* (*_scan) */ | ||
179 | |||
180 | /* appending messages */ | ||
181 | mailbox_unix_new_msg, /* (*_new_msg) */ | ||
182 | mailbox_unix_set_header, /* (*_set_header) */ | ||
183 | mailbox_unix_set_body, /* (*_set_body) */ | ||
184 | mailbox_unix_append, /* (*_append) */ | ||
185 | mailbox_unix_destroy_msg, /* (*_destroy_msg) */ | ||
186 | |||
187 | /* external locking */ | ||
188 | mailbox_unix_lock, /* (*_lock) */ | ||
189 | mailbox_unix_unlock, /* (*_unlock) */ | ||
190 | /* internal locking */ | ||
191 | mailbox_unix_ilock, /* (*_ilock) */ | ||
192 | mailbox_unix_iunlock, /* (*_iunlock) */ | ||
193 | |||
194 | /* reading mesgs */ | ||
195 | mailbox_unix_get_body, /* (*_get_body) */ | ||
196 | NULL, /* (*_get_mbody) */ | ||
197 | mailbox_unix_get_header, /* (*_get_header) */ | ||
198 | NULL, /* (*_get_mheader) */ | ||
199 | mailbox_unix_get_size, /* (*_get_msg_size) */ | ||
200 | |||
201 | /* setting flags */ | ||
202 | mailbox_unix_is_read, /* (*_msg_is_read) */ | ||
203 | mailbox_unix_set_read, /* (*_msg_set_read) */ | ||
204 | mailbox_unix_is_seen, /* (*_msg_is_seen) */ | ||
205 | mailbox_unix_set_seen, /* (*_msg_set_seen) */ | ||
206 | |||
207 | /* owner and group */ | ||
208 | NULL, /* (*_set_owner) */ | ||
209 | NULL, /* (*_get_owner) */ | ||
210 | NULL, /* (*_set_group) */ | ||
211 | NULL, /* (*_get_group) */ | ||
212 | |||
213 | mailbox_unix_size, /* (*_size) */ | ||
214 | NULL, /* (*_get_timeout) */ | ||
215 | NULL, /* (*_set_timeout) */ | ||
216 | NULL, /* (*_get_refresh) */ | ||
217 | NULL, /* (*_set_refresh) */ | ||
218 | NULL, /* (*_set_notification) */ | ||
219 | }; | ||
220 | 114 | ||
221 | int | 115 | static int |
222 | mailbox_unix_init (mailbox_t *pmbox, const char *name) | 116 | mailbox_unix_init (mailbox_t *pmbox, const char *name) |
223 | { | 117 | { |
224 | mailbox_t mbox; | 118 | mailbox_t mbox; |
225 | size_t len; | ||
226 | mailbox_unix_data_t mud; | 119 | mailbox_unix_data_t mud; |
227 | char *sep; | 120 | const char *sep; |
228 | 121 | size_t name_len; | |
122 | int i; | ||
229 | 123 | ||
230 | /* sanity check */ | 124 | /* sanity check */ |
231 | if (name == NULL || *name == '\0') | 125 | if (name == NULL || *name == '\0') |
232 | { | 126 | return EINVAL; |
233 | return EINVAL; | 127 | |
234 | } | 128 | name_len = strlen (name); |
129 | |||
130 | #define UNIX_SCHEME "unix:" | ||
131 | #define UNIX_SCHEME_LEN 5 | ||
132 | #define SEPARATOR '/' | ||
235 | 133 | ||
236 | /* pass the url */ | 134 | /* pass the url */ |
237 | sep = strstr (name, "unix://"); | 135 | if (name_len > UNIX_SCHEME_LEN && |
238 | if (sep) | 136 | name[0] == 'u' && name[1] == 'n' && |
239 | name += 7; | 137 | name[2] == 'i' && name[3] == 'x' && |
138 | name[4] == ':') | ||
139 | { | ||
140 | name += UNIX_SCHEME_LEN; | ||
141 | name_len -= UNIX_SCHEME_LEN; | ||
142 | } | ||
240 | 143 | ||
241 | /* allocate memory for mbox */ | 144 | /* allocate memory for mbox */ |
242 | mbox = calloc (1, sizeof (*mbox)); | 145 | mbox = calloc (1, sizeof (*mbox)); |
243 | if (mbox == NULL) | 146 | if (mbox == NULL) |
244 | { | 147 | return ENOMEM; |
245 | return ENOMEM; /* errno set by calloc() */ | ||
246 | } | ||
247 | |||
248 | /* FIXME: what does the next comment mean? */ | ||
249 | /* binary copy of the function */ | ||
250 | *mbox = unixmbox; | ||
251 | 148 | ||
252 | /* specific unix mbox data */ | 149 | /* allocate specific unix mbox data */ |
253 | mud = mbox->data = calloc (1, sizeof (*mud)); | 150 | mud = mbox->data = calloc (1, sizeof (*mud)); |
254 | if (mbox->data == NULL) | 151 | if (mbox->data == NULL) |
255 | { | 152 | { |
... | @@ -258,21 +155,29 @@ mailbox_unix_init (mailbox_t *pmbox, const char *name) | ... | @@ -258,21 +155,29 @@ mailbox_unix_init (mailbox_t *pmbox, const char *name) |
258 | } | 155 | } |
259 | 156 | ||
260 | /* copy the name */ | 157 | /* copy the name */ |
261 | len = strlen (name) + 1; | 158 | mbox->name = calloc (name_len + 1, sizeof (char)); |
262 | mbox->name = calloc (len, sizeof (char)); | ||
263 | if (mbox->name == NULL) | 159 | if (mbox->name == NULL) |
264 | { | 160 | { |
265 | mailbox_unix_destroy (&mbox); | 161 | mailbox_unix_destroy (&mbox); |
266 | return ENOMEM; | 162 | return ENOMEM; |
267 | } | 163 | } |
268 | memcpy (mbox->name, name, len); | 164 | memcpy (mbox->name, name, name_len); |
269 | 165 | ||
270 | /* save the basename and dirname */ | 166 | /* save the basename and dirname */ |
271 | sep = strrchr (name, '/'); | 167 | for (i = name_len, sep = NULL; i >= 0; i--) |
168 | { | ||
169 | /* break on the first separator */ | ||
170 | if (name[i] == SEPARATOR) | ||
171 | { | ||
172 | sep = &(name[i]); | ||
173 | break; | ||
174 | } | ||
175 | } | ||
176 | |||
272 | if (sep) | 177 | if (sep) |
273 | { | 178 | { |
274 | size_t baseln; | 179 | /* split it into two */ |
275 | mud->dirname = calloc (sep - name + 1, sizeof (char)); | 180 | mud->dirname = calloc ((sep - name) + 1, sizeof (char)); |
276 | if (mud->dirname == NULL) | 181 | if (mud->dirname == NULL) |
277 | { | 182 | { |
278 | mailbox_unix_destroy (&mbox); | 183 | mailbox_unix_destroy (&mbox); |
... | @@ -280,17 +185,19 @@ mailbox_unix_init (mailbox_t *pmbox, const char *name) | ... | @@ -280,17 +185,19 @@ mailbox_unix_init (mailbox_t *pmbox, const char *name) |
280 | } | 185 | } |
281 | memcpy (mud->dirname, name, sep - name); | 186 | memcpy (mud->dirname, name, sep - name); |
282 | 187 | ||
283 | baseln = strlen (++sep) + 1; | 188 | ++sep; |
284 | mud->basename = calloc (baseln, sizeof (char)); | 189 | mud->basename = calloc (name_len - (sep - name) + 1, sizeof (char)); |
285 | if (mud->basename == NULL) | 190 | if (mud->basename == NULL) |
286 | { | 191 | { |
287 | mailbox_unix_destroy (&mbox); | 192 | mailbox_unix_destroy (&mbox); |
288 | return ENOMEM; | 193 | return ENOMEM; |
289 | } | 194 | } |
290 | memcpy (mud->basename, sep, baseln); | 195 | memcpy (mud->basename, sep, name_len - (sep - name)); |
291 | } | 196 | } |
292 | else | 197 | else |
293 | { | 198 | { |
199 | /* use the relative directory "." */ | ||
200 | /* FIXME: should we call getcwd() instead ? */ | ||
294 | mud->dirname = calloc (2 , sizeof (char)); | 201 | mud->dirname = calloc (2 , sizeof (char)); |
295 | if (mud->dirname == NULL) | 202 | if (mud->dirname == NULL) |
296 | { | 203 | { |
... | @@ -299,13 +206,13 @@ mailbox_unix_init (mailbox_t *pmbox, const char *name) | ... | @@ -299,13 +206,13 @@ mailbox_unix_init (mailbox_t *pmbox, const char *name) |
299 | } | 206 | } |
300 | mud->dirname[0] = '.'; | 207 | mud->dirname[0] = '.'; |
301 | 208 | ||
302 | mud->basename = calloc (len, sizeof (char)); | 209 | mud->basename = calloc (name_len + 1, sizeof (char)); |
303 | if (mud->basename == NULL) | 210 | if (mud->basename == NULL) |
304 | { | 211 | { |
305 | mailbox_unix_destroy (&mbox); | 212 | mailbox_unix_destroy (&mbox); |
306 | return ENOMEM; | 213 | return ENOMEM; |
307 | } | 214 | } |
308 | memcpy (mud->basename, name, len); | 215 | memcpy (mud->basename, name, name_len); |
309 | } | 216 | } |
310 | 217 | ||
311 | /* mutex when accessing the structure fields */ | 218 | /* mutex when accessing the structure fields */ |
... | @@ -314,13 +221,35 @@ mailbox_unix_init (mailbox_t *pmbox, const char *name) | ... | @@ -314,13 +221,35 @@ mailbox_unix_init (mailbox_t *pmbox, const char *name) |
314 | pthread_mutex_init (&(mud->mutex), NULL); | 221 | pthread_mutex_init (&(mud->mutex), NULL); |
315 | #endif | 222 | #endif |
316 | 223 | ||
224 | mbox->_init = mailbox_unix_init; | ||
225 | mbox->_destroy = mailbox_unix_destroy; | ||
226 | |||
227 | mbox->_open = mailbox_unix_open; | ||
228 | mbox->_close = mailbox_unix_close; | ||
229 | |||
230 | /* messages */ | ||
231 | mbox->_append_message = mailbox_unix_append_message; | ||
232 | mbox->_messages_count = mailbox_unix_messages_count; | ||
233 | mbox->_delete = mailbox_unix_delete; | ||
234 | mbox->_undelete = mailbox_unix_undelete; | ||
235 | mbox->_is_deleted = mailbox_unix_is_deleted; | ||
236 | mbox->_expunge = mailbox_unix_expunge; | ||
237 | mbox->_num_deleted = mailbox_unix_num_deleted; | ||
238 | mbox->_get_size = mailbox_unix_get_size; | ||
239 | |||
240 | mbox->_is_updated = mailbox_unix_is_updated; | ||
241 | |||
242 | mbox->_size = mailbox_unix_size; | ||
243 | |||
244 | mbox->_get_header = mailbox_unix_get_header; | ||
245 | mbox->_get_body = mailbox_unix_get_body; | ||
317 | 246 | ||
318 | (*pmbox) = mbox; | 247 | (*pmbox) = mbox; |
319 | 248 | ||
320 | return 0; /* okdoke */ | 249 | return 0; /* okdoke */ |
321 | } | 250 | } |
322 | 251 | ||
323 | void | 252 | static void |
324 | mailbox_unix_destroy (mailbox_t *pmbox) | 253 | mailbox_unix_destroy (mailbox_t *pmbox) |
325 | { | 254 | { |
326 | if (pmbox && *pmbox) | 255 | if (pmbox && *pmbox) |
... | @@ -329,114 +258,124 @@ mailbox_unix_destroy (mailbox_t *pmbox) | ... | @@ -329,114 +258,124 @@ mailbox_unix_destroy (mailbox_t *pmbox) |
329 | mailbox_unix_close (mbox); | 258 | mailbox_unix_close (mbox); |
330 | if (mbox->data) | 259 | if (mbox->data) |
331 | { | 260 | { |
261 | size_t i; | ||
332 | mailbox_unix_data_t mud = mbox->data; | 262 | mailbox_unix_data_t mud = mbox->data; |
333 | if (mud->dirname) | 263 | free (mud->dirname); |
334 | free (mud->dirname); | 264 | free (mud->basename); |
335 | if (mud->basename) | 265 | for (i = 0; i < mud->messages_count; i++) |
336 | free (mud->basename); | 266 | { |
337 | if (mud->messages) | 267 | /* orphan the message */ |
338 | free (mud->messages); | 268 | mud->messages[i].attribute->message = NULL; |
269 | attribute_destroy (&(mud->messages[i].attribute)); | ||
270 | } | ||
271 | free (mud->messages); | ||
339 | free (mbox->data); | 272 | free (mbox->data); |
340 | } | 273 | } |
341 | if (mbox->name) | 274 | free (mbox->name); |
342 | free (mbox->name); | 275 | if (mbox->messages) |
276 | { | ||
277 | size_t i; | ||
278 | for (i = 0; i < mbox->messages_num; i++) | ||
279 | { | ||
280 | /* first orphan them */ | ||
281 | mbox->messages[i]->mailbox = NULL; | ||
282 | message_destroy (&(mbox->messages[i])); | ||
283 | } | ||
284 | } | ||
285 | free (mbox->messages); | ||
343 | free (*pmbox); | 286 | free (*pmbox); |
344 | pmbox = NULL; | 287 | *pmbox = NULL; |
345 | } | 288 | } |
346 | } | 289 | } |
347 | 290 | ||
348 | 291 | /* start of mbox Implementation */ | |
349 | /* start of Mbox Implementation */ | ||
350 | |||
351 | static int | 292 | static int |
352 | mailbox_unix_open (mailbox_t mbox, int flags) | 293 | mailbox_unix_open (mailbox_t mbox, int flags) |
353 | { | 294 | { |
354 | mailbox_unix_data_t mud = mbox->data; | 295 | mailbox_unix_data_t mud; |
355 | int fd = -1; | 296 | int fd = -1; |
356 | int flg = 0; | 297 | int flg = 0; |
357 | char * mode; | 298 | char *mode; |
358 | 299 | ||
359 | /* | 300 | if (mbox == NULL || |
360 | FIXME: This is another problem, should we have a special set of flags | 301 | (mud = (mailbox_unix_data_t)mbox->data) == NULL) |
361 | MU_MB_{CREAT,APPEND,RDONLY,RDWR} or use the default open(2) | 302 | return EINVAL; |
362 | and if RDONLY, should we have some security checks ? | 303 | |
363 | */ | 304 | if (flags & MU_MAILBOX_WRONLY) |
364 | if (flags & MU_MB_WRONLY) | 305 | flg = O_WRONLY; |
365 | { | 306 | else if (flags & MU_MAILBOX_RDWR) |
366 | flg = O_WRONLY; | 307 | flg = O_RDWR; |
367 | } | ||
368 | else if (flags & MU_MB_RDWR) | ||
369 | { | ||
370 | flg = O_RDWR; | ||
371 | } | ||
372 | else /* default */ | 308 | else /* default */ |
373 | { | 309 | flg = O_RDONLY; |
374 | flg = O_RDONLY; | ||
375 | } | ||
376 | 310 | ||
377 | if (flags & MU_MB_APPEND) | 311 | /* FIXME: only if the file is open Write */ |
378 | { | 312 | if (flags & MU_MAILBOX_APPEND) |
379 | flg |= O_APPEND; | 313 | flg |= O_APPEND; |
380 | } | 314 | |
315 | /* FIXME: does not really work, but local folders | ||
316 | * should not block since it is local disk ??? | ||
317 | */ | ||
318 | if (flags & MU_MAILBOX_NONBLOCK) | ||
319 | flg |= O_NONBLOCK; | ||
381 | 320 | ||
382 | /* handle CREAT with care, not to follow symlinks */ | 321 | /* handle CREAT with care, not to follow symlinks */ |
383 | if (flags & MU_MB_CREAT) | 322 | if (flags & MU_MAILBOX_CREAT) |
384 | { | 323 | { |
385 | /* first see if the file already exists */ | 324 | /* Grab the lock for any race conditions */ |
386 | fd = open(mbox->name, flg); | 325 | mailbox_unix_lock (mbox, MU_LOCKER_WRLOCK); |
387 | if (fd == -1) | 326 | { |
388 | { | 327 | /* first see if the file already exists */ |
389 | /* oops bail out */ | 328 | fd = open(mbox->name, flg); |
390 | if (errno != ENOENT) | 329 | if (fd == -1) |
391 | { | 330 | { |
331 | /* oops bail out */ | ||
332 | if (errno != ENOENT) | ||
392 | return errno; | 333 | return errno; |
393 | } | 334 | /* Create the file */ |
394 | /* Create the file */ | 335 | fd = open(mbox->name, flg|O_CREAT|O_EXCL, 0600); |
395 | fd = open(mbox->name, flg|O_CREAT|O_EXCL, 0600); | 336 | if (fd < 0) |
396 | if (fd < 0) | ||
397 | { | ||
398 | return errno; | 337 | return errno; |
399 | } | 338 | } |
400 | } | 339 | /* |
401 | /* | 340 | FIXME: How about owner(uid), to whom we set it to ? |
402 | FIXME: How about owner(uid), to whom we set it to ? | 341 | do We need a _set_owner(uid) to mailbox_t |
403 | do We need a _set_owner(uid) to mailbox_t | 342 | */ |
404 | */ | 343 | if (mbox->auth) |
405 | (void)fchown (fd, mbox->owner, mbox->group); | 344 | { |
406 | /* FIXME: should we have a mode field ? */ | 345 | auth_t auth = mbox->auth; |
407 | (void)fchmod (fd, 0600); | 346 | gid_t g ; uid_t u; mode_t m; |
347 | g = u = -1; m = 0600; | ||
348 | /* FIXME: what to do when they failed */ | ||
349 | auth_get_owner (auth, &u); | ||
350 | auth_get_group (auth, &g); | ||
351 | auth_get_mode (auth, &m); | ||
352 | (void)fchown (fd, u, g); | ||
353 | (void)fchmod (fd, m); | ||
354 | } | ||
355 | } | ||
356 | mailbox_unix_unlock (mbox); | ||
408 | } | 357 | } |
409 | else | 358 | else |
410 | { | 359 | { |
411 | fd = open (mbox->name, flg); | 360 | fd = open (mbox->name, flg); |
412 | if (fd < 0) | 361 | if (fd < 0) |
413 | { | 362 | return errno; |
414 | return errno; | ||
415 | } | ||
416 | } | 363 | } |
417 | 364 | ||
418 | /* we use FILE * object */ | 365 | /* we use FILE * object */ |
419 | if (flg & MU_MB_RDWR) | 366 | if (flags & MU_MAILBOX_APPEND) |
420 | { | 367 | mode = "a"; |
421 | mode = "r+"; | 368 | else if (flags & MU_MAILBOX_RDWR) |
422 | } | 369 | mode = "r+"; |
423 | else if (flg & MU_MB_WRONLY) | 370 | else if (flags & MU_MAILBOX_WRONLY) |
424 | { | 371 | mode = "w"; |
425 | mode = "w"; | ||
426 | } | ||
427 | else if (flg & MU_MB_APPEND) | ||
428 | { | ||
429 | mode = "a"; | ||
430 | } | ||
431 | else /* default readonly*/ | 372 | else /* default readonly*/ |
432 | { | 373 | mode = "r"; |
433 | mode = "r"; | ||
434 | } | ||
435 | 374 | ||
436 | /* clean up */ | 375 | /* clean up, make sure there was nothing before */ |
437 | mailbox_unix_close (mbox); | 376 | mailbox_unix_close (mbox); |
438 | 377 | ||
439 | mailbox_unix_ilock (mbox, MU_MB_WRLOCK); | 378 | mailbox_unix_ilock (mbox, MU_LOCKER_WRLOCK); |
440 | { | 379 | { |
441 | mud->file = fdopen (fd, mode); | 380 | mud->file = fdopen (fd, mode); |
442 | if (mud->file == NULL) | 381 | if (mud->file == NULL) |
... | @@ -445,15 +384,15 @@ mailbox_unix_open (mailbox_t mbox, int flags) | ... | @@ -445,15 +384,15 @@ mailbox_unix_open (mailbox_t mbox, int flags) |
445 | mailbox_unix_iunlock (mbox); | 384 | mailbox_unix_iunlock (mbox); |
446 | return ENOMEM; | 385 | return ENOMEM; |
447 | } | 386 | } |
387 | /* Is this necessary ?? */ | ||
388 | /* Check to make sure this is indeed a Unix Mail format */ | ||
448 | flockfile (mud->file); | 389 | flockfile (mud->file); |
449 | { | 390 | { |
450 | char buf [BUFSIZ]; | 391 | char buf [BUFSIZ]; |
451 | if (fgets (buf, sizeof (buf), mud->file) == NULL) | 392 | if (fgets (buf, sizeof (buf), mud->file) == NULL) |
452 | { | 393 | { |
453 | if (feof (mud->file)) | 394 | if (feof (mud->file)) |
454 | { | 395 | clearerr (mud->file); /* the file maybe empty */ |
455 | clearerr (mud->file); /* the file maybe empty */ | ||
456 | } | ||
457 | else if (ferror (mud->file)) | 396 | else if (ferror (mud->file)) |
458 | { | 397 | { |
459 | mailbox_unix_iunlock (mbox); | 398 | mailbox_unix_iunlock (mbox); |
... | @@ -470,88 +409,108 @@ mailbox_unix_open (mailbox_t mbox, int flags) | ... | @@ -470,88 +409,108 @@ mailbox_unix_open (mailbox_t mbox, int flags) |
470 | return EIO; | 409 | return EIO; |
471 | } | 410 | } |
472 | else | 411 | else |
473 | { | 412 | rewind (mud->file); |
474 | rewind (mud->file); | ||
475 | } | ||
476 | } | 413 | } |
477 | } | 414 | } |
478 | funlockfile (mud->file); | 415 | funlockfile (mud->file); |
479 | } | 416 | } |
480 | mailbox_unix_iunlock (mbox); | 417 | mailbox_unix_iunlock (mbox); |
418 | mud->flags = flags; | ||
481 | return 0; | 419 | return 0; |
482 | } | 420 | } |
483 | 421 | ||
484 | static int | 422 | static int |
485 | mailbox_unix_close (mailbox_t mbox) | 423 | mailbox_unix_close (mailbox_t mbox) |
486 | { | 424 | { |
487 | mailbox_unix_data_t mud = (mailbox_unix_data_t)mbox->data; | 425 | mailbox_unix_data_t mud; |
488 | |||
489 | mailbox_unix_ilock (mbox, MU_MB_WRLOCK); | ||
490 | { | ||
491 | 426 | ||
492 | /* make sure we do not hold any lock for that file */ | 427 | if (mbox == NULL || |
428 | (mud = (mailbox_unix_data_t)mbox->data) == NULL) | ||
429 | return EINVAL; | ||
493 | 430 | ||
494 | mailbox_unix_unlock (mbox); | 431 | mailbox_unix_ilock (mbox, MU_LOCKER_WRLOCK); |
432 | { | ||
495 | if (mud->file) | 433 | if (mud->file) |
496 | { | 434 | fclose (mud->file); |
497 | fclose (mud->file); | ||
498 | } | ||
499 | mud->file = NULL; | 435 | mud->file = NULL; |
436 | /* make sure we do not hold any lock for that file */ | ||
437 | mailbox_unix_unlock (mbox); | ||
500 | } | 438 | } |
501 | mailbox_unix_iunlock (mbox); | 439 | mailbox_unix_iunlock (mbox); |
502 | return 0; | 440 | return 0; |
503 | } | 441 | } |
504 | 442 | ||
505 | /* | ||
506 | static int | ||
507 | mailbox_unix_get_name (mailbox_t mbox, int *id, char *name, | ||
508 | size_t len, size_t *n) | ||
509 | { | ||
510 | char *s = _mailbox_unix_type.name; | ||
511 | size_t i = strlen (s); | ||
512 | if (id) | ||
513 | { | ||
514 | *id = _mailbox_unix_type.id; | ||
515 | } | ||
516 | if (name && len > 0) | ||
517 | { | ||
518 | i = (len < i) ? len : i; | ||
519 | strncpy (name, s, i - 1); | ||
520 | name [i - 1] = 0; | ||
521 | } | ||
522 | if (n) | ||
523 | { | ||
524 | *n = i; | ||
525 | } | ||
526 | return 0; | ||
527 | } | ||
528 | */ | ||
529 | |||
530 | /* passwd */ | ||
531 | /* We don't care */ | ||
532 | 443 | ||
533 | /* FIXME: hmmm, all of the files i check lack a timezone field */ | ||
534 | /* FIXME: a little weak, we should do full reconnaissance of the | 444 | /* FIXME: a little weak, we should do full reconnaissance of the |
535 | the "From " header : | 445 | * the "From " header : |
536 | From email weekday month day time timezone year | 446 | * From <user> <weekday> <month> <day> <hr:min:sec> |
447 | * [T1 [T2]] <year> [remote-list] | ||
537 | */ | 448 | */ |
538 | static int | 449 | static int |
539 | mailbox_unix_is_from (const char *from) | 450 | mailbox_unix_is_from (const char *from) |
540 | { | 451 | { |
541 | const char *sep; | 452 | const char *sep; |
542 | return (strncmp (from, "From ", 5) == 0 | 453 | |
543 | && (sep = strchr (from, ':')) != NULL | 454 | /* From_ */ |
544 | && strchr (sep, ':') != NULL); | 455 | if (strncmp (from, "From ", 5) != 0) |
456 | return 0; | ||
457 | from += 5; | ||
458 | |||
459 | /* <user> */ | ||
460 | sep = strchr (from, ' '); | ||
461 | if (sep == NULL) | ||
462 | return 0; | ||
463 | from = ++sep; | ||
464 | |||
465 | /* weekday */ | ||
466 | sep = strchr (from, ' '); | ||
467 | if (sep == NULL) | ||
468 | return 0; | ||
469 | from = ++sep; | ||
470 | |||
471 | /* month */ | ||
472 | sep = strchr (from, ' '); | ||
473 | if (sep == NULL) | ||
474 | return 0; | ||
475 | from = ++sep; | ||
476 | |||
477 | /* day */ | ||
478 | sep = strchr (from, ' '); | ||
479 | if (sep == NULL) | ||
480 | return 0; | ||
481 | from = ++sep; | ||
482 | |||
483 | /* hr:min:sec */ | ||
484 | /* hr */ | ||
485 | sep = strchr (from, ':'); | ||
486 | if (sep == NULL) | ||
487 | return 0; | ||
488 | from = ++sep; | ||
489 | /* min */ | ||
490 | sep = strchr (from, ':'); | ||
491 | if (sep == NULL) | ||
492 | return 0; | ||
493 | from = ++sep ; | ||
494 | /* sec */ | ||
495 | sep = strchr (from, ' '); | ||
496 | if (sep == NULL) | ||
497 | return 0; | ||
498 | |||
499 | /* FIXME PLEASE: the rest is getting more complex, finish it later */ | ||
500 | return 1; | ||
545 | } | 501 | } |
546 | 502 | ||
503 | /* | ||
504 | * We skip over the rest of the header. Scan for | ||
505 | * Status: to set the attribute. Hopfully the Content-Length | ||
506 | * in there too. | ||
507 | */ | ||
547 | static int | 508 | static int |
548 | mailbox_unix_readhdr (mailbox_t mbox, char *buf, size_t len, | 509 | mailbox_unix_readhdr (mailbox_t mbox, char *buf, size_t len, |
549 | off_t *content_length) | 510 | off_t *content_length, attribute_t attribute) |
550 | { | 511 | { |
551 | mailbox_unix_data_t mud = (mailbox_unix_data_t)mbox->data; | 512 | mailbox_unix_data_t mud = (mailbox_unix_data_t)mbox->data; |
552 | mailbox_unix_msg_t mum = mud->messages; | ||
553 | char *sep; | 513 | char *sep; |
554 | size_t count = mbox->messages; | ||
555 | 514 | ||
556 | /* skip over the remaining header */ | 515 | /* skip over the remaining header */ |
557 | while (fgets (buf, len, mud->file)) | 516 | while (fgets (buf, len, mud->file)) |
... | @@ -563,9 +522,7 @@ mailbox_unix_readhdr (mailbox_t mbox, char *buf, size_t len, | ... | @@ -563,9 +522,7 @@ mailbox_unix_readhdr (mailbox_t mbox, char *buf, size_t len, |
563 | */ | 522 | */ |
564 | if (strcmp (buf, "\n") == 0 || strcmp (buf, "\r\n") == 0 | 523 | if (strcmp (buf, "\n") == 0 || strcmp (buf, "\r\n") == 0 |
565 | || (isalpha (buf[0]) && (sep = strchr (buf, ':')) == NULL)) | 524 | || (isalpha (buf[0]) && (sep = strchr (buf, ':')) == NULL)) |
566 | { | 525 | break; |
567 | break; | ||
568 | } | ||
569 | /* get the the Content lenght of the body if possible */ | 526 | /* get the the Content lenght of the body if possible */ |
570 | if (strncmp (buf, "Content-Length:", 15) == 0) | 527 | if (strncmp (buf, "Content-Length:", 15) == 0) |
571 | { | 528 | { |
... | @@ -573,27 +530,34 @@ mailbox_unix_readhdr (mailbox_t mbox, char *buf, size_t len, | ... | @@ -573,27 +530,34 @@ mailbox_unix_readhdr (mailbox_t mbox, char *buf, size_t len, |
573 | sep[strlen (sep) - 1] = '\0'; /* chop the newline */ | 530 | sep[strlen (sep) - 1] = '\0'; /* chop the newline */ |
574 | *content_length = strtol (sep + 1, NULL, 10); | 531 | *content_length = strtol (sep + 1, NULL, 10); |
575 | } | 532 | } |
533 | /* Set the attribute */ | ||
576 | if (strncmp (buf, "Status:", 7) == 0) | 534 | if (strncmp (buf, "Status:", 7) == 0) |
577 | { | 535 | { |
578 | sep = strchr(buf, ':'); /* pass the ':' */ | 536 | sep = strchr(buf, ':'); /* pass the ':' */ |
579 | if (strchr (sep, 'R') != NULL) | 537 | if (strchr (sep, 'R') != NULL) |
580 | { | 538 | attribute_set_read (attribute); |
581 | mum[count - 1].is_read = 1; | 539 | if (strchr (sep, 'O') != NULL) |
582 | } | 540 | attribute_set_seen (attribute); |
583 | if (strchr (sep, 'O') != NULL) | 541 | if (strchr (sep, 'A') != NULL) |
584 | { | 542 | attribute_set_answered (attribute); |
585 | mum[count - 1].is_seen = 1; | 543 | if (strchr (sep, 'F') != NULL) |
586 | } | 544 | attribute_set_flagged (attribute); |
587 | } | 545 | } |
588 | } | 546 | } |
547 | /* check for any dubious conditions */ | ||
589 | if (feof (mud->file) || ferror (mud->file)) | 548 | if (feof (mud->file) || ferror (mud->file)) |
590 | { | 549 | return EIO; |
591 | return EIO; | ||
592 | } | ||
593 | return 0; | 550 | return 0; |
594 | } | 551 | } |
595 | 552 | ||
596 | /* Updating/deleting */ | 553 | /* Parsing. |
554 | * This a bit fragile, I need to secure this. | ||
555 | * The approach is to detect the "From " as start of a | ||
556 | * new message give the position of the header and scan | ||
557 | * until "\n" set header_end, set body position, we have | ||
558 | * a Content-Length header jump to the point if not | ||
559 | * scan until we it another "From " and set body_end. | ||
560 | */ | ||
597 | static int | 561 | static int |
598 | mailbox_unix_scan (mailbox_t mbox, size_t *msgs) | 562 | mailbox_unix_scan (mailbox_t mbox, size_t *msgs) |
599 | { | 563 | { |
... | @@ -602,139 +566,131 @@ mailbox_unix_scan (mailbox_t mbox, size_t *msgs) | ... | @@ -602,139 +566,131 @@ mailbox_unix_scan (mailbox_t mbox, size_t *msgs) |
602 | int body = 0; | 566 | int body = 0; |
603 | off_t content_length = -1; | 567 | off_t content_length = -1; |
604 | size_t count = 0; | 568 | size_t count = 0; |
605 | mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data; | 569 | mailbox_unix_data_t mud; |
606 | mailbox_unix_msg_t mum; | 570 | mailbox_unix_message_t mum; |
607 | struct stat st; | 571 | struct stat st; |
608 | 572 | ||
609 | mailbox_unix_ilock (mbox, MU_MB_WRLOCK); | 573 | if (mbox == NULL || |
610 | /* FIXME: please clarify next comment */ | 574 | (mud = (mailbox_unix_data_t)mbox->data) == NULL) |
611 | /* FIXME: I should also block signals since | 575 | return EINVAL; |
612 | We can affor to be intr */ | 576 | |
577 | /* FIXME: I should also block signals and check cancelstate(Pthread) | ||
578 | since We can not afford to be intr */ | ||
579 | mailbox_unix_ilock (mbox, MU_LOCKER_WRLOCK); | ||
580 | mailbox_unix_lock (mbox, MU_LOCKER_RDLOCK); | ||
613 | flockfile (mud->file); | 581 | flockfile (mud->file); |
614 | rewind (mud->file); | ||
615 | 582 | ||
616 | if (fstat (fileno (mud->file), &st) != 0) | 583 | if (fstat (fileno (mud->file), &st) != 0) |
617 | { | 584 | { |
618 | funlockfile (mud->file); | 585 | funlockfile (mud->file); |
619 | mailbox_unix_iunlock (mbox); | 586 | mailbox_unix_iunlock (mbox); |
587 | mailbox_unix_unlock (mbox); | ||
620 | return EIO; | 588 | return EIO; |
621 | } | 589 | } |
622 | mud->mtime = st.st_mtime; | 590 | mud->mtime = st.st_mtime; |
623 | mud->size = st.st_size; | 591 | mud->size = st.st_size; |
624 | 592 | ||
593 | rewind (mud->file); | ||
594 | |||
625 | while (fgets (buf, sizeof (buf), mud->file)) | 595 | while (fgets (buf, sizeof (buf), mud->file)) |
626 | { | 596 | { |
597 | if (mailbox_unix_is_from (buf)) | ||
598 | { | ||
599 | if (body && count) | ||
600 | { | ||
601 | int over = strlen (buf); | ||
602 | mum[count - 1].body_end = ftell (mud->file); | ||
603 | mum[count - 1].body_end -= (over + 1); | ||
604 | body = 0; | ||
605 | } | ||
606 | header = 1; | ||
607 | } | ||
608 | |||
627 | /* header */ | 609 | /* header */ |
628 | if ((header && mailbox_unix_is_from (buf))) | 610 | if (header) |
629 | { | 611 | { |
630 | /* FIXME: What happen if some mailer violates the rfc822 and the | 612 | /* FIXME: What happen if some mailer violates the rfc822 and the |
631 | "From " field contains a NULL byte */ | 613 | "From " field contains a NULL byte */ |
632 | int over = strlen (buf); | 614 | int over = strlen (buf); |
615 | |||
633 | count++; | 616 | count++; |
634 | if (count > mbox->messages) | 617 | /* FIXME: This is a bad idea, we should not be allowed to |
618 | * jump out from the scanning this way. We sit at the mercy | ||
619 | * of this function(_progress) waiting for disaster. | ||
620 | */ | ||
621 | if (mbox->_progress) | ||
622 | { | ||
623 | /* FIXME: and its getting better, they can even bailout */ | ||
624 | if (mbox->_progress (count, mbox->progress_arg) != 0) | ||
625 | { | ||
626 | funlockfile (mud->file); | ||
627 | mailbox_unix_iunlock (mbox); | ||
628 | mailbox_unix_unlock (mbox); | ||
629 | return EINTR; | ||
630 | } | ||
631 | } | ||
632 | if (count > mud->messages_count) | ||
635 | { | 633 | { |
636 | mum = realloc (mud->messages, count * sizeof (*mum)); | 634 | mum = realloc (mud->messages, count * sizeof (*mum)); |
637 | if (mum == NULL) | 635 | if (mum == NULL) |
638 | { | 636 | { |
639 | funlockfile (mud->file); | 637 | funlockfile (mud->file); |
640 | mailbox_unix_iunlock (mbox); | 638 | mailbox_unix_iunlock (mbox); |
639 | mailbox_unix_unlock (mbox); | ||
641 | return ENOMEM; | 640 | return ENOMEM; |
642 | } | 641 | } |
643 | mbox->messages++; | 642 | mud->messages_count++; |
644 | memset (&mum[count - 1], 0, sizeof (*mum)); | 643 | memset (&mum[count - 1], 0, sizeof (*mum)); |
644 | attribute_init (&(mum[count - 1].attribute)); | ||
645 | } | 645 | } |
646 | mud->messages = mum; | 646 | mud->messages = mum; |
647 | mum[count - 1].header = ftell (mud->file); | 647 | mum[count - 1].header = ftell (mud->file); |
648 | mum[count - 1].header -= over; | 648 | mum[count - 1].header -= over; |
649 | 649 | ||
650 | /* skip over the remaining header */ | 650 | /* skip over the remaining header */ |
651 | if (mailbox_unix_readhdr (mbox, buf, sizeof (buf), | 651 | if (mailbox_unix_readhdr (mbox, buf, sizeof (buf), &content_length, |
652 | &content_length) != 0) | 652 | mum[count - 1].attribute) != 0) |
653 | { | 653 | { |
654 | funlockfile (mud->file); | 654 | funlockfile (mud->file); |
655 | mailbox_unix_iunlock (mbox); | 655 | mailbox_unix_iunlock (mbox); |
656 | mailbox_unix_unlock (mbox); | ||
656 | return EIO; | 657 | return EIO; |
657 | } | 658 | } |
659 | mum[count - 1].header_end = ftell (mud->file) - strlen(buf); | ||
658 | header = 0; | 660 | header = 0; |
659 | body = !header; | 661 | body = !header; |
660 | } /* header */ | 662 | } /* header */ |
661 | 663 | ||
662 | /* body */ | 664 | /* body */ |
663 | if (body && content_length >= 0) | 665 | if (body) |
664 | { | ||
665 | /* ouf ! we got the size */ | ||
666 | mum[count - 1].body = ftell (mud->file) - strlen (buf); | ||
667 | fseek (mud->file, content_length, SEEK_CUR); | ||
668 | mum[count - 1].end = ftell (mud->file); | ||
669 | content_length = -1; | ||
670 | header = 1; | ||
671 | body = !header; | ||
672 | } | ||
673 | else if (body) | ||
674 | { | 666 | { |
675 | /* oops! some heuristic since we do not know the size of the body */ | ||
676 | if (mum[count - 1].body == 0) | 667 | if (mum[count - 1].body == 0) |
677 | { | 668 | mum[count - 1].body = ftell (mud->file); |
678 | mum[count - 1].body = ftell (mud->file) - strlen (buf); | ||
679 | } | ||
680 | 669 | ||
681 | if (mailbox_unix_is_from (buf)) | 670 | if (content_length >= 0) |
682 | { | 671 | { |
683 | int over = strlen (buf); | 672 | /* ouf ! we got the size */ |
684 | mum[count - 1].end = ftell (mud->file); | 673 | mum[count - 1].body_end = mum[count -1].body + content_length; |
685 | mum[count - 1].end -= over; | 674 | fseek (mud->file, content_length, SEEK_CUR); |
686 | count++; | 675 | content_length = -1; |
687 | if (count > mbox->messages) | 676 | body = 0; |
688 | { | ||
689 | mum = realloc (mud->messages, count * sizeof (*mum)); | ||
690 | if (mum == NULL) | ||
691 | { | ||
692 | funlockfile (mud->file); | ||
693 | mailbox_unix_iunlock (mbox); | ||
694 | return ENOMEM; | ||
695 | } | ||
696 | mbox->messages++; | ||
697 | memset (&mum[count - 1], 0, sizeof (*mum)); | ||
698 | } | ||
699 | mud->messages = mum; | ||
700 | mum[count - 1].header = ftell (mud->file); | ||
701 | mum[count - 1].header -= over; | ||
702 | |||
703 | /* skip over the remaining header */ | ||
704 | if (mailbox_unix_readhdr (mbox, buf, sizeof (buf), | ||
705 | &content_length) != 0) | ||
706 | { | ||
707 | funlockfile (mud->file); | ||
708 | mailbox_unix_iunlock (mbox); | ||
709 | return EIO; | ||
710 | } | ||
711 | |||
712 | mum[count - 1].body = ftell (mud->file) - strlen (buf); | ||
713 | if (content_length >= 0) | ||
714 | { | ||
715 | fseek (mud->file, content_length, SEEK_CUR); | ||
716 | mum[count - 1].end = ftell (mud->file); | ||
717 | content_length = -1; | ||
718 | header = 0; | ||
719 | body = !header; | ||
720 | } | ||
721 | } | 677 | } |
722 | } /* body */ | 678 | } |
723 | } /* while */ | 679 | } /* while */ |
724 | mum[count - 1].end = ftell (mud->file); | 680 | mum[count - 1].body_end = ftell (mud->file); |
725 | if (feof (mud->file)) | 681 | if (feof (mud->file)) |
726 | { | 682 | clearerr (mud->file); |
727 | clearerr (mud->file); | ||
728 | } | ||
729 | else if (ferror (mud->file)) | 683 | else if (ferror (mud->file)) |
730 | { | 684 | { |
731 | funlockfile (mud->file); | 685 | funlockfile (mud->file); |
732 | mailbox_unix_iunlock (mbox); | 686 | mailbox_unix_iunlock (mbox); |
687 | mailbox_unix_unlock (mbox); | ||
733 | return EIO; | 688 | return EIO; |
734 | } | 689 | } |
735 | rewind (mud->file); | 690 | rewind (mud->file); |
736 | funlockfile (mud->file); | 691 | funlockfile (mud->file); |
737 | mailbox_unix_iunlock (mbox); | 692 | mailbox_unix_iunlock (mbox); |
693 | mailbox_unix_unlock (mbox); | ||
738 | if (msgs) | 694 | if (msgs) |
739 | *msgs = count; | 695 | *msgs = count; |
740 | return 0; | 696 | return 0; |
... | @@ -743,118 +699,132 @@ mailbox_unix_scan (mailbox_t mbox, size_t *msgs) | ... | @@ -743,118 +699,132 @@ mailbox_unix_scan (mailbox_t mbox, size_t *msgs) |
743 | static int | 699 | static int |
744 | mailbox_unix_is_updated (mailbox_t mbox) | 700 | mailbox_unix_is_updated (mailbox_t mbox) |
745 | { | 701 | { |
746 | mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data; | 702 | mailbox_unix_data_t mud; |
747 | struct stat st; | 703 | struct stat st; |
748 | if (mud == 0 || fstat (fileno (mud->file), &st) < 0) | 704 | if (mbox == NULL || |
749 | { | 705 | (mud = (mailbox_unix_data_t)mbox->data) == NULL || |
750 | return 0; | 706 | fstat (fileno (mud->file), &st) < 0) |
751 | } | 707 | return 0; |
752 | return (mud->mtime == st.st_mtime); | 708 | return (mud->mtime == st.st_mtime); |
753 | } | 709 | } |
754 | 710 | ||
755 | static int | 711 | static int |
756 | mailbox_unix_is_valid (mailbox_t mbox, size_t msgno) | 712 | mailbox_unix_is_valid (mailbox_t mbox, size_t msgno) |
757 | { | 713 | { |
714 | mailbox_unix_data_t mud; | ||
715 | if (mbox == NULL || (mud = (mailbox_unix_data_t) mbox->data) == NULL) | ||
716 | return 0; | ||
758 | /* valid ? */ | 717 | /* valid ? */ |
759 | return (mbox->messages > 0 && msgno <= mbox->messages); | 718 | return (mud->messages_count > 0 && msgno <= mud->messages_count); |
760 | } | 719 | } |
761 | 720 | ||
762 | static int | 721 | static int |
763 | mailbox_unix_is_deleted (mailbox_t mbox, size_t msgno) | 722 | mailbox_unix_is_deleted (mailbox_t mbox, size_t msgno) |
764 | { | 723 | { |
765 | mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data; | 724 | mailbox_unix_data_t mud; |
766 | 725 | ||
767 | /* Do we have a consistent view of the mbox ? */ | 726 | /* Do we have a consistent view of the mbox ? */ |
768 | if (mud == NULL || ! mailbox_unix_is_valid (mbox, msgno)) | 727 | if (mbox == NULL || |
769 | { | 728 | (mud = (mailbox_unix_data_t)mbox->data) == NULL || |
770 | return 0; | 729 | ! mailbox_unix_is_valid (mbox, msgno)) |
771 | } | 730 | return 0; |
772 | return mud->messages[msgno].deleted; | 731 | return attribute_is_deleted (mud->messages[msgno].attribute); |
773 | } | 732 | } |
774 | 733 | ||
775 | static int | 734 | static int |
776 | mailbox_unix_delete (mailbox_t mbox, size_t msgno) | 735 | mailbox_unix_delete (mailbox_t mbox, size_t msgno) |
777 | { | 736 | { |
778 | mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data; | 737 | mailbox_unix_data_t mud; |
738 | |||
739 | if (mbox == NULL || | ||
740 | (mud = (mailbox_unix_data_t) mbox->data) == NULL) | ||
741 | return EINVAL; | ||
779 | 742 | ||
780 | /* oops out of range ? */ | 743 | /* oops out of range ? */ |
781 | /* if already deleted, noop */ | 744 | /* if already deleted, noop */ |
782 | if (mud == NULL || ! mailbox_unix_is_valid (mbox, msgno) | 745 | if (! mailbox_unix_is_valid (mbox, msgno) || |
783 | || mailbox_unix_is_deleted (mbox, msgno)) | 746 | mailbox_unix_is_deleted (mbox, msgno)) |
784 | { | 747 | return 0; |
785 | return 0; | ||
786 | } | ||
787 | 748 | ||
788 | /* Mark for deletion */ | 749 | /* Mark for deletion */ |
789 | mud->messages[msgno].deleted = 1; | 750 | attribute_set_deleted (mud->messages[msgno].attribute); |
790 | mbox->num_deleted++; | 751 | mud->num_deleted++; |
752 | return 0; | ||
753 | } | ||
754 | |||
755 | static int | ||
756 | mailbox_unix_num_deleted (mailbox_t mbox, size_t *num) | ||
757 | { | ||
758 | mailbox_unix_data_t mud; | ||
759 | if (mbox == NULL || | ||
760 | (mud = (mailbox_unix_data_t) mbox->data) == NULL) | ||
761 | return EINVAL; | ||
762 | if (num) | ||
763 | *num = mud->num_deleted; | ||
791 | return 0; | 764 | return 0; |
792 | } | 765 | } |
793 | 766 | ||
794 | static int | 767 | static int |
795 | mailbox_unix_undelete (mailbox_t mbox, size_t msgno) | 768 | mailbox_unix_undelete (mailbox_t mbox, size_t msgno) |
796 | { | 769 | { |
797 | mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data; | 770 | mailbox_unix_data_t mud; |
798 | 771 | ||
772 | if (mbox == NULL || | ||
773 | (mud = (mailbox_unix_data_t) mbox->data) == NULL) | ||
774 | return EINVAL; | ||
799 | /* oops out of range ? */ | 775 | /* oops out of range ? */ |
800 | /* if already undeleted, noop */ | 776 | /* if already undeleted, noop */ |
801 | if (mud == 0 || ! mailbox_unix_is_valid (mbox, msgno) | 777 | if (! mailbox_unix_is_valid (mbox, msgno) || |
802 | || ! mailbox_unix_is_deleted (mbox, msgno)) | 778 | ! mailbox_unix_is_deleted (mbox, msgno)) |
803 | { | 779 | return 0; |
804 | return 0; | ||
805 | } | ||
806 | 780 | ||
807 | /* Mark undeletion */ | 781 | /* Mark undeletion */ |
808 | mud->messages[msgno].deleted = 0; | 782 | attribute_unset_deleted (mud->messages[msgno].attribute); |
809 | mbox->num_deleted--; | 783 | mud->num_deleted--; |
810 | return 0; | 784 | return 0; |
811 | } | 785 | } |
812 | 786 | ||
787 | /* | ||
788 | FIXME: the use of tmpfile() on some system can lead to | ||
789 | race condition, We should use a safer approach. | ||
790 | We take a very naive approach for this, it involves unfortunately | ||
791 | two copies. | ||
792 | */ | ||
813 | static FILE * | 793 | static FILE * |
814 | mailbox_unix_tmpfile () | 794 | mailbox_unix_tmpfile () |
815 | { | 795 | { |
816 | /*FIXME: racing conidtions, to correct, .i.e don;t use tmpfile*/ | 796 | /*FIXME: racing conditions, to correct, .i.e don;t use tmpfile*/ |
817 | //return tmpfile (); | 797 | //return tmpfile (); |
818 | return fopen ("/tmp/mymail", "w"); | 798 | return fopen ("/tmp/mymail", "w"); |
819 | } | 799 | } |
820 | 800 | ||
821 | /* | ||
822 | FIXME: the use of tmpfile() on some system can lead to | ||
823 | race condition, We should use a safer approach. | ||
824 | We take a very naive approach to this, it involves unfortunately | ||
825 | two copies. | ||
826 | */ | ||
827 | static int | 801 | static int |
828 | mailbox_unix_expunge (mailbox_t mbox) | 802 | mailbox_unix_expunge (mailbox_t mbox) |
829 | { | 803 | { |
830 | mailbox_unix_data_t mud = (mailbox_unix_data_t)mbox->data; | 804 | mailbox_unix_data_t mud; |
831 | mailbox_unix_msg_t mum; | 805 | mailbox_unix_message_t mum; |
832 | sigset_t sigset; | 806 | sigset_t sigset; |
833 | FILE *tmpfile; | 807 | FILE *tmpfile; |
834 | size_t i; | 808 | size_t i; |
835 | off_t total = 0; | 809 | off_t total = 0; |
836 | char buffer [BUFSIZ]; | 810 | char buffer [BUFSIZ]; |
837 | 811 | ||
838 | if (mud == NULL) | 812 | if (mbox == NULL || |
839 | { | 813 | (mud = (mailbox_unix_data_t)mbox->data) == NULL) |
840 | return EINVAL; | 814 | return EINVAL; |
841 | } | 815 | |
842 | if (mbox->messages == 0 || mbox->num_deleted <= 0) | 816 | /* noop */ |
843 | { | 817 | if (mud->messages_count == 0 || mud->num_deleted <= 0) |
844 | /* noop */ | 818 | return 0; |
845 | return 0; | ||
846 | } | ||
847 | 819 | ||
848 | tmpfile = mailbox_unix_tmpfile (); | 820 | tmpfile = mailbox_unix_tmpfile (); |
849 | if (tmpfile == NULL) | 821 | if (tmpfile == NULL) |
850 | { | 822 | return errno; |
851 | return errno; | ||
852 | } | ||
853 | 823 | ||
854 | /* Get the lock */ | 824 | /* Get the lock */ |
855 | mailbox_unix_ilock (mbox, MU_MB_RDLOCK); | 825 | mailbox_unix_ilock (mbox, MU_LOCKER_RDLOCK); |
856 | flockfile (mud->file); | 826 | flockfile (mud->file); |
857 | if (mailbox_unix_lock (mbox, MU_MB_WRLOCK) < 0) | 827 | if (mailbox_unix_lock (mbox, MU_LOCKER_WRLOCK) < 0) |
858 | { | 828 | { |
859 | funlockfile (mud->file); | 829 | funlockfile (mud->file); |
860 | mailbox_unix_iunlock (mbox); | 830 | mailbox_unix_iunlock (mbox); |
... | @@ -873,13 +843,12 @@ mailbox_unix_expunge (mailbox_t mbox) | ... | @@ -873,13 +843,12 @@ mailbox_unix_expunge (mailbox_t mbox) |
873 | return EAGAIN; | 843 | return EAGAIN; |
874 | } | 844 | } |
875 | 845 | ||
876 | |||
877 | rewind (mud->file); | 846 | rewind (mud->file); |
878 | /* copy to temp file emails not mark deleted emails */ | 847 | /* copy to temp file emails not mark deleted emails */ |
879 | for (i = 1; i <= mbox->messages; i++) | 848 | for (i = 1; i <= mud->messages_count; i++) |
880 | { | 849 | { |
881 | mum = &mud->messages[i]; | 850 | mum = &mud->messages[i]; |
882 | if ( ! mum->deleted) | 851 | if ( ! attribute_is_deleted (mum->attribute)) |
883 | { | 852 | { |
884 | size_t len = mum->body - mum->header; | 853 | size_t len = mum->body - mum->header; |
885 | size_t nread; | 854 | size_t nread; |
... | @@ -908,10 +877,8 @@ mailbox_unix_expunge (mailbox_t mbox) | ... | @@ -908,10 +877,8 @@ mailbox_unix_expunge (mailbox_t mbox) |
908 | total += nread; | 877 | total += nread; |
909 | } | 878 | } |
910 | 879 | ||
911 | /* FIXME: We should set the seen flag also here */ | ||
912 | |||
913 | /* copy the body */ | 880 | /* copy the body */ |
914 | len = mum->end - mum->body; | 881 | len = mum->body_end - mum->body; |
915 | if (fseek (mud->file, mum->body, SEEK_SET) < 0) | 882 | if (fseek (mud->file, mum->body, SEEK_SET) < 0) |
916 | { | 883 | { |
917 | mailbox_unix_unlock (mbox); | 884 | mailbox_unix_unlock (mbox); |
... | @@ -987,265 +954,290 @@ mailbox_unix_expunge (mailbox_t mbox) | ... | @@ -987,265 +954,290 @@ mailbox_unix_expunge (mailbox_t mbox) |
987 | return 0; | 954 | return 0; |
988 | } | 955 | } |
989 | 956 | ||
990 | /* appending */ | ||
991 | static int | ||
992 | mailbox_unix_new_msg (mailbox_t mbox, size_t *msgno) | ||
993 | { | ||
994 | (void)mbox; (void)msgno; | ||
995 | return ENOSYS; | ||
996 | } | ||
997 | static int | ||
998 | mailbox_unix_set_header (mailbox_t mbox, size_t msgno, const char *h, | ||
999 | size_t len, int replace) | ||
1000 | { | ||
1001 | (void)mbox; (void)msgno; (void)h; (void)len; (void)replace; | ||
1002 | return ENOSYS; | ||
1003 | } | ||
1004 | static int | ||
1005 | mailbox_unix_set_body (mailbox_t mbox, size_t msgno, const char *b, | ||
1006 | size_t len, int replace) | ||
1007 | { | ||
1008 | (void)mbox; (void)msgno; (void)b; (void)len; (void)replace; | ||
1009 | return ENOSYS; | ||
1010 | } | ||
1011 | static int | ||
1012 | mailbox_unix_append (mailbox_t mbox, size_t msgno) | ||
1013 | { | ||
1014 | (void)mbox; (void)msgno; | ||
1015 | return ENOSYS; | ||
1016 | } | ||
1017 | static int | ||
1018 | mailbox_unix_destroy_msg (mailbox_t mbox, size_t msgno) | ||
1019 | { | ||
1020 | (void)mbox; (void)msgno; | ||
1021 | return ENOSYS; | ||
1022 | } | ||
1023 | |||
1024 | /* reading */ | 957 | /* reading */ |
1025 | static int | 958 | static ssize_t |
1026 | mailbox_unix_get_body (mailbox_t mbox, size_t msgno, off_t off, | 959 | mailbox_unix_get_body (mailbox_t mbox, size_t msgno, char *buffer, |
1027 | char *buffer, size_t len, size_t *n) | 960 | size_t len, off_t off, int *err) |
1028 | { | 961 | { |
1029 | mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data; | 962 | mailbox_unix_data_t mud; |
1030 | size_t nread; | 963 | size_t nread = 0; |
964 | |||
965 | if (mbox == NULL || | ||
966 | (mud = (mailbox_unix_data_t)mbox->data) == NULL) | ||
967 | { | ||
968 | if (err) | ||
969 | *err = EINVAL; | ||
970 | return -1; | ||
971 | } | ||
1031 | 972 | ||
1032 | /* check if valid */ | 973 | /* check if valid */ |
1033 | if (len < 1 || mud == NULL || ! mailbox_unix_is_valid (mbox, msgno)) | 974 | if (len < 1 || mud == NULL || ! mailbox_unix_is_valid (mbox, msgno)) |
1034 | { | 975 | { |
1035 | return EINVAL; | 976 | if (err) |
977 | *err = EINVAL; | ||
978 | return -1; | ||
1036 | } | 979 | } |
1037 | 980 | ||
1038 | mailbox_unix_ilock (mbox, MU_MB_RDLOCK); | 981 | mailbox_unix_ilock (mbox, MU_LOCKER_RDLOCK); |
1039 | flockfile (mud->file); | 982 | flockfile (mud->file); |
1040 | { | 983 | { |
1041 | mailbox_unix_msg_t mum = &(mud->messages[msgno]); | 984 | mailbox_unix_message_t mum = &(mud->messages[msgno]); |
1042 | off_t ln = mum->end - mum->body + off; | 985 | off_t ln = mum->body_end - (mum->body + off); |
1043 | if (ln < 0) | 986 | if (ln > 0) |
1044 | { | ||
1045 | funlockfile (mud->file); | ||
1046 | mailbox_unix_iunlock (mbox); | ||
1047 | return EIO; | ||
1048 | } | ||
1049 | nread = ((size_t)ln < len) ? ln : len; | ||
1050 | /* position the file pointer and the buffer */ | ||
1051 | if (fseek (mud->file, mum->body + off, SEEK_SET) < 0) | ||
1052 | { | ||
1053 | funlockfile (mud->file); | ||
1054 | mailbox_unix_iunlock (mbox); | ||
1055 | return EIO; | ||
1056 | } | ||
1057 | if (fread (buffer, sizeof (*buffer), nread, mud->file) != nread) | ||
1058 | { | 987 | { |
1059 | funlockfile (mud->file); | 988 | nread = ((size_t)ln < len) ? ln : len; |
1060 | mailbox_unix_iunlock (mbox); | 989 | /* position the file pointer and the buffer */ |
1061 | return EIO; | 990 | if (fseek (mud->file, mum->body + off, SEEK_SET) < 0) |
991 | { | ||
992 | funlockfile (mud->file); | ||
993 | mailbox_unix_iunlock (mbox); | ||
994 | if (err) | ||
995 | *err = EIO; | ||
996 | return -1; | ||
997 | } | ||
998 | if (fread (buffer, sizeof (*buffer), nread, mud->file) != nread) | ||
999 | { | ||
1000 | funlockfile (mud->file); | ||
1001 | mailbox_unix_iunlock (mbox); | ||
1002 | if (err) | ||
1003 | *err = EIO; | ||
1004 | return -1; | ||
1005 | } | ||
1062 | } | 1006 | } |
1063 | buffer[nread - 1] = '\0'; | 1007 | else |
1008 | nread = 0; | ||
1064 | } | 1009 | } |
1065 | funlockfile (mud->file); | 1010 | funlockfile (mud->file); |
1066 | mailbox_unix_iunlock (mbox); | 1011 | mailbox_unix_iunlock (mbox); |
1067 | 1012 | ||
1068 | if (n) | 1013 | return nread; |
1069 | *n = nread; | ||
1070 | return 0; | ||
1071 | } | 1014 | } |
1072 | static int | 1015 | |
1073 | mailbox_unix_get_header (mailbox_t mbox, size_t msgno, off_t off, | 1016 | static ssize_t |
1074 | char *buffer, size_t len, size_t *n) | 1017 | mailbox_unix_get_header (mailbox_t mbox, size_t msgno, char *buffer, |
1018 | size_t len, off_t off, int *err) | ||
1075 | { | 1019 | { |
1076 | mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data; | 1020 | mailbox_unix_data_t mud; |
1077 | size_t nread = 0; | 1021 | size_t nread = 0; |
1078 | 1022 | ||
1023 | if (mbox == NULL || | ||
1024 | (mud = (mailbox_unix_data_t)mbox->data) == NULL) | ||
1025 | { | ||
1026 | if (err) | ||
1027 | *err = EINVAL; | ||
1028 | return -1; | ||
1029 | } | ||
1030 | |||
1079 | /* check if valid */ | 1031 | /* check if valid */ |
1080 | if ( len < 1 || mud == NULL || ! mailbox_unix_is_valid (mbox, msgno)) | 1032 | if (len < 1 || ! mailbox_unix_is_valid (mbox, msgno)) |
1081 | { | 1033 | { |
1082 | return EINVAL; | 1034 | if (err) |
1035 | *err = EINVAL; | ||
1036 | return -1; | ||
1083 | } | 1037 | } |
1084 | 1038 | ||
1085 | mailbox_unix_ilock (mbox, MU_MB_RDLOCK); | 1039 | mailbox_unix_ilock (mbox, MU_LOCKER_RDLOCK); |
1086 | flockfile (mud->file); | 1040 | flockfile (mud->file); |
1087 | { | 1041 | { |
1088 | mailbox_unix_msg_t mum = &(mud->messages[msgno]); | 1042 | mailbox_unix_message_t mum = &(mud->messages[msgno]); |
1089 | off_t ln = mum->body - mum->header + off; | 1043 | off_t ln = mum->header_end - (mum->header + off); |
1090 | if (ln < 0) | 1044 | if (ln > 0) |
1091 | { | 1045 | { |
1092 | funlockfile (mud->file); | 1046 | nread = ((size_t)ln < len) ? ln : len; |
1093 | mailbox_unix_iunlock (mbox); | 1047 | /* position the file pointer and the buffer */ |
1094 | return EIO; | 1048 | if (fseek (mud->file, mum->header + off, SEEK_SET) < 0) |
1049 | { | ||
1050 | funlockfile (mud->file); | ||
1051 | mailbox_unix_iunlock (mbox); | ||
1052 | if (err) | ||
1053 | *err = EIO; | ||
1054 | return -1; | ||
1055 | } | ||
1056 | if (fread (buffer, sizeof (*buffer), nread, mud->file) != nread) | ||
1057 | { | ||
1058 | funlockfile (mud->file); | ||
1059 | mailbox_unix_iunlock (mbox); | ||
1060 | if (err) | ||
1061 | *err = EIO; | ||
1062 | return -1; | ||
1063 | } | ||
1095 | } | 1064 | } |
1096 | nread = ((size_t)ln < len) ? ln : len; | 1065 | else |
1097 | /* position the file pointer and the buffer */ | 1066 | nread = 0; |
1098 | if (fseek (mud->file, mum->header + off, SEEK_SET) < 0) | 1067 | } |
1068 | funlockfile (mud->file); | ||
1069 | mailbox_unix_iunlock (mbox); | ||
1070 | |||
1071 | return nread; | ||
1072 | } | ||
1073 | |||
1074 | static int | ||
1075 | mailbox_unix_append_message (mailbox_t mbox, message_t msg) | ||
1076 | { | ||
1077 | mailbox_unix_data_t mud; | ||
1078 | if (mbox == NULL || msg == NULL || | ||
1079 | (mud = (mailbox_unix_data_t)mbox->data) == NULL) | ||
1080 | return EINVAL; | ||
1081 | if (! ((mud->flags & MU_MAILBOX_APPEND) || | ||
1082 | (mud->flags & MU_MAILBOX_RDWR) || | ||
1083 | (mud->flags & MU_MAILBOX_WRONLY))) | ||
1084 | return EACCES; | ||
1085 | |||
1086 | mailbox_unix_lock (mbox, MU_LOCKER_WRLOCK); | ||
1087 | flockfile (mud->file); | ||
1088 | { | ||
1089 | struct stat st; | ||
1090 | int fd; | ||
1091 | char buffer[BUFSIZ]; | ||
1092 | header_t hdr; | ||
1093 | off_t off = 0; | ||
1094 | int err; | ||
1095 | size_t nread; | ||
1096 | |||
1097 | fd = fileno (mud->file); | ||
1098 | if (fstat (fd, &st) != 0) | ||
1099 | { | 1099 | { |
1100 | funlockfile (mud->file); | 1100 | funlockfile (mud->file); |
1101 | mailbox_unix_iunlock (mbox); | 1101 | mailbox_unix_unlock (mbox); |
1102 | return EIO; | 1102 | return errno; |
1103 | } | 1103 | } |
1104 | if (fread (buffer, sizeof (*buffer), nread, mud->file) != nread) | 1104 | if (fseek(mud->file, st.st_size, SEEK_SET) != 0) |
1105 | { | 1105 | { |
1106 | funlockfile (mud->file); | 1106 | funlockfile (mud->file); |
1107 | mailbox_unix_iunlock (mbox); | 1107 | mailbox_unix_unlock (mbox); |
1108 | return EIO; | 1108 | return errno; |
1109 | } | ||
1110 | message_get_header (msg, &hdr); | ||
1111 | if (st.st_size != 0) | ||
1112 | fputc ('\n', mud->file); | ||
1113 | while ((nread = header_get_data (hdr, buffer, sizeof (buffer), | ||
1114 | off, &err)) > 0) | ||
1115 | { | ||
1116 | fwrite (buffer, sizeof (*buffer), nread, mud->file); | ||
1117 | off += nread; | ||
1118 | } | ||
1119 | fputc ('\n', mud->file); | ||
1120 | off = 0; | ||
1121 | while ((nread = message_get_content (msg, buffer, sizeof (buffer), | ||
1122 | off, &err)) > 0) | ||
1123 | { | ||
1124 | fwrite (buffer, sizeof (*buffer), nread, mud->file); | ||
1125 | off += nread; | ||
1109 | } | 1126 | } |
1110 | buffer[nread - 1] = '\0'; | ||
1111 | } | 1127 | } |
1128 | fflush(mud->file); | ||
1112 | funlockfile (mud->file); | 1129 | funlockfile (mud->file); |
1113 | mailbox_unix_iunlock (mbox); | 1130 | mailbox_unix_unlock (mbox); |
1114 | |||
1115 | if (n) | ||
1116 | *n = nread; | ||
1117 | return 0; | 1131 | return 0; |
1118 | } | 1132 | } |
1119 | 1133 | ||
1120 | /* setting flags */ | ||
1121 | static int | 1134 | static int |
1122 | mailbox_unix_is_read (mailbox_t mbox, size_t msgno) | 1135 | mailbox_unix_size (mailbox_t mbox, off_t *size) |
1123 | { | 1136 | { |
1124 | mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data; | 1137 | mailbox_unix_data_t mud; |
1125 | if (mud == 0 || ! mailbox_unix_is_valid (mbox, msgno)) | 1138 | struct stat st; |
1126 | { | 1139 | int fd; |
1127 | return 0; | 1140 | |
1128 | } | 1141 | if (mbox == NULL || |
1129 | return mud->messages[msgno].is_read; | 1142 | (mud = (mailbox_unix_data_t)mbox->data) == NULL) |
1143 | return EINVAL; | ||
1144 | |||
1145 | /* maybe was not open yet ?? */ | ||
1146 | if (mud->file == NULL) | ||
1147 | return EIO; | ||
1148 | fd = fileno (mud->file); | ||
1149 | /* oops !! */ | ||
1150 | if (fstat (fd, &st) != 0) | ||
1151 | return errno; | ||
1152 | *size = st.st_size; | ||
1153 | return 0; | ||
1130 | } | 1154 | } |
1131 | 1155 | ||
1132 | static int | 1156 | static int |
1133 | mailbox_unix_set_read (mailbox_t mbox, size_t msgno) | 1157 | mailbox_unix_get_size (mailbox_t mbox, size_t msgno, size_t *h, size_t *b) |
1134 | { | 1158 | { |
1135 | mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data; | 1159 | mailbox_unix_data_t mud; |
1136 | if (mud == 0 || ! mailbox_unix_is_valid (mbox, msgno)) | 1160 | mailbox_unix_message_t mum; |
1137 | { | 1161 | |
1138 | return EINVAL; | 1162 | if (mbox == NULL || |
1139 | } | 1163 | (mud = (mailbox_unix_data_t)mbox->data) == NULL) |
1140 | mud->messages[msgno].is_read = 1;; | 1164 | return EINVAL; |
1165 | |||
1166 | if (mailbox_unix_is_valid (mbox, msgno)) | ||
1167 | return EINVAL; | ||
1168 | mum = &(mud->messages[msgno]); | ||
1169 | if (h) | ||
1170 | *h = mum->header_end - mum->header; | ||
1171 | if (b) | ||
1172 | *b = mum->body_end - mum->body; | ||
1173 | return 0; | ||
1174 | } | ||
1175 | |||
1176 | static int mailbox_unix_messages_count (mailbox_t mbox, size_t *count) | ||
1177 | { | ||
1178 | mailbox_unix_data_t mud; | ||
1179 | if (mbox == NULL || (mud = (mailbox_unix_data_t) mbox->data) == NULL) | ||
1180 | return EINVAL; | ||
1181 | |||
1182 | if (! mailbox_is_updated (mbox)) | ||
1183 | return mailbox_unix_scan (mbox, count); | ||
1184 | |||
1185 | if (count) | ||
1186 | *count = mud->messages_count; | ||
1187 | |||
1141 | return 0; | 1188 | return 0; |
1142 | } | 1189 | } |
1190 | |||
1191 | /* locking */ | ||
1143 | static int | 1192 | static int |
1144 | mailbox_unix_is_seen (mailbox_t mbox, size_t msgno) | 1193 | mailbox_unix_lock (mailbox_t mbox, int flag) |
1145 | { | 1194 | { |
1146 | mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data; | 1195 | if (mbox && mbox->locker != NULL) |
1147 | if (mud == 0 || ! mailbox_unix_is_valid (mbox, msgno)) | ||
1148 | { | 1196 | { |
1149 | return 0; | 1197 | locker_t locker = mbox->locker; |
1198 | locker_lock (locker, flag); | ||
1150 | } | 1199 | } |
1151 | return mud->messages[msgno].is_seen; | 1200 | return 0; |
1152 | } | 1201 | } |
1153 | 1202 | ||
1154 | static int | 1203 | static int |
1155 | mailbox_unix_set_seen (mailbox_t mbox, size_t msgno) | 1204 | mailbox_unix_unlock (mailbox_t mbox) |
1156 | { | 1205 | { |
1157 | mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data; | 1206 | if (mbox && mbox->locker != NULL) |
1158 | if (mud == 0 || ! mailbox_unix_is_valid (mbox, msgno)) | ||
1159 | { | 1207 | { |
1160 | return EINVAL; | 1208 | locker_t locker = mbox->locker; |
1209 | locker_unlock (locker); | ||
1161 | } | 1210 | } |
1162 | mud->messages[msgno].is_seen = 1; | ||
1163 | return 0; | 1211 | return 0; |
1164 | } | 1212 | } |
1165 | 1213 | ||
1166 | /* locking */ | ||
1167 | static int | 1214 | static int |
1168 | mailbox_unix_ilock (mailbox_t mbox, int flag) | 1215 | mailbox_unix_ilock (mailbox_t mbox, int flag) |
1169 | { | 1216 | { |
1170 | #ifdef HAVE_PTHREAD_H | 1217 | #ifdef HAVE_PTHREAD_H |
1171 | mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data; | 1218 | mailbox_unix_data_t mud; |
1172 | (void)flag; /* we should use rwlocks for more concurency */ | 1219 | (void)flag; /* we should use rwlocks for more concurency */ |
1173 | pthread_mutex_lock (&(mud->mutex)); | 1220 | if (mbox == NULL || |
1221 | (mud = (mailbox_unix_data_t)mbox->data) == NULL) | ||
1222 | return EINVAL; | ||
1223 | return pthread_mutex_lock (&(mud->mutex)); | ||
1174 | #else | 1224 | #else |
1175 | (void)mbox; (void)flag; | 1225 | (void)mbox; (void)flag; |
1176 | #endif | ||
1177 | return 0; | 1226 | return 0; |
1227 | #endif | ||
1178 | } | 1228 | } |
1179 | 1229 | ||
1180 | static int | 1230 | static int |
1181 | mailbox_unix_iunlock (mailbox_t mbox) | 1231 | mailbox_unix_iunlock (mailbox_t mbox) |
1182 | { | 1232 | { |
1183 | #ifdef HAVE_PTHREAD_H | 1233 | #ifdef HAVE_PTHREAD_H |
1184 | mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data; | 1234 | mailbox_unix_data_t mud; |
1185 | pthread_mutex_unlock (&(mud->mutex)); | 1235 | if (mbox == NULL || |
1236 | (mud = (mailbox_unix_data_t)mbox->data) == NULL) | ||
1237 | return EINVAL; | ||
1238 | return pthread_mutex_unlock (&(mud->mutex)); | ||
1186 | #else | 1239 | #else |
1187 | (void)mbox; | 1240 | (void)mbox; |
1188 | #endif | ||
1189 | return 0; | ||
1190 | } | ||
1191 | |||
1192 | static int | ||
1193 | mailbox_unix_lock (mailbox_t mbox, int flag) | ||
1194 | { | ||
1195 | #ifdef HAVE_MAILOCK_H | ||
1196 | #else | ||
1197 | (void)mbox; (void)flag; | ||
1198 | #endif | ||
1199 | return 0; | 1241 | return 0; |
1200 | } | ||
1201 | static int | ||
1202 | mailbox_unix_unlock (mailbox_t mbox) | ||
1203 | { | ||
1204 | #ifdef HAVE_MAILOCK_H | ||
1205 | #else | ||
1206 | (void)mbox; | ||
1207 | #endif | 1242 | #endif |
1208 | return 0; | ||
1209 | } | ||
1210 | |||
1211 | /* miscellany */ | ||
1212 | static int | ||
1213 | mailbox_unix_size (mailbox_t mbox, off_t *size) | ||
1214 | { | ||
1215 | mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data; | ||
1216 | struct stat st; | ||
1217 | int fd; | ||
1218 | |||
1219 | if (mud == NULL || mud->file == NULL) | ||
1220 | { | ||
1221 | /* maybe was not open yet ?? */ | ||
1222 | return EIO; | ||
1223 | } | ||
1224 | fd = fileno (mud->file); | ||
1225 | if (fstat (fd, &st) != 0) | ||
1226 | { | ||
1227 | /* oops !! */ | ||
1228 | /* errno set by fstat () */ | ||
1229 | return EIO; | ||
1230 | } | ||
1231 | *size = st.st_size; | ||
1232 | return 0; | ||
1233 | } | ||
1234 | |||
1235 | static int | ||
1236 | mailbox_unix_get_size (mailbox_t mbox, size_t msgno, size_t *h, size_t *b) | ||
1237 | { | ||
1238 | mailbox_unix_data_t mud = (mailbox_unix_data_t) mbox->data; | ||
1239 | mailbox_unix_msg_t mum; | ||
1240 | |||
1241 | if (mailbox_unix_is_valid (mbox, msgno)) | ||
1242 | { | ||
1243 | return EINVAL; | ||
1244 | } | ||
1245 | mum = &(mud->messages[msgno]); | ||
1246 | if (h) | ||
1247 | *h = mum->header - mum->body; | ||
1248 | if (b) | ||
1249 | *b = mum->body - mum->header; | ||
1250 | return 0; | ||
1251 | } | 1243 | } | ... | ... |
-
Please register or sign in to post a comment