Commit d4627cb0 d4627cb03d501d30fba4fb85ec2b4cbd64372e53 by Sergey Poznyakoff

To avoid confusion, pruned libmailbox directory

1 parent f167317c
1 # Use automake to process this file -*-Makefile-*-
2
3 AUTOMAKE_OPTIONS = ../lib/ansi2knr
4
5 CFLAGS = -Wall -pedantic -g -DTESTING
6
7 include_HEADERS = mailbox.h
8 lib_LTLIBRARIES = libmailbox.la
9
10 libmailbox_la_SOURCES = mailbox.c unixmbox.c unixmbox.h
11 libmailbox_la_LDFLAGS = -version-info 0:0:0
12
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21
22 #include "mailbox.h"
23 #include "unixmbox.h"
24
25 #ifdef _HAVE_ERRNO_H
26 #include <errno.h>
27 #endif
28
29 #include <ctype.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32
33 int _mbox_dummy1 (mailbox * mbox);
34 int _mbox_dummy2 (mailbox * mbox, unsigned int num);
35 int _mbox_dummy3 (mailbox * mbox, char *c);
36 char *_mbox_dummy4 (mailbox * mbox, unsigned int num);
37
38 mailbox *
39 mbox_open (const char *name)
40 {
41 mailbox *mbox;
42 struct stat st;
43
44 if ( name == NULL )
45 {
46 errno = EINVAL;
47 return NULL;
48 }
49
50 mbox = malloc (sizeof (mailbox));
51 if (mbox == NULL)
52 {
53 errno = ENOMEM;
54 return NULL;
55 }
56
57 /* Set up with default data and dummy functions */
58 mbox->name = strdup (name);
59 if (mbox->name == NULL)
60 {
61 errno = ENOMEM;
62 free (mbox);
63 return NULL;
64 }
65 /* check if we can look at file, prep for checks later in function */
66 if (stat (mbox->name, &st) == -1)
67 {
68 free (mbox->name);
69 free (mbox);
70 return NULL; /* errno set by stat() */
71 }
72
73 mbox->messages = 0;
74 mbox->num_deleted = 0;
75 mbox->sizes = NULL;
76 mbox->_data = NULL;
77 mbox->_close = _mbox_dummy1;
78 mbox->_delete = _mbox_dummy2;
79 mbox->_undelete = _mbox_dummy2;
80 mbox->_expunge = _mbox_dummy1;
81 mbox->_scan = _mbox_dummy1;
82 mbox->_add_message = _mbox_dummy3;
83 mbox->_is_deleted = _mbox_dummy2;
84 mbox->_is_updated = _mbox_dummy1;
85 mbox->_lock = _mbox_dummy2;
86 mbox->_get_body = _mbox_dummy4;
87 mbox->_get_header = _mbox_dummy4;
88 #ifdef TESTING
89 mbox->_tester = _mbox_dummy2;
90 #endif
91
92 if (S_ISREG (st.st_mode))
93 {
94 if (unixmbox_open (mbox) == 0)
95 return mbox;
96 else
97 {
98 /*
99 * Check errno to find out why it failed, if it's simply not a
100 * unix mbox format message, then try other mailbox types,
101 * otherwise, leave errno set and return NULL
102 */
103 if (errno == EBADMSG)
104 errno = ENOSYS; /* no other mailboxes supported right now */
105 }
106 }
107 else if (S_ISDIR (st.st_mode))
108 {
109 /* for example...
110 if (maildir_open (mbox, name) == 1)
111 return mbox;
112 */
113 errno = ENOSYS;
114 }
115 else
116 errno = EINVAL; /* neither directory nor file, so bomb */
117
118 free (mbox->name);
119 free (mbox);
120 return NULL;
121 }
122
123 /*
124 * Gets the contents of a header field
125 */
126 char *
127 mbox_header_line (mailbox *mbox, unsigned int num, const char *header)
128 {
129 char *full, *tmp, *line;
130 int try = 1;
131 size_t i = 0, j = 0;
132 size_t len, lh;
133
134 if ( mbox == NULL || header == NULL )
135 {
136 errno = EINVAL;
137 return NULL;
138 }
139
140 full = mbox_get_header (mbox, num);
141 if (full == NULL)
142 return NULL;
143
144 lh = strlen (header);
145 len = strlen (full);
146 tmp = NULL;
147
148 /* First get the appropriate line at the beginning */
149 for (i=0; i < len-(lh+2); i++)
150 {
151 if (try == 1)
152 {
153 if (!strncasecmp(&full[i], header, lh) && full[i+lh] == ':')
154 {
155 tmp = strdup (&full[i+lh+2]);
156 if (tmp == NULL)
157 {
158 free(full);
159 return NULL;
160 }
161 break;
162 }
163 else
164 try = 0;
165 }
166 else if (full[i] == '\n')
167 try = 1;
168 else
169 try = 0;
170 }
171
172 /* FIXME: hmm, no valid header found, what should errno be? */
173 if (tmp == NULL)
174 {
175 free(full);
176 return NULL;
177 }
178 /* Now trim the fat */
179 len = strlen (tmp);
180 for (i = 0; i < len; i++)
181 {
182 if (tmp[i] == '\n' && i < (len - 1) && isspace (tmp[i+1]))
183 {
184 if (tmp[i+1] == '\t')
185 tmp[i + 1] = ' ';
186 for (j = i; j < len; j++)
187 tmp[j] = tmp[j+1];
188 }
189 else if (tmp[i] == '\n')
190 {
191 tmp[i] = '\0';
192 break;
193 }
194 }
195 line = strdup (tmp);
196 free (tmp);
197 free (full);
198 return line;
199 }
200
201 /*
202 * Gets first LINES lines from message body
203 */
204 char *
205 mbox_body_lines (mailbox *mbox, unsigned int num, unsigned int lines)
206 {
207 char *full, *buf = NULL;
208 int i=0, line = 0, len;
209 if (mbox == NULL)
210 {
211 errno = EINVAL;
212 return NULL;
213 }
214 if (lines == 0)
215 return strdup ("");
216 full = mbox_get_body (mbox, num);
217 if (full == NULL)
218 return NULL;
219 len = strlen (full);
220 for (i=0; i < len && line < lines; i++)
221 {
222 if (full[i] == '\n')
223 {
224 line++;
225 if (line >= lines)
226 {
227 full[i+1] = '\0';
228 buf = strdup (full);
229 break;
230 }
231 }
232 }
233 if (buf == NULL)
234 buf = strdup (full);
235 free (full);
236 return buf;
237 }
238
239 /*
240 * Bogus functions for unimplemented functions that return int
241 */
242 int
243 _mbox_dummy1 (mailbox * mbox)
244 {
245 errno = ENOSYS;
246 return -1;
247 }
248
249 int
250 _mbox_dummy2 (mailbox * mbox, unsigned int num)
251 {
252 return _mbox_dummy1 (mbox);
253 }
254 int
255 _mbox_dummy3 (mailbox * mbox, char *c)
256 {
257 return _mbox_dummy1 (mbox);
258 }
259
260 /*
261 * Bogus function for unimplemented functions that return char *
262 */
263 char *
264 _mbox_dummy4 (mailbox * mbox, unsigned int num)
265 {
266 errno = ENOSYS;
267 return NULL;
268 }
269
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #ifndef _MAILBOX_H
19 #define _MAILBOX_H 1
20
21 #ifndef __P
22 #if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
23 #define __P(args) args
24 #else
25 #define __P(args) ()
26 #endif
27 #endif /*!__P */
28
29 /* These need to be documented */
30 #define mbox_close(m) m->_close(m)
31 #define mbox_delete(m,n) m->_delete(m,n)
32 #define mbox_undelete(m,n) m->_undelete(m,n)
33 #define mbox_expunge(m) m->_expunge(m)
34 #define mbox_scan(m) m->_scan(m)
35 #define mbox_is_deleted(m,n) m->_is_deleted(m,n)
36 #define mbox_is_updated(m) m->_is_updated(m)
37 #define mbox_add_message(m,s) m->_add_message(m,s)
38 #define mbox_get_body(m,n) m->_get_body(m,n)
39 #define mbox_get_header(m,n) m->_get_header(m,n)
40 #define mbox_lock(m,n) m->_lock(m,n)
41 #ifdef TESTING
42 #define mbox_tester(m,n) m->_tester(m,n)
43 #endif
44
45 #include <stdlib.h>
46
47 /* Lock settings */
48 /* define this way so that it is opaque and can later become a struct w/o
49 * people noticing (-:
50 */
51 enum _mailbox_lock_t {MO_ULOCK, MO_RLOCK, MO_WLOCK}; /* new type */
52 typedef enum _mailbox_lock_t mailbox_lock_t;
53
54 typedef struct _mailbox
55 {
56 /* Data */
57 char *name;
58 unsigned int messages;
59 unsigned int num_deleted;
60 size_t *sizes;
61 void *_data;
62
63 /* Functions */
64 int (*_close) __P ((struct _mailbox *));
65 int (*_delete) __P ((struct _mailbox *, unsigned int));
66 int (*_undelete) __P ((struct _mailbox *, unsigned int));
67 int (*_expunge) __P ((struct _mailbox *));
68 int (*_add_message) __P ((struct _mailbox *, char *));
69 int (*_scan) __P ((struct _mailbox *));
70 int (*_is_deleted) __P ((struct _mailbox *, unsigned int));
71 int (*_is_updated) __P ((struct _mailbox *));
72 int (*_lock) __P((struct _mailbox *, mailbox_lock_t));
73 char *(*_get_body) __P ((struct _mailbox *, unsigned int));
74 char *(*_get_header) __P ((struct _mailbox *, unsigned int));
75 #ifdef TESTING
76 void (*_tester) __P ((struct _mailbox *, unsigned int));
77 #endif
78 }
79 mailbox;
80
81 mailbox *mbox_open __P ((const char *name));
82
83 char *mbox_header_line __P ((mailbox *mbox, unsigned int num, const char *header));
84 char *mbox_body_lines __P ((mailbox *mbox, unsigned int num, unsigned int lines));
85
86 #endif
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21
22 #include "maildir.h"
23
24 /*
25 * Opens a mailbox
26 */
27 int
28 maildir_open (mailbox * mbox)
29 {
30 int i;
31 int alloced = 0;
32 maildir_data *data;
33 struct dirent *entry;
34 char old_dir[PATH_MAX];
35 struct utsname *utsinfo;
36 uname (utsinfo);
37
38 getcwd (old_dir, PATH_MAX);
39 chdir (mbox->name);
40
41 data->new = opendir ("new");
42 data->tmp = opendir ("tmp");
43 data->cur = opendir ("cur");
44 data->time = time (NULL);
45 data->pid = getpid ();
46 data->sequence = 0;
47 /* data->host = strdup (utsinfo->sysname); */
48 data->messages = malloc (10 * sizeof (maildir_message));
49 alloced = 10;
50
51 /* process the new directory */
52 while (entry = readdir (data->new))
53 {
54 /* no dot files */
55 if (entry->d_name[0] != '.')
56 {
57 if (mbox->messages >= alloced)
58 {
59 alloced *= 2;
60 data->messages = realloc (data->messages,
61 alloced * sizeof (maildir_message));
62 /* check */
63 }
64 data->messages[mbox->messages].deleted = 0;
65 data->messages[mbox->messages].info = NULL;
66 data->messages[mbox->messages].location = new;
67 data->messages[mbox->messages].file = strdup (entry->d_name);
68 /* check */
69 mbox->messages++;
70 }
71 }
72
73 /* then the cur directory */
74 while (entry = readdir (data->cur))
75 {
76 if (entry->d_name[0] != '.')
77 {
78 if (mbox->messages >= alloced)
79 {
80 alloced *= 2;
81 data->messages = realloc (data->messages,
82 alloced * sizeof (maildir_message));
83 /* check */
84 }
85 data->messages[mbox->messages].deleted = 0;
86 data->messages[mbox->messages].location = cur;
87 data->messages[mbox->messages].file = strdup (entry->d_name);
88 /* check */
89 /* data->messages[i].info = parse_for_info (entry->d_name); */
90 mbox->messages++;
91 }
92 }
93
94 for (i=0; i < mbox->messages; i++)
95 {
96 FILE *f;
97 char buf[80];
98 chdir (mbox->name);
99 if (data->messages[i].location == new)
100 chdir ("new");
101 else if (data->messages[i].location == cur)
102 chdir ("cur");
103 f = fopen (data->messages[i].file, "r");
104 data->messages[i].body = 0;
105 while (fgets (buf, 80, f))
106 if (!strncmp (buf, "\r\n", 2) || strlen (buf) <= 1)
107 fgetpos (f, &(data->messages[i].body));
108 fclose (f);
109 }
110
111 mbox->_data = data;
112 mbox->_close = maildir_close;
113 mbox->_delete = maildir_delete;
114 mbox->_undelete = maildir_undelete;
115 mbox->_expunge = maildir_expunge;
116 mbox->_add_message = maildir_add_message;
117 mbox->_is_deleted = maildir_is_deleted;
118 mbox->_lock = maildir_lock;
119 mbox->_get_body = maildir_get_body;
120 mbox->_get_header = maildir_get_header;
121
122 chdir (old_dir);
123 return 0;
124 }
125
126 /*
127 * Closes and unlocks a mailbox, does not expunge
128 */
129 int
130 maildir_close (mailbox * mbox)
131 {
132 /* FIXME: hack from unixmbox */
133 return 0;
134 }
135
136 /*
137 * Marks a message for deletion
138 */
139 int
140 maildir_delete (mailbox * mbox, unsigned int num)
141 {
142 maildir_data *data;
143
144 if (mbox == NULL)
145 {
146 errno = EINVAL;
147 return -1;
148 }
149
150 if (num > mbox->messages || mbox_is_deleted (mbox, num))
151 {
152 errno = ERANGE;
153 return -1;
154 }
155
156 data = mbox->_data;
157 data->messages[num].deleted = 1;
158 mbox->num_deleted++;
159
160 return 0;
161 }
162
163 /*
164 * Unmark a message for deletion
165 */
166 int
167 maildir_undelete (mailbox * mbox, unsigned int num)
168 {
169 maildir_data *data;
170
171 if (mbox == NULL)
172 {
173 errno = EINVAL;
174 return -1;
175 }
176
177 if (num > mbox->messages || !mbox_is_deleted (mbox, num))
178 {
179 errno = ERANGE;
180 return -1;
181 }
182
183 data = mbox->_data;
184 data->messages[num].deleted = 0;
185 mbox->num_deleted--;
186
187 return 0;
188 }
189
190 /*
191 * Updates a mailbox to remove message marked for deletion
192 */
193 int
194 maildir_expunge (mailbox * mbox)
195 {
196 maildir_data *data;
197 int i = 0;
198 char old_dir[PATH_MAX];
199
200 if (mbox == NULL)
201 {
202 errno = EINVAL;
203 return -1;
204 }
205
206 getcwd (old_dir, PATH_MAX);
207 chdir (mbox->name);
208
209 if (mbox->num_deleted)
210 {
211 data = mbox->_data;
212
213 for (i = 0; i < mbox->messages; i++)
214 {
215 if (data->messages[i].deleted == 0)
216 {
217 unlink (data->messages[i].file);
218 mbox->num_deleted--;
219 }
220 }
221 }
222 /* reorder messages? */
223
224 chdir (old_dir);
225 return 0;
226 }
227
228 /*
229 * Determines whether or a not a message is marked for deletion
230 */
231 int
232 maildir_is_deleted (mailbox * mbox, unsigned int num)
233 {
234 maildir_data *data;
235
236 if (mbox == NULL)
237 {
238 errno = EINVAL;
239 return -1;
240 }
241 if (mbox->num_deleted == 0)
242 return 0;
243 data = mbox->_data;
244 return (data->messages[num].deleted == 1);
245 }
246
247 int
248 maildir_is_updated (mailbox *mbox)
249 {
250 struct stat st;
251 maildir_data *data;
252
253 if (mbox == NULL)
254 {
255 errno = EINVAL;
256 return -1;
257 }
258 if (stat (mbox->name, &st) == -1)
259 return -1;
260 data = mbox->_data;
261 return (st.st_mtime > data->last_mod_time);
262 }
263
264 /*
265 * Adds a message to the mailbox
266 */
267 int
268 maildir_add_message (mailbox * mbox, char *message)
269 {
270 /*
271 * FIXME: please write me
272 * http://www.qmail.org/man/man5/maildir.html
273 */
274 errno = ENOSYS;
275 return -1;
276 }
277
278 /*
279 * Returns a message body
280 */
281 char *
282 maildir_get_body (mailbox * mbox, unsigned int num)
283 {
284 maildir_data *data;
285 char *buf;
286 char old_dir[PATH_MAX];
287 FILE *f;
288 struct stat st;
289 size_t size;
290
291 if (mbox == NULL)
292 {
293 errno = EINVAL;
294 return NULL;
295 }
296 if (num > mbox->messages || num < 0)
297 {
298 errno = ERANGE;
299 return NULL;
300 }
301
302 data = mbox->_data;
303 getcwd (old_dir, PATH_MAX);
304 chdir (mbox->name);
305
306 if (data->messages[num].location == cur)
307 chdir ("cur");
308 else if (data->messages[num].location == tmp)
309 chdir ("tmp");
310 else if (data->messages[num].location == new)
311 chdir ("new");
312
313 f = fopen (data->messages[num].file, "r");
314 if (f == NULL)
315 {
316 chdir (old_dir);
317 perror (NULL);
318 return NULL;
319 }
320
321 stat (data->messages[num].file, &st);
322 size = st.st_size - data->messages[num].body + 1;
323
324 buf = malloc (sizeof (char) * size);
325 if (buf == NULL)
326 {
327 fclose (f);
328 chdir (old_dir);
329 errno = ENOMEM;
330 return NULL;
331 }
332
333 memset (buf, 0, size);
334 if (fsetpos (f, &(data->messages[num].body)) == -1)
335 {
336 fclose (f);
337 chdir (old_dir);
338 free (buf);
339 return NULL;
340 }
341
342 if (fread (buf, sizeof (char), size-1, f) < size)
343 {
344 fclose (f);
345 chdir (old_dir);
346 free (buf);
347 return NULL;
348 }
349
350 fclose (f);
351 chdir (old_dir);
352 return buf;
353 }
354
355 /*
356 * Returns just the header of a message
357 */
358 char *
359 maildir_get_header (mailbox * mbox, unsigned int num)
360 {
361 maildir_data *data;
362 char *buf;
363
364 if ( mbox == NULL )
365 {
366 errno = EINVAL;
367 return NULL;
368 }
369
370 if (num > mbox->messages)
371 {
372 errno = ERANGE;
373 return NULL;
374 }
375
376 data = mbox->_data;
377 buf = NULL; /* FIXME: read the file until data->message[num].body */
378 return buf;
379 }
380
381 /*
382 * Sets lock mode for a mailbox
383 * FIXME: What to do for Maildir? no locking?
384 */
385 int
386 maildir_lock (mailbox *mbox, mailbox_lock_t mode)
387 {
388 return 0;
389 }
390
391 /* FIXME: not implemented */
392 int
393 maildir_scan (mailbox *mbox)
394 {
395 errno = ENOSYS;
396 return -1;
397 }
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #ifndef _MAILDIR_H
19 #define _MAILDIR_H 1
20 #include <mailbox.h>
21 #include "config.h"
22
23 #ifdef HAVE_STDIO_H
24 #include <stdio.h>
25 #endif
26
27 #ifdef HAVE_STDLIB_H
28 #include <stdlib.h>
29 #endif
30
31 /* FIXME need auto* wrapper */
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <dirent.h>
35 #include <sys/utsname.h>
36 #include <time.h>
37
38 #include <fcntl.h>
39
40 #ifdef HAVE_UNISTD_H
41 #include <unistd.h>
42 #endif
43
44 #ifdef HAVE_ERRNO_H
45 #include <errno.h>
46 #endif
47
48 #ifdef HAVE_STRING_H
49 #include <string.h>
50 #elif HAVE_STRINGS_H
51 #include <strings.h>
52 #endif
53
54 typedef struct _maildir_message
55 {
56 off_t body;
57 char deleted;
58 enum { new, tmp, cur } location;
59 char *file;
60 char *info;
61 }
62 maildir_message;
63
64 typedef struct _maildir_data
65 {
66 maildir_message *messages;
67 DIR *new;
68 DIR *cur;
69 DIR *tmp;
70 time_t time;
71 pid_t pid;
72 unsigned int sequence;
73 char *host;
74 time_t last_mod_time;
75 }
76 maildir_data;
77
78 int maildir_open (mailbox *mbox);
79 int maildir_close (mailbox *mbox);
80 int maildir_delete (mailbox *mbox, unsigned int num);
81 int maildir_undelete (mailbox *mbox, unsigned int num);
82 int maildir_expunge (mailbox *mbox);
83 int maildir_scan (mailbox *mbox);
84 int maildir_is_deleted (mailbox *mbox, unsigned int num);
85 int maildir_is_updated (mailbox *mbox);
86 int maildir_lock (mailbox *mbox, mailbox_lock_t mode);
87 int maildir_add_message (mailbox *mbox, char *message);
88 char *maildir_get_body (mailbox *mbox, unsigned int num);
89 char *maildir_get_header (mailbox *mbox, unsigned int num);
90
91 #endif
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21
22 #include "mh.h"
23
24 /*
25 * Opens a mailbox
26 */
27 int
28 mh_open (mailbox * mbox)
29 {
30 unsigned long seq_num = 0;
31 struct dirent *entry;
32 mh_data *data;
33
34 if(mbox == NULL)
35 return EINVAL;
36
37 data = malloc (sizeof (mh_data));
38 data->dir = opendir (mbox->name);
39 if(data->dir == NULL)
40 return errno; /* set by opendir() */
41
42 /* process directory */
43 while ((entry = readdir (data->dir)))
44 {
45 char *foo = NULL;
46 char fname[PATH_MAX];
47 char line[80];
48 FILE *fp;
49 mh_message message;
50
51 if (entry->d_name[0] == '.')
52 {
53 if (strcmp(entry->d_name, ".mh_sequences") == 0)
54 /* TODO: deal with mh sequence files */;
55 continue;
56 }
57
58 if (entry->d_name[0] == ',')
59 {
60 message.deleted = 1;
61 seq_num = strtoul ((entry->d_name) + 1, &foo, 10);
62 }
63 else
64 {
65 /* TODO: handle ERANGE */
66 seq_num = strtoul (entry->d_name, &foo, 10);
67 }
68 if (*foo != '\0') /* invalid sequence number */
69 {
70 printf("skipping invalid message: %s\n", entry->d_name);
71 continue; /* TODO: handle this better? */
72 }
73
74 sprintf(fname, "%s/%ld", mbox->name, seq_num);
75 if ((fp = fopen(fname, "r")) == NULL)
76 continue; /* TODO: handle the error */
77 /* TODO: handle corrupt files */
78 while (fgets (line, 80, fp))
79 {
80 if ((line[0] == '\r' && line[1] == '\n') || line[0] == '\n')
81 {
82 fgetpos(fp, &message.body);
83 break;
84 }
85 }
86 fclose (fp);
87 mbox->messages++;
88 }
89
90 /* store next sequence number to use */
91 data->sequence = seq_num + 1;
92
93 mbox->_data = data;
94 #if 0
95 mbox->_close = mh_close;
96 mbox->_delete = mh_delete;
97 mbox->_undelete = mh_undelete;
98 mbox->_expunge = mh_expunge;
99 mbox->_add_message = mh_add_message;
100 mbox->_is_deleted = mh_is_deleted;
101 mbox->_lock = mh_lock;
102 mbox->_get_body = mh_get_body;
103 mbox->_get_header = mh_get_header;
104 #endif
105
106 return 0;
107 }
108
109 #if 0
110 /*
111 * Closes and unlocks a mailbox, does not expunge
112 */
113 int
114 mh_close (mailbox * mbox)
115 {
116 /* FIXME: hack from unixmbox */
117 return 0;
118 }
119
120 /*
121 * Marks a message for deletion
122 */
123 int
124 mh_delete (mailbox * mbox, unsigned int num)
125 {
126 mh_data *data;
127
128 if (mbox == NULL)
129 {
130 errno = EINVAL;
131 return -1;
132 }
133
134 if (num > mbox->messages || mbox_is_deleted (mbox, num))
135 {
136 errno = ERANGE;
137 return -1;
138 }
139
140 data = mbox->_data;
141 data->messages[num].deleted = 1;
142 mbox->num_deleted++;
143
144 return 0;
145 }
146
147 /*
148 * Unmark a message for deletion
149 */
150 int
151 mh_undelete (mailbox * mbox, unsigned int num)
152 {
153 mh_data *data;
154
155 if (mbox == NULL)
156 {
157 errno = EINVAL;
158 return -1;
159 }
160
161 if (num > mbox->messages || !mbox_is_deleted (mbox, num))
162 {
163 errno = ERANGE;
164 return -1;
165 }
166
167 data = mbox->_data;
168 data->messages[num].deleted = 0;
169 mbox->num_deleted--;
170
171 return 0;
172 }
173
174 /*
175 * Updates a mailbox to remove message marked for deletion
176 */
177 int
178 mh_expunge (mailbox * mbox)
179 {
180 mh_data *data;
181 int i = 0;
182 char old_dir[PATH_MAX];
183
184 if (mbox == NULL)
185 {
186 errno = EINVAL;
187 return -1;
188 }
189
190 getcwd (old_dir, PATH_MAX);
191 chdir (mbox->name);
192
193 if (mbox->num_deleted)
194 {
195 data = mbox->_data;
196
197 for (i = 0; i < mbox->messages; i++)
198 {
199 if (data->messages[i].deleted == 0)
200 {
201 unlink (data->messages[i].file);
202 mbox->num_deleted--;
203 }
204 }
205 }
206 /* reorder messages? */
207
208 chdir (old_dir);
209 return 0;
210 }
211
212 /*
213 * Determines whether or a not a message is marked for deletion
214 */
215 int
216 mh_is_deleted (mailbox * mbox, unsigned int num)
217 {
218 mh_data *data;
219
220 if (mbox == NULL)
221 {
222 errno = EINVAL;
223 return -1;
224 }
225 if (mbox->num_deleted == 0)
226 return 0;
227 data = mbox->_data;
228 return (data->messages[num].deleted == 1);
229 }
230
231 int
232 mh_is_updated (mailbox *mbox)
233 {
234 struct stat st;
235 mh_data *data;
236
237 if (mbox == NULL)
238 {
239 errno = EINVAL;
240 return -1;
241 }
242 if (stat (mbox->name, &st) == -1)
243 return -1;
244 data = mbox->_data;
245 return (st.st_mtime > data->last_mod_time);
246 }
247
248 /*
249 * Adds a message to the mailbox
250 */
251 int
252 mh_add_message (mailbox * mbox, char *message)
253 {
254 /*
255 * FIXME: please write me
256 * http://www.qmail.org/man/man5/mh.html
257 */
258 errno = ENOSYS;
259 return -1;
260 }
261
262 /*
263 * Returns a message body
264 */
265 char *
266 mh_get_body (mailbox * mbox, unsigned int num)
267 {
268 mh_data *data;
269 char *buf;
270 char old_dir[PATH_MAX];
271 FILE *f;
272 struct stat st;
273 size_t size;
274
275 if (mbox == NULL)
276 {
277 errno = EINVAL;
278 return NULL;
279 }
280 if (num > mbox->messages || num < 0)
281 {
282 errno = ERANGE;
283 return NULL;
284 }
285
286 data = mbox->_data;
287 getcwd (old_dir, PATH_MAX);
288 chdir (mbox->name);
289
290 if (data->messages[num].location == cur)
291 chdir ("cur");
292 else if (data->messages[num].location == tmp)
293 chdir ("tmp");
294 else if (data->messages[num].location == new)
295 chdir ("new");
296
297 f = fopen (data->messages[num].file, "r");
298 if (f == NULL)
299 {
300 chdir (old_dir);
301 perror (NULL);
302 return NULL;
303 }
304
305 stat (data->messages[num].file, &st);
306 size = st.st_size - data->messages[num].body + 1;
307
308 buf = malloc (sizeof (char) * size);
309 if (buf == NULL)
310 {
311 fclose (f);
312 chdir (old_dir);
313 errno = ENOMEM;
314 return NULL;
315 }
316
317 memset (buf, 0, size);
318 if (fsetpos (f, &(data->messages[num].body)) == -1)
319 {
320 fclose (f);
321 chdir (old_dir);
322 free (buf);
323 return NULL;
324 }
325
326 if (fread (buf, sizeof (char), size-1, f) < size)
327 {
328 fclose (f);
329 chdir (old_dir);
330 free (buf);
331 return NULL;
332 }
333
334 fclose (f);
335 chdir (old_dir);
336 return buf;
337 }
338
339 /*
340 * Returns just the header of a message
341 */
342 char *
343 mh_get_header (mailbox * mbox, unsigned int num)
344 {
345 mh_data *data;
346 char *buf;
347
348 if ( mbox == NULL )
349 {
350 errno = EINVAL;
351 return NULL;
352 }
353
354 if (num > mbox->messages)
355 {
356 errno = ERANGE;
357 return NULL;
358 }
359
360 data = mbox->_data;
361 buf = NULL; /* FIXME: read the file until data->message[num].body */
362 return buf;
363 }
364
365 /*
366 * Sets lock mode for a mailbox
367 * FIXME: What to do for Mh? no locking?
368 */
369 int
370 mh_lock (mailbox *mbox, mailbox_lock_t mode)
371 {
372 return 0;
373 }
374
375 /* FIXME: not implemented */
376 int
377 mh_scan (mailbox *mbox)
378 {
379 errno = ENOSYS;
380 return -1;
381 }
382 #endif
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #ifndef _MH_H
19 #define _MH_H 1
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <mailbox.h>
26
27 #ifdef HAVE_STDIO_H
28 #include <stdio.h>
29 #endif
30
31 #ifdef HAVE_STDLIB_H
32 #include <stdlib.h>
33 #endif
34
35 /* FIXME need auto* wrapper */
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <dirent.h>
39 #include <sys/utsname.h>
40 #include <time.h>
41
42 #include <fcntl.h>
43
44 #ifdef HAVE_UNISTD_H
45 #include <unistd.h>
46 #endif
47
48 #ifdef HAVE_ERRNO_H
49 #include <errno.h>
50 #endif
51
52 #ifdef HAVE_STRING_H
53 #include <string.h>
54 #elif HAVE_STRINGS_H
55 #include <strings.h>
56 #endif
57
58 typedef struct _mh_message
59 {
60 off_t body;
61 char deleted;
62 }
63 mh_message;
64
65 typedef struct _mh_data
66 {
67 mh_message *messages;
68 DIR *dir;
69 unsigned int sequence;
70 }
71 mh_data;
72
73 int mh_open (mailbox *mbox);
74 int mh_close (mailbox *mbox);
75 int mh_delete (mailbox *mbox, unsigned int num);
76 int mh_undelete (mailbox *mbox, unsigned int num);
77 int mh_expunge (mailbox *mbox);
78 int mh_scan (mailbox *mbox);
79 int mh_is_deleted (mailbox *mbox, unsigned int num);
80 int mh_is_updated (mailbox *mbox);
81 int mh_lock (mailbox *mbox, mailbox_lock_t mode);
82 int mh_add_message (mailbox *mbox, char *message);
83 char *mh_get_body (mailbox *mbox, unsigned int num);
84 char *mh_get_header (mailbox *mbox, unsigned int num);
85
86 #endif
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21
22 #include "unixmbox.h"
23
24 /*
25 * Opens a mailbox
26 */
27 int
28 unixmbox_open (mailbox * mbox)
29 {
30 char buf[80];
31 unsigned int max_count = 10;
32 int mess = 0;
33 unixmbox_data *data;
34 struct stat st;
35
36 if (mbox == NULL)
37 {
38 errno = EINVAL;
39 return -1;
40 }
41
42 data = malloc (sizeof (unixmbox_data));
43 if (data == NULL)
44 {
45 errno = ENOMEM;
46 free (data);
47 return -1;
48 }
49
50 mbox->_data = data;
51 data->file = fopen (mbox->name, "r+");
52 if (data->file == NULL)
53 {
54 /* errno is set by fopen() */
55 free (data);
56 return -1;
57 }
58
59 data->messages = malloc (sizeof (unixmbox_message) * max_count);
60 mbox->sizes = malloc (sizeof (int) * max_count);
61 if (data->messages == NULL || mbox->sizes == NULL)
62 {
63 unixmbox_close (mbox);
64 errno = ENOMEM;
65 return -1;
66 }
67 if (stat (mbox->name, &st) == -1)
68 {
69 unixmbox_close (mbox);
70 return -1;
71 }
72 data->last_mod_time = st.st_mtime;
73
74 if (fgets (buf, 80, data->file) == NULL)
75 {
76 if (feof(data->file))
77 goto END; /* empty file, no messages */
78 unixmbox_close (mbox);
79 return -1;
80 }
81 if (strncmp (buf, "From ", 5))
82 {
83 /* This is NOT an mbox file */
84 unixmbox_close (mbox);
85 errno = EBADMSG; /* use this to signify wrong mbox type */
86 return -1;
87 }
88
89 do
90 {
91 if (!strncmp (buf, "From ", 5))
92 {
93 /* Beginning of a header */
94 while (strchr (buf, '\n') == NULL)
95 if (fgets (buf, 80, data->file) == NULL) /* eat the From line */
96 {
97 if (feof (data->file))
98 errno = EIO; /* corrupted mailbox? */
99 unixmbox_close (mbox);
100 return -1;
101 }
102
103 mbox->messages++;
104
105 if (mbox->messages > max_count)
106 {
107 max_count = mbox->messages * 2;
108 data->messages = realloc (data->messages,
109 max_count * sizeof (unixmbox_message));
110 mbox->sizes = realloc (mbox->sizes, max_count * sizeof (int));
111 if (data->messages == NULL || mbox->sizes == NULL)
112 {
113 unixmbox_close (mbox);
114 errno = ENOMEM;
115 return -1;
116 }
117 }
118
119 fgetpos (data->file, &(data->messages[mbox->messages - 1].header));
120 mbox->sizes[mbox->messages - 1] = 0;
121 data->messages[mbox->messages - 1].deleted = 0;
122 mess = 0;
123 }
124 else if (((!strncmp (buf, "\r\n", 2) || strlen (buf) <= 1)) && mess == 0)
125 {
126 /* Beginning of a body */
127 fgetpos (data->file, &(data->messages[mbox->messages - 1].body));
128 mbox->sizes[mbox->messages - 1] += strlen (buf) + 1;
129 mess = 1;
130 }
131 else
132 {
133 mbox->sizes[mbox->messages - 1] += strlen (buf) + 1;
134 fgetpos (data->file, &(data->messages[mbox->messages - 1].end));
135 }
136 }
137 while (fgets (buf, 80, data->file));
138
139 if (!feof (data->file)) /* stopped due to error, not EOF */
140 {
141 unixmbox_close (mbox);
142 return -1; /* errno is set */
143 }
144
145 END:
146 mbox->_close = unixmbox_close;
147 mbox->_delete = unixmbox_delete;
148 mbox->_undelete = unixmbox_undelete;
149 mbox->_expunge = unixmbox_expunge;
150 mbox->_add_message = unixmbox_add_message;
151 mbox->_is_deleted = unixmbox_is_deleted;
152 mbox->_lock = unixmbox_lock;
153 mbox->_get_body = unixmbox_get_body;
154 mbox->_get_header = unixmbox_get_header;
155 #ifdef TESTING
156 mbox->_tester = unixmbox_tester;
157 #endif
158
159 return 0;
160 }
161
162 /*
163 * Closes and unlocks a mailbox, does not expunge
164 */
165 int
166 unixmbox_close (mailbox * mbox)
167 {
168 unixmbox_data *data;
169
170 if (mbox == NULL)
171 {
172 errno = EINVAL;
173 return -1;
174 }
175 data = mbox->_data;
176 unixmbox_lock (mbox, MO_ULOCK);
177 if (data->file)
178 fclose (data->file);
179 free (data->messages);
180 free (mbox->sizes);
181 free (data);
182 return 0;
183 }
184
185 /*
186 * Marks a message for deletion
187 */
188 int
189 unixmbox_delete (mailbox * mbox, unsigned int num)
190 {
191 unixmbox_data *data;
192
193 if (mbox == NULL)
194 {
195 errno = EINVAL;
196 return -1;
197 }
198
199 if (num > mbox->messages || mbox_is_deleted (mbox, num))
200 {
201 errno = ERANGE;
202 return -1;
203 }
204
205 data = mbox->_data;
206 data->messages[num].deleted = 1;
207 mbox->num_deleted++;
208
209 return 0;
210 }
211
212 /*
213 * Unmark a message for deletion
214 */
215 int
216 unixmbox_undelete (mailbox * mbox, unsigned int num)
217 {
218 unixmbox_data *data;
219
220 if (mbox == NULL)
221 {
222 errno = EINVAL;
223 return -1;
224 }
225
226 if (num > mbox->messages || !mbox_is_deleted (mbox, num))
227 {
228 errno = ERANGE;
229 return -1;
230 }
231
232 data = mbox->_data;
233 data->messages[num].deleted = 0;
234 mbox->num_deleted--;
235
236 return 0;
237 }
238
239 /*
240 * Updates a mailbox to remove message marked for deletion
241 * FIXME: BROKEN! DOES NOT WORK! BLOWS UP REAL GOOD!
242 */
243 int
244 unixmbox_expunge (mailbox * mbox)
245 {
246 unixmbox_data *data;
247 int i = 0;
248 size_t size = 0, size_read = 0;
249 char *buf = NULL;
250 int file;
251 int deletion_needed = 0; /* true when a deleted message has been found */
252 size_t buff_size = 0;
253 size_t tmp = 0;
254
255 if (mbox == NULL)
256 {
257 errno = EINVAL;
258 return -1;
259 }
260 if (mbox->num_deleted)
261 {
262 data = mbox->_data;
263 fclose(data->file);
264 /* error handling */
265 data->file = NULL;
266 file = open(mbox->name, O_RDWR);
267 /* error handling */
268
269 for (i = 0; i < mbox->messages; i++)
270 {
271 if (data->messages[i].deleted == 0)
272 {
273 if (deletion_needed)
274 {
275 tmp = mbox->sizes[i];
276 if (tmp > buff_size)
277 {
278 buff_size = tmp;
279 buf = realloc (buf, tmp);
280 /* error checking */
281 }
282 lseek (file, data->messages[i].header, SEEK_SET);
283 size_read = read (file, buf, tmp);
284 /* error checking */
285 lseek (file, size, SEEK_SET);
286 write (file, buf, size_read);
287 /* error checking */
288 size += size_read;
289 }
290 else
291 {
292 size += mbox->sizes[i];
293 }
294 }
295 else
296 {
297 deletion_needed = 1;
298 }
299 }
300 close (file);
301 truncate (mbox->name, size);
302 free (buf);
303 }
304 return 0;
305 }
306
307 /*
308 * Determines whether or a not a message is marked for deletion
309 */
310 int
311 unixmbox_is_deleted (mailbox * mbox, unsigned int num)
312 {
313 unixmbox_data *data;
314
315 if (mbox == NULL)
316 {
317 errno = EINVAL;
318 return -1;
319 }
320 if (mbox->num_deleted == 0)
321 return 0;
322 data = mbox->_data;
323 return (data->messages[num].deleted == 1);
324 }
325
326 int
327 unixmbox_is_updated (mailbox *mbox)
328 {
329 struct stat st;
330 unixmbox_data *data;
331
332 if (mbox == NULL)
333 {
334 errno = EINVAL;
335 return -1;
336 }
337 if (stat (mbox->name, &st) == -1)
338 return -1;
339 data = mbox->_data;
340 return (st.st_mtime > data->last_mod_time);
341 }
342
343 /*
344 * Adds a message to the mailbox
345 */
346 int
347 unixmbox_add_message (mailbox * mbox, char *message)
348 {
349 /*
350 * FIXME: please write me
351 * move to end of file and write text, don't forget to update
352 * mbox->messages and mbox->_data->messages
353 */
354 errno = ENOSYS;
355 return -1;
356 }
357
358 /*
359 * Returns a message body
360 */
361 char *
362 unixmbox_get_body (mailbox * mbox, unsigned int num)
363 {
364 unixmbox_data *data;
365 size_t size;
366 char *buf;
367
368 if (mbox == NULL)
369 {
370 errno = EINVAL;
371 return NULL;
372 }
373 if (num > mbox->messages || num < 0)
374 {
375 errno = ERANGE;
376 return NULL;
377 }
378
379 data = mbox->_data;
380 size = data->messages[num].end - data->messages[num].body;
381 buf = malloc ((1 + size) * sizeof (char));
382 if (buf == NULL)
383 {
384 errno = ENOMEM;
385 return NULL;
386 }
387
388 memset (buf, 0, size + 1);
389 if (fsetpos (data->file, &(data->messages[num].body)) == -1)
390 {
391 free (buf);
392 return NULL;
393 }
394 if (fread (buf, sizeof (char), size, data->file) < size)
395 {
396 free (buf);
397 return NULL;
398 }
399 return buf;
400 }
401
402 /*
403 * Returns just the header of a message
404 */
405 char *
406 unixmbox_get_header (mailbox * mbox, unsigned int num)
407 {
408 unixmbox_data *data;
409 size_t size;
410 char *buf;
411
412 if ( mbox == NULL )
413 {
414 errno = EINVAL;
415 return NULL;
416 }
417
418 if (num > mbox->messages)
419 {
420 errno = ERANGE;
421 return NULL;
422 }
423
424 data = mbox->_data;
425 size = (data->messages[num].body - 1) - data->messages[num].header;
426 buf = malloc ((1 + size) * sizeof (char));
427 if (buf == NULL)
428 {
429 errno = ENOMEM;
430 return NULL;
431 }
432
433 memset (buf, 0, size + 1);
434
435 if (fsetpos (data->file, &(data->messages[num].header)) == -1)
436 {
437 free (buf);
438 return NULL;
439 }
440 if (fread (buf, sizeof (char), size, data->file) < size)
441 {
442 free (buf);
443 return NULL;
444 }
445 return buf;
446 }
447
448 /*
449 * Sets lock mode for a mailbox
450 * FIXME: this doesn't do anything, really
451 * Get locking code from Procmail and/or Exim
452 */
453 int
454 unixmbox_lock (mailbox *mbox, mailbox_lock_t mode)
455 {
456 unixmbox_data *data = mbox->_data;
457 data->lockmode = mode;
458 return 0;
459 }
460
461 /* FIXME: not implemented */
462 int
463 unixmbox_scan (mailbox *mbox)
464 {
465 errno = ENOSYS;
466 return -1;
467 }
468
469 #ifdef TESTING
470 void unixmbox_tester (mailbox *mbox, unsigned int num)
471 {
472 unixmbox_data *data = mbox->_data;
473 if (!data || num > mbox->messages || num < 0)
474 return;
475 printf ("Message size: %u\n", mbox->sizes[num]);
476 printf ("Message length: %lu\n",
477 data->messages[num].end - data->messages[num].header);
478 }
479 #endif
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #ifndef _UNIXMBOX_H
19 #define _UNIXMBOX_H 1
20 #include <mailbox.h>
21 #include "config.h"
22
23 #ifdef HAVE_STDIO_H
24 #include <stdio.h>
25 #endif
26
27 #ifdef HAVE_STDLIB_H
28 #include <stdlib.h>
29 #endif
30
31 /* FIXME need auto* wrapper */
32 #include <sys/types.h>
33 #include <sys/stat.h>
34
35 #include <fcntl.h>
36
37 #ifdef HAVE_UNISTD_H
38 #include <unistd.h>
39 #endif
40
41 #ifdef HAVE_ERRNO_H
42 #include <errno.h>
43 #endif
44
45 #ifdef HAVE_STRING_H
46 #include <string.h>
47 #elif HAVE_STRINGS_H
48 #include <strings.h>
49 #endif
50
51 typedef struct _unixmbox_message
52 {
53 off_t header;
54 off_t body;
55 off_t end;
56 char deleted;
57 }
58 unixmbox_message;
59
60 typedef struct _unixmbox_data
61 {
62 unixmbox_message *messages;
63 FILE *file;
64 mailbox_lock_t lockmode;
65 time_t last_mod_time;
66 }
67 unixmbox_data;
68
69 int unixmbox_open (mailbox *mbox);
70 int unixmbox_close (mailbox *mbox);
71 int unixmbox_delete (mailbox *mbox, unsigned int num);
72 int unixmbox_undelete (mailbox *mbox, unsigned int num);
73 int unixmbox_expunge (mailbox *mbox);
74 int unixmbox_scan (mailbox *mbox);
75 int unixmbox_is_deleted (mailbox *mbox, unsigned int num);
76 int unixmbox_is_updated (mailbox *mbox);
77 int unixmbox_lock (mailbox *mbox, mailbox_lock_t mode);
78 int unixmbox_add_message (mailbox *mbox, char *message);
79 char *unixmbox_get_body (mailbox *mbox, unsigned int num);
80 char *unixmbox_get_header (mailbox *mbox, unsigned int num);
81
82 #ifdef TESTING
83 void unixmbox_tester (mailbox *mbox, unsigned int num);
84 #endif
85
86 #endif