static char rcsid[] = "@(#)$Id: messages.c,v 1.19 2006/04/09 07:37:36 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.19 $ $State: Exp $
*
* Author: Kari Hurtta <hurtta+elm@posti.FMI.FI> (was hurtta+elm@ozone.FMI.FI)
*****************************************************************************/
#include "def_messages.h"
DEBUG_VAR(Debug,__FILE__,"messages");
static struct MailboxView ** mailbox_list = NULL;
static int mailbox_list_len = 0;
struct MailboxView * give_next_open_mailbox(idx, signal)
int *idx;
int signal;
{
int i = *idx;
struct MailboxView *ret = NULL;
do {
if (*idx >= mailbox_list_len || *idx < 0)
return NULL;
if (mailbox_list[*idx]) {
if (mailbox_list[*idx]->magic != MAILBOXVIEW_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"malloc_view",
"Bad type magic number",signal);
ret = mailbox_list[*idx];
}
(*idx)++;
} while (!ret);
SIGDPRINT(Debug,7,(&Debug,
"give_next_open_mailbox[%d->%d] = %p\n",
i,*idx,ret));
return ret;
}
struct MailboxView * malloc_view(t)
struct mailbox_type *t;
{
int idx;
struct MailboxView *ret, **X;
ret = safe_malloc(sizeof (*ret));
/* bzero is defined hdrs/defs.h */
bzero((void *)ret,sizeof (*ret));
ret->magic = MAILBOXVIEW_magic;
ret->mailbox_type = t;
ret->status_type = &status_common; /* Caller may override */
ret->u.dummy = NULL;
ret->current = 0;
ret->selected = 0;
ret->mailbox_title = NULL;
ret->view = NULL;
ret->view_len = 0;
ret->thread_view = NULL;
if (ret->mailbox_type->magic != MAILBOXTYPE_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"malloc_view",
"Bad type magic number",0);
ret->mailbox_type->mt_init_it(ret);
for (idx = 0; idx < mailbox_list_len; idx++)
if (!mailbox_list[idx]) {
DPRINT(Debug,7,(&Debug,
"malloc_view: Re-using mailbox index %d\n",
idx));
goto found;
}
X = safe_realloc(mailbox_list,(mailbox_list_len+1)* sizeof (*X));
X[mailbox_list_len] = NULL;
mailbox_list = X;
idx = mailbox_list_len++;
DPRINT(Debug,7,(&Debug,
"malloc_view: Allocing new mailbox index %d\n",
idx));
found:
mailbox_list[idx] = ret;
return ret;
}
void add_storage(mailbox,storage)
struct MailboxView *mailbox;
struct current_storage *storage;
{
if (mailbox->magic != MAILBOXVIEW_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"add_storage",
"Bad magic number",0);
if (mailbox->mailbox_type->magic != MAILBOXTYPE_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"add_storage",
"Bad type magic number",0);
mailbox->mailbox_type->mt_add_it_storage(mailbox,storage);
}
void add_digest(mailbox,list,received_time,env_from,F,defcharset)
struct MailboxView *mailbox;
mime_t *list;
time_t received_time;
char *env_from;
FILE *F;
charset_t defcharset;
{
if (mailbox->magic != MAILBOXVIEW_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"add_storage",
"Bad magic number",0);
if (mailbox->mailbox_type->magic != MAILBOXTYPE_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"add_storage",
"Bad type magic number",0);
if (list->magic != MIME_magic)
mime_panic(__FILE__,__LINE__,"add_digest",
"Bad magic number");
mailbox->mailbox_type->mt_add_it_digest(mailbox,list,received_time,
env_from,F, defcharset);
}
static void free_mailbox1 P_((struct MailboxView **mailbox));
static void free_mailbox1(mailbox)
struct MailboxView **mailbox;
{
if ((*mailbox)->mailbox_type->magic != MAILBOXTYPE_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"free_mailbox1",
"Bad type magic number",0);
(*mailbox)->mailbox_type->mt_free_it(*mailbox);
if ((*mailbox)->mailbox_title)
free_string (& ((*mailbox)->mailbox_title));
if ((*mailbox)->view) {
free((*mailbox)->view);
(*mailbox)->view = NULL;
}
(*mailbox)->view_len = 0;
if ((*mailbox)->thread_view)
free_thread_view(& ((*mailbox)->thread_view));
(*mailbox)->magic = 0; /* Invalidate */
free(*mailbox);
*mailbox = NULL;
}
void free_mailbox(mailbox)
struct MailboxView **mailbox;
{
int i;
if ((*mailbox)->magic != MAILBOXVIEW_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"free_mailbox",
"Bad magic number",0);
for ( i = 0; i < mailbox_list_len; i++) {
if (mailbox_list[i] == *mailbox) {
SIGDPRINT(Debug,7,(&Debug,
"free_mailbox: Mailbox index %d goes free\n",
i));
mailbox_list[i] = NULL;
goto okei;
}
}
panic("MBX VIEW PANIC",__FILE__,__LINE__,"free_mailbox",
"mailbox not found from list",0);
okei:
free_mailbox1(mailbox);
}
void free_all_mailboxes()
{
if (mailbox_list) {
int i;
for ( i = 0; i < mailbox_list_len; i++) {
if (mailbox_list[i]) {
SIGDPRINT(Debug,7,(&Debug,"free_all_mailboxes: [%d]\n",
i));
if (mailbox_list[i]->magic != MAILBOXVIEW_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"free_all_mailboxes",
"Bad magic number",0);
free_mailbox1(& (mailbox_list[i]));
}
}
free(mailbox_list);
mailbox_list = NULL;
}
mailbox_list_len = 0;
}
/* Return 1 if redraw required */
int update_view(mailbox)
struct MailboxView *mailbox;
{
int ret;
struct folder_view cur;
int current_set = 0;
zero_folder_view(& cur);
if (mailbox->magic != MAILBOXVIEW_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"update_view",
"Bad magic number",0);
if (mailbox->mailbox_type->magic != MAILBOXTYPE_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"update_view",
"Bad type magic number",0);
if (mailbox->current > 0 && mailbox->current <= mailbox->view_len) {
cur = mailbox->view[mailbox->current-1];
current_set++;
}
ret = mailbox->mailbox_type->mt_update_view_it(mailbox);
if (ret && current_set) {
int i;
for (i = 0; i < mailbox->view_len; i++)
if (cur.mailbox_number == mailbox->view[i].mailbox_number &&
cur.index == mailbox->view[i].index) {
DPRINT(Debug,7,(&Debug,
"update_view: Channing current %d -> %d\n",
mailbox->current,i+1));
mailbox->current = i+1;
break;
}
}
DPRINT(Debug,7,(&Debug,
"update_view=%d\n",ret));
return ret;
}
struct folder_info * get_main_folder(mailbox)
struct MailboxView *mailbox;
{
if (mailbox->magic != MAILBOXVIEW_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"get_main_folder",
"Bad magic number",0);
if (mailbox->mailbox_type->magic != MAILBOXTYPE_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"get_main_folder",
"Bad type magic number",0);
return mailbox->mailbox_type->mt_get_main_it_folder(mailbox);
}
/* Can be called from signal handler */
struct current_storage * get_storage(mailbox,i)
struct MailboxView *mailbox;
int i;
{
if (mailbox->magic != MAILBOXVIEW_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"get_storage",
"Bad magic number",1);
if (mailbox->mailbox_type->magic != MAILBOXTYPE_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"get_storage",
"Bad type magic number",1);
return mailbox->mailbox_type->mt_get_it_storage(mailbox,i);
}
/* Can be called from signal handler */
int get_storage_count(mailbox)
struct MailboxView *mailbox;
{
if (mailbox->magic != MAILBOXVIEW_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"get_storage_count",
"Bad magic number",1);
if (mailbox->mailbox_type->magic != MAILBOXTYPE_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"get_storage_count",
"Bad type magic number",1);
return mailbox->mailbox_type->mt_get_it_storage_count(mailbox);
}
void give_index_number(mailbox,index,res)
struct MailboxView *mailbox;
int index;
struct folder_view *res;
{
zero_folder_view(res);
if (index < 0 || index >= mailbox->view_len)
return;
*res = mailbox->view[index];
}
struct header_rec * give_header(mailbox,index)
struct MailboxView *mailbox;
int index;
{
if (mailbox->magic != MAILBOXVIEW_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"give_header",
"Bad magic number",0);
if (mailbox->mailbox_type->magic != MAILBOXTYPE_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"give_header",
"Bad type magic number",0);
if (index < 0 || index >= mailbox->view_len)
return NULL;
return mailbox->mailbox_type->mt_give_header_it(mailbox,index,
& mailbox->view[index]);
}
/* current == index+1 value is used only by caller */
int get_current(mailbox)
struct MailboxView *mailbox;
{
return mailbox->current;
}
/* current == index+1 value is used only by caller */
void set_current(mailbox,cur)
struct MailboxView *mailbox;
int cur;
{
mailbox->current = cur;
}
int get_selected(mailbox)
struct MailboxView *mailbox;
{
return mailbox->selected;
}
void set_selected(mailbox,sel)
struct MailboxView *mailbox;
int sel;
{
mailbox->selected = sel;
}
int get_message_count(mailbox)
struct MailboxView *mailbox;
{
return mailbox->view_len;
}
struct header_rec * give_header_s(s)
struct sort_data *s;
{
if (s->sort_data_type->magic != SORTDATATYPE_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"give_header_s",
"Bad magic number",0);
return s->sort_data_type->sdt_give_header(s,& s->w);
}
void give_index_number_s(s,res)
struct sort_data *s;
struct folder_view *res;
{
*res = s->w;
}
void sort_mailbox_view(mailbox,func)
struct MailboxView *mailbox;
hdr_compare_func *func;
{
if (mailbox->magic != MAILBOXVIEW_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"sort_mailbox_view",
"Bad magic number",0);
if (mailbox->mailbox_type->magic != MAILBOXTYPE_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"sort_mailbox_view",
"Bad type magic number",0);
if (mailbox->view_len < 2)
return;
mailbox->mailbox_type->mt_sort_it_view(mailbox,func);
}
/* Return 1 if succeed, 0 is fails --
seeks to {header}->offset (if ret_F set)
*/
int give_message_data(mailbox,index,ret_header,ret_F,
counter,parse_mime)
struct MailboxView *mailbox;
int index;
struct header_rec **ret_header;
FILE **ret_F;
struct counter_data *counter;
parse_mime_callback *parse_mime;
{
if (mailbox->magic != MAILBOXVIEW_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"give_message_data",
"Bad magic number",0);
if (mailbox->mailbox_type->magic != MAILBOXTYPE_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"give_message_data",
"Bad type magic number",0);
if (index < 0 || index >= mailbox->view_len)
return 0;
if (ret_header)
*ret_header = NULL;
if (ret_F)
*ret_F = NULL;
return mailbox->mailbox_type->
mt_give_message_data_it(mailbox,index,
ret_header,ret_F,
counter,parse_mime,
& mailbox->view[index]);
}
void write_mailbox_info(fp,mailbox)
FILE *fp;
struct MailboxView *mailbox;
{
int i,j;
int count;
int cur_s = -1;
int cur_idx = -1;
int s;
if (mailbox->magic != MAILBOXVIEW_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"write_mailbox_info",
"Bad magic number",0);
if (mailbox->mailbox_type->magic != MAILBOXTYPE_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"write_mailbox_info",
"Bad type magic number",0);
count = mailbox->mailbox_type->mt_get_it_storage_count(mailbox);
fprintf(fp, "S%d\n", count);
/* HACK */
if (mailbox->current > 0 && mailbox->current <= mailbox->view_len) {
cur_s = mailbox->view[mailbox->current -1].mailbox_number;
cur_idx = mailbox->view[mailbox->current -1].index;
}
for (s = 0; s < count; s++) {
fprintf(fp, "=%d\n",s);
if (s == cur_s)
mailbox->mailbox_type->mt_write_it_info(fp,mailbox,s,cur_idx);
else
mailbox->mailbox_type->mt_write_it_info(fp,mailbox,s,-1);
}
fprintf(fp, "V%d\n", mailbox->view_len);
for (i = 0; i < mailbox->view_len; i++) {
fprintf(fp, "i%d %d %d\n",
mailbox->view[i].mailbox_number,
mailbox->view[i].index,
mailbox->view[i].thread_number);
}
/* count up the number of tagged messages */
count = 0;
for (i = 0 ; i < mailbox->view_len ; i++) {
struct header_rec * hdr = give_header(mailbox,i);
if (hdr &&
(hdr->status & TAGGED))
++count;
}
/* write out selected messages */
if (count > 0) {
/* we found tagged messages - write them out */
fprintf(fp, "C%d\n", count);
for (i = 0 ; i < mailbox->view_len ; i++) {
struct header_rec * hdr = give_header(mailbox,i);
if (hdr && (hdr->status & TAGGED))
fprintf(fp, "S%d\n", i+1);
}
} else if (mailbox->current > 0) {
/* no tagged messages - write out the selected message */
fprintf(fp, "C1\nS%d\n", mailbox->current);
} else {
/* hmmm...must be an empty mailbox */
fprintf(fp, "C0\n");
}
}
/* caller must string_free() result -- calculated if not set */
struct string * mailbox_title(mailbox)
struct MailboxView *mailbox;
{
if (mailbox->magic != MAILBOXVIEW_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"mailbox_title",
"Bad magic number",0);
if (mailbox->mailbox_title) {
return dup_string(mailbox->mailbox_title);
}
if (mailbox->mailbox_type->magic != MAILBOXTYPE_magic)
panic("MBX VIEW PANIC",__FILE__,__LINE__,"mailbox_title",
"Bad type magic number",0);
return mailbox->mailbox_type->mt_it_title(mailbox);
}
/* must not freed -- shared/stored to structure
-- set_mailbox_title will free_string()
it later */
void set_mailbox_title(mailbox,value)
struct MailboxView *mailbox;
struct string *value;
{
if (mailbox->mailbox_title)
free_string( & (mailbox->mailbox_title) );
mailbox->mailbox_title = value;
}
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1