static char rcsid[] = "@(#)$Id: mailmsg1.c,v 1.72 2006/06/27 19:35:35 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.72 $ $State: Exp $
*
* Modified by: Kari Hurtta <hurtta+elm@posti.FMI.FI>
* (was hurtta+elm@ozone.FMI.FI)
******************************************************************************
* The Elm Mail System
*
* Copyright (c) 1988-1992 USENET Community Trust
* Copyright (c) 1986,1987 Dave Taylor
*****************************************************************************/
/** Interface to allow mail to be sent to users. Part of ELM **/
#include "def_elm.h"
#include "s_elm.h"
DEBUG_VAR(Debug,__FILE__,"mail");
static unsigned char *s2us P_((char *str));
static unsigned char *s2us(str)
char *str;
{
return (unsigned char *)str;
}
static enum copy_msg_mode { cm_no_copy = 0, cm_get_copy, cm_canceled_mail,
cm_mimeforward, cm_CANCEL
} copy_the_msg P_((struct mailing_headers *headers,
int options,
struct menu_context *page,
struct menu_context *prompt_area));
static CONST unsigned char * csUs P_((const char *str));
static CONST unsigned char * csUs(str)
CONST char *str;
{
return (CONST unsigned char *)str;
}
static void output_to_tail P_((struct string *newaddress,
struct menu_context *page,
int to_line, int to_col));
static void output_to_tail(newaddress,page,to_line,to_col)
struct string *newaddress;
struct menu_context *page;
int to_line;
int to_col;
{
int wide = 0 == to_col; /* mail only */
int li, co;
menu_get_sizes(page,&li, &co);
if (wide)
if (string_len(newaddress) > 80)
menu_PutLineX(page,to_line, to_col,
CATGETS(elm_msg_cat, ElmSet, ElmToParen,
"To: (%.*S...)"),
60,newaddress);
else
menu_PutLineX(page,to_line, to_col,
CATGETS(elm_msg_cat, ElmSet, ElmToNoParen,
"To: %S"),
newaddress);
/* FIXME: Not completely correct ... */
else if (string_len(newaddress) + to_col +7 < co ) {
int LI, CO;
int newpos = co - string_len(newaddress) -7;
menu_GetXYLocation(page,&LI,&CO);
if (LI == to_line && CO <= newpos) {
menu_CleartoEOLN(page);
} else {
menu_MoveCursor(page,to_line,to_col);
menu_CleartoEOLN(page);
}
menu_PutLineX(page,to_line, newpos,
CATGETS(elm_msg_cat, ElmSet, ElmToNoParen,
"To: %S"),
newaddress);
} else if (string_len(newaddress) > 50)
menu_PutLineX(page,to_line, to_col,
CATGETS(elm_msg_cat, ElmSet, ElmToParen,
"To: (%.*S...)"),
40,newaddress);
else {
if (string_len(newaddress) > 30)
menu_PutLineX(page,to_line, to_col,
CATGETS(elm_msg_cat, ElmSet, ElmToNoParen,
"To: %S"),
newaddress);
else
menu_PutLineX(page,to_line, to_col,
CATGETS(elm_msg_cat, ElmSet, ElmToNoParen2,
" To: %S"),
newaddress);
menu_CleartoEOLN(page);
}
}
static void output_abbreviated_to P_((struct addr_item *addrs,
struct menu_context *page,
int to_line, int to_col
));
static void output_abbreviated_to (addrs, page, to_line, to_col)
struct addr_item *addrs;
struct menu_context *page;
int to_line;
int to_col;
{
struct string *newaddress = NULL;
struct addr_item *p;
for (p = addrs; p && p->fullname && p->addr; p++) {
if (newaddress)
add_ascii_to_string(newaddress,s2us(", "));
else
newaddress = new_string(display_charset);
if (string_len(p->fullname)) {
struct string * temp = cat_strings(newaddress,p->fullname,1);
free_string(&newaddress);
newaddress = temp;
} else {
add_ascii_to_string(newaddress,csUs(p->addr));
}
}
if (!newaddress)
return;
output_to_tail(newaddress,page,to_line,to_col);
free_string(&newaddress);
return;
}
void display_to(address,page,prompt_area)
struct expanded_address address;
struct menu_context *page;
struct menu_context *prompt_area; /* NULL if mail only mode */
{
/** Simple routine to display the "To:" line according to the
current configuration (etc)
**/
struct string *addr_string;
struct menu_context *p;
int to_line, to_col;
int li, co;
if (prompt_area) {
menu_get_sizes(prompt_area,&li, &co);
to_line = 0;
to_col = co -50;
p = prompt_area;
} else { /* Mail only */
menu_get_sizes(page,&li, &co);
to_line = 3;
to_col = 0;
p = page;
}
if (names_only) {
output_abbreviated_to(address.addrs,p,to_line,to_col);
return;
}
addr_string = hdr_to_expval(address);
if (!addr_string)
return;
output_to_tail(addr_string,p,to_line,to_col);
free_string(&addr_string);
}
int get_to(to,mailer_info,aview, page, cancel_view, cancel_selection,
prompt_area)
struct expanded_address *to;
struct mailer_info *mailer_info;
struct AliasView *aview;
struct menu_context *page;
struct MailboxView *cancel_view;
int *cancel_selection;
struct menu_context *prompt_area;
{
struct string * buffer = NULL;
int li, co;
int delay_redraw = 0;
int can_flag = 0;
menu_get_sizes(prompt_area,&li, &co);
if (cancel_selection)
*cancel_selection = -1;
/** prompt for the "To:" field, expanding into address if possible.
This routine returns ZERO if errored, or non-zero if okay **/
expanded_to_edit_buffer(&buffer, *to);
if (to->surface_len == 0) {
int canceled_count = 0;
int flag = 0;
int line;
int code;
int ul = give_dt_enumerate_as_int(&user_level);
if (cancel_view)
canceled_count = get_message_count(cancel_view);
DPRINT(Debug,7,(&Debug,
"canceled_count=%d\n",
canceled_count));
redraw:
line = 1;
if (canceled_count > 1 && cancel_selection) {
menu_print_format_center(prompt_area,line,
CATGETS(elm_msg_cat, ElmSet,
ElmIsCanceledX,
"%d canceled mails. Use / to select one of them."),
canceled_count);
line++;
flag |= OE_ALT_SOLIDUS;
} else if (1 == canceled_count && cancel_selection) {
menu_print_format_center(prompt_area,line,
CATGETS(elm_msg_cat, ElmSet,
ElmIsCanceled1,
"1 canceled mail. Use / to select it."));
line++;
flag |= OE_ALT_SOLIDUS;
}
/* On redrawing / sould not go to cancel view */
if (delay_redraw && buffer && string_len(buffer) > 0)
flag = OE_APPEND_CURRENT;
if (ul < 2) {
/* FIXME --optionally_enter* should use prompt_area */
int line1 = menu_GetAbsLine(prompt_area,line);
code = optionally_enter2(page,
&buffer, line1, 0,
OE_REDRAW_MARK|flag|
OE_SIG_CHAR /* Ctrl-C */,
CATGETS(elm_msg_cat, ElmSet,
ElmSendTheMessageTo,
"Send the message to: "));
if (REDRAW_MARK == code) {
menu_ClearScreen(page); /* Clear possible redraw mark */
/* Call refresh routines of children */
menu_redraw_children(page);
if (menu_need_redraw(prompt_area))
menu_ClearScreen(prompt_area); /* but clear redraw mark from prompt_area*/
/* NOTICE: using menu_trigger_redraw(page) on here
may cause redraw loop!
*/
delay_redraw++;
goto redraw;
}
} else {
/* FIXME --optionally_enter* should use prompt_area */
int line1 = menu_GetAbsLine(prompt_area,line);
code = optionally_enter2(page,
&buffer, line1, 0,
OE_REDRAW_MARK|flag|
OE_SIG_CHAR /* Ctrl-C */,
CATGETS(elm_msg_cat, ElmSet, ElmTo,
"To: "));
if (code == REDRAW_MARK) {
menu_ClearScreen(page); /* Clear possible redraw mark */
/* Call refresh routines of children */
menu_redraw_children(page);
if (menu_need_redraw(prompt_area))
menu_ClearScreen(prompt_area); /* but clear redraw mark from prompt_area*/
/* NOTICE: using menu_trigger_redraw(page) on here
may cause redraw loop!
*/
delay_redraw++;
goto redraw;
}
}
if (OE_ALT_SOLIDUS == code) {
can_flag = view_canceled_mails(cancel_view,
cancel_selection,aview);
menu_ClearScreen(page);
/* Call refresh routines of children */
menu_redraw_children(page);
if (menu_need_redraw(prompt_area))
menu_ClearScreen(prompt_area); /* Clear redraw mark from prompt_area*/
delay_redraw = 1;
}
if (0 != code || can_flag) {
if (-1 == code) { /* Ctrl-C */
menu_ClearLine(prompt_area,1);
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmMailNotSent,
"Mail not sent."));
}
if (buffer)
free_string(&buffer);
if (delay_redraw)
menu_trigger_redraw(page);
if (can_flag > 0) {
DPRINT(Debug,4,(&Debug, "get_to: Canceled mail selected\n"));
return 1; /* Canceled mail selected */
}
return 0;
}
if (string_len(buffer) == 0) {
free_expanded_address(to);
menu_ClearLine(prompt_area,1);
free_string(&buffer);
if (delay_redraw)
menu_trigger_redraw(page);
return 0;
}
update_expanded_from_edit_buffer(to,buffer,mailer_info,
aview);
}
build_address_l(to,mailer_info,aview);
if (to->addrs_len == 0) { /* bad address! Removed!! */
menu_ClearLine(prompt_area,1);
free_string(&buffer);
if (delay_redraw)
menu_trigger_redraw(page);
return 0;
}
free_string(&buffer);
if (delay_redraw)
menu_trigger_redraw(page);
return 1; /* everything is okay... */
}
static int get_copies P_((struct expanded_address * cc,
int copy_message,
struct mailer_info *mailer_info,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area));
static int get_subject P_((struct string **field,
struct menu_context *page,
struct menu_context *prompt_area));
int send_msg_middle2(headers,index,options,form_letter,mailer_info,
mailbox,aview,page,prompt_area,body)
struct mailing_headers *headers;
int index;
int options;
int form_letter;
struct mailer_info *mailer_info;
struct MailboxView *mailbox;
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area;
struct text_block *body;
{
enum copy_msg_mode copy_msg = cm_no_copy;
char *p;
struct MailboxView *cancel_view = NULL;
int cancel_selection = -1;
int forwarding = 0 != (options & MAIL_FORWARDING);
int replying = 0 != (options & MAIL_REPLYING);
int ask_send = 0 != (options & MAIL_ASK_SEND);
int r = 0;
if ((p = getenv("REPLYTO")) != NULL) {
struct string * X = new_string2(system_charset,
s2us(p));
update_expanded_from_edit_buffer(&(headers->reply_to),X,
mailer_info,aview);
free_string(&X);
}
/* auto bcc line */
if ((p = getenv("BCC")) != NULL) {
struct string * X = new_string2(system_charset,
s2us(p));
update_expanded_from_edit_buffer(&(headers->bcc),X,mailer_info,
aview);
free_string(&X);
}
if (prompt_area) { /* Not a batch mode */
DPRINT(Debug,7,(&Debug,
"prompt_area=%p prompt questions -- not in batch mode\n",
prompt_area));
/* copy msg into edit buffer? */
copy_msg = copy_the_msg(headers,
options, page, prompt_area);
switch (copy_msg) {
case cm_CANCEL:
goto free_it;
case cm_get_copy:
options |= MAIL_COPY_MSG;
break;
case cm_mimeforward:
options |= MAIL_MIME_ATTCH;
options |= MAIL_COPY_MSG;
break;
default:
if (!forwarding &&
!replying)
cancel_view = give_canceled_mail();
DPRINT(Debug,7,(&Debug,"cancel_view=%p%s\n",
cancel_view,
cancel_view ? "" : " (NULL)"));
break;
}
/* get the To: address and expand --
*/
if (! get_to(&(headers->to),mailer_info,aview, page,cancel_view,
&cancel_selection,prompt_area)) {
goto free_it;
}
if (cancel_selection >= 0) {
struct header_rec * H = give_header(cancel_view,cancel_selection);
if (H) {
options |= MAIL_COPY_SELECTION | MAIL_DELETE_CANCEL;
/* Copy some addresses from header struct
*
* Actually these addresses will be overwritten whan
* canceled mail is readed and parsed
*/
if (!(headers->subject) && H->subject)
headers->subject = dup_string(H->subject);
expanded_address_from_items (&(headers->from), H->from);
expanded_address_from_items (&(headers->to), H->to);
expanded_address_from_items (&(headers->cc), H->cc);
}
}
} else { /* batch mode */
/* expand the To: address */
if (headers->to.surface_len)
build_address_l(&(headers->to),mailer_info,aview);
}
/* expand the Cc: address */
if (headers->cc.surface_len)
build_address_l(&(headers->cc),mailer_info,aview);
/* expand the Reply-To: address */
if (headers->reply_to.surface_len)
build_address_l(&(headers->reply_to),mailer_info,aview);
/* expand the bcc address */
if (headers->bcc.surface_len)
build_address_l(&(headers->bcc),mailer_info,aview);
DPRINT(Debug,4,(&Debug, "send_msg_middle2 -- options (%d): %s%s%s%s%s%s%s%s\n",
options,
options & MAIL_COPY_MSG ? " MAIL_COPY_MSG" : "",
options & MAIL_EDIT_MSG ? " MAIL_EDIT_MSG" : "",
options & MAIL_ISFORM ? " MAIL_ISFORM" : "",
options & MAIL_REPLYING ? " MAIL_REPLYING" : "",
options & MAIL_FORWARDING ? " MAIL_FORWARDING" : "",
options & MAIL_MIME_ATTCH ? " MAIL_MIME_ATTCH" : "",
options & MAIL_COPY_SELECTION ? " MAIL_COPY_SELECTION" : "",
options & MAIL_DELETE_CANCEL ? " MAIL_DELETE_CANCEL" : ""));
/** if we're batchmailing, let's send it and GET OUTTA HERE!
**
** If MAIL_COPY_SELECTION is set data for headers will be readed
** from canceled mail, do not prompt anything
**/
dump_expanded_address(4,"send_msg_middle2 -- from ",headers->from);
dump_expanded_address(4,"send_msg_middle2 -- to ",headers->to);
dump_expanded_address(4,"send_msg_middle2 -- cc ",headers->cc);
if (!prompt_area ||
(options & MAIL_COPY_SELECTION)) {
mail(index, options, form_letter,headers,mailer_info,
mailbox, aview, page,
cancel_view,cancel_selection,body);
/* mail does menu_trigger_redraw(), not need to be examine */
} else {
int redraw1 = 0;
struct menu_context *use_prompt_area = mail_only ? NULL : prompt_area;
again1:
display_to(headers->to, page, use_prompt_area);
/* URL code may want verify sending ... */
if (ask_send && use_prompt_area) {
struct string * addr_string = hdr_to_expval(headers->to);
int X1;
if (!addr_string) {
goto free_it;
}
X1 = prompt_letter(1,"",*def_ans_no,
PROMPT_yesno|PROMPT_cancel|
PROMPT_redraw_mark|PROMPT_ctrlL,
prompt_area,
CATGETS(elm_msg_cat, ElmSet, ElmAskSendMailTo,
"Send mail to %.50S%s ? (%c/%c) "),
addr_string,
string_len(addr_string) > 50 ? "..." : "",
*def_ans_yes, *def_ans_no);
free_string(&addr_string);
if (TERMCH_interrupt_char == X1 ||
EOF == X1) {
goto free_it;
}
if (X1 == ('L'&31) || X1 == REDRAW_MARK) {
menu_ClearScreen(page); /* Clear possible redraw mark */
/* Call refresh routines of children */
menu_redraw_children(page);
if (menu_need_redraw(prompt_area))
menu_ClearScreen(prompt_area); /* but clear redraw mark from prompt_area*/
/* NOTICE: using menu_trigger_redraw(page) on here
may cause redraw loop!
*/
redraw1 = 1;
goto again1;
}
if (X1 != *def_ans_yes)
goto free_it;
}
if (redraw1)
menu_trigger_redraw(page);
/* get the Subject: field */
if (get_subject(&(headers->subject), page,
use_prompt_area) == 0) {
goto free_it;
}
if (prompt_for_cc) {
if (get_copies(&(headers->cc), copy_msg, mailer_info,
aview, page,
use_prompt_area) == 0) {
goto free_it;
}
}
menu_MoveCursor(prompt_area,3,0); /* so you know you've hit <return> ! */
FlushBuffer();
/** generate the In-Reply-To: header... **/
if ( 0 != (options & MAIL_REPLYING)) {
struct header_rec *current_header = give_header(mailbox,index);
if (current_header)
generate_reply_to(current_header,headers);
}
/* and mail that puppy outta here! */
DPRINT(Debug,3,(&Debug,
"\nsend_msg() ready to mail...\n"));
dump_expanded_address(3,"to",headers->to);
if (headers->subject) {
DPRINT(Debug,3,
(&Debug,"subject=\"%S\"\n",
headers->subject));
}
dump_expanded_address(5,"cc",headers->cc);
dump_expanded_address(5,"bcc",headers->bcc);
mail(index,options, form_letter,headers,
mailer_info,
mailbox, aview, page,
cancel_view,cancel_selection,body);
/* mail does menu_trigger_redraw(), not need to be examine */
}
r = 1;
free_it:
if (cancel_view)
sync_canceled_mails(cancel_view);
if (prompt_area)
menu_trigger_redraw(prompt_area);
return r;
}
static int send_msg_middle P_((
int index,
struct expanded_address *given_to,
struct expanded_address *given_cc,
char *given_subject,
int options, int form_letter,
struct mailer_info *mailer_info,
struct MailboxView *mailbox,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area,
struct text_block *body));
static int send_msg_middle(index,
given_to, given_cc, given_subject, options,
form_letter,mailer_info,
mailbox,aview, page, prompt_area,body)
int index;
struct expanded_address *given_to, *given_cc;
char *given_subject;
int options, form_letter;
struct mailer_info *mailer_info;
struct MailboxView *mailbox;
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area; /* NULL in patch mode */
struct text_block *body;
{
struct mailing_headers headers;
int r = 0;
zero_mailing_headers(&headers);
if (!mailer_info)
return 0;
if (given_subject)
headers.subject = new_string2(display_charset,s2us(given_subject));
if (given_to)
copy_expanded_address(&headers.to,*given_to);
if (given_cc)
copy_expanded_address(&headers.cc,*given_cc);
r = send_msg_middle2(&headers,index,options,form_letter,mailer_info,
mailbox, aview,page,prompt_area,body);
free_mailing_headers(&headers);
return r;
}
int send_msg_l(index,
given_to, given_cc, given_subject, options, form_letter,
mailbox, aview, page, prompt_area
)
int index;
struct addr_item *given_to, *given_cc;
char *given_subject;
int options, form_letter;
struct MailboxView *mailbox;
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area;
{
int r;
/* If redraw is needed use
menu_trigger_redraw(page)
*/
struct expanded_address A, B;
struct mailer_info *mailer_info = get_mailer_info();
if (!mailer_info)
return 0;
zero_expanded_address(&A);
zero_expanded_address(&B);
addr_to_expanded(&A,given_to,mailer_info,aview);
addr_to_expanded(&B,given_cc,mailer_info,aview);
r = send_msg_middle(index,&A,&B,
given_subject,options,form_letter,
mailer_info,
mailbox, aview, page,
prompt_area,NULL);
/* send_msg_middle does menu_trigger_redraw(page),
do not need examine */
free_expanded_address(&A);
free_expanded_address(&B);
free_mailer_info(&mailer_info);
return r;
}
int send_msg_argv(argv, given_subject, options, form, aview,
page, prompt_area)
char *argv[];
char *given_subject;
int options;
int form;
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area; /* NULL in patch mode */
{
struct expanded_address A, B;
struct mailer_info *mailer_info = get_mailer_info();
struct text_block *body = NULL;
int ret = 0;
if (!mailer_info)
return 0;
zero_expanded_address(&A);
zero_expanded_address(&B);
argv_to_expanded(&A,argv,mailer_info,aview);
if (included_file[0]) {
body = block_from_filename(included_file,
system_charset /* Is correct? */,
0);
if (!body) {
DPRINT(Debug,4,(&Debug,
"send_msg_argv: block_from_filename() failed to include %s\n",
included_file));
goto fail;
}
} else if (batch_only) {
body = block_from_stdin();
if (!body) {
DPRINT(Debug,4,(&Debug,
"send_msg_argv: block_from_stdin() failed to include stdin\n",
included_file));
goto fail;
}
}
ret = send_msg_middle(-1,&A,&B,
given_subject,options,form,mailer_info,
NULL, aview, page, prompt_area,
body);
/* send_msg_middle uses menu_trigger_redraw(),
need not examine
*/
fail:
if (body)
free_block(&body);
free_expanded_address(&A);
free_expanded_address(&B);
free_mailer_info(&mailer_info);
return ret;
}
int send_msg_url(url,given_subject,options,form,aview,page,prompt_area)
CONST struct url *url;
char *given_subject;
int options;
int form;
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area;
{
struct mailer_info *mailer_info = get_mailer_info();
struct mailing_headers headers;
int r = 0;
struct text_block *body = NULL;
int errors = 0;
zero_mailing_headers(&headers);
if (!mailer_info) {
DPRINT(Debug,5,(&Debug,
"send_msg_url: No mailer_info\n"));
return 0;
}
body = give_text_body_from_url(url,mime_body_keywords,&errors);
if (errors)
goto fail;
if (body) {
if (included_file[0]) {
lib_error(CATGETS(elm_msg_cat, ElmSet,
ElmUrlSubjectandInclude,
"Both -i %s and body on -O given"),
included_file);
goto fail;
}
} else if (included_file[0]) {
body = block_from_filename(included_file,
system_charset /* Is correct? */,
0);
if (!body)
goto fail;
} else if (batch_only) {
body = block_from_stdin();
if (!body)
goto fail;
}
r = set_mailing_headers_from_url(&headers,url,mailer_info);
if (!r) {
DPRINT(Debug,5,(&Debug,
"send_msg_url: set_mailing_headers_from_url failed!\n"));
goto fail;
}
if (given_subject && !headers.subject)
headers.subject = new_string2(display_charset,s2us(given_subject));
r = send_msg_middle2(&headers,-1,options,form,mailer_info,NULL,aview,
page,prompt_area,body);
fail:
if (body)
free_block(&body);
free_mailing_headers(&headers);
free_mailer_info(&mailer_info);
DPRINT(Debug,5,(&Debug,
"send_msg_url=%d\n",r));
return r;
}
static int get_subject(subject_field, page, prompt_area)
struct string **subject_field;
struct menu_context *page;
struct menu_context *prompt_area; /* NULL if mail only mode */
{
char ch, msgbuf[SLEN];
int code;
charset_t utf7;
int prompt_line;
int delay_redraw = 0;
struct menu_context *p;
int flag = 0;
int ul = give_dt_enumerate_as_int(&user_level);
redraw:
if (!prompt_area) { /* Mail only */
p = page;
prompt_line = 4;
} else {
/* FIXME --optionally_enter* should use prompt_area */
p = prompt_area;
prompt_line = menu_GetAbsLine(prompt_area,1);
}
if (ul == 0) {
code = optionally_enter2(page,
subject_field, prompt_line, 0,
OE_APPEND_CURRENT|OE_REDRAW_MARK
/* Allow user paste mime encoded
words to buffer */
|OE_ALLOW_MIMEENC
|OE_SIG_CHAR /* Ctrl-C */,
CATGETS(elm_msg_cat, ElmSet,
ElmSubjectOfMessage,
"Subject of message: "));
} else
code = optionally_enter2(page,
subject_field, prompt_line, 0,
OE_APPEND_CURRENT|OE_REDRAW_MARK
/* Allow user paste mime encoded
words to buffer */
|OE_ALLOW_MIMEENC
|OE_SIG_CHAR /* Ctrl-C */,
CATGETS(elm_msg_cat, ElmSet, ElmSubject,
"Subject: "));
if (REDRAW_MARK == code) {
/* NOTICE: using menu_trigger_redraw(page) on here
may cause redraw loop!
*/
menu_ClearScreen(page); /* Clear possible redraw mark */
/* Call refresh routines of children */
menu_redraw_children(page);
delay_redraw++;
if (prompt_area && menu_need_redraw(prompt_area))
menu_ClearScreen(prompt_area); /* but Clear redraw mark from prompt_area */
goto redraw;
}
if(code==-1){
cancel:
/** User hit Ctrl-C key! **/
MoveCursor(prompt_line,0);
CleartoEOLN();
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmMailNotSent,
"Mail not sent."));
if (delay_redraw)
menu_trigger_redraw(page);
return(0);
}
if (!*subject_field ||
string_len(*subject_field) == 0) { /* zero length subject?? */
int answer;
redraw2:
if (prompt_area)
answer = prompt_letter(1,"",*def_ans_no,
PROMPT_yesno|PROMPT_redraw_mark|
PROMPT_ctrlL|PROMPT_cancel,
prompt_area,
CATGETS(elm_msg_cat, ElmSet,
ElmNoSubjectContinue,
"No subject - Continue with message? (%c/%c) "),
*def_ans_yes, *def_ans_no);
else
answer = prompt_letter(4,"",*def_ans_no,
PROMPT_yesno|PROMPT_redraw_mark|
PROMPT_ctrlL|PROMPT_cancel,
page,
CATGETS(elm_msg_cat, ElmSet,
ElmNoSubjectContinue,
"No subject - Continue with message? (%c/%c) "),
*def_ans_yes, *def_ans_no);
if (('L'&31) == answer ||
REDRAW_MARK == answer) {
menu_ClearScreen(page); /* Reset possible redraw flag */
/* Call refresh routines of children */
menu_redraw_children(page);
if (prompt_area && menu_need_redraw(prompt_area))
menu_ClearScreen(prompt_area);
delay_redraw++; /* Can't trigger redraw yet... */
goto redraw2;
}
if (TERMCH_interrupt_char == answer ||
EOF == answer)
goto cancel;
if (answer != *def_ans_yes) { /* user says no! */
if (sleepmsg > 0)
sleep((sleepmsg + 1) / 2);
ClearLine(prompt_line);
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmMailNotSend,
"Mail not sent."));
if (delay_redraw)
menu_trigger_redraw(page);
return(0);
} else {
PutLineX(prompt_line,0,
CATGETS(elm_msg_cat, ElmSet,
ElmSubjectNone,
"Subject: <none>"));
CleartoEOLN();
if (!*subject_field)
*subject_field = new_string(display_charset);
}
}
if (convert_utf_header && (*subject_field)->string_type->MIME_name &&
0 == istrcmp((*subject_field)->string_type->MIME_name,"UTF-8") &&
0 != (CS_mapping & charset_properties((*subject_field)->string_type)) &&
(utf7 = MIME_name_to_charset("UTF-7",0)) &&
0 != (CS_mapping & charset_properties(utf7))) {
struct string * XX = convert_string(utf7,*subject_field,1);
free_string(subject_field);
*subject_field = XX;
}
if (delay_redraw)
menu_trigger_redraw(page);
return(1); /** everything is cruising along okay **/
}
static int get_copies P_((struct expanded_address *cc,
int copy_message,
struct mailer_info *mailer_info,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area));
static int get_copies(cc,copy_message,mailer_info,aview, page,
prompt_area)
struct expanded_address * cc;
int copy_message;
struct mailer_info *mailer_info;
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area; /* NULL if mail only */
{
/* Get the list of people that should be cc'd, returning ZERO if
* any problems arise.
*
* If copy-message, that means that we're going to have to invoke
* a screen editor, so we'll need to delay after displaying the
* possibly rewritten Cc: line...
*/
int prompt_line;
int code;
struct string *buffer = NULL;
int delay_redraw = 0;
struct menu_context *p;
int flag = 0;
hdr_to_buffer(*cc,&buffer);
redraw:
if (!prompt_area) { /* Mail only */
p = page;
prompt_line = 5;
} else {
/* FIXME --optionally_enter* should use prompt_area */
p = prompt_area;
prompt_line = menu_GetAbsLine(prompt_area,2);
}
FlushBuffer();
if (delay_redraw && buffer &&
string_len(buffer) >0 )
flag = OE_APPEND_CURRENT;
code = optionally_enter2(page,
&buffer, prompt_line,0,
OE_REDRAW_MARK|flag|
OE_SIG_CHAR /* Ctrl-C */,
CATGETS(elm_msg_cat, ElmSet, ElmCopiesTo,
"Copies to: "));
if (REDRAW_MARK == code) {
/* NOTICE: using menu_trigger_redraw(page) on here
may cause redraw loop!
*/
menu_ClearScreen(page); /* Clear possible redraw mark */
/* Call refresh routines of children */
menu_redraw_children(page);
delay_redraw++;
if (prompt_area && menu_need_redraw(prompt_area))
menu_ClearScreen(prompt_area); /* Clear redraw mark from prompt_area */
goto redraw;
}
if (code == -1) { /* Ctrl-C */
ClearLine(prompt_line-1);
ClearLine(prompt_line);
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmMailNotSend,
"Mail not sent."));
/* Free it */
if (buffer)
buffer_to_header(cc,&buffer,TRUE,mailer_info,aview);
if (delay_redraw)
menu_trigger_redraw(page);
return(0);
}
/** The following test is that if the build_address routine had
reason to rewrite the entry given, then, if we're mailing only
print the new Cc line below the old one. If we're not, then
assume we're in screen mode and replace the incorrect entry on
the line above where we are (e.g. where we originally prompted
for the Cc: field).
**/
buffer_to_header(cc,&buffer,FALSE,mailer_info, aview);
if (build_address_l(cc,mailer_info, aview)) {
struct string * B = hdr_to_expval(*cc);
if (B) {
char * editor_val = give_dt_estr_as_str(&editor_e,"editor");
PutLineX(prompt_line, 11, FRM("%S"), B);
if (!editor_val ||
(strcmp(editor_val, "builtin") != 0 &&
strcmp(editor_val, "none") != 0)
|| copy_message)
sleep_message();
free_string(&B);
}
}
if (delay_redraw)
menu_trigger_redraw(page);
return(1); /* everything looks okay! */
}
static enum copy_msg_mode copy_the_msg(headers, options, page, prompt_area)
struct mailing_headers *headers;
int options;
struct menu_context *page;
struct menu_context *prompt_area;
{
int forwarding = 0 != (options & MAIL_FORWARDING);
int replying = 0 != (options & MAIL_REPLYING);
/** Returns True iff the user wants to copy the message being
replied to into the edit buffer before invoking the editor!
**/
char msg[SLEN];
enum copy_msg_mode answer = cm_no_copy;
int redraw = 0;
again:
if (forwarding) {
int X = mimeforward;
if (askmimeforward) {
int def = mimeforward ? *def_ans_yes : *def_ans_no;
int X1;
/* NOTICE: prompt_letter may return EOF */
X1 = prompt_letter(0,"",def,
PROMPT_yesno|PROMPT_cancel|
PROMPT_redraw_mark|PROMPT_ctrlL,
prompt_area,
CATGETS(elm_msg_cat, ElmSet, ElmMimeFWMessageYN,
"Forward message as separate part? (%c/%c) "),
*def_ans_yes, *def_ans_no);
if (TERMCH_interrupt_char == X1) {
answer = cm_CANCEL;
goto out;
}
if (EOF == X1)
goto out;
if (X1 == ('L'&31) || X1 == REDRAW_MARK) {
menu_ClearScreen(page); /* Clear possible redraw mark */
/* Call refresh routines of children */
menu_redraw_children(page);
if (menu_need_redraw(prompt_area))
menu_ClearScreen(prompt_area); /* Clear redraw mark from prompt_area*/
/* NOTICE: using menu_trigger_redraw(page) on here
may cause redraw loop!
*/
redraw = 1;
goto again;
}
X = (X1 == *def_ans_yes);
}
answer = X ? cm_mimeforward : cm_get_copy;
} else if (replying) {
/* predefined 'to' line! */
if (auto_copy)
answer = cm_get_copy;
else {
int X,X1;
/* NOTICE: prompt_letter may return EOF */
X1 = prompt_letter(0,"",*def_ans_no,
PROMPT_yesno|PROMPT_cancel|
PROMPT_redraw_mark|PROMPT_ctrlL,
prompt_area,
CATGETS(elm_msg_cat, ElmSet, ElmCopyMessageYN,
"Copy message? (%c/%c) "),
*def_ans_yes, *def_ans_no);
if (TERMCH_interrupt_char == X1) {
answer = cm_CANCEL;
goto out;
}
if (EOF == X1)
goto out;
if (X1 == ('L'&31) || X1 == REDRAW_MARK) {
menu_ClearScreen(page); /* Clear possible redraw mark */
/* Call refresh routines of children */
menu_redraw_children(page);
if (menu_need_redraw(prompt_area))
menu_ClearScreen(prompt_area); /* Clear redraw mark from prompt_area*/
/* NOTICE: using menu_trigger_redraw(page) on here
may cause redraw loop!
*/
redraw = 1;
goto again;
}
X = (X1 == *def_ans_yes);
answer = X ? cm_get_copy : cm_no_copy;
}
}
out:
if (redraw)
menu_trigger_redraw(page);
DPRINT(Debug,7,(&Debug,"copy_the_msg=%d\n",answer));
return(answer);
}
void a_sendmsg(edit_message, form_letter, mailbox, aview,
page, LOC)
int edit_message, form_letter;
struct MailboxView *mailbox;
struct AliasView *aview;
struct menu_context *page;
struct screen_parts *LOC;
{
/** Prompt for fields and then call mail() to send the specified
message. If 'edit_message' is true then by defualt go to
editor. 'form_letter' can be "YES" "NO" or "MAYBE".
if YES, then add the header. If MAYBE, then add the M)ake form
option to the last question (see mailsg2.c) etc. etc.
If redraw is needed use menu_trigger_redraw(page)
**/
register int tagged = 0, i;
struct mailing_headers headers;
struct mailer_info *mailer_info = get_mailer_info();
zero_mailing_headers(&headers);
tagged = aliases_to_expanded(&headers.to, aview);
DPRINT(Debug,4, (&Debug, "%d aliases tagged for mailing (a_sndmsg)\n",
tagged));
/******* And now the real stuff! *******/
/* build the To: address and expand */
if (build_address_l(&headers.to,mailer_info, aview) == 0) {
free_mailer_info(&mailer_info);
return;
}
display_to(headers.to,page,LOC->prompt_page); /* display the To: field on screen... */
/* get the Subject: field */
if (get_subject(&headers.subject,page,
LOC->prompt_page) == 0) {
goto free_it;
}
if (prompt_for_cc) {
if (get_copies(&headers.cc, FALSE,mailer_info, aview,
page, LOC->prompt_page) == 0) {
goto free_it;
}
}
menu_MoveCursor(LOC->prompt_page,3,0); /* so you know you've hit <return> ! */
FlushBuffer();
/* and mail that puppy outta here! */
DPRINT(Debug,3,(&Debug,
"\na_sendmsg() ready to mail...\n"));
dump_expanded_address(3,"to",headers.to);
if (headers.subject) {
DPRINT(Debug,4, (&Debug,
"subject=\"%S\"\n",
headers.subject));
}
dump_expanded_address(5,"cc",headers.cc);
dump_expanded_address(5,"bcc",headers.bcc);
mail(-1, edit_message ? MAIL_EDIT_MSG : 0, form_letter,
&headers,mailer_info,
mailbox, aview, page,
NULL,-1,NULL);
/*
* Since we got this far, it must be okay to clear the tags.
*/
i = 0;
while (tagged) {
struct alias_rec * a = give_alias(aview,i);
if (a &&
ison(a->status, TAGGED)) {
struct menu_common MENU;
int vis;
clearit(a->status, TAGGED);
set_mcommon_from_aliasview(&MENU,aview);
vis = compute_visible(i+1, &MENU);
menu_header_status_update(LOC->header_page,vis-1);
tagged--;
}
i++;
}
free_it:
free_mailing_headers(&headers);
free_mailer_info(&mailer_info);
/* mail() uses menu_trigger_redraw(page), do not need examine */
return;
}
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1