/* This file is part of Mailfromd. -*- c -*-
Copyright (C) 2008 Sergey Poznyakoff
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see . */
#include "msg.h"
static int
do_close(void *item, void *data)
{
bi_close_message(item);
return 0;
}
static void
close_mbox(struct mf_mbox *mp)
{
if (mp->mbox) {
mu_mailbox_close(mp->mbox);
mu_mailbox_destroy(&mp->mbox);
mu_list_do(mp->msglist, do_close, NULL);
mu_list_destroy(&mp->msglist);
memset(mp, 0, sizeof mp[0]);
}
}
static void *
alloc_mboxes()
{
return xcalloc(NMBOXES, sizeof(struct mf_mbox));
}
static void
destroy_mboxes(void *data)
{
struct mf_mbox *mtab = data;
struct mf_mbox *p;
for (p = mtab; p < mtab + NMBOXES; p++) {
close_mbox(p);
}
free(mtab);
}
MF_DECLARE_DATA(MBOXTAB, alloc_mboxes, destroy_mboxes)
static int
find_slot(struct mf_mbox *tab)
{
int i;
for (i = 0; i < NMBOXES; i++)
if (tab[i].mbox == NULL)
return i;
return -1;
}
/* number mailbox_open(string url) */
MF_DEFUN(mailbox_open, NUMBER, STRING url, OPTIONAL, STRING mode, STRING perms)
{
int rc;
int md;
struct mf_mbox *mbtab = MF_GET_DATA;
struct mf_mbox *mp;
int flags;
char *p;
md = find_slot(mbtab);
MF_ASSERT(md >= 0,
mfe_failure,
_("No more mailboxes available"));
debug1(10, "opening mailbox %s", url);
mp = mbtab + md;
flags = 0;
for (p = MF_OPTVAL(mode, "r"); *p; p++) {
switch (*p) {
case 'a':
flags |= MU_STREAM_APPEND;
break;
case 'r':
flags |= MU_STREAM_READ;
break;
case 'w':
flags |= MU_STREAM_WRITE;
break;
case '+':
if (flags & MU_STREAM_READ)
flags |= MU_STREAM_WRITE;
else if (flags & MU_STREAM_WRITE)
/* FIXME: should truncate as well */
flags |= MU_STREAM_READ|MU_STREAM_CREAT;
else if (flags & MU_STREAM_APPEND) {
flags |= MU_STREAM_RDWR | MU_STREAM_CREAT;
} else
MF_THROW(mfe_range,
_("Incorrect mode near `%s'"),
p);
break;
default:
MF_THROW(mfe_range,
_("Incorrect mode near `%s'"),
p);
}
}
/* FIXME: MU: This is ridiculous! */
if ((flags & (MU_STREAM_READ|MU_STREAM_WRITE))
== (MU_STREAM_READ|MU_STREAM_WRITE)) {
flags &= ~(MU_STREAM_READ|MU_STREAM_WRITE);
flags |= MU_STREAM_RDWR;
}
if (MF_DEFINED(perms)) {
/* If MU_STREAM_IRGRP is defined, the remaining three
permissions flags are defined as well.
FIXME: Remove ifdef when MU 2.0 is out. */
#ifdef MU_STREAM_IRGRP
int f;
const char *p;
MF_ASSERT(mu_parse_stream_perm_string(&f, MF_OPTVAL(mode), &p)
== 0,
mfe_range, /* FIXME: introduce mfe_inval? */
_("invalid permissions (near %s)"), p);
flags |= f;
#else
MF_THROW(mfe_failure,
_("This version of Mailutils does not support "
"configurable mailbox permissions"));
#endif
}
rc = mu_mailbox_create(&mp->mbox, url);
MF_ASSERT(rc == 0,
mfe_failure,
_("Cannot create mailbox `%s': %s"), url,
mu_strerror(rc));
rc = mu_mailbox_open(mp->mbox, flags);
if (rc) {
mu_mailbox_destroy(&mp->mbox);
MF_THROW(mfe_failure,
_("Cannot open mailbox `%s': %s"), url,
mu_strerror(rc));
}
mu_list_create(&mp->msglist);
MF_RETURN(md);
}
END
/* void mailbox_close(number mbx) */
MF_DEFUN(mailbox_close, VOID, NUMBER md)
{
struct mf_mbox *mbtab = MF_GET_DATA;
MF_ASSERT(md >= 0 && md < NMBOXES,
mfe_range,
_("Invalid mailbox descriptor"));
close_mbox(mbtab + md);
}
END
m4_define([],[<
struct mf_mbox *mbtab = MF_GET_DATA;
struct mf_mbox *$1;
MF_ASSERT($2 >= 0 && $2 < NMBOXES,
mfe_range,
_("Invalid mailbox descriptor"));
$1 = mbtab + $2;
MF_ASSERT($1->mbox,
mfe_failure,
_("Mailbox not open"))
>])
/* number mailbox_messages_count(number mbx) */
MF_DEFUN(mailbox_messages_count, NUMBER, NUMBER nmbx)
{
size_t count;
int rc;
DCL_MBOX(mp, nmbx);
rc = mu_mailbox_messages_count(mp->mbox, &count);
MF_ASSERT(rc == 0,
mfe_failure,
"%s",
mu_strerror(rc));
MF_RETURN(count);
}
END
/* number mailbox_get_message(number mbx, number msg-no) */
MF_DEFUN(mailbox_get_message, NUMBER, NUMBER nmbx, NUMBER msgno)
{
int rc;
mu_message_t msg;
DCL_MBOX(mp, nmbx);
rc = mu_mailbox_get_message(mp->mbox, msgno, &msg);
MF_ASSERT(rc == 0,
mfe_failure,
"%s",
mu_strerror(rc));
rc = bi_message_register(env, mp->msglist, msg, 0);
MF_ASSERT(rc >= 0,
mfe_failure,
_("No more message slots available"));
MF_RETURN(rc);
}
END
/* void mailbox_append_message(number mbx, number msg-no) */
MF_DEFUN(mailbox_append_message, VOID, NUMBER nmbx, NUMBER msgno)
{
int rc;
mu_message_t msg;
DCL_MBOX(mp, nmbx);
msg = bi_message_from_descr(env, msgno);
rc = mu_mailbox_append_message(mp->mbox, msg);
MF_ASSERT(rc == 0,
mfe_failure,
_("Cannot append message: %s"),
mu_strerror(rc));
}
END
MF_INIT