Implement `remove' method for mailboxes.
* include/mailutils/mailbox.h (mu_mailbox_remove): New function. * include/mailutils/stream.h: Add some comments. * include/mailutils/sys/amd.h (_amd_data)<remove>: New method. (amd_remove_dir): New function. * include/mailutils/sys/mailbox.h (_mu_mailbox)<_remove>: New method. * libmailutils/amd.c (amd_remove_mbox): New function. (amd_init_mailbox): Initialize the _remove method. (amd_remove_dir): New function. * libmailutils/errors (MU_ERR_MBX_REMOVED) (MU_ERR_NOT_OPEN, MU_ERR_OPEN): New error codes. * libmailutils/mailbox.c: Keep state of the mailbox (open vs. not open, removed). Check it before doing anything on it. (_MU_MAILBOX_OPEN, _MU_MAILBOX_REMOVED, _MU_MAILBOX_MASK): New defines. (mu_mailbox_open): Set _MU_MAILBOX_OPEN if the operation succeeds. (mu_mailbox_close): Clear _MU_MAILBOX_OPEN if the operation succeeds. Refuse to run if the mailbox was not opened. (mu_mailbox_remove): New function. (all functions): return MU_ERR_MBX_NULL if the mbox argument is NULL. Check mailbox state on entry and proceed accordingly. * libproto/maildir/mbox.c: Implement _remove method. (maildir_remove): New function. (_mailbox_maildir_init): Initialize amd->_remove. * libproto/mbox/mbox.c: Implement _remove method. (mbox_remove): New function. (_mailbox_mbox_init): Initialize amd->_remove. * libproto/mh/mbox.c: Implement _remove method. (mh_remove): New function. (_mailbox_mh_init): Initialize amd->_remove. * libmailutils/tests/mbdel.c: New file. * libmailutils/tests/.gitignore: Add mbdel. * libmailutils/tests/Makefile.am (noinst_PROGRAMS): Likewise. (LDADD): List all mailbox formats. * imap4d/delete.c (imap4d_delete): Use mu_mailbox_remove to delete the folder. Fall back to remove() if it does not appear to be a mailbox.
Showing
15 changed files
with
327 additions
and
56 deletions
... | @@ -37,7 +37,8 @@ imap4d_delete (struct imap4d_command *command, imap4d_tokbuf_t tok) | ... | @@ -37,7 +37,8 @@ imap4d_delete (struct imap4d_command *command, imap4d_tokbuf_t tok) |
37 | const char *msg = "Completed"; | 37 | const char *msg = "Completed"; |
38 | const char *delim = "/"; | 38 | const char *delim = "/"; |
39 | char *name; | 39 | char *name; |
40 | 40 | mu_mailbox_t tmpbox; | |
41 | |||
41 | if (imap4d_tokbuf_argc (tok) != 3) | 42 | if (imap4d_tokbuf_argc (tok) != 3) |
42 | return io_completion_response (command, RESP_BAD, "Invalid arguments"); | 43 | return io_completion_response (command, RESP_BAD, "Invalid arguments"); |
43 | name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1); | 44 | name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1); |
... | @@ -54,7 +55,22 @@ imap4d_delete (struct imap4d_command *command, imap4d_tokbuf_t tok) | ... | @@ -54,7 +55,22 @@ imap4d_delete (struct imap4d_command *command, imap4d_tokbuf_t tok) |
54 | if (!name) | 55 | if (!name) |
55 | return io_completion_response (command, RESP_NO, "Cannot remove"); | 56 | return io_completion_response (command, RESP_NO, "Cannot remove"); |
56 | 57 | ||
57 | if (remove (name) != 0) | 58 | rc = mu_mailbox_create (&tmpbox, name); |
59 | if (rc == 0) | ||
60 | { | ||
61 | rc = mu_mailbox_remove (tmpbox); | ||
62 | mu_mailbox_destroy (&tmpbox); | ||
63 | if (rc) | ||
64 | mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_remove", name, rc); | ||
65 | } | ||
66 | else | ||
67 | { | ||
68 | rc = remove (name); | ||
69 | if (rc) | ||
70 | mu_diag_funcall (MU_DIAG_ERROR, "remove", name, errno); | ||
71 | } | ||
72 | |||
73 | if (rc) | ||
58 | { | 74 | { |
59 | rc = RESP_NO; | 75 | rc = RESP_NO; |
60 | msg = "Cannot remove"; | 76 | msg = "Cannot remove"; | ... | ... |
... | @@ -49,6 +49,7 @@ extern void mu_mailbox_destroy (mu_mailbox_t *); | ... | @@ -49,6 +49,7 @@ extern void mu_mailbox_destroy (mu_mailbox_t *); |
49 | 49 | ||
50 | extern int mu_mailbox_open (mu_mailbox_t, int flag); | 50 | extern int mu_mailbox_open (mu_mailbox_t, int flag); |
51 | extern int mu_mailbox_close (mu_mailbox_t); | 51 | extern int mu_mailbox_close (mu_mailbox_t); |
52 | extern int mu_mailbox_remove (mu_mailbox_t mbox); | ||
52 | extern int mu_mailbox_flush (mu_mailbox_t mbox, int expunge); | 53 | extern int mu_mailbox_flush (mu_mailbox_t mbox, int expunge); |
53 | extern int mu_mailbox_get_folder (mu_mailbox_t, mu_folder_t *); | 54 | extern int mu_mailbox_get_folder (mu_mailbox_t, mu_folder_t *); |
54 | extern int mu_mailbox_set_folder (mu_mailbox_t, mu_folder_t); | 55 | extern int mu_mailbox_set_folder (mu_mailbox_t, mu_folder_t); | ... | ... |
... | @@ -27,7 +27,6 @@ enum mu_buffer_type | ... | @@ -27,7 +27,6 @@ enum mu_buffer_type |
27 | mu_buffer_full | 27 | mu_buffer_full |
28 | }; | 28 | }; |
29 | 29 | ||
30 | |||
31 | #define MU_SEEK_SET 0 | 30 | #define MU_SEEK_SET 0 |
32 | #define MU_SEEK_CUR 1 | 31 | #define MU_SEEK_CUR 1 |
33 | #define MU_SEEK_END 2 | 32 | #define MU_SEEK_END 2 |
... | @@ -38,8 +37,10 @@ enum mu_buffer_type | ... | @@ -38,8 +37,10 @@ enum mu_buffer_type |
38 | #define MU_STREAM_SEEK 0x00000004 | 37 | #define MU_STREAM_SEEK 0x00000004 |
39 | #define MU_STREAM_APPEND 0x00000008 | 38 | #define MU_STREAM_APPEND 0x00000008 |
40 | #define MU_STREAM_CREAT 0x00000010 | 39 | #define MU_STREAM_CREAT 0x00000010 |
40 | /* So far used only by TCP streams. */ | ||
41 | #define MU_STREAM_NONBLOCK 0x00000020 | 41 | #define MU_STREAM_NONBLOCK 0x00000020 |
42 | #define MU_STREAM_AUTOCLOSE 0x00000040 | 42 | #define MU_STREAM_AUTOCLOSE 0x00000040 |
43 | /* Not used. Intended for mailboxes only. */ | ||
43 | #define MU_STREAM_NONLOCK 0x00000080 | 44 | #define MU_STREAM_NONLOCK 0x00000080 |
44 | #define MU_STREAM_ALLOW_LINKS 0x00000100 | 45 | #define MU_STREAM_ALLOW_LINKS 0x00000100 |
45 | /* FIXME: This one affects only mailboxes */ | 46 | /* FIXME: This one affects only mailboxes */ | ... | ... |
... | @@ -82,6 +82,7 @@ struct _amd_data | ... | @@ -82,6 +82,7 @@ struct _amd_data |
82 | int (*msg_cmp) (struct _amd_message *, struct _amd_message *); | 82 | int (*msg_cmp) (struct _amd_message *, struct _amd_message *); |
83 | int (*message_uid) (mu_message_t msg, size_t *puid); | 83 | int (*message_uid) (mu_message_t msg, size_t *puid); |
84 | size_t (*next_uid) (struct _amd_data *mhd); | 84 | size_t (*next_uid) (struct _amd_data *mhd); |
85 | int (*remove) (struct _amd_data *); | ||
85 | 86 | ||
86 | /* List of messages: */ | 87 | /* List of messages: */ |
87 | size_t msg_count; /* number of messages in the list */ | 88 | size_t msg_count; /* number of messages in the list */ |
... | @@ -112,5 +113,6 @@ void amd_cleanup (void *arg); | ... | @@ -112,5 +113,6 @@ void amd_cleanup (void *arg); |
112 | struct _amd_message *_amd_get_message (struct _amd_data *amd, size_t msgno); | 113 | struct _amd_message *_amd_get_message (struct _amd_data *amd, size_t msgno); |
113 | int amd_msg_lookup (struct _amd_data *amd, struct _amd_message *msg, | 114 | int amd_msg_lookup (struct _amd_data *amd, struct _amd_message *msg, |
114 | size_t *pret); | 115 | size_t *pret); |
116 | int amd_remove_dir (const char *name); | ||
115 | 117 | ||
116 | #endif | 118 | #endif | ... | ... |
... | @@ -54,6 +54,7 @@ struct _mu_mailbox | ... | @@ -54,6 +54,7 @@ struct _mu_mailbox |
54 | 54 | ||
55 | int (*_open) (mu_mailbox_t, int); | 55 | int (*_open) (mu_mailbox_t, int); |
56 | int (*_close) (mu_mailbox_t); | 56 | int (*_close) (mu_mailbox_t); |
57 | int (*_remove) (mu_mailbox_t); | ||
57 | 58 | ||
58 | /* messages */ | 59 | /* messages */ |
59 | int (*_get_message) (mu_mailbox_t, size_t, mu_message_t *); | 60 | int (*_get_message) (mu_mailbox_t, size_t, mu_message_t *); | ... | ... |
... | @@ -112,6 +112,7 @@ static int amd_envelope_date (mu_envelope_t envelope, char *buf, size_t len, | ... | @@ -112,6 +112,7 @@ static int amd_envelope_date (mu_envelope_t envelope, char *buf, size_t len, |
112 | size_t *psize); | 112 | size_t *psize); |
113 | static int amd_envelope_sender (mu_envelope_t envelope, char *buf, size_t len, | 113 | static int amd_envelope_sender (mu_envelope_t envelope, char *buf, size_t len, |
114 | size_t *psize); | 114 | size_t *psize); |
115 | static int amd_remove_mbox (mu_mailbox_t mailbox); | ||
115 | 116 | ||
116 | 117 | ||
117 | static int amd_body_stream_read (mu_stream_t str, char *buffer, | 118 | static int amd_body_stream_read (mu_stream_t str, char *buffer, |
... | @@ -309,7 +310,8 @@ amd_init_mailbox (mu_mailbox_t mailbox, size_t amd_size, | ... | @@ -309,7 +310,8 @@ amd_init_mailbox (mu_mailbox_t mailbox, size_t amd_size, |
309 | mailbox->_is_updated = amd_is_updated; | 310 | mailbox->_is_updated = amd_is_updated; |
310 | 311 | ||
311 | mailbox->_get_size = amd_get_size; | 312 | mailbox->_get_size = amd_get_size; |
312 | 313 | mailbox->_remove = amd_remove_mbox; | |
314 | |||
313 | MU_DEBUG1 (mailbox->debug, MU_DEBUG_TRACE1, "amd_init(%s)\n", amd->name); | 315 | MU_DEBUG1 (mailbox->debug, MU_DEBUG_TRACE1, "amd_init(%s)\n", amd->name); |
314 | *pamd = amd; | 316 | *pamd = amd; |
315 | return 0; | 317 | return 0; |
... | @@ -1100,6 +1102,40 @@ compute_mailbox_size (struct _amd_data *amd, const char *name, mu_off_t *psize) | ... | @@ -1100,6 +1102,40 @@ compute_mailbox_size (struct _amd_data *amd, const char *name, mu_off_t *psize) |
1100 | } | 1102 | } |
1101 | 1103 | ||
1102 | static int | 1104 | static int |
1105 | amd_remove_mbox (mu_mailbox_t mailbox) | ||
1106 | { | ||
1107 | int rc; | ||
1108 | struct _amd_data *amd = mailbox->data; | ||
1109 | |||
1110 | if (!amd->remove) | ||
1111 | return ENOSYS; | ||
1112 | rc = amd->remove (amd); | ||
1113 | if (rc == 0) | ||
1114 | { | ||
1115 | char *name = make_size_file_name (amd); | ||
1116 | if (!name) | ||
1117 | return ENOMEM; | ||
1118 | if (unlink (name) && errno != ENOENT) | ||
1119 | rc = errno; | ||
1120 | free (name); | ||
1121 | } | ||
1122 | |||
1123 | if (rc == 0) | ||
1124 | { | ||
1125 | if (rmdir (amd->name) && errno != ENOENT) | ||
1126 | { | ||
1127 | rc = errno; | ||
1128 | /* POSIX.1-2001 allows EEXIST to be returned if the directory | ||
1129 | contained entries other than . and .. */ | ||
1130 | if (rc == EEXIST) | ||
1131 | rc = ENOTEMPTY; | ||
1132 | } | ||
1133 | } | ||
1134 | |||
1135 | return rc; | ||
1136 | } | ||
1137 | |||
1138 | static int | ||
1103 | amd_expunge (mu_mailbox_t mailbox) | 1139 | amd_expunge (mu_mailbox_t mailbox) |
1104 | { | 1140 | { |
1105 | struct _amd_data *amd = mailbox->data; | 1141 | struct _amd_data *amd = mailbox->data; |
... | @@ -1922,4 +1958,81 @@ amd_envelope_sender (mu_envelope_t envelope, char *buf, size_t len, size_t *psiz | ... | @@ -1922,4 +1958,81 @@ amd_envelope_sender (mu_envelope_t envelope, char *buf, size_t len, size_t *psiz |
1922 | return 0; | 1958 | return 0; |
1923 | } | 1959 | } |
1924 | 1960 | ||
1961 | |||
1962 | int | ||
1963 | amd_remove_dir (const char *name) | ||
1964 | { | ||
1965 | DIR *dir; | ||
1966 | struct dirent *ent; | ||
1967 | char *namebuf; | ||
1968 | size_t namelen, namesize; | ||
1969 | int rc = 0; | ||
1970 | int has_subdirs = 0; | ||
1971 | |||
1972 | namelen = strlen (name); | ||
1973 | namesize = namelen + 128; | ||
1974 | namebuf = malloc (namesize); | ||
1975 | if (!namebuf) | ||
1976 | return ENOMEM; | ||
1977 | memcpy (namebuf, name, namelen); | ||
1978 | if (namebuf[namelen - 1] != '/') | ||
1979 | namebuf[namelen++] = '/'; | ||
1980 | |||
1981 | dir = opendir (name); | ||
1982 | if (!dir) | ||
1983 | return errno; | ||
1984 | while ((ent = readdir (dir))) | ||
1985 | { | ||
1986 | struct stat st; | ||
1987 | size_t len; | ||
1988 | |||
1989 | if (strcmp (ent->d_name, ".") == 0 || | ||
1990 | strcmp (ent->d_name, "..") == 0) | ||
1991 | continue; | ||
1992 | len = strlen (ent->d_name); | ||
1993 | if (namelen + len >= namesize) | ||
1994 | { | ||
1995 | char *p; | ||
1996 | |||
1997 | namesize += len + 1; | ||
1998 | p = realloc (namebuf, namesize); | ||
1999 | if (!p) | ||
2000 | { | ||
2001 | rc = ENOMEM; | ||
2002 | break; | ||
2003 | } | ||
2004 | } | ||
2005 | strcpy (namebuf + namelen, ent->d_name); | ||
2006 | if (stat (namebuf, &st) == 0 && S_ISDIR (st.st_mode)) | ||
2007 | { | ||
2008 | has_subdirs = 1; | ||
2009 | continue; | ||
2010 | } | ||
2011 | |||
2012 | if (unlink (namebuf)) | ||
2013 | { | ||
2014 | rc = errno; | ||
2015 | mu_diag_output (MU_DIAG_WARNING, | ||
2016 | "failed to remove %s: %s", | ||
2017 | namebuf, mu_strerror (rc)); | ||
2018 | break; | ||
2019 | } | ||
2020 | } | ||
2021 | closedir (dir); | ||
2022 | free (namebuf); | ||
2023 | |||
2024 | if (rc == 0 && !has_subdirs) | ||
2025 | { | ||
2026 | if (rmdir (name)) | ||
2027 | { | ||
2028 | rc = errno; | ||
2029 | /* POSIX.1-2001 allows EEXIST to be returned if the directory | ||
2030 | contained entries other than . and .. */ | ||
2031 | if (rc == EEXIST) | ||
2032 | rc = ENOTEMPTY; | ||
2033 | } | ||
2034 | } | ||
2035 | return rc; | ||
2036 | } | ||
2037 | |||
1925 | 2038 | ... | ... |
... | @@ -26,6 +26,10 @@ MU_ERR_OUT_NULL _("Pointer to output null") | ... | @@ -26,6 +26,10 @@ MU_ERR_OUT_NULL _("Pointer to output null") |
26 | MU_ERR_OUT_PTR_NULL _("Pointer to output pointer null") | 26 | MU_ERR_OUT_PTR_NULL _("Pointer to output pointer null") |
27 | 27 | ||
28 | MU_ERR_MBX_NULL _("Mailbox null") | 28 | MU_ERR_MBX_NULL _("Mailbox null") |
29 | MU_ERR_MBX_REMOVED _("Mailbox removed") | ||
30 | |||
31 | MU_ERR_NOT_OPEN _("Resource not open") | ||
32 | MU_ERR_OPEN _("Resource still open") | ||
29 | 33 | ||
30 | MU_ERR_BAD_822_FORMAT _("Format of RFC822 object is bad") | 34 | MU_ERR_BAD_822_FORMAT _("Format of RFC822 object is bad") |
31 | MU_ERR_EMPTY_ADDRESS _("Address contains no addr specs") | 35 | MU_ERR_EMPTY_ADDRESS _("Address contains no addr specs") | ... | ... |
... | @@ -121,7 +121,7 @@ fd_open (struct _mu_stream *str) | ... | @@ -121,7 +121,7 @@ fd_open (struct _mu_stream *str) |
121 | { | 121 | { |
122 | struct stat fdbuf, filebuf; | 122 | struct stat fdbuf, filebuf; |
123 | 123 | ||
124 | /* The next two stats should never fail. */ | 124 | /* The following two stats should never fail. */ |
125 | if (fstat (fd, &fdbuf) == -1 | 125 | if (fstat (fd, &fdbuf) == -1 |
126 | || lstat (fstr->filename, &filebuf) == -1) | 126 | || lstat (fstr->filename, &filebuf) == -1) |
127 | { | 127 | { | ... | ... |
... | @@ -44,6 +44,11 @@ | ... | @@ -44,6 +44,11 @@ |
44 | #include <mailutils/sys/mailbox.h> | 44 | #include <mailutils/sys/mailbox.h> |
45 | #include <mailutils/sys/url.h> | 45 | #include <mailutils/sys/url.h> |
46 | 46 | ||
47 | /* Mailbox-specific flags */ | ||
48 | #define _MU_MAILBOX_OPEN 0x10000000 | ||
49 | #define _MU_MAILBOX_REMOVED 0x20000000 | ||
50 | #define _MU_MAILBOX_MASK 0xF0000000 | ||
51 | |||
47 | static int | 52 | static int |
48 | mailbox_folder_create (mu_mailbox_t mbox, const char *name, | 53 | mailbox_folder_create (mu_mailbox_t mbox, const char *name, |
49 | mu_record_t record) | 54 | mu_record_t record) |
... | @@ -287,7 +292,11 @@ mu_mailbox_destroy (mu_mailbox_t *pmbox) | ... | @@ -287,7 +292,11 @@ mu_mailbox_destroy (mu_mailbox_t *pmbox) |
287 | int | 292 | int |
288 | mu_mailbox_open (mu_mailbox_t mbox, int flag) | 293 | mu_mailbox_open (mu_mailbox_t mbox, int flag) |
289 | { | 294 | { |
290 | if (mbox == NULL || mbox->_open == NULL) | 295 | int rc; |
296 | |||
297 | if (!mbox) | ||
298 | return MU_ERR_MBX_NULL; | ||
299 | if (mbox->_open == NULL) | ||
291 | return MU_ERR_EMPTY_VFN; | 300 | return MU_ERR_EMPTY_VFN; |
292 | if (flag & MU_STREAM_QACCESS) | 301 | if (flag & MU_STREAM_QACCESS) |
293 | { | 302 | { |
... | @@ -296,16 +305,42 @@ mu_mailbox_open (mu_mailbox_t mbox, int flag) | ... | @@ -296,16 +305,42 @@ mu_mailbox_open (mu_mailbox_t mbox, int flag) |
296 | | MU_STREAM_APPEND | MU_STREAM_CREAT)) | 305 | | MU_STREAM_APPEND | MU_STREAM_CREAT)) |
297 | return EINVAL; /* FIXME: Better error code, please? */ | 306 | return EINVAL; /* FIXME: Better error code, please? */ |
298 | } | 307 | } |
299 | return mbox->_open (mbox, flag); | 308 | rc = mbox->_open (mbox, flag); |
309 | if (rc == 0) | ||
310 | mbox->flags |= _MU_MAILBOX_OPEN; | ||
311 | return rc; | ||
300 | } | 312 | } |
301 | 313 | ||
302 | int | 314 | int |
303 | mu_mailbox_close (mu_mailbox_t mbox) | 315 | mu_mailbox_close (mu_mailbox_t mbox) |
304 | { | 316 | { |
317 | int rc; | ||
318 | |||
319 | if (!mbox) | ||
320 | return MU_ERR_MBX_NULL; | ||
321 | if (!(mbox->flags & _MU_MAILBOX_OPEN)) | ||
322 | return MU_ERR_NOT_OPEN; | ||
305 | if (mbox == NULL || mbox->_close == NULL) | 323 | if (mbox == NULL || mbox->_close == NULL) |
306 | return MU_ERR_EMPTY_VFN; | 324 | return MU_ERR_EMPTY_VFN; |
307 | 325 | ||
308 | return mbox->_close (mbox); | 326 | rc = mbox->_close (mbox); |
327 | if (rc == 0) | ||
328 | mbox->flags &= ~_MU_MAILBOX_OPEN; | ||
329 | return rc; | ||
330 | } | ||
331 | |||
332 | int | ||
333 | mu_mailbox_remove (mu_mailbox_t mbox) | ||
334 | { | ||
335 | if (!mbox) | ||
336 | return MU_ERR_MBX_NULL; | ||
337 | if (mbox->flags & _MU_MAILBOX_OPEN) | ||
338 | return MU_ERR_OPEN; | ||
339 | if (mbox->flags & _MU_MAILBOX_REMOVED) | ||
340 | return MU_ERR_MBX_REMOVED; | ||
341 | if (!mbox->_remove) | ||
342 | return MU_ERR_EMPTY_VFN; | ||
343 | return mbox->_remove (mbox); | ||
309 | } | 344 | } |
310 | 345 | ||
311 | int | 346 | int |
... | @@ -315,7 +350,11 @@ mu_mailbox_flush (mu_mailbox_t mbox, int expunge) | ... | @@ -315,7 +350,11 @@ mu_mailbox_flush (mu_mailbox_t mbox, int expunge) |
315 | int status = 0; | 350 | int status = 0; |
316 | 351 | ||
317 | if (!mbox) | 352 | if (!mbox) |
318 | return EINVAL; | 353 | return MU_ERR_MBX_NULL; |
354 | if (mbox->flags & _MU_MAILBOX_REMOVED) | ||
355 | return MU_ERR_MBX_REMOVED; | ||
356 | if (!(mbox->flags & _MU_MAILBOX_OPEN)) | ||
357 | return _MU_MAILBOX_OPEN; | ||
319 | if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND))) | 358 | if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND))) |
320 | return 0; | 359 | return 0; |
321 | 360 | ||
... | @@ -338,12 +377,29 @@ mu_mailbox_flush (mu_mailbox_t mbox, int expunge) | ... | @@ -338,12 +377,29 @@ mu_mailbox_flush (mu_mailbox_t mbox, int expunge) |
338 | return status; | 377 | return status; |
339 | } | 378 | } |
340 | 379 | ||
380 | #define _MBOX_CHECK_FLAGS(mbox) \ | ||
381 | if (mbox == NULL) \ | ||
382 | return MU_ERR_MBX_NULL; \ | ||
383 | if (mbox->flags & _MU_MAILBOX_REMOVED) \ | ||
384 | return MU_ERR_MBX_REMOVED; \ | ||
385 | if (!(mbox->flags & _MU_MAILBOX_OPEN)) \ | ||
386 | return _MU_MAILBOX_OPEN | ||
387 | |||
388 | #define _MBOX_CHECK(mbox,method) \ | ||
389 | _MBOX_CHECK_FLAGS(mbox); \ | ||
390 | if (mbox->method == NULL) \ | ||
391 | return MU_ERR_EMPTY_VFN | ||
392 | |||
393 | #define _MBOX_CHECK_Q(mbox,method) \ | ||
394 | _MBOX_CHECK(mbox,method); \ | ||
395 | if (mbox->flags & MU_STREAM_QACCESS) \ | ||
396 | return MU_ERR_BADOP | ||
397 | |||
341 | /* messages */ | 398 | /* messages */ |
342 | int | 399 | int |
343 | mu_mailbox_append_message (mu_mailbox_t mbox, mu_message_t msg) | 400 | mu_mailbox_append_message (mu_mailbox_t mbox, mu_message_t msg) |
344 | { | 401 | { |
345 | if (mbox == NULL || mbox->_append_message == NULL) | 402 | _MBOX_CHECK_Q (mbox, _append_message); |
346 | return MU_ERR_EMPTY_VFN; | ||
347 | if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND))) | 403 | if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND))) |
348 | return EACCES; | 404 | return EACCES; |
349 | return mbox->_append_message (mbox, msg); | 405 | return mbox->_append_message (mbox, msg); |
... | @@ -352,10 +408,7 @@ mu_mailbox_append_message (mu_mailbox_t mbox, mu_message_t msg) | ... | @@ -352,10 +408,7 @@ mu_mailbox_append_message (mu_mailbox_t mbox, mu_message_t msg) |
352 | int | 408 | int |
353 | mu_mailbox_get_message (mu_mailbox_t mbox, size_t msgno, mu_message_t *pmsg) | 409 | mu_mailbox_get_message (mu_mailbox_t mbox, size_t msgno, mu_message_t *pmsg) |
354 | { | 410 | { |
355 | if (mbox == NULL || mbox->_get_message == NULL) | 411 | _MBOX_CHECK_Q (mbox, _get_message); |
356 | return MU_ERR_EMPTY_VFN; | ||
357 | if (mbox->flags & MU_STREAM_QACCESS) | ||
358 | return MU_ERR_BADOP; | ||
359 | return mbox->_get_message (mbox, msgno, pmsg); | 412 | return mbox->_get_message (mbox, msgno, pmsg); |
360 | } | 413 | } |
361 | 414 | ||
... | @@ -363,8 +416,7 @@ int | ... | @@ -363,8 +416,7 @@ int |
363 | mu_mailbox_quick_get_message (mu_mailbox_t mbox, mu_message_qid_t qid, | 416 | mu_mailbox_quick_get_message (mu_mailbox_t mbox, mu_message_qid_t qid, |
364 | mu_message_t *pmsg) | 417 | mu_message_t *pmsg) |
365 | { | 418 | { |
366 | if (mbox == NULL || mbox->_quick_get_message == NULL) | 419 | _MBOX_CHECK (mbox, _quick_get_message); |
367 | return MU_ERR_EMPTY_VFN; | ||
368 | if (!(mbox->flags & MU_STREAM_QACCESS)) | 420 | if (!(mbox->flags & MU_STREAM_QACCESS)) |
369 | return MU_ERR_BADOP; | 421 | return MU_ERR_BADOP; |
370 | return mbox->_quick_get_message (mbox, qid, pmsg); | 422 | return mbox->_quick_get_message (mbox, qid, pmsg); |
... | @@ -373,38 +425,28 @@ mu_mailbox_quick_get_message (mu_mailbox_t mbox, mu_message_qid_t qid, | ... | @@ -373,38 +425,28 @@ mu_mailbox_quick_get_message (mu_mailbox_t mbox, mu_message_qid_t qid, |
373 | int | 425 | int |
374 | mu_mailbox_messages_count (mu_mailbox_t mbox, size_t *num) | 426 | mu_mailbox_messages_count (mu_mailbox_t mbox, size_t *num) |
375 | { | 427 | { |
376 | if (mbox == NULL || mbox->_messages_count == NULL) | 428 | _MBOX_CHECK_Q (mbox, _messages_count); |
377 | return MU_ERR_EMPTY_VFN; | ||
378 | if (mbox->flags & MU_STREAM_QACCESS) | ||
379 | return MU_ERR_BADOP; | ||
380 | return mbox->_messages_count (mbox, num); | 429 | return mbox->_messages_count (mbox, num); |
381 | } | 430 | } |
382 | 431 | ||
383 | int | 432 | int |
384 | mu_mailbox_messages_recent (mu_mailbox_t mbox, size_t *num) | 433 | mu_mailbox_messages_recent (mu_mailbox_t mbox, size_t *num) |
385 | { | 434 | { |
386 | if (mbox == NULL || mbox->_messages_recent == NULL) | 435 | _MBOX_CHECK_Q (mbox, _messages_recent); |
387 | return MU_ERR_EMPTY_VFN; | ||
388 | if (mbox->flags & MU_STREAM_QACCESS) | ||
389 | return MU_ERR_BADOP; | ||
390 | return mbox->_messages_recent (mbox, num); | 436 | return mbox->_messages_recent (mbox, num); |
391 | } | 437 | } |
392 | 438 | ||
393 | int | 439 | int |
394 | mu_mailbox_message_unseen (mu_mailbox_t mbox, size_t *num) | 440 | mu_mailbox_message_unseen (mu_mailbox_t mbox, size_t *num) |
395 | { | 441 | { |
396 | if (mbox == NULL || mbox->_message_unseen == NULL) | 442 | _MBOX_CHECK_Q (mbox, _message_unseen); |
397 | return MU_ERR_EMPTY_VFN; | ||
398 | if (mbox->flags & MU_STREAM_QACCESS) | ||
399 | return MU_ERR_BADOP; | ||
400 | return mbox->_message_unseen (mbox, num); | 443 | return mbox->_message_unseen (mbox, num); |
401 | } | 444 | } |
402 | 445 | ||
403 | int | 446 | int |
404 | mu_mailbox_sync (mu_mailbox_t mbox) | 447 | mu_mailbox_sync (mu_mailbox_t mbox) |
405 | { | 448 | { |
406 | if (mbox == NULL || mbox->_sync == NULL) | 449 | _MBOX_CHECK_Q (mbox, _sync); |
407 | return MU_ERR_EMPTY_VFN; | ||
408 | if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND))) | 450 | if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND))) |
409 | return 0; | 451 | return 0; |
410 | return mbox->_sync (mbox); | 452 | return mbox->_sync (mbox); |
... | @@ -414,18 +456,13 @@ mu_mailbox_sync (mu_mailbox_t mbox) | ... | @@ -414,18 +456,13 @@ mu_mailbox_sync (mu_mailbox_t mbox) |
414 | int | 456 | int |
415 | mu_mailbox_save_attributes (mu_mailbox_t mbox) | 457 | mu_mailbox_save_attributes (mu_mailbox_t mbox) |
416 | { | 458 | { |
417 | if (mbox == NULL || mbox->_sync == NULL) | 459 | return mu_mailbox_sync (mbox); |
418 | return MU_ERR_EMPTY_VFN; | ||
419 | if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND))) | ||
420 | return EACCES; | ||
421 | return mbox->_sync (mbox); | ||
422 | } | 460 | } |
423 | 461 | ||
424 | int | 462 | int |
425 | mu_mailbox_expunge (mu_mailbox_t mbox) | 463 | mu_mailbox_expunge (mu_mailbox_t mbox) |
426 | { | 464 | { |
427 | if (mbox == NULL || mbox->_expunge == NULL) | 465 | _MBOX_CHECK_Q (mbox, _expunge); |
428 | return MU_ERR_EMPTY_VFN; | ||
429 | if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND))) | 466 | if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND))) |
430 | return EACCES; | 467 | return EACCES; |
431 | return mbox->_expunge (mbox); | 468 | return mbox->_expunge (mbox); |
... | @@ -434,7 +471,10 @@ mu_mailbox_expunge (mu_mailbox_t mbox) | ... | @@ -434,7 +471,10 @@ mu_mailbox_expunge (mu_mailbox_t mbox) |
434 | int | 471 | int |
435 | mu_mailbox_is_updated (mu_mailbox_t mbox) | 472 | mu_mailbox_is_updated (mu_mailbox_t mbox) |
436 | { | 473 | { |
437 | if (mbox == NULL || mbox->_is_updated == NULL) | 474 | if (mbox == NULL || |
475 | !(mbox->flags & _MU_MAILBOX_OPEN) || | ||
476 | (mbox->flags & _MU_MAILBOX_REMOVED) || | ||
477 | mbox->_is_updated == NULL) | ||
438 | return 1; | 478 | return 1; |
439 | if (mbox->flags & MU_STREAM_QACCESS) | 479 | if (mbox->flags & MU_STREAM_QACCESS) |
440 | return 1; | 480 | return 1; |
... | @@ -444,10 +484,7 @@ mu_mailbox_is_updated (mu_mailbox_t mbox) | ... | @@ -444,10 +484,7 @@ mu_mailbox_is_updated (mu_mailbox_t mbox) |
444 | int | 484 | int |
445 | mu_mailbox_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount) | 485 | mu_mailbox_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount) |
446 | { | 486 | { |
447 | if (mbox == NULL || mbox->_scan == NULL) | 487 | _MBOX_CHECK_Q (mbox, _scan); |
448 | return MU_ERR_EMPTY_VFN; | ||
449 | if (mbox->flags & MU_STREAM_QACCESS) | ||
450 | return MU_ERR_BADOP; | ||
451 | return mbox->_scan (mbox, msgno, pcount); | 488 | return mbox->_scan (mbox, msgno, pcount); |
452 | } | 489 | } |
453 | 490 | ||
... | @@ -455,8 +492,8 @@ int | ... | @@ -455,8 +492,8 @@ int |
455 | mu_mailbox_get_size (mu_mailbox_t mbox, mu_off_t *psize) | 492 | mu_mailbox_get_size (mu_mailbox_t mbox, mu_off_t *psize) |
456 | { | 493 | { |
457 | int status; | 494 | int status; |
458 | if (mbox == NULL) | 495 | |
459 | return MU_ERR_EMPTY_VFN; | 496 | _MBOX_CHECK_FLAGS (mbox); |
460 | if (mbox->flags & MU_STREAM_QACCESS) | 497 | if (mbox->flags & MU_STREAM_QACCESS) |
461 | return MU_ERR_BADOP; | 498 | return MU_ERR_BADOP; |
462 | if (mbox->_get_size == NULL | 499 | if (mbox->_get_size == NULL |
... | @@ -489,20 +526,14 @@ mu_mailbox_get_size (mu_mailbox_t mbox, mu_off_t *psize) | ... | @@ -489,20 +526,14 @@ mu_mailbox_get_size (mu_mailbox_t mbox, mu_off_t *psize) |
489 | int | 526 | int |
490 | mu_mailbox_uidvalidity (mu_mailbox_t mbox, unsigned long *pvalid) | 527 | mu_mailbox_uidvalidity (mu_mailbox_t mbox, unsigned long *pvalid) |
491 | { | 528 | { |
492 | if (mbox == NULL || mbox->_uidvalidity == NULL) | 529 | _MBOX_CHECK_Q (mbox, _uidvalidity); |
493 | return MU_ERR_EMPTY_VFN; | ||
494 | if (mbox->flags & MU_STREAM_QACCESS) | ||
495 | return MU_ERR_BADOP; | ||
496 | return mbox->_uidvalidity (mbox, pvalid); | 530 | return mbox->_uidvalidity (mbox, pvalid); |
497 | } | 531 | } |
498 | 532 | ||
499 | int | 533 | int |
500 | mu_mailbox_uidnext (mu_mailbox_t mbox, size_t *puidnext) | 534 | mu_mailbox_uidnext (mu_mailbox_t mbox, size_t *puidnext) |
501 | { | 535 | { |
502 | if (mbox == NULL || mbox->_uidnext == NULL) | 536 | _MBOX_CHECK_Q (mbox, _uidnext); |
503 | return MU_ERR_EMPTY_VFN; | ||
504 | if (mbox->flags & MU_STREAM_QACCESS) | ||
505 | return MU_ERR_BADOP; | ||
506 | return mbox->_uidnext (mbox, puidnext); | 537 | return mbox->_uidnext (mbox, puidnext); |
507 | } | 538 | } |
508 | 539 | ||
... | @@ -536,7 +567,7 @@ mu_mailbox_get_flags (mu_mailbox_t mbox, int *flags) | ... | @@ -536,7 +567,7 @@ mu_mailbox_get_flags (mu_mailbox_t mbox, int *flags) |
536 | return MU_ERR_MBX_NULL; | 567 | return MU_ERR_MBX_NULL; |
537 | if (!*flags) | 568 | if (!*flags) |
538 | return MU_ERR_OUT_NULL; | 569 | return MU_ERR_OUT_NULL; |
539 | *flags = mbox->flags; | 570 | *flags = mbox->flags & ~_MU_MAILBOX_MASK; |
540 | return 0; | 571 | return 0; |
541 | } | 572 | } |
542 | 573 | ... | ... |
... | @@ -47,6 +47,7 @@ noinst_PROGRAMS = \ | ... | @@ -47,6 +47,7 @@ noinst_PROGRAMS = \ |
47 | fltst\ | 47 | fltst\ |
48 | listop\ | 48 | listop\ |
49 | mailcap\ | 49 | mailcap\ |
50 | mbdel\ | ||
50 | mimetest\ | 51 | mimetest\ |
51 | url-parse | 52 | url-parse |
52 | 53 | ||
... | @@ -55,6 +56,10 @@ LDADD =\ | ... | @@ -55,6 +56,10 @@ LDADD =\ |
55 | ${MU_LIB_MBOX}\ | 56 | ${MU_LIB_MBOX}\ |
56 | ${MU_LIB_IMAP}\ | 57 | ${MU_LIB_IMAP}\ |
57 | ${MU_LIB_POP}\ | 58 | ${MU_LIB_POP}\ |
59 | ${MU_LIB_NNTP}\ | ||
60 | ${MU_LIB_MH}\ | ||
61 | ${MU_LIB_MAILDIR}\ | ||
62 | ${MU_LIB_MAILER}\ | ||
58 | ${MU_LIB_AUTH}\ | 63 | ${MU_LIB_AUTH}\ |
59 | @MU_AUTHLIBS@\ | 64 | @MU_AUTHLIBS@\ |
60 | ${MU_LIB_MAILUTILS} | 65 | ${MU_LIB_MAILUTILS} | ... | ... |
libmailutils/tests/mbdel.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2010 Free Software Foundation, Inc. | ||
3 | |||
4 | GNU Mailutils 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 3, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | GNU Mailutils 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, see <http://www.gnu.org/licenses/>. */ | ||
16 | |||
17 | #ifdef HAVE_CONFIG_H | ||
18 | # include <config.h> | ||
19 | #endif | ||
20 | #include <unistd.h> | ||
21 | #include <stdio.h> | ||
22 | #include <stdlib.h> | ||
23 | #include <mailutils/mailutils.h> | ||
24 | |||
25 | int | ||
26 | main (int argc, char **argv) | ||
27 | { | ||
28 | int rc; | ||
29 | mu_mailbox_t mbox; | ||
30 | |||
31 | if (argc != 2) | ||
32 | { | ||
33 | fprintf (stderr, "usage: %s URL\n", argv[0]); | ||
34 | return 1; | ||
35 | } | ||
36 | |||
37 | mu_register_all_mbox_formats (); | ||
38 | |||
39 | MU_ASSERT (mu_mailbox_create (&mbox, argv[1])); | ||
40 | rc = mu_mailbox_remove (mbox); | ||
41 | if (rc) | ||
42 | { | ||
43 | if (rc == ENOTEMPTY) | ||
44 | { | ||
45 | printf ("mailbox removed, but has subfolders\n"); | ||
46 | rc = 0; | ||
47 | } | ||
48 | else | ||
49 | fprintf (stderr, "%s\n", mu_strerror (rc)); | ||
50 | } | ||
51 | mu_mailbox_destroy (&mbox); | ||
52 | |||
53 | return rc != 0; | ||
54 | } |
... | @@ -765,6 +765,28 @@ maildir_qfetch (struct _amd_data *amd, mu_message_qid_t qid) | ... | @@ -765,6 +765,28 @@ maildir_qfetch (struct _amd_data *amd, mu_message_qid_t qid) |
765 | return 0; | 765 | return 0; |
766 | } | 766 | } |
767 | 767 | ||
768 | |||
769 | static int | ||
770 | maildir_remove (struct _amd_data *amd) | ||
771 | { | ||
772 | int i; | ||
773 | static char *suf[3] = { NEWSUF, CURSUF, TMPSUF }; | ||
774 | int rc = 0; | ||
775 | |||
776 | for (i = 0; rc == 0 && i < 3; i++) | ||
777 | { | ||
778 | char *name = maildir_mkfilename (amd->name, suf[i], NULL); | ||
779 | rc = amd_remove_dir (name); | ||
780 | if (rc) | ||
781 | mu_diag_output (MU_DIAG_WARNING, | ||
782 | "removing contents of %s failed: %s", name, | ||
783 | mu_strerror (rc)); | ||
784 | free (name); | ||
785 | } | ||
786 | |||
787 | return rc; | ||
788 | } | ||
789 | |||
768 | 790 | ||
769 | int | 791 | int |
770 | _mailbox_maildir_init (mu_mailbox_t mailbox) | 792 | _mailbox_maildir_init (mu_mailbox_t mailbox) |
... | @@ -788,6 +810,7 @@ _mailbox_maildir_init (mu_mailbox_t mailbox) | ... | @@ -788,6 +810,7 @@ _mailbox_maildir_init (mu_mailbox_t mailbox) |
788 | amd->msg_cmp = maildir_message_cmp; | 810 | amd->msg_cmp = maildir_message_cmp; |
789 | amd->message_uid = maildir_message_uid; | 811 | amd->message_uid = maildir_message_uid; |
790 | amd->next_uid = maildir_next_uid; | 812 | amd->next_uid = maildir_next_uid; |
813 | amd->remove = maildir_remove; | ||
791 | 814 | ||
792 | /* Set our properties. */ | 815 | /* Set our properties. */ |
793 | { | 816 | { | ... | ... |
... | @@ -174,6 +174,16 @@ mbox_close (mu_mailbox_t mailbox) | ... | @@ -174,6 +174,16 @@ mbox_close (mu_mailbox_t mailbox) |
174 | return mu_stream_close (mailbox->stream); | 174 | return mu_stream_close (mailbox->stream); |
175 | } | 175 | } |
176 | 176 | ||
177 | static int | ||
178 | mbox_remove (mu_mailbox_t mailbox) | ||
179 | { | ||
180 | mbox_data_t mud = mailbox->data; | ||
181 | |||
182 | MU_DEBUG1 (mailbox->debug, MU_DEBUG_TRACE1, | ||
183 | "mbox_remove (%s)\n", mud->name); | ||
184 | return unlink (mud->name); | ||
185 | } | ||
186 | |||
177 | /* Cover function that calls the real thing, mbox_scan(), with | 187 | /* Cover function that calls the real thing, mbox_scan(), with |
178 | notification set. */ | 188 | notification set. */ |
179 | static int | 189 | static int |
... | @@ -1479,7 +1489,8 @@ _mailbox_mbox_init (mu_mailbox_t mailbox) | ... | @@ -1479,7 +1489,8 @@ _mailbox_mbox_init (mu_mailbox_t mailbox) |
1479 | 1489 | ||
1480 | mailbox->_open = mbox_open; | 1490 | mailbox->_open = mbox_open; |
1481 | mailbox->_close = mbox_close; | 1491 | mailbox->_close = mbox_close; |
1482 | 1492 | mailbox->_remove = mbox_remove; | |
1493 | |||
1483 | /* Overloading of the entire mailbox object methods. */ | 1494 | /* Overloading of the entire mailbox object methods. */ |
1484 | mailbox->_get_message = mbox_get_message; | 1495 | mailbox->_get_message = mbox_get_message; |
1485 | mailbox->_append_message = mbox_append_message; | 1496 | mailbox->_append_message = mbox_append_message; | ... | ... |
... | @@ -353,6 +353,13 @@ _mh_msg_init (struct _amd_data *amd, struct _amd_message *amm) | ... | @@ -353,6 +353,13 @@ _mh_msg_init (struct _amd_data *amd, struct _amd_message *amm) |
353 | } | 353 | } |
354 | 354 | ||
355 | 355 | ||
356 | static int | ||
357 | mh_remove (struct _amd_data *amd) | ||
358 | { | ||
359 | return amd_remove_dir (amd->name); | ||
360 | } | ||
361 | |||
362 | |||
356 | 363 | ||
357 | int | 364 | int |
358 | _mailbox_mh_init (mu_mailbox_t mailbox) | 365 | _mailbox_mh_init (mu_mailbox_t mailbox) |
... | @@ -375,7 +382,8 @@ _mailbox_mh_init (mu_mailbox_t mailbox) | ... | @@ -375,7 +382,8 @@ _mailbox_mh_init (mu_mailbox_t mailbox) |
375 | amd->msg_cmp = mh_message_cmp; | 382 | amd->msg_cmp = mh_message_cmp; |
376 | amd->message_uid = mh_message_uid; | 383 | amd->message_uid = mh_message_uid; |
377 | amd->next_uid = _mh_next_seq; | 384 | amd->next_uid = _mh_next_seq; |
378 | 385 | amd->remove = mh_remove; | |
386 | |||
379 | /* Set our properties. */ | 387 | /* Set our properties. */ |
380 | { | 388 | { |
381 | mu_property_t property = NULL; | 389 | mu_property_t property = NULL; | ... | ... |
-
Please register or sign in to post a comment