/* 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) { 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); } } 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