Commit bd507cf1 bd507cf116ad3a56e979f406fabe3d0cef5e05a8 by Alain Magloire

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.
1 parent 3f2a7da5
...@@ -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 }
......