Commit 756eb2bc 756eb2bcfb781350f70e77d2e41fa8ae6e692cdd by Sergey Poznyakoff

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.
1 parent ec989a56
...@@ -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
......
...@@ -11,5 +11,6 @@ encode2047 ...@@ -11,5 +11,6 @@ encode2047
11 fltst 11 fltst
12 listop 12 listop
13 mailcap 13 mailcap
14 mbdel
14 mimetest 15 mimetest
15 url-parse 16 url-parse
......
...@@ -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}
......
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;
......