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 (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: */