summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-09-17 12:27:52 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-09-17 12:27:52 +0300
commita70b48462860546915aa3f71d0fb16b871ef2f62 (patch)
tree40716353a4b13f090ddda30a87d03b333fd3525f
parent23321cf7f5561b96d8bf970da217c8968e0175c8 (diff)
downloadmailutils-a70b48462860546915aa3f71d0fb16b871ef2f62.tar.gz
mailutils-a70b48462860546915aa3f71d0fb16b871ef2f62.tar.bz2
Implement `remove' method for mailboxes: port commit 756eb2bcfb781350 from HEAD.
-rw-r--r--imap4d/delete.c20
-rw-r--r--include/mailutils/mailbox.h1
-rw-r--r--libproto/include/amd.h2
-rw-r--r--libproto/include/mailbox0.h1
-rw-r--r--libproto/maildir/mbox.c23
-rw-r--r--libproto/mbox/mbox.c14
-rw-r--r--libproto/mh/mbox.c10
-rw-r--r--mailbox/amd.c115
-rw-r--r--mailbox/errors4
-rw-r--r--mailbox/mailbox.c129
10 files changed, 265 insertions, 54 deletions
diff --git a/imap4d/delete.c b/imap4d/delete.c
index b6f4f9045..74fe13c27 100644
--- a/imap4d/delete.c
+++ b/imap4d/delete.c
@@ -37,7 +37,8 @@ imap4d_delete (struct imap4d_command *command, imap4d_tokbuf_t tok)
const char *msg = "Completed";
const char *delim = "/";
char *name;
-
+ mu_mailbox_t tmpbox;
+
if (imap4d_tokbuf_argc (tok) != 3)
return util_finish (command, RESP_BAD, "Invalid arguments");
name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1);
@@ -54,7 +55,22 @@ imap4d_delete (struct imap4d_command *command, imap4d_tokbuf_t tok)
if (!name)
return util_finish (command, RESP_NO, "Cannot remove");
- if (remove (name) != 0)
+ rc = mu_mailbox_create (&tmpbox, name);
+ if (rc == 0)
+ {
+ rc = mu_mailbox_remove (tmpbox);
+ mu_mailbox_destroy (&tmpbox);
+ if (rc)
+ mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_remove", name, rc);
+ }
+ else
+ {
+ rc = remove (name);
+ if (rc)
+ mu_diag_funcall (MU_DIAG_ERROR, "remove", name, errno);
+ }
+
+ if (rc)
{
rc = RESP_NO;
msg = "Cannot remove";
diff --git a/include/mailutils/mailbox.h b/include/mailutils/mailbox.h
index b8567a9a1..7efe50813 100644
--- a/include/mailutils/mailbox.h
+++ b/include/mailutils/mailbox.h
@@ -49,6 +49,7 @@ extern void mu_mailbox_destroy (mu_mailbox_t *);
extern int mu_mailbox_open (mu_mailbox_t, int flag);
extern int mu_mailbox_close (mu_mailbox_t);
+extern int mu_mailbox_remove (mu_mailbox_t mbox);
extern int mu_mailbox_flush (mu_mailbox_t mbox, int expunge);
extern int mu_mailbox_get_folder (mu_mailbox_t, mu_folder_t *);
extern int mu_mailbox_set_folder (mu_mailbox_t, mu_folder_t);
diff --git a/libproto/include/amd.h b/libproto/include/amd.h
index f6434531c..dca96d3e3 100644
--- a/libproto/include/amd.h
+++ b/libproto/include/amd.h
@@ -80,6 +80,7 @@ struct _amd_data
int (*msg_cmp) (struct _amd_message *, struct _amd_message *);
int (*message_uid) (mu_message_t msg, size_t *puid);
size_t (*next_uid) (struct _amd_data *mhd);
+ int (*remove) (struct _amd_data *);
/* List of messages: */
size_t msg_count; /* number of messages in the list */
@@ -110,3 +111,4 @@ void amd_cleanup (void *arg);
struct _amd_message *_amd_get_message (struct _amd_data *amd, size_t msgno);
int amd_msg_lookup (struct _amd_data *amd, struct _amd_message *msg,
size_t *pret);
+int amd_remove_dir (const char *name);
diff --git a/libproto/include/mailbox0.h b/libproto/include/mailbox0.h
index a052e43ab..11f57a66c 100644
--- a/libproto/include/mailbox0.h
+++ b/libproto/include/mailbox0.h
@@ -58,6 +58,7 @@ struct _mu_mailbox
int (*_open) (mu_mailbox_t, int);
int (*_close) (mu_mailbox_t);
+ int (*_remove) (mu_mailbox_t);
/* messages */
int (*_get_message) (mu_mailbox_t, size_t, mu_message_t *);
diff --git a/libproto/maildir/mbox.c b/libproto/maildir/mbox.c
index c9d74708e..c3df63909 100644
--- a/libproto/maildir/mbox.c
+++ b/libproto/maildir/mbox.c
@@ -765,6 +765,28 @@ maildir_qfetch (struct _amd_data *amd, mu_message_qid_t qid)
return 0;
}
+
+static int
+maildir_remove (struct _amd_data *amd)
+{
+ int i;
+ static char *suf[3] = { NEWSUF, CURSUF, TMPSUF };
+ int rc = 0;
+
+ for (i = 0; rc == 0 && i < 3; i++)
+ {
+ char *name = maildir_mkfilename (amd->name, suf[i], NULL);
+ rc = amd_remove_dir (name);
+ if (rc)
+ mu_diag_output (MU_DIAG_WARNING,
+ "removing contents of %s failed: %s", name,
+ mu_strerror (rc));
+ free (name);
+ }
+
+ return rc;
+}
+
int
_mailbox_maildir_init (mu_mailbox_t mailbox)
@@ -788,6 +810,7 @@ _mailbox_maildir_init (mu_mailbox_t mailbox)
amd->msg_cmp = maildir_message_cmp;
amd->message_uid = maildir_message_uid;
amd->next_uid = maildir_next_uid;
+ amd->remove = maildir_remove;
/* Set our properties. */
{
diff --git a/libproto/mbox/mbox.c b/libproto/mbox/mbox.c
index 826098d04..3c9908f8b 100644
--- a/libproto/mbox/mbox.c
+++ b/libproto/mbox/mbox.c
@@ -84,6 +84,7 @@ static int mbox_envelope_sender (mu_envelope_t, char *, size_t,
static int mbox_envelope_date (mu_envelope_t, char *, size_t,
size_t *);
static int mbox_tmpfile (mu_mailbox_t, char **pbox);
+static int mbox_remove (mu_mailbox_t mailbox);
/* Allocate the mbox_data_t struct(concrete mailbox), but don't do any
parsing on the name or even test for existence. However we do strip any
@@ -129,7 +130,8 @@ _mailbox_mbox_init (mu_mailbox_t mailbox)
mailbox->_open = mbox_open;
mailbox->_close = mbox_close;
-
+ mailbox->_remove = mbox_remove;
+
/* Overloading of the entire mailbox object methods. */
mailbox->_get_message = mbox_get_message;
mailbox->_append_message = mbox_append_message;
@@ -299,6 +301,16 @@ mbox_close (mu_mailbox_t mailbox)
return mu_stream_close (mailbox->stream);
}
+static int
+mbox_remove (mu_mailbox_t mailbox)
+{
+ mbox_data_t mud = mailbox->data;
+
+ MU_DEBUG1 (mailbox->debug, MU_DEBUG_TRACE1,
+ "mbox_remove (%s)\n", mud->name);
+ return unlink (mud->name) == 0 ? 0 : errno;
+}
+
/* Cover function that call the real thing, mbox_scan(), with
notification set. */
static int
diff --git a/libproto/mh/mbox.c b/libproto/mh/mbox.c
index da7da4d99..707f63b49 100644
--- a/libproto/mh/mbox.c
+++ b/libproto/mh/mbox.c
@@ -353,6 +353,13 @@ _mh_msg_init (struct _amd_data *amd, struct _amd_message *amm)
}
+static int
+mh_remove (struct _amd_data *amd)
+{
+ return amd_remove_dir (amd->name);
+}
+
+
int
_mailbox_mh_init (mu_mailbox_t mailbox)
@@ -375,7 +382,8 @@ _mailbox_mh_init (mu_mailbox_t mailbox)
amd->msg_cmp = mh_message_cmp;
amd->message_uid = mh_message_uid;
amd->next_uid = _mh_next_seq;
-
+ amd->remove = mh_remove;
+
/* Set our properties. */
{
mu_property_t property = NULL;
diff --git a/mailbox/amd.c b/mailbox/amd.c
index b5fdab398..7d82e4c18 100644
--- a/mailbox/amd.c
+++ b/mailbox/amd.c
@@ -116,6 +116,7 @@ static int amd_envelope_date (mu_envelope_t envelope, char *buf, size_t len,
size_t *psize);
static int amd_envelope_sender (mu_envelope_t envelope, char *buf, size_t len,
size_t *psize);
+static int amd_remove_mbox (mu_mailbox_t mailbox);
/* Operations on message array */
@@ -293,7 +294,8 @@ amd_init_mailbox (mu_mailbox_t mailbox, size_t amd_size,
mailbox->_is_updated = amd_is_updated;
mailbox->_get_size = amd_get_size;
-
+ mailbox->_remove = amd_remove_mbox;
+
MU_DEBUG1 (mailbox->debug, MU_DEBUG_TRACE1, "amd_init(%s)\n", amd->name);
*pamd = amd;
return 0;
@@ -1060,6 +1062,40 @@ compute_mailbox_size (struct _amd_data *amd, const char *name, mu_off_t *psize)
}
static int
+amd_remove_mbox (mu_mailbox_t mailbox)
+{
+ int rc;
+ struct _amd_data *amd = mailbox->data;
+
+ if (!amd->remove)
+ return ENOSYS;
+ rc = amd->remove (amd);
+ if (rc == 0)
+ {
+ char *name = make_size_file_name (amd);
+ if (!name)
+ return ENOMEM;
+ if (unlink (name) && errno != ENOENT)
+ rc = errno;
+ free (name);
+ }
+
+ if (rc == 0)
+ {
+ if (rmdir (amd->name) && errno != ENOENT)
+ {
+ rc = errno;
+ /* POSIX.1-2001 allows EEXIST to be returned if the directory
+ contained entries other than . and .. */
+ if (rc == EEXIST)
+ rc = ENOTEMPTY;
+ }
+ }
+
+ return rc;
+}
+
+static int
amd_expunge (mu_mailbox_t mailbox)
{
struct _amd_data *amd = mailbox->data;
@@ -1791,4 +1827,81 @@ amd_envelope_sender (mu_envelope_t envelope, char *buf, size_t len, size_t *psiz
return 0;
}
+
+int
+amd_remove_dir (const char *name)
+{
+ DIR *dir;
+ struct dirent *ent;
+ char *namebuf;
+ size_t namelen, namesize;
+ int rc = 0;
+ int has_subdirs = 0;
+
+ namelen = strlen (name);
+ namesize = namelen + 128;
+ namebuf = malloc (namesize);
+ if (!namebuf)
+ return ENOMEM;
+ memcpy (namebuf, name, namelen);
+ if (namebuf[namelen - 1] != '/')
+ namebuf[namelen++] = '/';
+
+ dir = opendir (name);
+ if (!dir)
+ return errno;
+ while ((ent = readdir (dir)))
+ {
+ struct stat st;
+ size_t len;
+
+ if (strcmp (ent->d_name, ".") == 0 ||
+ strcmp (ent->d_name, "..") == 0)
+ continue;
+ len = strlen (ent->d_name);
+ if (namelen + len >= namesize)
+ {
+ char *p;
+
+ namesize += len + 1;
+ p = realloc (namebuf, namesize);
+ if (!p)
+ {
+ rc = ENOMEM;
+ break;
+ }
+ }
+ strcpy (namebuf + namelen, ent->d_name);
+ if (stat (namebuf, &st) == 0 && S_ISDIR (st.st_mode))
+ {
+ has_subdirs = 1;
+ continue;
+ }
+
+ if (unlink (namebuf))
+ {
+ rc = errno;
+ mu_diag_output (MU_DIAG_WARNING,
+ "failed to remove %s: %s",
+ namebuf, mu_strerror (rc));
+ break;
+ }
+ }
+ closedir (dir);
+ free (namebuf);
+
+ if (rc == 0 && !has_subdirs)
+ {
+ if (rmdir (name))
+ {
+ rc = errno;
+ /* POSIX.1-2001 allows EEXIST to be returned if the directory
+ contained entries other than . and .. */
+ if (rc == EEXIST)
+ rc = ENOTEMPTY;
+ }
+ }
+ return rc;
+}
+
diff --git a/mailbox/errors b/mailbox/errors
index 49910eee7..59f416ae1 100644
--- a/mailbox/errors
+++ b/mailbox/errors
@@ -26,6 +26,10 @@ MU_ERR_OUT_NULL _("Pointer to output null")
MU_ERR_OUT_PTR_NULL _("Pointer to output pointer null")
MU_ERR_MBX_NULL _("Mailbox null")
+MU_ERR_MBX_REMOVED _("Mailbox removed")
+
+MU_ERR_NOT_OPEN _("Resource not open")
+MU_ERR_OPEN _("Resource still open")
MU_ERR_BAD_822_FORMAT _("Format of RFC822 object is bad")
MU_ERR_EMPTY_ADDRESS _("Address contains no addr specs")
diff --git a/mailbox/mailbox.c b/mailbox/mailbox.c
index 917c5806b..fc908d8ca 100644
--- a/mailbox/mailbox.c
+++ b/mailbox/mailbox.c
@@ -44,6 +44,11 @@
#include <mailbox0.h>
#include <url0.h>
+/* Mailbox-specific flags */
+#define _MU_MAILBOX_OPEN 0x10000000
+#define _MU_MAILBOX_REMOVED 0x20000000
+#define _MU_MAILBOX_MASK 0xF0000000
+
static int
mailbox_folder_create (mu_mailbox_t mbox, const char *name,
mu_record_t record)
@@ -287,7 +292,11 @@ mu_mailbox_destroy (mu_mailbox_t *pmbox)
int
mu_mailbox_open (mu_mailbox_t mbox, int flag)
{
- if (mbox == NULL || mbox->_open == NULL)
+ int rc;
+
+ if (!mbox)
+ return MU_ERR_MBX_NULL;
+ if (mbox->_open == NULL)
return MU_ERR_EMPTY_VFN;
if (flag & MU_STREAM_QACCESS)
{
@@ -296,16 +305,42 @@ mu_mailbox_open (mu_mailbox_t mbox, int flag)
| MU_STREAM_APPEND | MU_STREAM_CREAT))
return EINVAL; /* FIXME: Better error code, please? */
}
- return mbox->_open (mbox, flag);
+ rc = mbox->_open (mbox, flag);
+ if (rc == 0)
+ mbox->flags |= _MU_MAILBOX_OPEN;
+ return rc;
}
int
mu_mailbox_close (mu_mailbox_t mbox)
{
+ int rc;
+
+ if (!mbox)
+ return MU_ERR_MBX_NULL;
+ if (!(mbox->flags & _MU_MAILBOX_OPEN))
+ return MU_ERR_NOT_OPEN;
if (mbox == NULL || mbox->_close == NULL)
return MU_ERR_EMPTY_VFN;
- return mbox->_close (mbox);
+ rc = mbox->_close (mbox);
+ if (rc == 0)
+ mbox->flags &= ~_MU_MAILBOX_OPEN;
+ return rc;
+}
+
+int
+mu_mailbox_remove (mu_mailbox_t mbox)
+{
+ if (!mbox)
+ return MU_ERR_MBX_NULL;
+ if (mbox->flags & _MU_MAILBOX_OPEN)
+ return MU_ERR_OPEN;
+ if (mbox->flags & _MU_MAILBOX_REMOVED)
+ return MU_ERR_MBX_REMOVED;
+ if (!mbox->_remove)
+ return MU_ERR_EMPTY_VFN;
+ return mbox->_remove (mbox);
}
int
@@ -315,7 +350,11 @@ mu_mailbox_flush (mu_mailbox_t mbox, int expunge)
int status = 0;
if (!mbox)
- return EINVAL;
+ return MU_ERR_MBX_NULL;
+ if (mbox->flags & _MU_MAILBOX_REMOVED)
+ return MU_ERR_MBX_REMOVED;
+ if (!(mbox->flags & _MU_MAILBOX_OPEN))
+ return _MU_MAILBOX_OPEN;
if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND)))
return 0;
@@ -338,12 +377,29 @@ mu_mailbox_flush (mu_mailbox_t mbox, int expunge)
return status;
}
+#define _MBOX_CHECK_FLAGS(mbox) \
+ if (mbox == NULL) \
+ return MU_ERR_MBX_NULL; \
+ if (mbox->flags & _MU_MAILBOX_REMOVED) \
+ return MU_ERR_MBX_REMOVED; \
+ if (!(mbox->flags & _MU_MAILBOX_OPEN)) \
+ return _MU_MAILBOX_OPEN
+
+#define _MBOX_CHECK(mbox,method) \
+ _MBOX_CHECK_FLAGS(mbox); \
+ if (mbox->method == NULL) \
+ return MU_ERR_EMPTY_VFN
+
+#define _MBOX_CHECK_Q(mbox,method) \
+ _MBOX_CHECK(mbox,method); \
+ if (mbox->flags & MU_STREAM_QACCESS) \
+ return MU_ERR_BADOP
+
/* messages */
int
mu_mailbox_append_message (mu_mailbox_t mbox, mu_message_t msg)
{
- if (mbox == NULL || mbox->_append_message == NULL)
- return MU_ERR_EMPTY_VFN;
+ _MBOX_CHECK_Q (mbox, _append_message);
if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND)))
return EACCES;
return mbox->_append_message (mbox, msg);
@@ -352,10 +408,7 @@ mu_mailbox_append_message (mu_mailbox_t mbox, mu_message_t msg)
int
mu_mailbox_get_message (mu_mailbox_t mbox, size_t msgno, mu_message_t *pmsg)
{
- if (mbox == NULL || mbox->_get_message == NULL)
- return MU_ERR_EMPTY_VFN;
- if (mbox->flags & MU_STREAM_QACCESS)
- return MU_ERR_BADOP;
+ _MBOX_CHECK_Q (mbox, _get_message);
return mbox->_get_message (mbox, msgno, pmsg);
}
@@ -363,8 +416,7 @@ int
mu_mailbox_quick_get_message (mu_mailbox_t mbox, mu_message_qid_t qid,
mu_message_t *pmsg)
{
- if (mbox == NULL || mbox->_quick_get_message == NULL)
- return MU_ERR_EMPTY_VFN;
+ _MBOX_CHECK (mbox, _quick_get_message);
if (!(mbox->flags & MU_STREAM_QACCESS))
return MU_ERR_BADOP;
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,
int
mu_mailbox_messages_count (mu_mailbox_t mbox, size_t *num)
{
- if (mbox == NULL || mbox->_messages_count == NULL)
- return MU_ERR_EMPTY_VFN;
- if (mbox->flags & MU_STREAM_QACCESS)
- return MU_ERR_BADOP;
+ _MBOX_CHECK_Q (mbox, _messages_count);
return mbox->_messages_count (mbox, num);
}
int
mu_mailbox_messages_recent (mu_mailbox_t mbox, size_t *num)
{
- if (mbox == NULL || mbox->_messages_recent == NULL)
- return MU_ERR_EMPTY_VFN;
- if (mbox->flags & MU_STREAM_QACCESS)
- return MU_ERR_BADOP;
+ _MBOX_CHECK_Q (mbox, _messages_recent);
return mbox->_messages_recent (mbox, num);
}
int
mu_mailbox_message_unseen (mu_mailbox_t mbox, size_t *num)
{
- if (mbox == NULL || mbox->_message_unseen == NULL)
- return MU_ERR_EMPTY_VFN;
- if (mbox->flags & MU_STREAM_QACCESS)
- return MU_ERR_BADOP;
+ _MBOX_CHECK_Q (mbox, _message_unseen);
return mbox->_message_unseen (mbox, num);
}
int
mu_mailbox_sync (mu_mailbox_t mbox)
{
- if (mbox == NULL || mbox->_sync == NULL)
- return MU_ERR_EMPTY_VFN;
+ _MBOX_CHECK_Q (mbox, _sync);
if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND)))
return 0;
return mbox->_sync (mbox);
@@ -414,18 +456,13 @@ mu_mailbox_sync (mu_mailbox_t mbox)
int
mu_mailbox_save_attributes (mu_mailbox_t mbox)
{
- if (mbox == NULL || mbox->_sync == NULL)
- return MU_ERR_EMPTY_VFN;
- if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND)))
- return EACCES;
- return mbox->_sync (mbox);
+ return mu_mailbox_sync (mbox);
}
int
mu_mailbox_expunge (mu_mailbox_t mbox)
{
- if (mbox == NULL || mbox->_expunge == NULL)
- return MU_ERR_EMPTY_VFN;
+ _MBOX_CHECK_Q (mbox, _expunge);
if (!(mbox->flags & (MU_STREAM_RDWR|MU_STREAM_WRITE|MU_STREAM_APPEND)))
return EACCES;
return mbox->_expunge (mbox);
@@ -434,7 +471,10 @@ mu_mailbox_expunge (mu_mailbox_t mbox)
int
mu_mailbox_is_updated (mu_mailbox_t mbox)
{
- if (mbox == NULL || mbox->_is_updated == NULL)
+ if (mbox == NULL ||
+ !(mbox->flags & _MU_MAILBOX_OPEN) ||
+ (mbox->flags & _MU_MAILBOX_REMOVED) ||
+ mbox->_is_updated == NULL)
return 1;
if (mbox->flags & MU_STREAM_QACCESS)
return 1;
@@ -444,10 +484,7 @@ mu_mailbox_is_updated (mu_mailbox_t mbox)
int
mu_mailbox_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount)
{
- if (mbox == NULL || mbox->_scan == NULL)
- return MU_ERR_EMPTY_VFN;
- if (mbox->flags & MU_STREAM_QACCESS)
- return MU_ERR_BADOP;
+ _MBOX_CHECK_Q (mbox, _scan);
return mbox->_scan (mbox, msgno, pcount);
}
@@ -455,8 +492,8 @@ int
mu_mailbox_get_size (mu_mailbox_t mbox, mu_off_t *psize)
{
int status;
- if (mbox == NULL)
- return MU_ERR_EMPTY_VFN;
+
+ _MBOX_CHECK_FLAGS (mbox);
if (mbox->flags & MU_STREAM_QACCESS)
return MU_ERR_BADOP;
if (mbox->_get_size == NULL
@@ -489,20 +526,14 @@ mu_mailbox_get_size (mu_mailbox_t mbox, mu_off_t *psize)
int
mu_mailbox_uidvalidity (mu_mailbox_t mbox, unsigned long *pvalid)
{
- if (mbox == NULL || mbox->_uidvalidity == NULL)
- return MU_ERR_EMPTY_VFN;
- if (mbox->flags & MU_STREAM_QACCESS)
- return MU_ERR_BADOP;
+ _MBOX_CHECK_Q (mbox, _uidvalidity);
return mbox->_uidvalidity (mbox, pvalid);
}
int
mu_mailbox_uidnext (mu_mailbox_t mbox, size_t *puidnext)
{
- if (mbox == NULL || mbox->_uidnext == NULL)
- return MU_ERR_EMPTY_VFN;
- if (mbox->flags & MU_STREAM_QACCESS)
- return MU_ERR_BADOP;
+ _MBOX_CHECK_Q (mbox, _uidnext);
return mbox->_uidnext (mbox, puidnext);
}
@@ -536,7 +567,7 @@ mu_mailbox_get_flags (mu_mailbox_t mbox, int *flags)
return MU_ERR_MBX_NULL;
if (!*flags)
return MU_ERR_OUT_NULL;
- *flags = mbox->flags;
+ *flags = mbox->flags & ~_MU_MAILBOX_MASK;
return 0;
}

Return to:

Send suggestions and report system problems to the System administrator.