static char rcsid[] = "@(#)$Id: hdrconfg.c,v 1.55 2006/05/22 19:17:14 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.55 $ $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
*****************************************************************************/
/** This file contains the routines necessary to be able to modify
the mail headers of messages on the way off the machine. The
headers currently supported for modification are:
Subject:
To:
Cc:
Bcc:
Reply-To:
Expires:
Priority:
Precedence:
In-Reply-To:
Action:
<user defined>
**/
#include "def_elm.h"
#include "s_elm.h"
#include <errno.h>
#ifndef ANSI_C
extern int errno;
#endif
DEBUG_VAR(Debug,__FILE__,"header");
static unsigned char *s2us P_((char *str));
static unsigned char *s2us(str)
char *str;
{
return (unsigned char *)str;
}
static char *us2s P_((unsigned char *str));
static char *us2s(str)
unsigned char *str;
{
return (char *)str;
}
/*
* Option flags for the fields in a (struct hdr_menu_item).
*/
#define HF_DISP_1ROW 0001 /* field is displayed on one line */
#define HF_DISP_2ROW 0002 /* field display spans two lines */
#define HF_DISP_3ROW 0003 /* field display spans three lines */
#define HF_DISP_LEFT 0004 /* field occupies left half of a line */
#define HF_DISP_RIGHT 0005 /* field occupies right half of a line */
#define HF_DISP_MASK 0007 /* -- mask to pull out display option */
#define HF_PROMPT_EXP 0010 /* prompt for expires data entry */
#define HF_PROMPT_USR 0020 /* prompt for user defined hdr entry */
#define HF_PROMPT_MASK 0070 /* -- mask to pull out prompt option */
#define HF_APPENDENTRY 0100 /* append user entry to existing value */
#define HF_ADD_COMMA 0200 /* add comma if already data */
#define HF_ONPRE_SENDMENU 0400
struct hdr_menu_item;
typedef void inpval_proc_t P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr,
charset_t hdr_charset
));
typedef struct string * expval_proc_t P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
charset_t hdr_charset
));
typedef int hdrproc_t P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr, int free_only,
struct mailer_info *mailer_info,
charset_t hdr_charset,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area
));
/*
* Structure to describe a header which can be edited in this menu.
*/
struct hdr_menu_item {
int menucmd; /* The single keystroke (lower-case letter) the *
* user strikes to edit this menu item. */
char *hdrname; /* Header name to display in the menu. Parens *
* should be used to bracket the "menucmd" *
* char in the name, e.g. "S)ubject". This *
* will be NULL for the user-defined header. */
int lineno; /* Screen line at which the field is displayed. */
int flags; /* Various flags which effect the display and *
* user entry of this item. */
inpval_proc_t *inpval_proc;
/* Returns pointer to the buffer to hold the *
* value entered by the user. Needs to be *
* dealloced with hdrproc */
expval_proc_t *expval_proc;
/* Returns to tointer to the expanded header *
* value to display. Returned valued need to *
* be free()ed. */
hdrproc_t *hdrproc; /* Pointer to a procedure which verifies the *
* user data entry, and if required converts *
* the "inpval" value to "expval" value. Does *
* needed deallocation of buffer returned by *
* inpval_proc */
};
/*
* Local procedures.
*/
static int hdrmenu_get P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct mailer_info *mailer_info,
charset_t hdr_charset,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area));
static void hdrmenu_put P_((struct hdr_menu_item *h,
int already_clear,
struct mailing_headers *headers,
charset_t hdr_charset,
struct menu_context *page));
/* From: -header -------------------------------------------------------- */
static void inpval_from P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr,
charset_t hdr_charset));
static struct string * expval_from P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
charset_t hdr_charset));
static int hdrproc_from P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr, int free_only,
struct mailer_info *mailer_info,
charset_t hdr_charset,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area
));
/* To: -header -------------------------------------------------------- */
static void inpval_to P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr,
charset_t hdr_charset));
static struct string * expval_to P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
charset_t hdr_charset));
static int hdrproc_to P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr, int free_only,
struct mailer_info *mailer_info,
charset_t hdr_charset,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area));
/* CC: -header -------------------------------------------------------- */
static void inpval_cc P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr,
charset_t hdr_charset));
static struct string * expval_cc P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
charset_t hdr_charset));
static int hdrproc_cc P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr, int free_only,
struct mailer_info *mailer_info,
charset_t hdr_charset,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area));
/* BCC: -header -------------------------------------------------------- */
static void inpval_bcc P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr,
charset_t hdr_charset));
static struct string * expval_bcc P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
charset_t hdr_charset));
static int hdrproc_bcc P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr, int free_only,
struct mailer_info *mailer_info,
charset_t hdr_charset,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area));
/* Subject: -header -------------------------------------------------------- */
static void inpval_subject P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr,
charset_t hdr_charset));
static struct string * expval_subject P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
charset_t hdr_charset));
static int hdrproc_subject P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr, int free_only,
struct mailer_info *mailer_info,
charset_t hdr_charset,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area));
/* Reply-To: -header -------------------------------------------------- */
static void inpval_reply_to P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr,
charset_t hdr_charset));
static struct string * expval_reply_to P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
charset_t hdr_charset));
static int hdrproc_reply_to P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr, int free_only,
struct mailer_info *mailer_info,
charset_t hdr_charset,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area));
/* Action: -header ---------------------------------------------------- */
static void inpval_action P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr,
charset_t hdr_charset));
static struct string * expval_action P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
charset_t hdr_charset));
static int hdrproc_action P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr, int free_only,
struct mailer_info *mailer_info,
charset_t hdr_charset,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area));
/* Expires: -header ---------------------------------------------------- */
static void inpval_expires P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr,
charset_t hdr_charset));
static struct string * expval_expires P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
charset_t hdr_charset));
static int hdrproc_expires P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr, int free_only,
struct mailer_info *mailer_info,
charset_t hdr_charset,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area));
/* Priority: -header ---------------------------------------------------- */
static void inpval_priority P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr,
charset_t hdr_charset));
static struct string * expval_priority P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
charset_t hdr_charset));
static int hdrproc_priority P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr, int free_only,
struct mailer_info *mailer_info,
charset_t hdr_charset,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area));
/* Precedence: -header ---------------------------------------------------- */
static void inpval_precedence P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr,
charset_t hdr_charset));
static struct string * expval_precedence P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
charset_t hdr_charset));
static int hdrproc_precedence P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr, int free_only,
struct mailer_info *mailer_info,
charset_t hdr_charset,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area));
/* In-Reply-To: -header ---------------------------------------------------- */
static void inpval_in_reply_to P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr,
charset_t hdr_charset));
static struct string * expval_in_reply_to P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
charset_t hdr_charset));
static int hdrproc_in_reply_to P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr, int free_only,
struct mailer_info *mailer_info,
charset_t hdr_charset,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area));
/* User defined header ---------------------------------------------------- */
static void inpval_userhdr P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr,
charset_t hdr_charset));
static struct string * expval_userhdr P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
charset_t hdr_charset));
static int hdrproc_userhdr P_((struct hdr_menu_item *h,
struct mailing_headers *headers,
struct string **ptr,
int free_only,
struct mailer_info *mailer_info,
charset_t hdr_charset,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area));
/*
* Definition of all the header editing menu fields.
*/
struct hdr_menu_item hmenu_item_list[] = {
{ 't', "T)o", 2, HF_DISP_3ROW|HF_APPENDENTRY|HF_ADD_COMMA|HF_ONPRE_SENDMENU,
inpval_to, expval_to, hdrproc_to },
{ 'c', "C)c", 5, HF_DISP_3ROW|HF_APPENDENTRY|HF_ADD_COMMA,
inpval_cc, expval_cc, hdrproc_cc },
{ 'b', "B)cc", 8, HF_DISP_2ROW|HF_APPENDENTRY|HF_ADD_COMMA,
inpval_bcc, expval_bcc, hdrproc_bcc },
{ 's', "S)ubject", 10, HF_DISP_2ROW,
inpval_subject, expval_subject, hdrproc_subject },
{ 'r', "R)eply-to", 12, HF_DISP_1ROW,
inpval_reply_to, expval_reply_to, hdrproc_reply_to },
{ 'a', "A)ction", 13, HF_DISP_LEFT,
inpval_action, expval_action, hdrproc_action },
{ 'e', "E)xpires", 13, HF_DISP_RIGHT|HF_PROMPT_EXP,
inpval_expires, expval_expires, hdrproc_expires },
{ 'p', "P)riority", 14, HF_DISP_LEFT,
inpval_priority, expval_priority, hdrproc_priority },
{ 'n', "Precede(n)ce", 14, HF_DISP_RIGHT,
inpval_precedence, expval_precedence, hdrproc_precedence },
{ 'i', "I)n-reply-to", 15, HF_DISP_2ROW,
inpval_in_reply_to, expval_in_reply_to, hdrproc_in_reply_to },
{ 'u', NULL, 17, HF_DISP_1ROW|HF_PROMPT_USR,
inpval_userhdr, expval_userhdr, hdrproc_userhdr },
{ 'f', "F)rom", -1, 0,
inpval_from, expval_from, hdrproc_from },
{ -1, NULL, -1, -1, NULL, NULL, NULL },
};
/*
* Selection of individual fields. The indices *must* correspond
* to the above "hmenu_item_list[]" list.
*/
#define hmenu_to (hmenu_item_list[0])
#define hmenu_cc (hmenu_item_list[1])
#define hmenu_bcc (hmenu_item_list[2])
#define hmenu_subject (hmenu_item_list[3])
#define hmenu_replyto (hmenu_item_list[4])
#define hmenu_action (hmenu_item_list[5])
#define hmenu_expires (hmenu_item_list[6])
#define hmenu_priority (hmenu_item_list[7])
#define hmenu_precedence (hmenu_item_list[8])
#define hmenu_inreplyto (hmenu_item_list[9])
#define hmenu_userdef (hmenu_item_list[10])
#define hmenu_from (hmenu_item_list[11])
void show_presend_headers(headers,hdr_charset,page)
struct mailing_headers *headers;
charset_t hdr_charset;
struct menu_context *page;
{
struct hdr_menu_item *h;
for (h = hmenu_item_list ; h->menucmd > 0 ; ++h) {
if (h->lineno > 0 && 0 != (h->flags & HF_ONPRE_SENDMENU))
hdrmenu_put(h, TRUE, headers,hdr_charset,page);
}
}
/* returns 0 if command not found
1 if found
REDRAW_MARK is redraw required
*/
int presend_action(headers,mailer_info,c,hdr_charset,aview,page,
prompt_area)
struct mailing_headers *headers;
struct mailer_info *mailer_info;
int c;
charset_t hdr_charset;
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area;
{
struct hdr_menu_item *h;
int LINES, COLUMNS;
menu_get_sizes(page, &LINES, &COLUMNS);
for (h = hmenu_item_list ; h->menucmd > 0 ; ++h) {
if (0 != (h->flags & HF_ONPRE_SENDMENU)) {
if (h->menucmd == c) {
int status;
MoveCursor(LINES-4,0);
CleartoEOS();
status = hdrmenu_get(h,headers,mailer_info,hdr_charset,aview,
page,prompt_area);
if (REDRAW_MARK == status) {
return REDRAW_MARK;
}
if (status != 0) {
Writechar('\007');
return 1;
}
if (h->lineno > 0)
hdrmenu_put(h, FALSE,headers,hdr_charset,page);
return 1;
}
}
}
return 0;
}
enum mode_xx { mode_plain, mode_phrase, mode_comment };
static void print_edit_string P_((enum mode_xx mode,FILE *F,charset_t edit_charset,
int encondig_supported,struct string *s));
static void print_edit_string(mode,F,edit_charset,encoding_supported,s)
enum mode_xx mode;
FILE *F;
charset_t edit_charset;
int encoding_supported;
struct string *s;
{
int mime_code = encoding_supported &&
s->string_type != edit_charset;
char * s1 = NULL;
switch (mode) {
case mode_phrase:
s1 = string_to_hdr(HDR_PHRASE,s, edit_charset,mime_code, NULL);
break;
case mode_comment: putc('(',F);
s1 = string_to_hdr(HDR_COMMENT,s, edit_charset,mime_code, NULL);
break;
default:
s1 = string_to_hdr(HDR_TEXT,s, edit_charset,mime_code, NULL);
break;
}
fputs(s1,F);
switch (mode) {
case mode_comment: putc(')',F); break;
}
free(s1);
}
static void add_addr_header P_((FILE * F,charset_t edit_charset,
int encoding_supported,char * name,
struct expanded_address *a));
static void add_addr_header(F,edit_charset,encoding_supported,name,a)
FILE * F;
charset_t edit_charset;
int encoding_supported;
char * name;
struct expanded_address *a;
{
int i;
int l = 0;
fprintf(F,"%s: ",name);
for (i = 0; i < a->addrs_len; i++) {
struct string * f = a->addrs[i].fullname;
char * ad = a->addrs[i].addr;
struct string * c = a->addrs[i].comment;
if (f && string_len(f) > 0) {
print_edit_string (mode_phrase,F,edit_charset,encoding_supported,f);
putc(' ',F);
l += string_len(f);
}
putc('<',F);
fputs(ad,F); l += strlen(ad);
putc('>',F);
if (c && string_len(c) > 0) {
putc(' ',F);
print_edit_string (mode_comment,F,edit_charset,encoding_supported,c);
l += string_len(c);
}
if (i < a->addrs_len-1) {
putc(',',F);
if (l > 60) {
putc('\n',F);
l = 0;
}
putc(' ',F);
}
}
putc('\n',F);
}
static void add_string_header P_((FILE * F,charset_t edit_charset,
int encoding_supported,char * name,
struct string *s));
static void add_string_header(F,edit_charset,encoding_supported,name,s)
FILE * F;
charset_t edit_charset;
int encoding_supported;
char * name;
struct string *s;
{
fprintf(F,"%s: ",name);
print_edit_string (mode_plain,F,edit_charset,encoding_supported,s);
putc('\n',F);
}
static void edit_headers_on_editor P_((struct mailing_headers *headers,
char *editor, int encoding_supported,
struct menu_context *page));
static void edit_headers_on_editor(headers,editor, encoding_supported,
page)
struct mailing_headers *headers;
char *editor;
int encoding_supported;
struct menu_context *page;
{
charset_t edit_charset = system_charset;
FILE * F = NULL;
char * tmp = give_dt_estr_as_str(&temp_dir_e,"tmpdir");
char * filename = elm_message(FRM("%s%sHDR%d"),
tmp ? tmp : "/tmp/",
temp_file, getpid());
char * buffer = NULL;
char buffer1[32*1024];
int stat;
int c;
int err;
int LINES, COLUMNS;
menu_get_sizes(page, &LINES, &COLUMNS);
if (in_string(editor, "%s"))
buffer = elm_message(FRM(editor),
filename);
else
buffer = elm_message(FRM("%s %s"),
editor, filename);
F = safeopen_rdwr(filename);
if (!F)
goto fail1;
PutLineX(LINES-1, 0, CATGETS(elm_msg_cat, ElmSet, ElmInvokeEditor,
"Invoking editor..."));
FlushBuffer();
/* FIX: Following prints with display_charset and
not with edit_charset (system_charset)
*/
elm_fprintf(F,
CATGETS(elm_msg_cat, ElmSet, ElmHdrEditComment,
"# Headers are automatically converted from %s charset and not need encoded\n"),
edit_charset->MIME_name ? edit_charset->MIME_name : "<no MIME name>");
if (encoding_supported) {
elm_fprintf(F,
CATGETS(elm_msg_cat, ElmSet, ElmHdrEditCommentEnc,
"# MIME encoding of headers is supported\n"));
} else {
elm_fprintf(F,
CATGETS(elm_msg_cat, ElmSet, ElmHdrEditCommentNo,
"# MIME encoding of headers is NOT supported\n"));
}
add_addr_header(F,edit_charset,encoding_supported,
"From", & headers->from);
add_addr_header(F,edit_charset,encoding_supported,
"To", & headers->to);
add_addr_header(F,edit_charset,encoding_supported,
"Cc", & headers->cc);
add_addr_header(F,edit_charset,encoding_supported,
"Bcc", & headers->bcc);
add_addr_header(F,edit_charset,encoding_supported,
"Reply-To", & headers->reply_to);
add_string_header(F,edit_charset,encoding_supported,
"Subject", headers->subject);
fclose(F);
(void) elm_chown(filename, userid, groupid);
Raw(OFF);
/* FIX: SY_DUMPSTATE should perhaps be supported? */
if ((stat = system_call(buffer, SY_ENAB_SIGHUP,
NULL)) == -1) {
int err = errno;
Raw(ON);
DPRINT(Debug,1,(&Debug,
"System call failed with stat %d (edit_the_message)\n",
stat));
DPRINT(Debug,1,(&Debug,
"** %s **\n", error_description(err)));
ClearLine(LINES-2);
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCantInvokeEditor,
"Can't invoke editor '%s' for composition."),
editor);
sleep_message();
goto fail2;
}
Raw(ON);
err = can_open(filename,"r");
if (err) {
lib_error(FRM("%s: %s"),filename,err);
goto fail1;
}
F = fopen(filename,"r");
if (!F) {
/* In than point opening should have succeed */
int err = errno;
lib_error(FRM("%s: %s"),filename,err);
goto fail1;
}
/* Skip comment block */
while ('#' == (c = getc(F))) {
while ('\n' != (c = getc(F))) {
if (EOF == c)
break;
}
}
if (EOF != c)
ungetc(c,F);
/* Read headers */
while (0 < read_header_line(F,buffer1,sizeof buffer1,0)) {
header_ptr header_name;
char *k;
if ('#' == buffer[0])
continue;
k = strchr(buffer1,':');
if (!k)
break;
*k = '\0';
k++;
while (whitespace(*k))
k++;
header_name = find_header(buffer1,1);
if (!add_to_mailing_header(headers,header_name,k,
encoding_supported,
edit_charset,1 /* REPLACE */ )) {
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmHdrNotSupported,
"Editing of %s header is not supported."),
buffer1);
}
}
if (!feof(F))
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmHdrGarbage,
"Garbage on header file"));
fclose(F);
fail2:
unlink(filename);
fail1:
free(filename); filename = NULL;
free(buffer); buffer = NULL;
}
void edit_headers(headers,mailer_info,hdr_charset, hdr_encoding_supported,
aview)
struct mailing_headers *headers;
struct mailer_info *mailer_info;
charset_t hdr_charset;
int hdr_encoding_supported;
struct AliasView *aview;
{
int c, do_redraw;
struct hdr_menu_item *h;
int precmd = 0;
char * editor_val = give_dt_estr_as_str(&editor_e,"editor");
int editor_available =
editor_val &&
strcmp(editor_val, "builtin") != 0 &&
strcmp(editor_val, "none") != 0;
int ul = give_dt_enumerate_as_int(&user_level);
int LINES, COLUMNS;
struct menu_context *page = new_menu_context();
struct menu_context * prompt_area = NULL;
menu_get_sizes(page, &LINES, &COLUMNS);
/*
* Placement of prompts and messages at the bottom of the screen.
*/
prompt_area =
new_menu_subpage(page,LINES-5,5,
subpage_simple_noredraw,NULL);
/* expand out all of the header values */
/* menu displays expanded values, user edits unexpended versions */
do_redraw = TRUE;
while (TRUE) { /* forever */
menu_set_default(page);
resize_mark:
if (menu_resized(page)) {
menu_get_sizes(page,&LINES, &COLUMNS);
menu_subpage_relocate(prompt_area,page,LINES-5,5);
do_redraw = 1;
} else if (menu_need_redraw(page))
do_redraw = 1;
if (headers->from.addrs_len > 0 &&
hmenu_from.lineno == -1 &&
(hmenu_to.flags & HF_DISP_MASK) == HF_DISP_3ROW) {
/* Hack:
From: -header take space from To: -header ...
*/
hmenu_from.lineno = hmenu_to.lineno++;
hmenu_to.flags = hmenu_to.flags & ~HF_DISP_MASK |
HF_DISP_2ROW;
hmenu_from.flags = HF_DISP_1ROW;
do_redraw = 1;
}
/* redraw the entire display if required */
if (do_redraw) {
menu_ClearScreen(page);
print_format_center(0,
CATGETS(elm_msg_cat, ElmSet,
ElmHdrmenuScreenTitle,
"Message Header Edit Screen"));
for (h = hmenu_item_list ; h->menucmd > 0 ; ++h) {
if (h->lineno > 0)
hdrmenu_put(h, TRUE, headers, hdr_charset, page);
}
do_redraw = FALSE;
menu_redraw_children(page);
}
if (menu_resized(prompt_area) ||
menu_need_redraw(prompt_area)) {
menu_ClearScreen(prompt_area);
/* display the instructions */
if (ul > 0 && editor_available) {
#ifdef ALLOW_SUBSHELL
menu_print_format_center(prompt_area,0,
CATGETS(elm_msg_cat, ElmSet,
ElmHdrmenuInstruct1,
"Choose header, u)ser defined header, !)shell, invoke e(d)itor, or <return>."));
#else
menu_print_format_center(prompt_area,0
CATGETS(elm_msg_cat, ElmSet,
ElmHdrmenuInstruct1NoShell,
"Choose header, u)ser defined header, invoke e(d)itor, or <return>."));
#endif
} else {
#ifdef ALLOW_SUBSHELL
menu_print_format_center(prompt_area,0,
CATGETS(elm_msg_cat, ElmSet,
ElmHdrmenuInstruct,
"Choose header, u)ser defined header, !)shell, or <return>."));
#else
menu_print_format_center(prompt_area,0,
CATGETS(elm_msg_cat, ElmSet,
ElmHdrmenuInstructNoShell,
"Choose header, u)ser defined header, or <return>."));
#endif
}
}
/* prompt for command */
menu_PutLineX(prompt_area,2, 0,
CATGETS(elm_msg_cat, ElmSet,
ElmHdrmenuPrompt, "Choice: "));
if (precmd) {
c = precmd;
precmd = 0;
} else {
c = menu_ReadCh(prompt_area,REDRAW_MARK|READCH_resize|READCH_sig_char);
if (c == 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*/
do_redraw = TRUE;
continue;
}
if (c == TERMCH_interrupt_char)
goto OUT;
if (c == RESIZE_MARK) {
DPRINT(Debug,4, (&Debug, " ... resizing\n"));
goto resize_mark;
}
}
#ifdef ASCII_CTYPE
if (isascii(c))
#endif
c = tolower(c);
menu_ClearScreen(prompt_area);
/* execute the command */
switch (c) {
case EOF:
case RETURN:
case LINE_FEED:
case 'q':
goto OUT;
#ifdef ALLOW_SUBSHELL
case '!':
subshell(NULL, page, prompt_area); /* !! */
if (menu_need_redraw(page))
do_redraw = TRUE;
break;
#endif
case ctrl('L'):
do_redraw = TRUE;
break;
case 'd':
if (editor_val) {
editor_available &= have_editor(editor_val);
if (editor_available)
edit_headers_on_editor(headers,editor_val,
hdr_encoding_supported,
page);
}
do_redraw = TRUE;
break;
default:
for (h = hmenu_item_list ; h->menucmd > 0 ; ++h) {
if (h->menucmd == c) {
int status = hdrmenu_get(h,headers,mailer_info,
hdr_charset,aview,
page,prompt_area);
if (REDRAW_MARK == status) {
precmd = c;
do_redraw = TRUE;
break;
}
if (status != 0) {
Writechar('\007');
break;
}
if (h->lineno > 0)
hdrmenu_put(h, FALSE,headers, hdr_charset, page);
break;
}
}
if (h->menucmd <= 0) {
menu_print_format_center(prompt_area,3,
CATGETS(elm_msg_cat, ElmSet,
ElmHdrmenuBadChoice,
"No such header!"));
Writechar('\007');
}
break;
}
}
OUT:
erase_menu_context(&prompt_area);
erase_menu_context(&page);
return;
}
/*
* Prompt the user for a header value, and do any required post-processing.
*/
static int hdrmenu_get(h,headers,mailer_info,hdr_charset,aview,page,
prompt_area)
struct hdr_menu_item *h;
struct mailing_headers *headers;
struct mailer_info *mailer_info;
charset_t hdr_charset;
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area;
{
char *s;
int plen, ret, do_append, do_comma;
struct string *buffer = NULL;
char header_name[20];
int LINES, COLUMNS;
menu_get_sizes(page,&LINES, &COLUMNS);
menu_ClearLine(prompt_area,0);
/* display the instructions */
switch (h->flags & HF_PROMPT_MASK) {
case HF_PROMPT_EXP:
menu_print_format_center(prompt_area,0,
CATGETS(elm_msg_cat, ElmSet,
ElmHdrmenuGetExpiresInstruct,
"In how many days should this message expire? "));
break;
case HF_PROMPT_USR:
menu_print_format_center(prompt_area,0,
CATGETS(elm_msg_cat, ElmSet,
ElmHdrmenuGetUserdefInstruct,
"Enter in the format \"HeaderName: HeaderValue\"."));
break;
default:
menu_print_format_center(prompt_area,0,
CATGETS(elm_msg_cat, ElmSet,
ElmHdrmenuGetInstruct,
"Enter value for the header."));
break;
}
/* display a prompt */
plen = 0;
if (h->hdrname != NULL) {
menu_MoveCursor(prompt_area,2,0);
for (s = h->hdrname ; *s != '\0' ; ++s) {
if (*s != '(' && *s != ')') {
if (plen > sizeof header_name -4)
break;
header_name[plen] = *s;
++plen;
}
}
header_name[plen++] = ':';
header_name[plen++] = ' ';
}
header_name[plen] = '\0';
/* get input from the user */
do_append = ((h->flags & HF_APPENDENTRY) != 0);
h->inpval_proc(h,headers,&buffer,hdr_charset);
do_comma = ((h->flags & HF_ADD_COMMA) != 0 &&
string_len(buffer));
{
/* FIXME --optionally_enter* should use prompt_area */
int line1 = menu_GetAbsLine(prompt_area,2);
ret = optionally_enter2(page, &buffer, line1, 0,
(do_append ? OE_APPEND_CURRENT : 0) |
(do_comma ? OE_ADD_COMMA : 0) |
OE_REDRAW_MARK|OE_SIG_CHAR /* Ctrl-C */,
FRM("%s"),header_name);
}
if (ret == REDRAW_MARK) {
h->hdrproc(h,headers,&buffer,TRUE,mailer_info,hdr_charset,aview,page,
prompt_area);
return REDRAW_MARK;
}
menu_ClearScreen(prompt_area);
/* bail out on error */
if (ret != 0) {
if (buffer)
h->hdrproc(h,headers,&buffer,TRUE,mailer_info,hdr_charset,aview,
page,prompt_area);
return -1;
}
/* see if there is some processing required on this value */
return h->hdrproc(h,headers,&buffer,FALSE,mailer_info,hdr_charset,
aview,page,prompt_area);
}
/*
* Dispay a header and its value in the appropriate field.
*/
static void hdrmenu_put(h, already_clear, headers, hdr_charset,
page)
struct hdr_menu_item *h;
int already_clear;
struct mailing_headers *headers;
charset_t hdr_charset;
struct menu_context *page;
{
struct string * buffer = NULL;
char *p;
int start_row, max_row, start_col, max_col, row, col;
int X;
int Bl;
int LINES, COLUMNS;
menu_get_sizes(page,&LINES, &COLUMNS);
/* figure out the dimensions of the field */
switch (h->flags & HF_DISP_MASK) {
case HF_DISP_LEFT:
start_row = h->lineno; max_row = h->lineno;
start_col = 0; max_col = COLUMNS/2 - 2;
break;
case HF_DISP_RIGHT:
start_row = h->lineno; max_row = h->lineno;
start_col = COLUMNS/2 + 1; max_col = COLUMNS-1;
break;
case HF_DISP_3ROW:
start_row = h->lineno; max_row = h->lineno+2;
start_col = 0; max_col = COLUMNS-1;
break;
case HF_DISP_2ROW:
start_row = h->lineno; max_row = h->lineno+1;
start_col = 0; max_col = COLUMNS-1;
break;
default:
start_row = h->lineno; max_row = h->lineno;
start_col = 0; max_col = COLUMNS-1;
break;
}
/* display the header name */
MoveCursor(start_row, start_col);
if (h->hdrname != NULL) {
for (p = h->hdrname ; *p != '\0' ; ++p)
Writechar(*p);
Writechar(':');
Writechar(' ');
}
/* display the header value */
GetXYLocation(&row, &col);
buffer=h->expval_proc(h,headers,hdr_charset);
Bl = buffer ? string_len(buffer) : 0;
for (X = 0; buffer && X < Bl && row <= max_row; row++) {
struct string * str = NULL;
int visible_len;
int space_left;
int cur_col = col;
retry:
if (row == max_row) /* neat hack alert */
space_left = max_col-cur_col-4;
else
space_left = max_col-cur_col;
str = curses_printable_clip(buffer,&X,Bl,&visible_len,space_left);
if (str) {
MoveCursor(row, col);
Write_to_screen(FRM("%S"),str);
if (row == max_row && X < string_len(buffer)) {
Write_to_screen(FRM(" ..."));
cur_col += 4;
}
free_string(&str);
cur_col += visible_len;
} else {
/* Treat next character as control character */
StartBold();
Writechar('?');
EndBold();
cur_col++;
if (cur_col < max_col && X < Bl)
goto retry;
}
/* If we are not end of string -- clear rest on case of double with characters */
if (X < Bl && cur_col < max_col && !already_clear) {
while (cur_col++ <= max_col)
Writechar(' ');
}
}
GetXYLocation(&row, &col);
/* save some drawing if we know the screen is already empty */
if (!already_clear) {
/* clear out remaining space in this line of the field */
if (max_col == COLUMNS-1) {
/* people on slow terminals might appreciate doing it this way */
CleartoEOLN();
} else {
while (col++ <= max_col)
Writechar(' ');
}
/* for multi-line fields, clear out any unused lines */
/* this assumes that multi-line fields span the entire screen width */
while (++row <= max_row) {
/* grrrrrr -- this is a multi-statement macro */
ClearLine(row);
}
}
if (buffer)
free_string(&buffer);
}
void hdr_to_buffer(addrs,ptr)
struct expanded_address addrs;
struct string **ptr;
{
expanded_to_edit_buffer(ptr,addrs);
}
struct string *hdr_to_expval(addrs)
struct expanded_address addrs;
{
struct addr_item *p;
struct string * buffer = NULL;
for (p = addrs.addrs; p < addrs.addrs + addrs.addrs_len; p++) {
if (buffer)
add_ascii_to_string(buffer,s2us(", "));
else
buffer = new_string(display_charset);
if (string_len(p->fullname) || ! p->addr[0] || '@' == p->addr[0]) {
int pd = give_dt_enumerate_as_int(&phrase_display_mode);
/* We do not quote displayed (only) address */
struct string * temp = NULL;
switch (pd) {
case 0:
temp = cat_strings(buffer,p->fullname,1);
break;
default:
/* We do not (backslash) quote displayed (only) address */
add_ascii_to_string(buffer,s2us("\""));
temp = cat_strings(buffer,p->fullname,1);
add_ascii_to_string(temp,s2us("\""));
break;
}
add_ascii_to_string(temp,s2us(" <"));
add_ascii_to_string(temp,s2us(p->addr));
add_ascii_to_string(temp,s2us(">"));
free_string(&buffer);
buffer = temp;
} else
add_ascii_to_string(buffer,s2us(p->addr));
if (string_len(p->comment)) {
/* We do not quote displayed (only) address */
struct string * temp;
add_ascii_to_string(buffer,s2us(" ("));
temp = cat_strings(buffer,p->comment,1);
add_ascii_to_string(temp,s2us(")"));
free_string(&buffer);
buffer = temp;
}
}
return buffer;
}
/*
* Process the to, cc, and bcc headers. The value entered by the
* user is expanded. A successful status is always returned.
*/
int buffer_to_header(addrs,ptr,free_only,mailer_info,aview)
struct expanded_address *addrs;
struct string **ptr;
int free_only;
struct mailer_info *mailer_info;
struct AliasView *aview;
{
if (!free_only) {
update_expanded_from_edit_buffer(addrs,*ptr,mailer_info, aview);
}
free_string(ptr);
return 0;
}
static void text_to_buffer P_((char *text,struct string **ptr,
charset_t hdr_charset));
static void text_to_buffer(text,ptr,hdr_charset)
char *text;
struct string **ptr;
charset_t hdr_charset;
{
if (text)
*ptr = new_string2(hdr_charset,s2us(text));
else
*ptr = new_string(hdr_charset);
}
static struct string * text_to_expval P_((char *text,
charset_t hdr_charset));
static struct string * text_to_expval(text,hdr_charset)
char *text;
charset_t hdr_charset;
{
if (!text)
return new_string(hdr_charset);
else
return new_string2(hdr_charset,s2us(text));
}
static int buffer_to_text P_((char **text,struct string **ptr,int free_only,
charset_t hdr_charset));
static int buffer_to_text(text,ptr,free_only,hdr_charset)
char **text;
struct string **ptr;
int free_only;
charset_t hdr_charset;
{
if (!free_only) {
struct string * X;
if (can_ascii_string(*ptr))
X = ascify_string(*ptr);
else
X = convert_string(hdr_charset,
*ptr,0);
if (*text)
free(*text);
*text = us2s(stream_from_string(X,0,NULL));
free_string(&X);
}
free_string(ptr);
return 0;
}
/* From: -header -------------------------------------------------------- */
static void inpval_from (h,headers,ptr,hdr_charset)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
struct string **ptr;
charset_t hdr_charset; /* NOT USED */
{
hdr_to_buffer(headers->from,ptr);
}
static struct string * expval_from (h,headers,hdr_charset)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
charset_t hdr_charset; /* NOT USED */
{
return hdr_to_expval(headers->from);
}
static int hdrproc_from (h,headers,ptr,free_only,mailer_info,hdr_charset,
aview,page,prompt_area)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
struct string **ptr;
int free_only;
struct mailer_info *mailer_info;
charset_t hdr_charset; /* NOT USED */
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area; /* NOT USED */
{
return buffer_to_header(&headers->from,ptr,free_only,mailer_info,
aview);
}
/* To: -header -------------------------------------------------------- */
static void inpval_to (h,headers,ptr,hdr_charset)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
struct string **ptr;
charset_t hdr_charset; /* NOT USED */
{
hdr_to_buffer(headers->to,ptr);
}
static struct string * expval_to (h,headers,hdr_charset)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
charset_t hdr_charset; /* NOT USED */
{
return hdr_to_expval(headers->to);
}
static int hdrproc_to (h,headers,ptr,free_only,mailer_info,hdr_charset,
aview,page,prompt_area)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
struct string **ptr;
int free_only;
struct mailer_info *mailer_info;
charset_t hdr_charset; /* NOT USED */
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area; /* NOT USED */
{
return buffer_to_header(&headers->to,ptr,free_only,mailer_info,
aview);
}
/* CC: -header -------------------------------------------------------- */
static void inpval_cc (h,headers,ptr,hdr_charset)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
struct string **ptr;
charset_t hdr_charset; /* NOT USED */
{
hdr_to_buffer(headers->cc,ptr);
}
static struct string * expval_cc (h,headers,hdr_charset)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
charset_t hdr_charset; /* NOT USED */
{
return hdr_to_expval(headers->cc);
}
static int hdrproc_cc (h,headers,ptr,free_only,mailer_info,hdr_charset,
aview,page,prompt_area)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
struct string **ptr;
int free_only;
struct mailer_info *mailer_info;
charset_t hdr_charset; /* NOT USED */
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area; /* NOT USED */
{
return buffer_to_header(&headers->cc,ptr,free_only,mailer_info,
aview);
}
/* BCC: -header -------------------------------------------------------- */
static void inpval_bcc (h,headers,ptr,hdr_charset)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
struct string **ptr;
charset_t hdr_charset; /* NOT USED */
{
hdr_to_buffer(headers->bcc,ptr);
}
static struct string * expval_bcc (h,headers,hdr_charset)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
charset_t hdr_charset; /* NOT USED */
{
return hdr_to_expval(headers->bcc);
}
static int hdrproc_bcc (h,headers,ptr,free_only,mailer_info,hdr_charset,
aview,page,prompt_area)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
struct string **ptr;
int free_only;
struct mailer_info *mailer_info;
charset_t hdr_charset; /* NOT USED */
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area; /* NOT USED */
{
return buffer_to_header(&headers->bcc,ptr,free_only,mailer_info,
aview);
}
/* Subject: -header -------------------------------------------------------- */
static void inpval_subject (h,headers,ptr,hdr_charset)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
struct string **ptr;
charset_t hdr_charset;
{
if (*ptr)
free_string(ptr);
if (headers->subject) {
*ptr = dup_string(headers->subject);
} else
*ptr = new_string(hdr_charset);
}
static struct string * expval_subject (h,headers,hdr_charset)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
charset_t hdr_charset;
{
struct string * r;
if (headers->subject)
r = dup_string(headers->subject);
else
r = new_string(hdr_charset);
return r;
}
static int hdrproc_subject (h,headers,ptr,free_only,mailer_info,hdr_charset,
aview,page,prompt_area)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
struct string **ptr;
int free_only;
struct mailer_info *mailer_info; /* NOT USED */
charset_t hdr_charset; /* NOT USED */
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area; /* NOT USED */
{
if (!free_only) {
charset_t utf7;
if (headers->subject)
free_string(&(headers->subject));
if (convert_utf_header && (*ptr)->string_type->MIME_name &&
0 == istrcmp((*ptr)->string_type->MIME_name,"UTF-8") &&
0 != (CS_mapping & charset_properties((*ptr)->string_type)) &&
(utf7 = MIME_name_to_charset("UTF-7",0)) &&
0 != (CS_mapping & charset_properties(utf7))) {
headers->subject = convert_string(utf7,*ptr,1);
free_string(ptr);
} else {
headers->subject = *ptr;
*ptr = NULL;
}
} else
free_string(ptr);
return 0;
}
/* Reply-To: -header -------------------------------------------------- */
static void inpval_reply_to (h,headers,ptr,hdr_charset)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
struct string **ptr;
charset_t hdr_charset; /* NOT USED */
{
hdr_to_buffer(headers->reply_to,ptr);
}
static struct string * expval_reply_to (h,headers,hdr_charset)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
charset_t hdr_charset; /* NOT USED */
{
return hdr_to_expval(headers->reply_to);
}
static int hdrproc_reply_to (h,headers,ptr,free_only,mailer_info,hdr_charset,
aview,page,prompt_area)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
struct string **ptr;
int free_only;
struct mailer_info *mailer_info;
charset_t hdr_charset; /* NOT USED */
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area; /* NOT USED */
{
return buffer_to_header(&headers->reply_to,ptr,free_only,mailer_info,
aview);
}
/* Action: -header ---------------------------------------------------- */
static void inpval_action (h,headers,ptr,hdr_charset)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
struct string **ptr;
charset_t hdr_charset;
{
text_to_buffer(headers->action,ptr,hdr_charset);
}
static struct string * expval_action (h,headers,hdr_charset)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
charset_t hdr_charset;
{
return text_to_expval(headers->action,hdr_charset);
}
static int hdrproc_action (h,headers,ptr,free_only,mailer_info,hdr_charset,
aview,page,prompt_area)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
struct string **ptr;
int free_only;
struct mailer_info *mailer_info;
charset_t hdr_charset;
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area; /* NOT USED */
{
return buffer_to_text(&headers->action,ptr,free_only,hdr_charset);
}
/* Expires: -header ---------------------------------------------------- */
static void inpval_expires (h,headers,ptr,hdr_charset)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
struct string **ptr;
charset_t hdr_charset;
{
text_to_buffer(headers->expires_days,ptr,hdr_charset);
}
static struct string * expval_expires (h,headers,hdr_charset)
struct hdr_menu_item *h; /* NOT USED */
struct mailing_headers *headers;
charset_t hdr_charset;
{
return text_to_expval(headers->expires,hdr_charset);
}
/*
* Process the expires header. The value entered by the user is interpreted
* as a number of days, and is expanded out to a date specification. If
* an error occurs a message is printed, the expanded value is cleared
* out, and a -1 is returned.
*/
static int hdrproc_expires (h,headers,ptr,free_only,mailer_info,hdr_charset,
aview,page,prompt_area)
struct hdr_menu_item *h;
struct mailing_headers *headers;
struct string **ptr;
int free_only;
struct mailer_info *mailer_info;
charset_t hdr_charset;
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area;
{
int ret_val = 0;
if (!free_only) {
char buffer[STRING];
int days;
int fail_pos;
struct string * X = NULL;
int LINES, COLUMNS;
menu_get_sizes(page,&LINES, &COLUMNS);
/* initialize expanded date spec to empty */
if (headers->expires)
free(headers->expires);
headers->expires = NULL;
/* blank is ok */
if (ptr[0] == '\0') {
if (headers->expires_days)
free(headers->expires_days);
headers->expires_days = NULL;
goto free_it;
}
/* verify the number of days is valid and in range */
days = string_to_long(*ptr,&fail_pos);
if (days < 1 || fail_pos >= 0) {
menu_print_format_center(prompt_area,3,
CATGETS(elm_msg_cat, ElmSet,
ElmHdrmenuExpiresNotNumber,
"Expiration must be specified as a number of days."));
ret_val = -1;
goto free_it;
}
if (days > 8*7) {
menu_print_format_center(prompt_area,3,
CATGETS(elm_msg_cat, ElmSet,
ElmHdrmenuExpiresOutOfRange,
"Expiration date must be within eight weeks of today."));
ret_val = -1;
goto free_it;
}
/* convert number of days to a date */
days_ahead(days, buffer, sizeof buffer);
headers->expires = strmcpy(headers->expires,buffer);
if (can_ascii_string(*ptr))
X = ascify_string(*ptr);
else
X = convert_string(hdr_charset,
*ptr,0);
if (headers->expires_days)
free(headers->expires_days);
headers->expires_days = us2s(stream_from_string(X,0,NULL));
free_string(&X);
ret_val = 0;
}
free_it:
free_string(ptr);
return ret_val;
}
/* Priority: -header ---------------------------------------------------- */
static void inpval_priority (h,headers,ptr,hdr_charset)
struct hdr_menu_item *h;
struct mailing_headers *headers;
struct string **ptr;
charset_t hdr_charset;
{
text_to_buffer(headers->priority,ptr,hdr_charset);
}
static struct string * expval_priority (h,headers,hdr_charset)
struct hdr_menu_item *h;
struct mailing_headers *headers;
charset_t hdr_charset;
{
return text_to_expval(headers->priority,hdr_charset);
}
static int hdrproc_priority(h,headers,ptr,free_only,mailer_info,hdr_charset,
aview,page,prompt_area)
struct hdr_menu_item *h;
struct mailing_headers *headers;
struct string **ptr;
int free_only;
struct mailer_info *mailer_info;
charset_t hdr_charset;
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area; /* NOT USED */
{
return buffer_to_text(&headers->priority,ptr,free_only,hdr_charset);
}
/* Precedence: -header ---------------------------------------------------- */
static void inpval_precedence (h,headers,ptr,hdr_charset)
struct hdr_menu_item *h;
struct mailing_headers *headers;
struct string **ptr;
charset_t hdr_charset;
{
text_to_buffer(headers->precedence,ptr,hdr_charset);
}
static struct string * expval_precedence (h,headers,hdr_charset)
struct hdr_menu_item *h;
struct mailing_headers *headers;
charset_t hdr_charset;
{
return text_to_expval(headers->precedence,hdr_charset);
}
/*
* Process the precedence header. The value entered by the user is
* checked against the list of allowed precedences, if one exists. If
* the precedence has a priority assigned to it, then an empty priority
* field will be filled in with that value. If an error occurs a message
* is printed, the precedence value is cleared out, and a -1 is returned.
*/
static int hdrproc_precedence(h,headers,ptr,free_only,mailer_info,
hdr_charset,aview,page,prompt_area)
struct hdr_menu_item *h;
struct mailing_headers *headers;
struct string **ptr;
int free_only;
struct mailer_info *mailer_info;
charset_t hdr_charset;
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area;
{
int ret_val = 0;
if (!free_only) {
char *buf, *bp;
char *prec = NULL, *prio = NULL;
int Lptr = string_len(*ptr);
struct string * X = NULL;
int LINES, COLUMNS;
menu_get_sizes(page,&LINES, &COLUMNS);
/* empty is ok */
if (0 == Lptr) {
if (headers->precedence)
free(headers->precedence);
headers->precedence = NULL;
goto free_it;
}
if (can_ascii_string(*ptr))
X = ascify_string(*ptr);
else
X = convert_string(hdr_charset,
*ptr,0);
/* if there are no restrictions on precedence then anything is ok */
if (allowed_precedences[0] == '\0') {
if (headers->precedence)
free(headers->precedence);
headers->precedence = us2s(stream_from_string(X,0,NULL));
free_string(&X);
goto free_it;
}
/* the "allowed_precedences[]" format is: */
/* precedence[:priority-value] precedence[:priority-value] ... */
bp = buf = safe_strdup(allowed_precedences);
while ((prec = strtok(bp, " \t\n")) != NULL) {
struct string *T = NULL;
int r;
bp = NULL;
if ((prio = index(prec, ':')) != NULL)
*prio++ = '\0';
/* TODO: This is ineffective
TODO: Should be case-insensitive
*/
T = new_string2(system_charset,s2us(prec));
r = string_cmp(*ptr,T,
999 /* == Not equal if not comparable */ );
free_string(&T);
if (0 == r)
break;
}
/* Do not
free(buf);
here because prio pointer must be valid!
*/
/* see if we reached the end of the list without a match */
if (prec == NULL) {
menu_print_format_center(prompt_area,3,
CATGETS(elm_msg_cat, ElmSet,
ElmHdrmenuPrecedenceBadValue,
"Unknown precedence value specified."));
ret_val = -1;
free_string(&X);
free(buf);
goto free_it;
}
if (headers->precedence)
free(headers->precedence);
headers->precedence = us2s(stream_from_string(X,0,NULL));
/* see if this precedence has an associated priority */
if (prio != NULL && headers->priority == NULL) {
headers->priority = strmcpy(headers->priority,prio);
hdrmenu_put(&hmenu_priority, FALSE,headers,hdr_charset,page);
}
free_string(&X);
free(buf);
ret_val = 0;
}
free_it:
free_string(ptr);
return ret_val;
}
/* In-Reply-To: -header ---------------------------------------------------- */
static void inpval_in_reply_to (h,headers,ptr,hdr_charset)
struct hdr_menu_item *h;
struct mailing_headers *headers;
struct string **ptr;
charset_t hdr_charset;
{
if (headers->in_reply_to.id && headers->in_reply_to.text)
*ptr = format_string(FRM("%s%S"),
headers->in_reply_to.id,
headers->in_reply_to.text);
else if (headers->in_reply_to.text)
*ptr = dup_string(headers->in_reply_to.text);
else if (headers->in_reply_to.id)
*ptr = new_string2(hdr_charset,
s2us(headers->in_reply_to.id));
else
*ptr = new_string(hdr_charset);
}
static struct string * expval_in_reply_to (h,headers,hdr_charset)
struct hdr_menu_item *h;
struct mailing_headers *headers;
charset_t hdr_charset;
{
struct string * m = new_string(hdr_charset);
struct string * r;
if (headers->in_reply_to.id)
add_ascii_to_string(m,s2us(headers->in_reply_to.id));
if (headers->in_reply_to.text) {
int pd = give_dt_enumerate_as_int(&phrase_display_mode);
switch (pd) {
int X;
struct string * temp;
case 0:
r = cat_strings(m,headers->in_reply_to.text,1);
break;
default:
/* We do not (backslash) quote displayed (only) values */
X = 0;
if (string_len(headers->in_reply_to.text) > 0 &&
0x0020 == give_unicode_from_string(headers->in_reply_to.text,
0)) {
add_ascii_to_string(m,s2us(" "));
X = 1;
}
temp = clip_from_string(headers->in_reply_to.text,
&X,
string_len(headers->in_reply_to.text));
add_ascii_to_string(m,s2us("\""));
r = cat_strings(m,temp,1);
add_ascii_to_string(r,s2us("\""));
free_string(&temp);
break;
}
} else
r = dup_string(m);
free_string(&m);
return r;
}
static int hdrproc_in_reply_to (h,headers,ptr,free_only,mailer_info,
hdr_charset,aview,page,prompt_area)
struct hdr_menu_item *h;
struct mailing_headers *headers;
struct string **ptr;
int free_only;
struct mailer_info *mailer_info;
charset_t hdr_charset;
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area;
{
int ret_val = 0;
if (!free_only) {
int Xl = string_len(*ptr);
int p = 0;
int p1 = 0;
int LINES, COLUMNS;
menu_get_sizes(page,&LINES, &COLUMNS);
while (Xl > p &&
0x0020 == give_unicode_from_string(*ptr,p))
p++;
if (Xl > p &&
0x003C /* < */ == give_unicode_from_string(*ptr,p)) {
struct string * X = NULL;
int x;
for (x = p; x < Xl; x++) {
if (0x003E /* > */ == give_unicode_from_string(*ptr,x)) {
p1 = x+1; /* past '>' */
break;
}
}
if (!p1) {
menu_print_format_center(prompt_area,3,
CATGETS(elm_msg_cat, ElmSet,
ElmHdrmenuMissAngle,
"Missing > after < on in-reply-to header."));
ret_val = -1;
goto free_it;
}
if (can_ascii_string(*ptr))
X = ascify_string(*ptr);
else
X = convert_string(hdr_charset,
*ptr,0);
if (headers->in_reply_to.id)
free(headers->in_reply_to.id);
headers->in_reply_to.id =
us2s(streamclip_from_string(X,&p,p1-p,NULL,NULL));
free_string(&X);
} else {
if (headers->in_reply_to.id)
free(headers->in_reply_to.id);
headers->in_reply_to.id = NULL;
}
if (headers->in_reply_to.text)
free_string(&(headers->in_reply_to.text));
if (p < Xl) {
if (!add_irt_phrase)
menu_print_format_center(prompt_area,3,
CATGETS(elm_msg_cat, ElmSet,
ElmHdrmenuPhraseIRT,
"In-reply-to header should include only message-id"));
headers->in_reply_to.text = clip_from_string(*ptr,&p,Xl);
}
}
free_it:
free_string(ptr);
return ret_val;
}
/* User defined header ---------------------------------------------------- */
static void inpval_userhdr(h,headers,ptr,hdr_charset)
struct hdr_menu_item *h;
struct mailing_headers *headers;
struct string **ptr;
charset_t hdr_charset;
{
if (headers->user_header_count > 0 &&
headers->user_header[0].value) {
*ptr = format_string(FRM("%s: %S"),
give_header_name(headers->user_header[0].name),
headers->user_header[0].value);
} else
*ptr = new_string(hdr_charset);
}
static struct string * expval_userhdr(h,headers,hdr_charset)
struct hdr_menu_item *h;
struct mailing_headers *headers;
charset_t hdr_charset;
{
if (headers->user_header_count > 0 &&
headers->user_header[0].value)
return format_string(FRM("%s: %S"),
give_header_name(headers->user_header[0].name),
headers->user_header[0].value);
return new_string(hdr_charset);
}
/*
* Process the user-defined header. The value entered by the user is
* verified for proper format. If an error occurs a message is printed,
* the expanded value is cleared out, and a -1 is returned.
*/
static int hdrproc_userhdr(h,headers,ptr,free_only,mailer_info,hdr_charset,
aview,page,prompt_area)
struct hdr_menu_item *h;
struct mailing_headers *headers;
struct string **ptr;
int free_only;
struct mailer_info *mailer_info;
charset_t hdr_charset;
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area;
{
int ret_val = 0;
if (!free_only) {
header_ptr header_name;
int Xl = string_len(*ptr);
charset_t utf8 = MIME_name_to_charset("UTF-8",0);
struct string * utf8_temp = NULL;
unsigned char * utf8_value = NULL;
char * s;
int LINES, COLUMNS;
menu_get_sizes(page,&LINES, &COLUMNS);
/* empty is ok */
if (0 == Xl) {
int i;
for (i = 0; i < headers->user_header_count; i++) {
if (headers->user_header[i].value)
free_string(&(headers->user_header[i].value));
headers->user_header[i].name = NULL;
}
headers->user_header_count = 0;
goto free_it;
}
/* HACK: We use UTF-8 version of header value .... */
if (!utf8)
panic("CHARSET PANIC",__FILE__,__LINE__,"hdrproc_userhdr",
"UTF-8 not found",0);
utf8_temp = convert_string(utf8,*ptr,0);
utf8_value = stream_from_string(utf8_temp,0,NULL);
/* make sure the header name doesn't begin with some strange
* character -- Note that only US-ASCII is allowed according
* of standards on headers
*/
if (!isascii(utf8_value[0]) &&
!isalnum(utf8_value[0])) {
menu_print_format_center(prompt_area,3,
CATGETS(elm_msg_cat, ElmSet,
ElmHdrmenuUserdefNotAlnum,
"The user-defined header must begin with a letter or number."));
ret_val = -1;
free(utf8_value);
free_string(&utf8_temp);
goto free_it;
}
/* locate the end of the header name */
for (s = us2s(utf8_value) ;
*s != ':' && isascii(*s) && isprint(*s) && !isspace(*s) ;
++s)
continue;
/* there needs to be a colon at the end of the header name */
if (*s != ':') {
menu_print_format_center(prompt_area,3,
CATGETS(elm_msg_cat, ElmSet,
ElmHdrmenuUserdefMissingColon,
"The user-defined header must have a colon after the field name."));
ret_val = -1;
free(utf8_value);
free_string(&utf8_temp);
goto free_it;
}
*s = '\0';
*s++;
while (whitespace(*s))
s++;
header_name = find_header(us2s(utf8_value),1);
/* Allow user to paste mime encoded words to buffer ... */
if (!add_to_mailing_header(headers,header_name,s,
1,utf8,1))
ret_val = -1;
else
ret_val = 0;
}
free_it:
free_string(ptr);
return ret_val;
}
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1