/* read.c */
#include "ml.h"
Menu read_save_menu[] = {
{ NULL, "fullhead", NUL_TERM,
read_savefull, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "parthead", NUL_TERM,
read_savepart, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "nonehead", NUL_TERM,
read_savenone, NULL, 0, NULL, NULL, BTN_ON },
};
Menu read_pipe_menu[] = {
{ NULL, "fullhead", NUL_TERM,
read_execfull, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "parthead", NUL_TERM,
read_execpart, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "nonehead", NUL_TERM,
read_execnone, NULL, 0, NULL, NULL, BTN_ON },
};
Menu read_print_menu[] = {
{ NULL, "fullhead", NUL_TERM,
read_printfull, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "parthead", NUL_TERM,
read_printpart, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "nonehead", NUL_TERM,
read_printnone, NULL, 0, NULL, NULL, BTN_ON },
};
Menu read_file_menu[] = {
{ NULL, "view_attachment", NUL_TERM,
read_view_attach, NULL, 0, NULL, NULL, BTN_NOATTACHSELECT },
{ NULL, "save_attachment", NUL_TERM,
read_save_attach, NULL, 0, NULL, NULL, BTN_NOATTACHSELECT },
{ NULL, "copy", NUL_TERM,
read_copy, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "print_menu", NUL_TERM,
NULL, read_print_menu, XtNumber(read_print_menu), NULL, NULL, BTN_ON },
{ NULL, "save_menu", NUL_TERM,
NULL, read_save_menu, XtNumber(read_save_menu), NULL, NULL, BTN_ON },
{ NULL, "pipe_menu", NUL_TERM,
NULL, read_pipe_menu, XtNumber(read_pipe_menu), NULL, NULL, BTN_ON },
{ NULL, "browse_url", NUL_TERM,
read_browse_url, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "address_book", NUL_TERM,
main_address_book, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "note_book", NUL_TERM,
main_note_book, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "close_window", NUL_TERM,
read_close_window, NULL, 0, NULL, NULL, BTN_ON },
};
Menu read_setflags_menu[] = {
{ NULL, "set_deleted", NUL_TERM,
read_set_deleted, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "set_seen", NUL_TERM,
read_set_seen, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "set_flagged", NUL_TERM,
read_set_flagged, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "set_answered", NUL_TERM,
read_set_answered, NULL, 0, NULL, NULL, BTN_ON },
};
Menu read_clearflags_menu[] = {
{ NULL, "clear_deleted", NUL_TERM,
read_clear_deleted, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "clear_seen", NUL_TERM,
read_clear_seen, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "clear_flagged", NUL_TERM,
read_clear_flagged, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "clear_answered", NUL_TERM,
read_clear_answered, NULL, 0, NULL, NULL, BTN_ON },
};
Menu read_edit_menu[] = {
{ NULL, "select_text", NUL_TERM,
read_select_text, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "copy_text", NUL_TERM,
read_copy_text, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "kill_current", NUL_TERM,
read_kill_current, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "trash_current", NUL_TERM,
read_trash_current, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "setflags_menu", NUL_TERM,
NULL, read_setflags_menu, XtNumber(read_setflags_menu),
NULL, NULL, BTN_ON },
{ NULL, "clearflags_menu", NUL_TERM,
NULL, read_clearflags_menu, XtNumber(read_clearflags_menu),
NULL, NULL, BTN_ON },
};
Menu read_option_menu[] = {
{ NULL, "full_header", NUL_TERM,
read_full_header, NULL, 0, NULL, NULL, BTN_SHORT_HEADER },
{ NULL, "short_header", NUL_TERM,
read_short_header, NULL, 0, NULL, NULL, BTN_LONG_HEADER },
{ NULL, "takeaddr", NUL_TERM,
read_address, NULL, 0, NULL, NULL, BTN_ON },
};
Menu read_reply_submenu[] = {
{ NULL, "reply_sender", NUL_TERM,
read_reply_sender, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "reply_all", NUL_TERM,
read_reply_all, NULL, 0, NULL, NULL, BTN_ON },
};
Menu read_forward_submenu[] = {
{ NULL, "forward", NUL_TERM,
read_forward, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "forward_attach", NUL_TERM,
read_forward_attach, NULL, 0, NULL, NULL, BTN_ON },
};
Menu read_send_menu[] = {
{ NULL, "compose_new", NUL_TERM,
main_compose, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "reply_menu", NUL_TERM,
NULL, read_reply_submenu, XtNumber(read_reply_submenu),
NULL, NULL, BTN_ON },
{ NULL, "forward_menu", NUL_TERM,
NULL, read_forward_submenu, XtNumber(read_forward_submenu),
NULL, NULL, BTN_ON },
{ NULL, "remail", NUL_TERM,
read_remail, NULL, 0, NULL, NULL, BTN_ON },
};
Menu read_menu[] = {
{ NULL, "file_menu", NUL_TERM,
NULL, read_file_menu, XtNumber(read_file_menu),
NULL, NULL, BTN_ON },
{ NULL, "edit_menu", NUL_TERM,
NULL, read_edit_menu, XtNumber(read_edit_menu),
NULL, NULL, BTN_ON },
{ NULL, "option_menu", NUL_TERM,
NULL, read_option_menu, XtNumber(read_option_menu),
NULL, NULL, BTN_ON },
{ NULL, "send_menu", NUL_TERM,
NULL, read_send_menu, XtNumber(read_send_menu),
NULL, NULL, BTN_ON },
{ NULL, "prevwin", NUL_TERM,
read_prev, NULL, 0, NULL, NULL, BTN_NOPREV },
{ NULL, "nextwin", NUL_TERM,
read_next, NULL, 0, NULL, NULL, BTN_NONEXT },
{ NULL, "read_delete", NUL_TERM,
read_set_deleted, NULL, 0, NULL, NULL, BTN_ON },
{ NULL, "HELP", NUL_TERM,
read_help, NULL, 0,
NULL, NULL, BTN_ON },
};
Button_Menu read_secondbuttons[] = {
{ "read_get_next_btn", read_get_next, NULL, BTN_ON, NULL },
{ "read_trash_btn", read_trash_current, NULL, BTN_ON, NULL },
{ "read_copy_btn", read_copy, NULL, BTN_ON, NULL },
{ "read_save_btn", read_savepart, NULL, BTN_ON, NULL },
{ "read_reply_btn", read_reply_sender, NULL, BTN_ON, NULL },
{ "read_replyall_btn", read_reply_all, NULL, BTN_ON, NULL },
{ "read_dismiss_btn", read_close_window, NULL, BTN_ON, NULL },
};
#ifdef __STDC__
void read_check_buttons(void)
#else
void read_check_buttons()
#endif
{
ButtonState state;
Read *read;
for(read = session->read; read; read = read->next) {
state = (read->current) ? read->current->button_state : BTN_ON;
update_buttons(read->buttonlist, state);
}
return;
}
#ifdef __STDC__
Read *new_read(void)
#else
Read *new_read()
#endif
{
Read *read = (Read *) fs_get(sizeof(Read));
read->current = NULL;
read->read_info = NULL;
read->is_realized = FALSE;
read->buttonlist = NULL;
read->next = NULL;
read->prev = NULL;
return(read);
}
#ifdef __STDC__
Read_Info *new_read_info(void)
#else
Read_Info *new_read_info()
#endif
{
Read_Info *read_info = (Read_Info *) fs_get(sizeof(Read_Info));
read_info->message_type = MESSAGE_NORMAL;
read_info->mailbox_type = MAILBOX_TYPE_MAIL;
read_info->message = NULL;
read_info->mailstream = NULL;
read_info->lview = NULL;
read_info->msgno = 0L;
read_info->serialno = 0L;
read_info->fetched = FALSE;
read_info->visible = FALSE;
read_info->expunged = FALSE;
read_info->selected = FALSE;
read_info->amount = 100;
read_info->server = NULL;
read_info->current_part_str = NULL;
read_info->base_part_str = NULL;
read_info->short_header = NULL;
read_info->header = NULL;
read_info->current_text = NULL;
read_info->alt_text = NULL;
read_info->current_part = NULL;
read_info->body = NULL;
read_info->envelope = NULL;
read_info->attachments = NULL;
read_info->button_state = BTN_ON | BTN_LONG_HEADER;
read_info->number = 0L;
read_info->selection = 0L;
read_info->show_long_header = FALSE;
read_info->show_entire = FALSE;
read_info->show_alt = FALSE;
read_info->rfc_msg_leaf = FALSE;
read_info->part_list = NULL;
read_info->next = NULL;
read_info->prev = NULL;
return(read_info);
}
#ifdef __STDC__
void free_read_info(Read_Info *read_info)
#else
void free_read_info(read_info)
Read_Info *read_info;
#endif
{
if(read_info == NULL)
return;
read_info->msgno = 0L;
if(read_info->current_part_str)
fs_give((void **) &read_info->current_part_str);
if(read_info->base_part_str)
fs_give((void **) &read_info->base_part_str);
if(read_info->short_header)
fs_give((void **) &read_info->short_header);
if(read_info->header)
fs_give((void **) &read_info->header);
if(read_info->current_text)
fs_give((void **) &read_info->current_text);
if(read_info->alt_text)
fs_give((void **) &read_info->alt_text);
if(read_info->part_list)
destroy_part_list(read_info->part_list);
read_info->part_list = NULL;
fs_give((void **) &read_info);
}
#ifdef __STDC__
void read_messagelist(MainWindow *mwin, Lview *lview,
Message_List *message_list, int amount, Boolean newwin)
#else
void read_messagelist(mwin,lview,message_list, amount, newwin)
MainWindow *mwin;
Lview *lview;
Message_List *message_list;
int amount;
Boolean newwin;
#endif
{
Read *read = NULL;
Message_List *select_list;
Read_Info *read_info;
Read_Info *first_message = NULL;
Message *message;
if(newwin == FALSE) {
for(read = session->read; read; read = read->next) {
if((read->read_info != NULL) && (read->read_info->lview == lview))
break;
}
}
if(read == NULL)
read = create_read_window();
if(read == NULL)
return;
de_iconify(read->shell);
for(select_list = message_list; select_list;
select_list = select_list->next) {
if(select_list->selected == TRUE) {
message = select_list->message;
if(message->fetched == FALSE)
continue;
read_info = new_read_info();
read_info->serialno = mwin->serialno;
if(first_message == NULL)
first_message = read_info;
read_info->lview = lview;
read_info->amount = amount;
read_info->mailstream = message->mailstream;
read_info->msgno = message->msgno;
read_info->message = message;
read_info->server = cpystr(message->mailbox->host);
read_info->current_part_str = cpystr(PART_ONE_STR);
read_info->mailbox_type = message->mailbox->type;
if(read_info->mailbox_type == MAILBOX_TYPE_NEWS)
read_info->button_state |= BTN_ISNEWS;
read_info->button_state |= BTN_NOATTACHSELECT;
read_info->envelope = message->envelope;
read_info->body = message->body;
if((read_info->body) && (read_info->body->type == TYPEMULTIPART))
read_info->attachments = read_info->body->contents.part;
read_new_link(read,read_info);
}
}
if(first_message != NULL) {
if((first_message->body != NULL)
&& (first_message->body->type == TYPEMESSAGE)
&& (first_message->body->subtype != NULL)
&& ((strcasecmp(first_message->body->subtype,"rfc822")) == STRMATCH)) {
read_rfc822(read_info,first_message->current_part_str,
first_message->body);
return;
}
read_fetch(first_message, first_message->body);
read_context_switch(read,NULL,first_message);
}
return;
}
#ifdef __STDC__
void read_load_next(Read_Info *info)
#else
void read_load_next(info)
Read_Info *info;
#endif
{
Read *read;
Mailbox *mailbox;
Message *message = NULL;
Message_List *ml;
Read_Info *read_info;
if((info == NULL) || (info->msgno == 0) || (info->mailstream == NULL)
|| (info->lview == NULL))
return;
read = find_read_window(info);
mailbox = info->lview->mailbox;
if((read == NULL) || (mailbox == NULL))
return;
for(ml = info->lview->message_list; ml; ml = ml->next ) {
if(ml->message == info->message) {
message = (ml->next) ? ml->next->message : NULL;
view_select_from_read(info->lview,message);
break;
}
}
if(message) {
if(message->fetched == FALSE)
return;
read_info = new_read_info();
read_info->serialno = info->serialno;
read_info->amount = info->amount;
read_info->mailstream = message->mailstream;
read_info->lview = info->lview;
read_info->msgno = message->msgno;
read_info->message = message;
read_info->server = cpystr(message->mailbox->host);
read_info->current_part_str = cpystr(PART_ONE_STR);
read_info->mailbox_type = message->mailbox->type;
if(read_info->mailbox_type == MAILBOX_TYPE_NEWS)
read_info->button_state |= BTN_ISNEWS;
read_info->button_state |= BTN_NOATTACHSELECT;
read_info->envelope = message->envelope;
read_info->body = message->body;
if((read_info->body) && (read_info->body->type == TYPEMULTIPART))
read_info->attachments = read_info->body->contents.part;
read_kill_all(NULL, read, NULL);
read_new_link(read,read_info);
if((read_info->body != NULL)
&& (read_info->body->type == TYPEMESSAGE)
&& (read_info->body->subtype != NULL)
&& ((strcasecmp(read_info->body->subtype,"rfc822")) == STRMATCH)) {
read_rfc822(read_info,read_info->current_part_str,
read_info->body);
return;
}
read_fetch(read_info, read_info->body);
read_context_switch(read,NULL,read_info);
read_check_buttons();
}
else
read_kill_all(NULL, read, NULL);
return;
}
#ifdef __STDC__
void read_lview_detach(Lview *lview)
#else
void read_lview_detach(lview)
Lview *lview;
#endif
{
Read *read;
Read_Info *info;
for(read = session->read; read; read = read->next )
for(info = read->read_info; info; info = info->prev)
if(info->lview == lview)
info->lview = NULL;
return;
}
#ifdef __STDC__
Read *create_read_window(void)
#else
Read *create_read_window()
#endif
{
Arg args[ARGLISTSIZE];
int n = 0;
XtTranslations translations;
Read *prev;
Read *read;
read = new_read();
if(session->read == NULL)
session->read = read;
else {
for(prev = session->read; prev->next; prev = prev->next)
;
prev->next = read;
read->prev = prev;
}
XtSetArg (args[n], XmNdeleteResponse, XmDO_NOTHING); n++;
read->shell = XtCreatePopupShell("read", topLevelShellWidgetClass,
session->shell, args,n);
n = 0;
AddDestroyCallback(read->shell);
setup_editres(read->shell);
if(read_icon != (Pixmap) None)
XtVaSetValues(read->shell,
XmNiconPixmap,read_icon,
NULL);
read->form = XmCreateForm(read->shell, "form", args, n); n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++;
read->menubar = XmCreateMenuBar(read->form,"menubar", args, n); n = 0;
XtManageChild(read->menubar);
make_buttons(&read->buttonlist, NULL, read->menubar,
read_menu, XtNumber(read_menu),
BTN_ON, (XtPointer) read, ROOTMENULEVEL);
XtSetArg(args[n], XmNadjustMargin, FALSE); n ++;
XtSetArg(args[n], XmNmarginWidth, 0); n ++;
XtSetArg(args[n], XmNborderWidth, 0); n ++;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n ++;
XtSetArg(args[n], XmNtopWidget, read->menubar); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n ++;
XtSetArg(args[n], XmNpacking, XmPACK_COLUMN); n ++;
read->rowcol = XmCreateRowColumn(read->form, "rowcol", args, n); n = 0;
XtManageChild(read->rowcol);
make_secondbuttons(read->buttonlist, read->rowcol,
read_secondbuttons, XtNumber(read_secondbuttons),
BTN_ON, (XtPointer) read);
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNtopWidget, read->rowcol); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNtraversalOn, FALSE); n ++;
XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n ++;
XtSetArg(args[n], XmNvalue, 100); n ++;
read->slider = XmCreateScale(read->form, "slider", args, n);
n = 0;
XtManageChild(read->slider);
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET ); n ++;
XtSetArg(args[n], XmNtopWidget, read->slider); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNsashHeight, 6); n ++;
XtSetArg(args[n], XmNsashWidth, 12); n ++;
XtSetArg(args[n], XmNspacing, 4); n ++;
read->pane = XmCreatePanedWindow(read->form,"pane", args, n); n = 0;
XtSetArg(args[n], XmNpaneMinimum, 30); n ++;
XtSetArg(args[n], XmNeditable, FALSE); n ++;
XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n ++;
XtSetArg(args[n], XmNwordWrap, TRUE); n ++;
XtSetArg(args[n], XmNrows, 4); n ++;
XtSetArg(args[n], XmNcolumns, 80); n ++;
XtSetArg(args[n], XmNscrollVertical, TRUE); n ++;
XtSetArg(args[n], XmNscrollHorizontal, FALSE ); n ++;
read->read_header =
XmCreateScrolledText(read->pane, "header", args, n); n = 0;
XtManageChild(read->read_header);
translations = XtParseTranslationTable(GLOBAL_text_translations);
XtOverrideTranslations(read->read_header, translations);
XtSetArg(args[n], XmNpaneMinimum, 45); n ++;
XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); n ++;
XtSetArg(args[n], XmNlistSizePolicy,XmCONSTANT); n ++;
XtSetArg(args[n], XmNvisibleItemCount, VISIBLE_ATTACHMENTS ); n ++;
XtSetArg(args[n], XmNselectionPolicy,XmSINGLE_SELECT); n ++;
read->read_attach = XmCreateScrolledList(read->pane,"list",args,n);
n = 0;
XtAddCallback(read->read_attach,
XmNsingleSelectionCallback,
(XtCallbackProc) read_select_attach, read);
XtAddCallback(read->read_attach,
XmNdefaultActionCallback,
(XtCallbackProc) read_exec_attach, read);
XtManageChild(read->read_attach);
XtSetArg(args[n], XmNpaneMinimum, 30); n ++;
XtSetArg(args[n], XmNeditable, FALSE); n ++;
XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n ++;
XtSetArg(args[n], XmNwordWrap, TRUE); n ++;
XtSetArg(args[n], XmNcolumns, 80); n ++;
XtSetArg(args[n], XmNscrollVertical, TRUE); n ++;
XtSetArg(args[n], XmNscrollHorizontal, FALSE ); n ++;
read->read_text =
XmCreateScrolledText(read->pane, "text", args, n); n = 0;
XtManageChild(read->read_text);
translations = XtParseTranslationTable(GLOBAL_text_translations);
XtOverrideTranslations(read->read_text, translations);
translations = XtParseTranslationTable(GLOBAL_read_pop_translations);
XtOverrideTranslations(read->read_text, translations);
XtAddCallback(read->shell, XmNdestroyCallback,
(XtCallbackProc) read_destroy, read);
XtManageChild(read->pane);
XtManageChild(read->form);
XtManageChild(read->shell);
XtPopup(read->shell,XtGrabNone);
XmProcessTraversal(read->read_text, XmTRAVERSE_CURRENT);
read->is_realized = TRUE;
return(read);
}
#ifdef __STDC__
void read_close_window(Widget w, Read *read, XtPointer xp)
#else
void read_close_window(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
if(read == session->read)
session->read = read->next;
if(read->next)
read->next->prev = read->prev;
if(read->prev)
read->prev->next = read->next;
XtPopdown(read->shell);
XtDestroyWidget(read->shell);
return;
}
#ifdef __STDC__
void read_destroy(Widget w, Read *read, XtPointer xp)
#else
void read_destroy(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
Read *dead;
for(dead = session->read; dead; dead = dead->next)
if(dead == read) { /* still linked to session */
if(read == session->read)
session->read = read->next;
if(read->next)
read->next->prev = read->prev;
if(read->prev)
read->prev->next = read->next;
}
read_kill_all(w,read,xp);
free_buttonlist(read->buttonlist);
fs_give((void **) &read);
return;
}
#ifdef __STDC__
void read_help(Widget w, Read *read, XtPointer xp)
#else
void read_help(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
help(read->shell, READWINDOWHELPFILE);
return;
}
#ifdef __STDC__
void read_next(Widget w, Read *read, XtPointer xp)
#else
void read_next(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
if(read->current->next)
read_context_switch(read,read->current,read->current->next);
return;
}
#ifdef __STDC__
void read_prev(Widget w, Read *read, XtPointer xp)
#else
void read_prev(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
if(read->current->prev)
read_context_switch(read,read->current,read->current->prev);
return;
}
#ifdef __STDC__
void read_address(Widget w, Read *read, XtPointer xp)
#else
void read_address(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
char *from;
char *name;
Address_Book_Info *info;
if((read == NULL)
|| (read->current == NULL)
|| (read->current->header == NULL))
return;
from = get_header_field_contents("reply-to",read->current->header);
if(from == NULL)
from = get_header_field_contents("sender", read->current->header);
if(from == NULL)
from = get_header_field_contents("from", read->current->header);
if(*from == NUL_TERM)
return;
name = input_string(read->shell,MLGetLocalized(XtNmsgAddressName,
MsgAddressName),
NULL,ADDRTAKEHELPFILE);
if(name == NULL) {
fs_give((void **) &from);
return;
}
info = new_address_book_info();
info->name = (unsigned char *) name;
info->address = (unsigned char *) from;
info->groups = (unsigned char *) cpystr(EMPTYSTR);
info->comment = (unsigned char *) cpystr(EMPTYSTR);
if(session->addresses == NULL)
session->addresses = info;
else {
info->prev = session->addresses;
session->addresses->next = info;
session->addresses = info;
}
if((session->address_book != NULL)
&& (session->address_book->is_realized == TRUE)) {
address_sort(session->address_book);
address_reset(NULL, session->address_book, NULL);
}
save_defaults();
return;
}
#ifdef __STDC__
void read_copy(Widget w, Read *read, XtPointer xp)
#else
void read_copy(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
char *mailboxname;
Boolean changed;
char sequence[32];
int result;
Boolean move;
if(read->current && read->current->mailstream && read->current->msgno) {
mailboxname =
get_mailbox_name(read->shell,
(read->current->server)
? read->current->server
: EMPTYSTR,
&changed, &move);
if(mailboxname == NULL)
return;
if(*mailboxname == NUL_TERM) {
fs_give((void **) &mailboxname);
return;
}
push_cursor(WATCH_CURSOR);
if(changed == TRUE) {
result = copy_message_to_mailbox(read->current->mailstream,
read->current->msgno,
mailboxname);
if(move) {
if(result == SYSCALL_SUCCESS) {
update_view_line_stream_msgno(read->current->mailstream,
read->current->msgno);
mm_log(MLGetLocalized(XtNmsgMoveSuccess,MsgMoveSuccess), NIL);
}
else
mm_log(MLGetLocalized(XtNmsgMoveFail,MsgMoveFail), WARN);
}
else {
if(result == SYSCALL_SUCCESS)
mm_log(MLGetLocalized(XtNmsgCopySuccess,MsgCopySuccess), NIL);
else
mm_log(MLGetLocalized(XtNmsgCopyFail,MsgCopyFail), WARN);
}
}
else {
sprintf(sequence,"%lu",read->current->msgno);
if(move) {
result = mail_move(read->current->mailstream, sequence, mailboxname);
if(result == T) {
update_view_line_stream_msgno(read->current->mailstream,
read->current->msgno);
mm_log(MLGetLocalized(XtNmsgMoveSuccess,MsgMoveSuccess), NIL);
}
else
mm_log(MLGetLocalized(XtNmsgMoveFail,MsgMoveFail), WARN);
}
else {
result = mail_copy(read->current->mailstream,
sequence, mailboxname);
if(result == T)
mm_log(MLGetLocalized(XtNmsgCopySuccess,MsgCopySuccess), NIL);
else
mm_log(MLGetLocalized(XtNmsgCopyFail,MsgCopyFail), WARN);
}
}
fs_give((void **) &mailboxname);
pop_cursor();
}
else
mm_log(MLGetLocalized(XtNmsgCopyFail,MsgCopyFail), WARN);
return;
}
#ifdef __STDC__
void read_full_header(Widget w, Read *read, XtPointer xp)
#else
void read_full_header(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read->current->show_long_header = TRUE;
read->current->button_state |= BTN_SHORT_HEADER;
read->current->button_state &= ~(BTN_LONG_HEADER);
read_context_switch(read,NULL, read->current);
return;
}
#ifdef __STDC__
void read_short_header(Widget w, Read *read, XtPointer xp)
#else
void read_short_header(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read->current->show_long_header = FALSE;
read->current->button_state |= BTN_LONG_HEADER;
read->current->button_state &= ~(BTN_SHORT_HEADER);
read_context_switch(read,NULL, read->current);
return;
}
#ifdef __STDC__
void read_savefull(Widget w, Read *read, XtPointer xp)
#else
void read_savefull(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read_save_dispatch(read,HEADER_FULL);
return;
}
#ifdef __STDC__
void read_savepart(Widget w, Read *read, XtPointer xp)
#else
void read_savepart(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read_save_dispatch(read,HEADER_PART);
return;
}
#ifdef __STDC__
void read_savenone(Widget w, Read *read, XtPointer xp)
#else
void read_savenone(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read_save_dispatch(read,HEADER_NONE);
return;
}
#ifdef __STDC__
void read_save_dispatch(Read *read, Header_Mode header_mode)
#else
void read_save_dispatch(read,header_mode)
Read *read;
Header_Mode header_mode;
#endif
{
FILE *fp;
char *filename;
int errors = 0;
char *header_text = NULL;
char *body_text;
Boolean append_it;
filename = file_select(read->shell, NULL, NULL, NULL, TRUE, &append_it);
if(filename == NULL)
return;
push_cursor(WATCH_CURSOR);
if(header_mode == HEADER_FULL)
header_text = read->current->header;
if(header_mode == HEADER_PART)
header_text = read->current->short_header;
if(read->current->alt_text)
body_text = read->current->alt_text;
else
body_text = read->current->current_text;
if((fp = fopen(filename,(append_it == TRUE) ? "a" : "w")) != NULL) {
(void) chmod(filename,S_IRWXU);
if((header_mode != HEADER_NONE) && (header_text != NULL)) {
if((fwrite(header_text,strlen(header_text),1,fp)) != 1)
errors ++;
if((fwrite(LFSTR,1,1,fp)) != 1)
errors ++;
}
if((fwrite(body_text,strlen(body_text),1,fp)) != 1)
errors ++;
if((fclose(fp)) != SYSCALL_SUCCESS)
errors ++;
}
else
errors ++;
fs_give((void **) &filename);
if(errors)
mm_log(MLGetLocalized(XtNmsgSaveFail,MsgSaveFail),WARN);
else
mm_log(MLGetLocalized(XtNmsgSaveSuccess,MsgSaveSuccess), NIL);
pop_cursor();
}
#ifdef __STDC__
void read_printfull(Widget w, Read *read, XtPointer xp)
#else
void read_printfull(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read_print_dispatch(w,read,HEADER_FULL);
return;
}
#ifdef __STDC__
void read_printpart(Widget w, Read *read, XtPointer xp)
#else
void read_printpart(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read_print_dispatch(w,read,HEADER_PART);
return;
}
#ifdef __STDC__
void read_printnone(Widget w, Read *read, XtPointer xp)
#else
void read_printnone(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read_print_dispatch(w,read,HEADER_NONE);
return;
}
#ifdef __STDC__
void read_print_dispatch(Widget w, Read *read, Header_Mode header_mode)
#else
void read_print_dispatch(w,read,header_mode)
Widget w;
Read *read;
Header_Mode header_mode;
#endif
{
char *header = NULL;
if(*preferences.print_command == NUL_TERM) {
mm_log(MLGetLocalized(XtNmsgNoPrintCommand,MsgNoPrintCommand), WARN);
return;
}
push_cursor(WATCH_CURSOR);
if(header_mode == HEADER_FULL)
header = read->current->header;
if(header_mode == HEADER_PART)
header = read->current->short_header;
if(write_to_pipe(preferences.print_command, header,
(read->current->alt_text)
? read->current->alt_text : read->current->current_text,
(read->current->alt_text)
? strlen(read->current->alt_text)
: strlen(read->current->current_text)))
mm_log(MLGetLocalized(XtNmsgPrintFail,MsgPrintFail), WARN);
else
mm_log(MLGetLocalized(XtNmsgPrintSuccess,MsgPrintSuccess), NIL);
pop_cursor();
return;
}
#ifdef __STDC__
char *find_url(char *s)
#else
char *find_url(s)
char *s;
#endif
{
char *ptr;
char *tmp;
char *ret;
int n = 0;
if((s == NULL) || (ptr = ML_Strstr(s,URL_SIG_STR)) == NULL)
return(NULL);
if(ptr > s)
ptr --;
while(ptr >= s && isalpha(*ptr))
ptr --;
ptr ++;
tmp = ptr;
while((*ptr) && ((!isspace(*ptr)) && (*ptr != '\"')
&& (*ptr != '}') && (*ptr != ')') && (*ptr != '>'))) {
ptr ++;
n ++;
}
ret = (char *) fs_get((unsigned) n + 16);
strncpy(ret,tmp,n);
ret[n] = 0;
return(ret);
}
#ifdef __STDC__
void read_browse_url(Widget w, Read *read, XtPointer xp)
#else
void read_browse_url(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
XmTextPosition left, right;
char command[FILEBUFFLEN];
char log[FILEBUFFLEN];
char *temp_url = NULL;
char *url = NULL;
if(*preferences.url_command == NUL_TERM) {
mm_log(MLGetLocalized(XtNmsgNoWebBrowser,MsgNoWebBrowser), WARN);
return;
}
if((ML_Strstr(preferences.url_command,"%s")) == NULL) {
mm_log(MLGetLocalized(XtNmsgWebCommand,MsgWebCommand), WARN);
return;
}
XmTextGetSelectionPosition(read->read_text, &left, &right);
if(left != right) {
temp_url = XmTextGetSelection(read->read_text);
}
else {
temp_url = find_url((read->current->alt_text)
? read->current->alt_text : read->current->current_text);
}
if(temp_url == NULL)
return;
url = input_string(read->shell, MLGetLocalized(XtNmsgShowURL,MsgShowURL),
temp_url, SHOWURLHELPFILE);
fs_give((void **) &temp_url);
if(url == NULL)
return;
if(*url == NUL_TERM) {
fs_give((void **) &url);
return;
}
push_cursor(WATCH_CURSOR);
sprintf(command,preferences.url_command,url);
sprintf(log,MLGetLocalized(XtNmsgExecuting,MsgExecuting), command);
mm_log(log,NIL);
system(command);
fs_give((void **) &url);
pop_cursor();
return;
}
#ifdef __STDC__
void read_execfull(Widget w, Read *read, XtPointer xp)
#else
void read_execfull(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read_exec_dispatch(w,read,HEADER_FULL);
return;
}
#ifdef __STDC__
void read_execpart(Widget w, Read *read, XtPointer xp)
#else
void read_execpart(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read_exec_dispatch(w,read,HEADER_PART);
return;
}
#ifdef __STDC__
void read_execnone(Widget w, Read *read, XtPointer xp)
#else
void read_execnone(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read_exec_dispatch(w,read,HEADER_NONE);
return;
}
#ifdef __STDC__
void read_exec_dispatch(Widget w, Read *read, Header_Mode header_mode)
#else
void read_exec_dispatch(w,read,header_mode)
Widget w;
Read *read;
Header_Mode header_mode;
#endif
{
char *command;
char *header = NULL;
command = input_string(read->shell,MLGetLocalized(XtNmsgInputCommand,
MsgInputCommand),
session->last_command, SHELLCOMMANDHELPFILE);
if(command == NULL)
return;
if(*command == NUL_TERM) {
fs_give((void **) &command);
return;
}
push_cursor(WATCH_CURSOR);
if(header_mode == HEADER_FULL)
header = read->current->header;
if(header_mode == HEADER_PART)
header = read->current->short_header;
if(write_to_pipe(command, header,
(read->current->alt_text)
? read->current->alt_text : read->current->current_text,
(read->current->alt_text)
? strlen(read->current->alt_text)
: strlen(read->current->current_text)))
mm_log(MLGetLocalized(XtNmsgPipeFail,MsgPipeFail), WARN);
if(session->last_command != NULL)
fs_give((void **) &session->last_command);
session->last_command = command;
pop_cursor();
return;
}
#ifdef __STDC__
void read_select_attach(Widget w, Read *read, XmListCallbackStruct *xp)
#else
void read_select_attach(w,read,xp)
Widget w;
Read *read;
XmListCallbackStruct *xp;
#endif
{
Part_List *part_list;
BODY *body = NULL;
if(xp->item_position == read->current->selection) {
read->current->selection = 0;
read->current->button_state |= BTN_NOATTACHSELECT;
read_check_buttons();
return;
}
read->current->selection = xp->item_position;
read->current->button_state &= (~BTN_NOATTACHSELECT);
read_check_buttons();
for(part_list = read->current->part_list;
((part_list) && part_list->partnumber != read->current->selection);
part_list = part_list->next);
if(part_list) {
if(part_list->part)
body = &(part_list->part->body);
read_message_part(read->current,part_list->partstr,body);
}
return;
}
#ifdef __STDC__
void read_view_attach(Widget w, Read *read, XtPointer xp)
#else
void read_view_attach(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
Part_List *part_list;
BODY *body = NULL;
int result;
char **ptrptr = NULL;
if(read->current->selection) {
for(part_list = read->current->part_list;
((part_list) && part_list->partnumber != read->current->selection);
part_list = part_list->next);
if(part_list) {
if(part_list->part)
body = &(part_list->part->body);
else
body = read->current->body;
/* On local connections, the body isn't cached. Grrrr. */
if(body) {
switch(body->type) {
case TYPEMULTIPART:
break;
case TYPEMESSAGE:
if(body->contents.msg.text == NULL) {
body->contents.msg.text =
mail_fetchbody(read->current->mailstream,
read->current->msgno,
(read->current->rfc_msg_leaf == TRUE)
? read->current->current_part_str
: part_list->partstr,
&body->size.bytes);
ptrptr = &body->contents.msg.text;
}
break;
case TYPETEXT:
case TYPEIMAGE:
case TYPEAUDIO:
case TYPEAPPLICATION:
case TYPEOTHER:
default:
if(body->contents.text == NULL) {
body->contents.text = (unsigned char *)
mail_fetchbody(read->current->mailstream,
read->current->msgno,
part_list->partstr,
&body->size.bytes);
ptrptr = (char **) &body->contents.text;
}
break;
}
result = show_mime(read->shell,body, FALSE);
}
}
}
if(ptrptr)
*ptrptr = NULL;
return;
}
#ifdef __STDC__
void read_save_attach(Widget w, Read *read, XtPointer xp)
#else
void read_save_attach(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
Part_List *part_list;
BODY *body = NULL;
int result;
char **ptrptr = NULL;
if(read->current->selection) {
for(part_list = read->current->part_list;
((part_list) && part_list->partnumber != read->current->selection);
part_list = part_list->next);
if(part_list) {
if(part_list->part)
body = &(part_list->part->body);
else
body = read->current->body;
/* On local connections, the body isn't cached. Grrrr. */
if(body) {
switch(body->type) {
case TYPEMULTIPART:
break;
case TYPEMESSAGE:
if(body->contents.msg.text == NULL) {
body->contents.msg.text =
mail_fetchbody(read->current->mailstream,
read->current->msgno,
(read->current->rfc_msg_leaf == TRUE)
? read->current->current_part_str
: part_list->partstr,
&body->size.bytes);
ptrptr = &body->contents.msg.text;
}
break;
case TYPETEXT:
case TYPEIMAGE:
case TYPEAUDIO:
case TYPEAPPLICATION:
case TYPEOTHER:
default:
if(body->contents.text == NULL) {
body->contents.text = (unsigned char *)
mail_fetchbody(read->current->mailstream,
read->current->msgno,
part_list->partstr,
&body->size.bytes);
ptrptr = (char **) &body->contents.text;
}
break;
}
result = show_mime(read->shell,body,TRUE);
}
}
}
if(ptrptr)
*ptrptr = NULL;
return;
}
#ifdef __STDC__
void read_exec_attach(Widget w, Read *read, XmListCallbackStruct *xp)
#else
void read_exec_attach(w,read,xp)
Widget w;
Read *read;
XmListCallbackStruct *xp;
#endif
{
Part_List *part_list;
BODY *body = NULL;
char **ptrptr = NULL;
int result;
read->current->selection = xp->item_position;
if(read->current->selection) {
for(part_list = read->current->part_list;
((part_list) && part_list->partnumber != read->current->selection);
part_list = part_list->next);
if(part_list) {
if(part_list->part)
body = &(part_list->part->body);
else
body = read->current->body;
/* On local connections, the body isn't cached. Grrrr. */
if(body) {
switch(body->type) {
case TYPEMULTIPART:
break;
case TYPEMESSAGE:
if(body->contents.msg.text == NULL) {
body->contents.msg.text =
mail_fetchbody(read->current->mailstream,
read->current->msgno,
(read->current->rfc_msg_leaf == TRUE)
? read->current->current_part_str
: part_list->partstr,
&body->size.bytes);
ptrptr = &body->contents.msg.text;
}
break;
case TYPETEXT:
case TYPEIMAGE:
case TYPEAUDIO:
case TYPEAPPLICATION:
case TYPEOTHER:
default:
if(body->contents.text == NULL) {
body->contents.text = (unsigned char *)
mail_fetchbody(read->current->mailstream,
read->current->msgno,
part_list->partstr,
&body->size.bytes);
ptrptr = (char **) &body->contents.text;
}
break;
}
result = show_mime(read->shell,body, FALSE);
}
}
}
if(ptrptr)
*ptrptr = NULL;
read->current->button_state &= (~BTN_NOATTACHSELECT);
read_check_buttons();
XmListSelectPos(read->read_attach,read->current->selection,FALSE);
return;
}
#ifdef __STDC__
void read_kill_current(Widget w, Read *read, XtPointer xp)
#else
void read_kill_current(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
Read_Info *this_one = NULL;
Read_Info *next_one = NULL;;
if(read == NULL)
return;
this_one = read->current;
if(this_one == NULL)
return;
if(this_one->expunged == TRUE) {
for(next_one = read->read_info; next_one; next_one = next_one->prev)
if(next_one->expunged == FALSE)
break;
}
else {
if(this_one->next)
next_one = this_one->next;
else
if(this_one->prev)
next_one = this_one->prev;
}
if(next_one) {
read_context_switch(read,this_one,next_one);
kill_read_info(this_one);
}
else {
read_close_window(w,read,xp);
return;
}
return;
}
#ifdef __STDC__
void read_get_next(Widget w, Read *read, XtPointer xp)
#else
void read_get_next(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
Read_Info *this_one = NULL;
Read_Info *next_one = NULL;;
if(read == NULL)
return;
this_one = read->current;
if(this_one == NULL)
return;
if(this_one->next) {
next_one = this_one->next;
while((next_one->next != NULL) && (next_one->next->expunged == TRUE))
next_one = next_one->next;
}
if(next_one) {
read_context_switch(read,this_one,next_one);
kill_read_info(this_one);
}
else {
read_load_next(this_one); /* wipe out the current queue as a result */
if(read->read_info == NULL)
read_close_window(w,read,xp);
else
de_iconify(read->shell);
return;
}
return;
}
/* Wipe out the current read queue */
#ifdef __STDC__
void read_kill_all(Widget w, Read *read, XtPointer xp)
#else
void read_kill_all(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
Read_Info *this_one = NULL;
Read_Info *next_one = NULL;;
if(read == NULL)
return;
this_one = read->read_info;
if(this_one == NULL)
return;
for(this_one = read->read_info; this_one; this_one = next_one ) {
next_one = this_one->prev;
kill_read_info(this_one);
}
read->current = NULL;
read->read_info = NULL;
return;
}
/*
* kill this message, and do a context switch to any message
* which isn't in this mailbox; which is being closed.
* If there aren't any, close the window.
*/
#ifdef __STDC__
void read_close_kill_current(Widget w, Read *read, XtPointer xp)
#else
void read_close_kill_current(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
Read_Info *this_one = NULL;
Read_Info *next_one = NULL;
Read_Info *current = NULL;
if(read == NULL)
return;
this_one = read->current;
if(this_one == NULL)
return;
for(current = read->read_info; current ; current = current->prev)
if(current->mailstream != this_one->mailstream) {
next_one = current;
break;
}
if(next_one) {
read_context_switch(read,this_one,next_one);
kill_read_info(this_one);
}
else {
read_close_window(w,read,xp);
return;
}
return;
}
#ifdef __STDC__
void read_trash_current(Widget w, Read *read, XtPointer xp)
#else
void read_trash_current(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
Read_Info *this_one = NULL;
Read_Info *next_one = NULL;
char sequence[32];
if(read == NULL)
return;
this_one = read->current;
if(this_one == NULL)
return;
if(read->current->mailstream && read->current->msgno) {
sprintf(sequence,"%lu",read->current->msgno);
push_cursor(WATCH_CURSOR);
mail_setflag(read->current->mailstream, sequence, DELETED_FLAG);
mm_flags(read->current->mailstream, read->current->msgno);
pop_cursor();
}
read_get_next(w,read,xp);
return;
}
#ifdef __STDC__
void kill_read_info(Read_Info *read_info)
#else
void kill_read_info(read_info)
Read_Info *read_info;
#endif
{
Read *read = find_read_window(read_info);
if((read == NULL) || (read_info == NULL))
return;
if(read->current == read_info)
read->current = NULL;
if(read->read_info == read_info)
read->read_info = read_info->prev;
if(read_info->prev) {
read_info->prev->next = read_info->next;
if(read_info->next == NULL)
read_info->prev->button_state |= BTN_NONEXT;
else
read_info->prev->button_state &= ~(BTN_NONEXT);
}
if(read_info->next) {
read_info->next->prev = read_info->prev;
if(read_info->prev == NULL)
read_info->next->button_state |= BTN_NOPREV;
else
read_info->next->button_state &= ~(BTN_NOPREV);
}
free_read_info(read_info);
read_check_buttons();
return;
}
#ifdef __STDC__
Read *find_read_window(Read_Info *info)
#else
Read *find_read_window(info)
Read_Info *info;
#endif
{
Read *read;
Read_Info *ri;
for(read = session->read; read; read = read->next)
for(ri = read->read_info; ri; ri = ri->prev)
if(ri == info)
return(read);
return(NULL);
}
#ifdef __STDC__
void read_rfc822(Read_Info *parent, char *partstr, BODY *body)
#else
void read_rfc822(parent,partstr,body)
Read_Info *parent;
char *partstr;
BODY *body;
#endif
{
Read *read = find_read_window(parent);
Read_Info *read_info;
char *basetxt = NULL;
unsigned long length;
unsigned long newlength;
char *tmpptr = NULL;
char *ptr = NULL;
int foo;
if(read == NULL)
return;
read_info = new_read_info();
read_info->serialno = parent->serialno;
parent->selection = 0L;
read_info->mailstream = parent->mailstream;
read_info->lview = parent->lview;
read_info->msgno = parent->msgno;
read_info->message = parent->message;
read_info->server = cpystr(parent->server);
read_info->mailbox_type = parent->mailbox_type;
read_info->envelope = parent->envelope;
read_info->base_part_str = cpystr(partstr);
read_info->message_type = MESSAGE_PART;
read_info->fetched = TRUE;
if(read_info->mailbox_type == MAILBOX_TYPE_NEWS)
read_info->button_state |= BTN_ISNEWS;
read_info->button_state |= BTN_NOATTACHSELECT;
basetxt = cpystr(mail_fetchbody(read_info->mailstream,
read_info->msgno,
partstr, &length));
if(basetxt == NULL)
basetxt = cpystr(EMPTYSTR);
stripcr(basetxt);
ptr = ML_Strstr(basetxt,"\n\n");
if(ptr != NULL) {
ptr ++;
*ptr = NUL_TERM;
ptr ++;
read_info->header = cpystr(basetxt);
}
else {
read_info->header = cpystr(EMPTYSTR);
ptr = basetxt;
}
read_info->short_header = get_short_header(read_info->header);
if(read_info->short_header == NULL)
read_info->short_header = cpystr(EMPTYSTR);
read_new_link(read,read_info);
if(body->contents.msg.body->type == TYPEMULTIPART) {
read_info->body = body->contents.msg.body;
read_info->current_part_str = (char *) fs_get(strlen(partstr) + 2);
sprintf(read_info->current_part_str,"%s.1",partstr);
read_info->attachments = read_info->body->contents.part;
read_fetch(read_info,body);
}
else {
read_info->body = body->contents.msg.body;
read_info->current_part_str = cpystr(partstr);
read_info->current_text = cpystr(ptr);
read_info->rfc_msg_leaf = TRUE;
if((body->type == TYPETEXT) || (body->type == TYPEMESSAGE))
read_info->visible = TRUE;
else
read_info->visible = FALSE;
length = strlen(ptr);
if((length != 0L) && (read_info->visible == TRUE)) {
switch(body->encoding) {
case ENCBASE64:
read_info->alt_text =
(char *) rfc822_base64((unsigned char *) ptr,
length,&newlength);
if(read_info->alt_text)
read_info->alt_text[newlength] = NUL_TERM;
break;
case ENCQUOTEDPRINTABLE:
read_info->alt_text =
(char *) rfc822_qprint((unsigned char *) ptr,
length,&newlength);
if(read_info->alt_text)
read_info->alt_text[newlength] = NUL_TERM;
break;
case ENCOTHER:
case ENC7BIT:
case ENC8BIT:
case ENCBINARY:
default:
break;
}
}
if(read_info->alt_text) {
if((foo = strlen(read_info->alt_text)) < newlength)
fs_give((void **) &read_info->alt_text);
else
stripcr(read_info->alt_text);
}
if((body->subtype)
&& (((strcasecmp(body->subtype,"html")) == STRMATCH))
|| ((strncasecmp(read_info->current_text,"<HTML>",6)) == STRMATCH)){
tmpptr = strip_html((read_info->alt_text)
? read_info->alt_text : read_info->current_text);
if(read_info->alt_text)
fs_give((void **) &read_info->alt_text);
read_info->alt_text = tmpptr;
}
}
fs_give((void **) &basetxt);
read_context_switch(read,read->current,read_info);
return;
}
#ifdef __STDC__
void read_message_part(Read_Info *read_info, char *partstr, BODY *body)
#else
void read_message_part(read_info,partstr,body)
Read_Info *read_info;
char *partstr;
BODY *body;
#endif
{
/* Don't recurse again... */
Read *read = find_read_window(read_info);
if((read == NULL) || (read_info->rfc_msg_leaf == TRUE))
return;
if(read_info->current_part_str)
fs_give((void **) &read_info->current_part_str);
read_info->current_part_str = cpystr(partstr);
read_info->message_type = MESSAGE_PART;
read_info->rfc_msg_leaf = FALSE;
if((body != NULL) && (body->type == TYPEMESSAGE) && (body->subtype != NULL)
&& ((strcasecmp(body->subtype,"rfc822")) == STRMATCH)) {
read_rfc822(read_info,partstr,body);
return;
}
read_fetch(read_info,body);
read_context_switch(read,NULL,read_info);
return;
}
#ifdef __STDC__
void read_new_link(Read *read, Read_Info *read_info)
#else
void read_new_link(read, read_info)
Read *read;
Read_Info *read_info;
#endif
{
if(read->read_info) {
read->read_info->next = read_info;
read->read_info->button_state &= ~(BTN_NONEXT);
read_info->button_state &= ~(BTN_NOPREV);
}
else
read_info->button_state |= BTN_NOPREV;
read_info->button_state |= BTN_NONEXT;
read_info->prev = read->read_info;
read->read_info = read_info;
return;
}
#ifdef __STDC__
void read_fetch(Read_Info *read_info, BODY *body)
#else
void read_fetch(read_info,body)
Read_Info *read_info;
BODY *body;
#endif
{
Read *read = find_read_window(read_info);
char sequence[16];
Arg args[ARGLISTSIZE];
int n = 0;
char *tmpptr = NULL;
char *src_text = NULL;
unsigned long length = 0L;
unsigned long newlength = 0L;
unsigned long foo;
char *decode_subject;
char *decode_ptr;
BODY *local_body = body;
char buffer[FILEBUFFLEN];
char *subject = NULL;
if(read == NULL)
return;
XmUpdateDisplay(read->shell);
if((local_body) && (local_body->type == TYPEMULTIPART))
local_body = &(body->contents.part->body);
if(body == NULL) /* should warn */
return;
if((local_body->type == TYPETEXT) || (local_body->type == TYPEMESSAGE))
read_info->visible = TRUE;
else
read_info->visible = FALSE;
push_cursor(WATCH_CURSOR);
switch(read_info->message_type) {
case MESSAGE_NORMAL:
if(read_info->fetched == TRUE)
break;
if(read_info->header == NULL) {
read_info->header = cpystr(mail_fetchheader(read_info->mailstream,
read_info->msgno));
stripcr(read_info->header);
if(read_info->header[strlen(read_info->header) - 1] == LFCHAR)
read_info->header[strlen(read_info->header) - 1] = NUL_TERM;
}
read_info->short_header = get_short_header(read_info->header);
if(read_info->short_header == NULL)
read_info->short_header = cpystr(EMPTYSTR);
if(read_info->visible) {
src_text = mail_fetchbody(read_info->mailstream,
read_info->msgno,
read_info->current_part_str, &length);
read_info->current_text = cpystr(src_text);
}
if(read_info->current_text == NULL)
read_info->current_text = cpystr(EMPTYSTR);
stripcr(read_info->current_text);
update_view_line_stream_msgno(read_info->mailstream, read_info->msgno);
break;
case MESSAGE_PART:
if(read_info->current_text)
fs_give((void **) &read_info->current_text);
src_text = mail_fetchbody(read_info->mailstream,
read_info->msgno,
read_info->current_part_str, &length);
read_info->current_text = cpystr(src_text);
if(read_info->current_text == NULL)
read_info->current_text = cpystr(EMPTYSTR);
stripcr(read_info->current_text);
break;
case MESSAGE_RAWPART:
case MESSAGE_IN_MEMORY:
case MESSAGE_FROM_FILE:
default:
break;
}
if(local_body) {
if(read_info->alt_text)
fs_give((void **) &read_info->alt_text);
if(read_info->envelope)
subject = read_info->envelope->subject;
if(subject == NULL)
subject = "No subject";
decode_subject = (char *) fs_get(strlen(subject) + 1);
*decode_subject = NUL_TERM;
while((decode_ptr = iso_decode(&subject, TRUE)) != NULL) {
strcat(decode_subject,decode_ptr);
fs_give((void **) &decode_ptr);
}
sprintf(buffer,"[%d] %-64.64s (Part %s%s)",
read_info->serialno,
decode_subject,read_info->current_part_str,
(read_info->base_part_str)
? MLGetLocalized(XtNstrRFC822,StrRFC822)
: EMPTYSTR);
XtSetArg(args[n], XmNtitle, buffer); n ++;
XtSetValues(read->shell, args, n); n = 0;
fs_give((void **) &decode_subject);
if((src_text != NULL) && (read_info->visible == TRUE)) {
switch(local_body->encoding) {
case ENCBASE64:
read_info->alt_text =
(char *) rfc822_base64((unsigned char *) src_text,
length,&newlength);
if(read_info->alt_text)
read_info->alt_text[newlength] = NUL_TERM;
break;
case ENCQUOTEDPRINTABLE:
read_info->alt_text =
(char *) rfc822_qprint((unsigned char *) src_text,
length,&newlength);
if(read_info->alt_text)
read_info->alt_text[newlength] = NUL_TERM;
break;
case ENCOTHER:
case ENC7BIT:
case ENC8BIT:
case ENCBINARY:
default:
break;
}
}
if(read_info->alt_text) {
if((foo = strlen(read_info->alt_text)) < newlength)
fs_give((void **) &read_info->alt_text);
else
stripcr(read_info->alt_text);
}
if((local_body->subtype)
&& (((strcasecmp(local_body->subtype,"html")) == STRMATCH))
|| ((strncasecmp(read_info->current_text,"<HTML>",6)) == STRMATCH)){
tmpptr = strip_html((read_info->alt_text)
? read_info->alt_text : read_info->current_text);
if(read_info->alt_text)
fs_give((void **) &read_info->alt_text);
read_info->alt_text = tmpptr;
}
}
if(read_info->mailstream && read_info->msgno) {
sprintf(sequence,"%lu",read_info->msgno);
mail_setflag(read_info->mailstream, sequence, SEEN_FLAG);
mm_flags(read_info->mailstream, read_info->msgno);
}
if(read_info->visible == TRUE)
read_info->fetched = TRUE;
pop_cursor();
return;
}
#ifdef __STDC__
void read_context_switch(Read *read, Read_Info *old, Read_Info *new)
#else
void read_context_switch(read,old,new)
Read *read;
Read_Info *old, *new;
#endif
{
char buffer[FILEBUFFLEN];
char *subject = NULL;
Arg args[ARGLISTSIZE];
int n = 0;
char *decode_subject = NULL;
char *decode_ptr = NULL;
unsigned long selection;
if((read == NULL) || (read->is_realized == FALSE) || (new == NULL))
return;
/*
* old isn't used here. It is only in the arg list to make
* this function syntactically compatible with other context
* switch functions in the program. The difference in the read
* window is that you can't type into it, so there's no old
* context to save. Instead we use this function whenever we
* need to update the contents of the read window, either to change
* messages, or to navigate a multipart, or just to toggle the
* header mode.
*/
read->current = new;
selection = read->current->selection;
/* zap! */
XmTextSetString(read->read_header, EMPTYSTR);
XmTextSetString(read->read_text,EMPTYSTR);
XmListDeselectAllItems(read->read_attach);
XmListDeleteAllItems(read->read_attach);
switch(new->message_type) {
case MESSAGE_NORMAL:
case MESSAGE_PART:
if(new->fetched == FALSE)
read_fetch(new,new->body);
if((new->show_long_header == TRUE) && (new->header))
XmTextSetString(read->read_header,new->header);
if((new->show_long_header == FALSE) && (new->short_header))
XmTextSetString(read->read_header,new->short_header);
if(new->visible) {
if(new->alt_text)
XmTextSetString(read->read_text,new->alt_text);
else
if(new->current_text)
XmTextSetString(read->read_text,new->current_text);
}
else
XmTextSetString(read->read_text,MLGetLocalized(XtNmsgBinaryMessage,
MsgBinaryMessage));
XtSetKeyboardFocus(read->shell, read->read_text);
read_make_attachment_list(read);
if(selection) {
read->current->selection = selection;
XmListSelectPos(read->read_attach,selection,FALSE);
XmListSetPos(read->read_attach,selection);
new->button_state &= (~BTN_NOATTACHSELECT);
}
else
new->button_state |= BTN_NOATTACHSELECT;
break;
case MESSAGE_RAWPART:
case MESSAGE_IN_MEMORY:
case MESSAGE_FROM_FILE:
default:
break;
}
if(new && new->envelope && new->envelope->subject) {
subject = new->envelope->subject;
if(subject == NULL)
subject = "No subject";
decode_subject = (char *) fs_get(strlen(subject) + 1);
*decode_subject = NUL_TERM;
while((decode_ptr = iso_decode(&subject, TRUE)) != NULL) {
strcat(decode_subject, decode_ptr);
fs_give((void **) &decode_ptr);
}
}
sprintf(buffer,"[%d] %-64.64s (Part %s%s)",
new->serialno,
(decode_subject) ? decode_subject : EMPTYSTR,
new->current_part_str,
(new->base_part_str)
? MLGetLocalized(XtNstrRFC822,StrRFC822) : EMPTYSTR);
XtSetArg(args[n], XmNtitle, buffer); n ++;
XtSetValues(read->shell, args, n); n = 0;
if(decode_subject)
fs_give((void **) &decode_subject);
read_check_buttons();
XmProcessTraversal(read->read_text, XmTRAVERSE_CURRENT);
XmUpdateDisplay(read->shell);
return;
}
#ifdef __STDC__
void read_make_attachment_list(Read *read)
#else
void read_make_attachment_list(read)
Read *read;
#endif
{
/* Erase current list contents and start over */
XmListDeselectAllItems(read->read_attach);
XmListDeleteAllItems(read->read_attach);
read->current->selection = 0;
if(read->current->part_list)
destroy_part_list(read->current->part_list);
read->current->part_list = NULL;
if(read->current->body == NULL) {
read_check_buttons();
return;
}
if(read->current->body->type != TYPEMULTIPART)
read_add_this_part(read->read_attach,read);
read_add_attach_strings(read->read_attach, read,
read->current->attachments,0,
(read->current->base_part_str)
? read->current->base_part_str : EMPTYSTR);
read->current->button_state &= ~(BTN_NOATTACH);
read_check_buttons();
return;
}
#ifdef __STDC__
void read_add_this_part(Widget w, Read *read)
#else
void read_add_this_part(w,read)
Widget w;
Read *read;
#endif
{
char buffer[FILEBUFFLEN];
char partbuff[FILEBUFFLEN];
Part_List *part_list;
XmString xstr;
int len;
struct mail_body_parameter *params;
strcpy(buffer,type_to_name(read->current->body->type));
strcat(buffer,TYPE_SEPARATOR_STR);
strcat(buffer,(read->current->body->subtype)
? read->current->body->subtype : NOSUBTYPE );
if(read->current->rfc_msg_leaf == TRUE)
strcpy(partbuff,read->current->base_part_str);
else {
if(read->current->base_part_str)
sprintf(partbuff,"%s.1", read->current->base_part_str);
else
sprintf(partbuff,"1");
}
strcat(buffer," (Part ");
strcat(buffer,partbuff);
strcat(buffer,") ");
for(len = strlen(buffer); len < (COMPOSEWIDTH/2); len ++)
strcat(buffer,SPACESTR);
if((read->current->body->description) &&
((int) (strlen(buffer)
+ strlen(read->current->body->description)) < FILEBUFFLEN))
strcat(buffer, read->current->body->description);
for(params = read->current->body->parameter;
params; params = params->next) {
if((int) (strlen(buffer) + strlen(params->attribute)
+ strlen(params->value) + 2) >= FILEBUFFLEN)
break;
strcat(buffer,SPACESTR);
strcat(buffer,params->attribute);
strcat(buffer,"=");
strcat(buffer,params->value);
}
xstr = XmStringCreateSimple(buffer);
XmListAddItemUnselected(w,xstr,0);
XmStringFree(xstr);
part_list = (Part_List *) fs_get(sizeof(Part_List));
part_list->partstr = cpystr("1");
part_list->partnumber = 1;
part_list->next = NULL;
part_list->prev = NULL;
part_list->part = NULL;
read->current->part_list = part_list;
return;
}
#ifdef __STDC__
void read_add_attach_strings(Widget w, Read *read, PART *part,
int level, char *partstr)
#else
void read_add_attach_strings(w,read,part,level, partstr)
Widget w;
Read *read;
PART *part;
int level;
char *partstr;
#endif
{
int len;
PART *curr;
char buffer[FILEBUFFLEN];
char partbuff[FILEBUFFLEN];
struct mail_body_parameter *params;
XmString xstr;
Part_List *part_list;
Part_List *curr_part_list;
int subpart_cnt = 0;
if(part == NULL)
return;
strcpy(partbuff,EMPTYSTR);
for(curr = part; curr; curr = curr->next) {
subpart_cnt ++;
if(*partstr == NUL_TERM)
sprintf(partbuff,"%d",subpart_cnt);
else
sprintf(partbuff,"%s.%d",partstr,subpart_cnt);
strcpy(buffer,EMPTYSTR);
for(len = 0; len < level; len ++)
strcat(buffer,SPACESTR);
strcat(buffer,type_to_name(curr->body.type));
strcat(buffer,TYPE_SEPARATOR_STR);
strcat(buffer,(curr->body.subtype) ? curr->body.subtype : NOSUBTYPE );
strcat(buffer," (Part ");
strcat(buffer,partbuff);
strcat(buffer,") ");
for(len = strlen(buffer); len < (COMPOSEWIDTH/2); len ++)
strcat(buffer,SPACESTR);
if((curr->body.description)
&& ((int) (strlen(buffer)
+ strlen(curr->body.description)) < FILEBUFFLEN)) {
strcat(buffer,curr->body.description);
strcat(buffer,SPACESTR);
}
for(params = curr->body.parameter; params; params = params->next) {
if((int) (strlen(buffer) + strlen(params->attribute)
+ strlen(params->value) + 2) >= FILEBUFFLEN)
break;
strcat(buffer,params->attribute);
strcat(buffer,"=");
strcat(buffer,params->value);
strcat(buffer,SPACESTR);
}
xstr = XmStringCreateSimple(buffer);
XmListAddItemUnselected(w,xstr,0);
XmStringFree(xstr);
part_list = (Part_List *) fs_get(sizeof(Part_List));
part_list->partstr = cpystr(partbuff);
part_list->next = NULL;
part_list->part = curr;
if(read->current->part_list == NULL) {
read->current->part_list = part_list;
part_list->partnumber = 1;
part_list->prev = NULL;
}
else {
for(curr_part_list = read->current->part_list; curr_part_list->next;
curr_part_list = curr_part_list->next);
curr_part_list->next = part_list;
part_list->prev = curr_part_list;
part_list->partnumber = curr_part_list->partnumber + 1;
}
if(curr->body.type == TYPEMULTIPART)
read_add_attach_strings(w, read, curr->body.contents.part,
level+1, partbuff);
}
return;
}
#ifdef __STDC__
void read_reply_sender(Widget w, Read *read, XtPointer xp)
#else
void read_reply_sender(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
compose_message(COMPOSE_REPLY, FALSE, NULL, NULL, read->current);
return;
}
#ifdef __STDC__
void read_reply_all(Widget w, Read *read, XtPointer xp)
#else
void read_reply_all(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
compose_message(COMPOSE_REPLYALL, FALSE, NULL, NULL, read->current);
return;
}
#ifdef __STDC__
void read_forward(Widget w, Read *read, XtPointer xp)
#else
void read_forward(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
compose_message(COMPOSE_FORWARD, FALSE, NULL, NULL, read->current);
return;
}
#ifdef __STDC__
void read_forward_attach(Widget w, Read *read, XtPointer xp)
#else
void read_forward_attach(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
compose_message(COMPOSE_FORWARDATTACH, FALSE, NULL, NULL, read->current);
return;
}
#ifdef __STDC__
void read_remail(Widget w, Read *read, XtPointer xp)
#else
void read_remail(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
compose_message(COMPOSE_REMAIL, FALSE, NULL, NULL, read->current);
return;
}
/* called from mm_expunged(). Just mark 'em, we'll clean up later. */
#ifdef __STDC__
void read_expunge(MAILSTREAM *mailstream, unsigned long msgno)
#else
void read_expunge(mailstream,msgno)
MAILSTREAM *mailstream;
unsigned long msgno;
#endif
{
Read *read;
Read_Info *read_info;
for(read = session->read; read; read = read->next)
for(read_info = read->read_info; read_info; read_info = read_info->prev) {
if(read_info->mailstream != mailstream)
continue;
if(read_info->msgno == msgno)
read_info->expunged = TRUE;
if(read_info->msgno > msgno)
read_info->msgno --;
}
return;
}
/*
* Called after an expunge has returned. This is so we don't
* run into a c-client recursion if the next message needs to be
* fetched.
*/
#ifdef __STDC__
void read_after_expunge(void)
#else
void read_after_expunge()
#endif
{
Read *read;
Read_Info *read_info;
Boolean found;
do {
found = FALSE;
for(read = session->read; read; read = read->next) {
for(read_info = read->read_info; read_info;
read_info = read_info->prev) {
if(read_info->expunged == TRUE) {
found = TRUE;
if(read_info == read->current)
read_kill_current(read->shell,read,NULL);
else
kill_read_info(read_info);
break;
}
}
}
} while (found == TRUE);
return;
}
#ifdef __STDC__
void read_set_deleted(Widget w, Read *read, XtPointer xp)
#else
void read_set_deleted(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read_setflag(w,read,DELETED_FLAG);
return;
}
#ifdef __STDC__
void read_set_seen(Widget w, Read *read, XtPointer xp)
#else
void read_set_seen(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read_setflag(w,read,SEEN_FLAG);
return;
}
#ifdef __STDC__
void read_set_flagged(Widget w, Read *read, XtPointer xp)
#else
void read_set_flagged(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read_setflag(w,read,FLAGGED_FLAG);
return;
}
#ifdef __STDC__
void read_set_answered(Widget w, Read *read, XtPointer xp)
#else
void read_set_answered(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read_setflag(w,read,ANSWERED_FLAG);
return;
}
#ifdef __STDC__
void read_clear_deleted(Widget w, Read *read, XtPointer xp)
#else
void read_clear_deleted(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read_clearflag(w,read,DELETED_FLAG);
return;
}
#ifdef __STDC__
void read_clear_seen(Widget w, Read *read, XtPointer xp)
#else
void read_clear_seen(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read_clearflag(w,read,SEEN_FLAG);
return;
}
#ifdef __STDC__
void read_clear_flagged(Widget w, Read *read, XtPointer xp)
#else
void read_clear_flagged(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read_clearflag(w,read,FLAGGED_FLAG);
return;
}
#ifdef __STDC__
void read_clear_answered(Widget w, Read *read, XtPointer xp)
#else
void read_clear_answered(w,read,xp)
Widget w;
Read *read;
XtPointer xp;
#endif
{
read_clearflag(w,read,ANSWERED_FLAG);
return;
}
#ifdef __STDC__
void read_setflag(Widget w, Read *read, char *flag)
#else
void read_setflag(w,read,flag)
Widget w;
Read *read;
char *flag;
#endif
{
char sequence[32];
if(read->current->mailstream && read->current->msgno) {
sprintf(sequence,"%lu",read->current->msgno);
push_cursor(WATCH_CURSOR);
mail_setflag(read->current->mailstream, sequence, flag);
mm_flags(read->current->mailstream, read->current->msgno);
pop_cursor();
}
return;
}
#ifdef __STDC__
void read_clearflag(Widget w, Read *read, char *flag)
#else
void read_clearflag(w,read,flag)
Widget w;
Read *read;
char *flag;
#endif
{
char sequence[32];
if(read->current->mailstream && read->current->msgno) {
sprintf(sequence,"%lu",read->current->msgno);
push_cursor(WATCH_CURSOR);
mail_clearflag(read->current->mailstream, sequence, flag);
mm_flags(read->current->mailstream, read->current->msgno);
pop_cursor();
}
return;
}
#ifdef __STDC__
void read_select_text(Widget w, Read *read, char *flag)
#else
void read_select_text(w,read,flag)
Widget w;
Read *read;
char *flag;
#endif
{
char *ptr = XmTextGetString(read->read_text);
if(ptr) {
XmTextSetSelection(read->read_text,0, strlen(ptr),
XtLastTimestampProcessed(display));
fs_give((void **) &ptr);
}
return;
}
#ifdef __STDC__
void read_copy_text(Widget w, Read *read, char *flag)
#else
void read_copy_text(w,read,flag)
Widget w;
Read *read;
char *flag;
#endif
{
XmTextCopy(read->read_text,
XtLastTimestampProcessed(display));
return;
}
#ifdef __STDC__
void read_pop(Widget w, XtPointer xp)
#else
void read_pop(w,xp)
Widget w;
XtPointer xp;
#endif
{
Read *read;
for(read = session->read; read; read = read->next) {
if(read->read_text == w) {
read_close_window(w,read,NULL);
break;
}
}
return;
}
syntax highlighted by Code2HTML, v. 0.9.1