Initial revision
0 parents
Showing
13 changed files
with
615 additions
and
0 deletions
ChangeLog
0 → 100644
Makefile.am
0 → 100644
NEWS
0 → 100644
File mode changed
README
0 → 100644
File mode changed
configure.in
0 → 100644
1 | dnl Process this file with autoconf to procude a configure script. -*-m4-*- | ||
2 | AC_INIT(libmailbox/mailbox.c) | ||
3 | AM_INIT_AUTOMAKE(libmailbox, 0.0.19990909) | ||
4 | AM_CONFIG_HEADER(config.h) | ||
5 | AM_MAINTAINER_MODE | ||
6 | |||
7 | AC_PROG_CC | ||
8 | AC_PROG_INSTALL | ||
9 | AC_PROG_LN_S | ||
10 | AC_PROG_LIBTOOL | ||
11 | |||
12 | AC_ARG_ENABLE(-mailbox-install, | ||
13 | [ --enable-mailbox-install install libmailbox]) | ||
14 | |||
15 | AM_CONDITIONAL(INSTALL_MAILBOX, test x"${enable_mailbox_install-no}" != xno) | ||
16 | |||
17 | AC_HEADER_STDC | ||
18 | AC_CHECK_HEADERS(malloc.h stdlib.h stdio.h errno.h unistd.h) | ||
19 | AC_CHECK_HEADERS(string.h strings.h, break) | ||
20 | |||
21 | AC_OUTPUT(Makefile libmailbox/Makefile mail/Makefile) |
libmailbox/Makefile.am
0 → 100644
1 | # Use automake to process this file -*-Makefile-*- | ||
2 | |||
3 | if INSTALL_MAILBOX | ||
4 | include_HEADERS = mailbox.h | ||
5 | lib_LTLIBRARIES = libmailbox.la | ||
6 | else | ||
7 | noinst_HEADERS = mailbox.h | ||
8 | noinst_LTLIBRARIES = libmailbox.la | ||
9 | endif | ||
10 | |||
11 | libmailbox_la_SOURCES = mailbox.c unixmbox.c unixmbox.h | ||
12 | libmailbox_la_LDFLAGS = -version-info 0:0:0 | ||
13 |
libmailbox/mailbox.c
0 → 100644
1 | /* copyright and license info go here */ | ||
2 | |||
3 | #include "mailbox.h" | ||
4 | #include "unixmbox.h" | ||
5 | |||
6 | #ifdef _HAVE_ERRNO_H | ||
7 | #include <errno.h> | ||
8 | #endif | ||
9 | |||
10 | int _mbox_dummy1 (mailbox * mbox); | ||
11 | int _mbox_dummy2 (mailbox * mbox, int num); | ||
12 | int _mbox_dummy3 (mailbox * mbox, char *c); | ||
13 | char *_mbox_dummy4 (mailbox * mbox, int num); | ||
14 | |||
15 | mailbox * | ||
16 | mbox_open (char *name) | ||
17 | { | ||
18 | mailbox *mbox = malloc (sizeof (mailbox)); | ||
19 | if (mbox == NULL) | ||
20 | { | ||
21 | errno = ENOMEM; | ||
22 | return NULL; | ||
23 | } | ||
24 | |||
25 | /* Set up with default data and dummy functions */ | ||
26 | mbox->name = strdup (name); | ||
27 | if (mbox->name == NULL) | ||
28 | { | ||
29 | errno = ENOMEM; | ||
30 | free (mbox); | ||
31 | return NULL; | ||
32 | } | ||
33 | mbox->messages = 0; | ||
34 | mbox->num_deleted = 0; | ||
35 | mbox->sizes = NULL; | ||
36 | mbox->_data = NULL; | ||
37 | mbox->_close = _mbox_dummy1; | ||
38 | mbox->_delete = _mbox_dummy2; | ||
39 | mbox->_undelete = _mbox_dummy2; | ||
40 | mbox->_expunge = _mbox_dummy1; | ||
41 | mbox->_add_message = _mbox_dummy3; | ||
42 | mbox->_is_deleted = _mbox_dummy2; | ||
43 | mbox->_get_body = _mbox_dummy4; | ||
44 | mbox->_get_header = _mbox_dummy4; | ||
45 | |||
46 | if (unixmbox_open (mbox) == 0) | ||
47 | return mbox; | ||
48 | else | ||
49 | { | ||
50 | /* | ||
51 | * Check errno to find out why it failed, if it's simply not a | ||
52 | * unix mbox format message, then try other mailbox types, | ||
53 | * otherwise, leave errno set and return NULL | ||
54 | */ | ||
55 | } | ||
56 | |||
57 | /* for example... | ||
58 | if (maildir_open (mbox, name) == 1) | ||
59 | return mbox; | ||
60 | else if (errno != 0) | ||
61 | return NULL; | ||
62 | else | ||
63 | errno = 0; | ||
64 | */ | ||
65 | |||
66 | errno = ENOSYS; | ||
67 | return NULL; | ||
68 | } | ||
69 | |||
70 | /* | ||
71 | * Bogus functions for unimplemented functions that return int | ||
72 | */ | ||
73 | int | ||
74 | _mbox_dummy1 (mailbox * mbox) | ||
75 | { | ||
76 | errno = ENOSYS; | ||
77 | return -1; | ||
78 | } | ||
79 | |||
80 | int | ||
81 | _mbox_dummy2 (mailbox * mbox, int num) | ||
82 | { | ||
83 | return _mbox_dummy1 (mbox); | ||
84 | } | ||
85 | int | ||
86 | _mbox_dummy3 (mailbox * mbox, char *c) | ||
87 | { | ||
88 | return _mbox_dummy1 (mbox); | ||
89 | } | ||
90 | |||
91 | /* | ||
92 | * Bogus function for unimplemented functions that return char * | ||
93 | */ | ||
94 | char * | ||
95 | _mbox_dummy4 (mailbox * mbox, int num) | ||
96 | { | ||
97 | errno = ENOSYS; | ||
98 | return NULL; | ||
99 | } |
libmailbox/mailbox.h
0 → 100644
1 | /* copyright and license info go here */ | ||
2 | |||
3 | #ifndef _MAILBOX_H | ||
4 | #define _MAILBOX_H 1 | ||
5 | |||
6 | #ifndef __P | ||
7 | #if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus) | ||
8 | #define __P(args) args | ||
9 | #else | ||
10 | #define __P(args) () | ||
11 | #endif | ||
12 | #endif /*!__P */ | ||
13 | |||
14 | /* These need to be documented */ | ||
15 | #define mbox_close(m) m->_close(m) | ||
16 | #define mbox_delete(m,n) m->_delete(m,n) | ||
17 | #define mbox_undelete(m,n) m->_undelete(m,n) | ||
18 | #define mbox_expunge(m) m->_expunge(m) | ||
19 | #define mbox_is_deleted(m,n) m->_is_deleted(m,n) | ||
20 | #define mbox_add_message(m,s) m->_add_message(m,s) | ||
21 | #define mbox_get_body(m,n) m->_get_body(m,n) | ||
22 | #define mbox_get_header(m,n) m->_get_header(m,n) | ||
23 | |||
24 | typedef struct _mailbox | ||
25 | { | ||
26 | /* Data */ | ||
27 | char *name; | ||
28 | int messages; | ||
29 | int num_deleted; | ||
30 | int *sizes; | ||
31 | void *_data; | ||
32 | |||
33 | /* Functions */ | ||
34 | int (*_close) __P ((struct _mailbox *)); | ||
35 | int (*_delete) __P ((struct _mailbox *, int)); | ||
36 | int (*_undelete) __P ((struct _mailbox *, int)); | ||
37 | int (*_expunge) __P ((struct _mailbox *)); | ||
38 | int (*_add_message) __P ((struct _mailbox *, char *)); | ||
39 | int (*_is_deleted) __P ((struct _mailbox *, int)); | ||
40 | char *(*_get_body) __P ((struct _mailbox *, int)); | ||
41 | char *(*_get_header) __P ((struct _mailbox *, int)); | ||
42 | } | ||
43 | mailbox; | ||
44 | |||
45 | mailbox *mbox_open __P ((char *name)); | ||
46 | |||
47 | #endif |
libmailbox/unixmbox.c
0 → 100644
1 | /* copyright and license info go here */ | ||
2 | |||
3 | #include "unixmbox.h" | ||
4 | |||
5 | /* | ||
6 | * Opens and locks a mailbox | ||
7 | */ | ||
8 | int | ||
9 | unixmbox_open (mailbox * mbox) | ||
10 | { | ||
11 | char buf[80]; | ||
12 | unsigned int max_count = 10; | ||
13 | int mess = 0; | ||
14 | unixmbox_data *data = malloc (sizeof (unixmbox_data)); | ||
15 | |||
16 | if (data == NULL) | ||
17 | { | ||
18 | errno = ENOMEM; | ||
19 | free (data); | ||
20 | return -1; | ||
21 | } | ||
22 | |||
23 | mbox->_data = data; | ||
24 | data->file = fopen (mbox->name, "r+"); | ||
25 | /* FIXME: do a good, NFS safe, file lock here, with error handling */ | ||
26 | if (data->file == NULL) | ||
27 | { | ||
28 | /* errno is set by fopen() */ | ||
29 | free (data); | ||
30 | return -1; | ||
31 | } | ||
32 | |||
33 | data->messages = malloc (sizeof (unixmbox_message) * max_count); | ||
34 | mbox->sizes = malloc (sizeof (int) * max_count); | ||
35 | if (data->messages == NULL || mbox->sizes == NULL) | ||
36 | { | ||
37 | unixmbox_close (mbox); | ||
38 | errno = ENOMEM; | ||
39 | return -1; | ||
40 | } | ||
41 | |||
42 | while (fgets (buf, 80, data->file)) | ||
43 | { | ||
44 | if (!strncmp (buf, "From ", 5)) | ||
45 | { | ||
46 | /* Beginning of a header */ | ||
47 | while (strchr (buf, '\n') == NULL) | ||
48 | fgets (buf, 80, data->file); | ||
49 | |||
50 | mbox->messages++; | ||
51 | |||
52 | if (mbox->messages > max_count) | ||
53 | { | ||
54 | max_count = mbox->messages * 2; | ||
55 | data->messages = realloc (data->messages, | ||
56 | max_count * sizeof (unixmbox_message)); | ||
57 | mbox->sizes = realloc (mbox->sizes, max_count * sizeof (int)); | ||
58 | if (data->messages == NULL || mbox->sizes == NULL) | ||
59 | { | ||
60 | unixmbox_close (mbox); | ||
61 | errno = ENOMEM; | ||
62 | return -1; | ||
63 | } | ||
64 | } | ||
65 | |||
66 | fgetpos (data->file, &(data->messages[mbox->messages - 1].header)); | ||
67 | mbox->sizes[mbox->messages - 1] = 0; | ||
68 | data->messages[mbox->messages - 1].deleted = 0; | ||
69 | mess = 0; | ||
70 | } | ||
71 | else if (((!strncmp (buf, "\r\n", 2) || strlen (buf) <= 1)) && mess == 0) | ||
72 | { | ||
73 | /* Beginning of a body */ | ||
74 | fgetpos (data->file, &(data->messages[mbox->messages - 1].body)); | ||
75 | mbox->sizes[mbox->messages - 1] += strlen (buf) + 1; | ||
76 | mess = 1; | ||
77 | } | ||
78 | else | ||
79 | { | ||
80 | mbox->sizes[mbox->messages - 1] += strlen (buf) + 1; | ||
81 | fgetpos (data->file, &(data->messages[mbox->messages - 1].end)); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | mbox->_close = unixmbox_close; | ||
86 | mbox->_delete = unixmbox_delete; | ||
87 | mbox->_undelete = unixmbox_undelete; | ||
88 | mbox->_expunge = unixmbox_expunge; | ||
89 | mbox->_add_message = unixmbox_add_message; | ||
90 | mbox->_is_deleted = unixmbox_is_deleted; | ||
91 | mbox->_get_body = unixmbox_get_body; | ||
92 | mbox->_get_header = unixmbox_get_header; | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * Closes and unlocks a mailbox, does not expunge | ||
99 | */ | ||
100 | int | ||
101 | unixmbox_close (mailbox * mbox) | ||
102 | { | ||
103 | unixmbox_data *data = mbox->_data; | ||
104 | /* FIXME: good file unlocking, to go along with the locking above */ | ||
105 | fclose (data->file); | ||
106 | free (data->messages); | ||
107 | free (mbox->sizes); | ||
108 | free (data); | ||
109 | free (mbox); | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | /* | ||
114 | * Marks a message for deletion | ||
115 | */ | ||
116 | int | ||
117 | unixmbox_delete (mailbox * mbox, int num) | ||
118 | { | ||
119 | unixmbox_data *data = mbox->_data; | ||
120 | if (num > mbox->messages || mbox_is_deleted (mbox, num)) | ||
121 | { | ||
122 | errno = ERANGE; | ||
123 | return -1; | ||
124 | } | ||
125 | else | ||
126 | { | ||
127 | data->messages[num].deleted = 1; | ||
128 | mbox->num_deleted++; | ||
129 | } | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * Unmark a message for deletion | ||
135 | */ | ||
136 | int | ||
137 | unixmbox_undelete (mailbox * mbox, int num) | ||
138 | { | ||
139 | unixmbox_data *data = mbox->_data; | ||
140 | if (num > mbox->messages || !mbox_is_deleted (mbox, num)) | ||
141 | { | ||
142 | errno = ERANGE; | ||
143 | return -1; | ||
144 | } | ||
145 | else | ||
146 | { | ||
147 | data->messages[num].deleted = 0; | ||
148 | mbox->num_deleted--; | ||
149 | } | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | /* | ||
154 | * Updates a mailbox to remove message marked for deletion | ||
155 | * FIXME: BROKEN! DOES NOT WORK! BLOWS UP REAL GOOD! | ||
156 | */ | ||
157 | int | ||
158 | unixmbox_expunge (mailbox * mbox) | ||
159 | { | ||
160 | unixmbox_data *data = mbox->_data; | ||
161 | int i = 0, size = 0; | ||
162 | char *buf; | ||
163 | fpos_t lastpos; | ||
164 | |||
165 | data->file = freopen (mbox->name, "r+", data->file); | ||
166 | if (data->file == NULL) | ||
167 | { | ||
168 | /* error handling */ | ||
169 | } | ||
170 | fgetpos (data->file, &lastpos); | ||
171 | |||
172 | for (i = 0; i < mbox->messages; i++) | ||
173 | { | ||
174 | if (data->messages[i].deleted == 0) | ||
175 | { | ||
176 | fgetpos (data->file, &lastpos); | ||
177 | fsetpos (data->file, &(data->messages[i].header)); | ||
178 | read (fileno (data->file), buf, | ||
179 | data->messages[i + 1].header - data->messages[i].header); | ||
180 | fprintf (data->file, "%s", buf); | ||
181 | size += strlen (buf); | ||
182 | free (buf); | ||
183 | } | ||
184 | } | ||
185 | ftruncate (fileno (data->file), size); | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | /* | ||
190 | * Determines whether or a not a message is marked for deletion | ||
191 | */ | ||
192 | int | ||
193 | unixmbox_is_deleted (mailbox * mbox, int num) | ||
194 | { | ||
195 | unixmbox_data *data = mbox->_data; | ||
196 | return (data->messages[num].deleted == 1); | ||
197 | } | ||
198 | |||
199 | /* | ||
200 | * Adds a message to the mailbox | ||
201 | */ | ||
202 | int | ||
203 | unixmbox_add_message (mailbox * mbox, char *message) | ||
204 | { | ||
205 | /* | ||
206 | * FIXME: please write me | ||
207 | * move to end of file and write text, don't forget to update | ||
208 | * mbox->messages and mbox->_data->messages | ||
209 | */ | ||
210 | errno = ENOSYS; | ||
211 | return -1; | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * Returns a message body | ||
216 | */ | ||
217 | char * | ||
218 | unixmbox_get_body (mailbox * mbox, int num) | ||
219 | { | ||
220 | unixmbox_data *data = mbox->_data; | ||
221 | int size = data->messages[num].end - data->messages[num].body; | ||
222 | char *buf = malloc ((1 + size) * sizeof (char)); | ||
223 | if (buf == NULL) | ||
224 | { | ||
225 | errno = ENOMEM; | ||
226 | free (buf); | ||
227 | return NULL; | ||
228 | } | ||
229 | else if (num > mbox->messages || num < 0) | ||
230 | { | ||
231 | errno = ERANGE; | ||
232 | free (buf); | ||
233 | return NULL; | ||
234 | } | ||
235 | |||
236 | memset (buf, 0, size + 1); | ||
237 | fsetpos (data->file, &(data->messages[num].body)); | ||
238 | fread (buf, size, sizeof (char), data->file); | ||
239 | return buf; | ||
240 | } | ||
241 | |||
242 | /* | ||
243 | * Returns just the header of a message | ||
244 | */ | ||
245 | char * | ||
246 | unixmbox_get_header (mailbox * mbox, int num) | ||
247 | { | ||
248 | unixmbox_data *data = mbox->_data; | ||
249 | int size = (data->messages[num].body - 1) - data->messages[num].header ; | ||
250 | char *buf = malloc ((1 + size) * sizeof (char)); | ||
251 | if (buf == NULL) | ||
252 | { | ||
253 | errno = ENOMEM; | ||
254 | free (buf); | ||
255 | return NULL; | ||
256 | } | ||
257 | else if (num > mbox->messages || num < 0) | ||
258 | { | ||
259 | errno = ERANGE; | ||
260 | free (buf); | ||
261 | return NULL; | ||
262 | } | ||
263 | |||
264 | memset (buf, 0, size + 1); | ||
265 | fsetpos (data->file, &(data->messages[num].header)); | ||
266 | fread (buf, size, sizeof (char), data->file); | ||
267 | return buf; | ||
268 | } |
libmailbox/unixmbox.h
0 → 100644
1 | /* copyright and license info go here */ | ||
2 | |||
3 | #ifndef _UNIXMBOX_H | ||
4 | #define _UNIXMBOX_H 1 | ||
5 | #include <mailbox.h> | ||
6 | #include "config.h" | ||
7 | |||
8 | #ifdef HAVE_STDIO_H | ||
9 | #include <stdio.h> | ||
10 | #endif | ||
11 | |||
12 | #ifdef HAVE_STDLIB_H | ||
13 | #include <stdlib.h> | ||
14 | #endif | ||
15 | |||
16 | #ifdef HAVE_UNISTD_H | ||
17 | #include <unistd.h> | ||
18 | #endif | ||
19 | |||
20 | #ifdef HAVE_ERRNO_H | ||
21 | #include <errno.h> | ||
22 | #endif | ||
23 | |||
24 | #ifdef HAVE_STRING_H | ||
25 | #include <string.h> | ||
26 | #elif HAVE_STRINGS_H | ||
27 | #include <strings.h> | ||
28 | #endif | ||
29 | |||
30 | typedef struct _unixmbox_message | ||
31 | { | ||
32 | off_t header; | ||
33 | off_t body; | ||
34 | off_t end; | ||
35 | short deleted; | ||
36 | } | ||
37 | unixmbox_message; | ||
38 | |||
39 | typedef struct _unixmbox_data | ||
40 | { | ||
41 | unixmbox_message *messages; | ||
42 | FILE *file; | ||
43 | } | ||
44 | unixmbox_data; | ||
45 | |||
46 | int unixmbox_open (mailbox *mbox); | ||
47 | int unixmbox_close (mailbox *mbox); | ||
48 | int unixmbox_delete (mailbox *mbox, int num); | ||
49 | int unixmbox_undelete (mailbox *mbox, int num); | ||
50 | int unixmbox_expunge (mailbox *mbox); | ||
51 | int unixmbox_is_deleted (mailbox *mbox, int num); | ||
52 | int unixmbox_add_message (mailbox *mbox, char *message); | ||
53 | char *unixmbox_get_body (mailbox *mbox, int num); | ||
54 | char *unixmbox_get_header (mailbox *mbox, int num); | ||
55 | |||
56 | #endif |
mail/Makefile.am
0 → 100644
mail/mail.c
0 → 100644
1 | /* copyright and license info go here */ | ||
2 | |||
3 | #include <mailbox.h> | ||
4 | #include <stdio.h> | ||
5 | #include <stdlib.h> | ||
6 | |||
7 | #ifdef HAVE_PATHS_H | ||
8 | #include <paths.h> | ||
9 | #endif | ||
10 | |||
11 | #ifndef _PATH_MAILDIR | ||
12 | #define _PATH_MAILDIR "/var/spool/mail" | ||
13 | #endif | ||
14 | |||
15 | int | ||
16 | main (int argc, char **argv) | ||
17 | { | ||
18 | char *foo, bar[80]; | ||
19 | int i = 0; | ||
20 | char c = 0; | ||
21 | char *mboxname; | ||
22 | mailbox *mbox; | ||
23 | |||
24 | if (argc != 1) | ||
25 | { | ||
26 | fprintf (stderr, "Usage: %s\n", argv[0]); | ||
27 | return 1; | ||
28 | } | ||
29 | |||
30 | mboxname = getenv ("MAIL"); | ||
31 | if (mboxname == NULL) | ||
32 | { | ||
33 | foo = getenv ("LOGNAME"); | ||
34 | mboxname = malloc ((strlen(foo) + strlen(_PATH_MAILDIR) + 2) * sizeof(char)); | ||
35 | strcpy (mboxname, _PATH_MAILDIR "/"); | ||
36 | strcat (mboxname, foo); | ||
37 | free (foo); | ||
38 | } | ||
39 | |||
40 | mbox = mbox_open (mboxname); | ||
41 | printf ("Number of messages: %d\n", mbox->messages); | ||
42 | while (1) | ||
43 | { | ||
44 | printf ("& "); | ||
45 | fflush (stdout); | ||
46 | fgets (bar, 80, stdin); | ||
47 | c = bar[0]; | ||
48 | if (c == 'd' || c == 'D' || c == 'b' || c == 'B' || c == 'h' || | ||
49 | c == 'H' || c == 'r' || c == 'R') | ||
50 | { | ||
51 | printf ("# "); | ||
52 | fgets (bar, 80, stdin); | ||
53 | } | ||
54 | switch (c) | ||
55 | { | ||
56 | case 'q': | ||
57 | case 'Q': | ||
58 | mbox_close (mbox); | ||
59 | return 0; | ||
60 | break; | ||
61 | case 'r': | ||
62 | case 'R': | ||
63 | foo = mbox_get_header (mbox, atoi (bar) - 1); | ||
64 | printf ("%s\n", foo); | ||
65 | free (foo); | ||
66 | foo = mbox_get_body (mbox, atoi (bar) - 1); | ||
67 | printf ("%s", foo); | ||
68 | free (foo); | ||
69 | break; | ||
70 | case 'h': | ||
71 | case 'H': | ||
72 | foo = mbox_get_header (mbox, atoi (bar) - 1); | ||
73 | printf ("%s", foo); | ||
74 | free (foo); | ||
75 | break; | ||
76 | case 'b': | ||
77 | case 'B': | ||
78 | foo = mbox_get_body (mbox, atoi (bar) - 1); | ||
79 | printf ("%s", foo); | ||
80 | free (foo); | ||
81 | break; | ||
82 | case 'd': | ||
83 | case 'D': | ||
84 | mbox_delete (mbox, atoi (bar) - 1); | ||
85 | break; | ||
86 | case 'x': | ||
87 | case 'X': | ||
88 | mbox_expunge (mbox); | ||
89 | break; | ||
90 | default: | ||
91 | break; | ||
92 | } | ||
93 | } | ||
94 | } |
-
Please register or sign in to post a comment