static char rcsid[] = "@(#)$Id: alias.c,v 1.60 2007/03/08 11:22:48 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.60 $ $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 alias stuff
**/
#include "def_elm.h"
#include "s_elm.h"
#include "s_aliases.h"
#include "ndbz.h"
DEBUG_VAR(Debug,__FILE__,"alias");
static char *us2s P_((unsigned char *str));
static char *us2s(str)
unsigned char *str;
{
return (char *)str;
}
#define ECHOIT 1 /* echo on for prompting */
static int add_to_alias_text P_((char *aliasname, char *firstname,
char *lastname, char *comment,
char *address));
static int get_aliasname P_((char *aliasname, char *buffer,int *duplicate,
int size,int buffer_size,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area));
static int superceed_system P_((int this_alias, char *buffer,
int buffer_size,
struct AliasView *aview,
struct menu_context *page,
struct menu_context *prompt_area));
/*
* A simple macro to make it easier to remember how to do a simple
* resync and not screw up whether or not to prompt on deletions.
*/
#define resync_aliases(newaliases,aview, page, prompt_area) \
delete_aliases(newaliases,TRUE, aview, page, prompt_area)
static int get_realnames P_((char *aliasname,
char *firstname,
char *lastname,
char *comment,
char *buffer,
int size_first,
int size_last,
int size_comment,
int size_buffer,
int is_group,
struct menu_context *page,
struct menu_context *prompt_area));
static int add_alias P_((int replace, int to_replace,
struct AliasView *aview,
struct menu_context *page,
struct screen_parts *LOC));
static int ask_accept P_((char *aliasname,
char *firstname,
char *lastname,
char *comment,
char *address,
char *buffer,
int replace,
int replacement,
int size_buffer,
struct AliasView *avies,
struct menu_context *page,
struct screen_parts *LOC));
static void alias_help P_((struct menu_context *page,
struct menu_context *prompt_area));
extern int is_system; /* system file updating? */
#include <errno.h>
#ifndef ANSI_C
extern int errno;
#endif
#if 0
DBZ *system_hash = NULL, *user_hash = NULL;
#endif
char *a_rev_alias_pad, *a_rev_alias_abr, *a_rev_alias_name,
*a_rev_full_pad, *a_full_abr, *a_rev_full_name,
*a_rev_text_pad, *a_text_abr, *a_rev_text_file,
*a_alias_pad, *a_alias_abr, *a_alias_name,
*a_full_pad, *a_full_name,
*a_text_pad, *a_text_file,
*a_group_name, *a_person_name, *a_system_flag;
void open_alias_files(aview, LOC)
struct AliasView *aview;
struct screen_parts *LOC;
{
/*
* Close and re-open the system and user alias files, if present,
* and if they have changed since last we opened them.
*
* Also, parse the data files into memory if needed
*/
int A,B;
if (update_aview(aview)) {
if (!mail_only && !check_only) {
int tac = get_total_alias_count(aview);
set_alias_current(aview,0);
if (tac) {
sort_aliases(tac, FALSE, LOC ? 1 : 0,aview);
set_alias_current(aview,1);
}
if (LOC) {
struct menu_common MENU;
set_mcommon_from_aliasview(&MENU, aview);
copy_current(&MENU,LOC->header_page);
get_page(&MENU, LOC->header_page);
}
}
}
}
static int add_alias(replace, to_replace, aview, page, LOC)
int replace, to_replace;
struct AliasView *aview;
struct menu_context *page;
struct screen_parts *LOC;
{
/*
* Add an alias to the user alias text file. If there
* are aliases tagged, the user is asked if he wants to
* create a group alias from the tagged files.
*
* Return zero if alias not added in actuality.
*
* If replace == FALSE, then we will ask for the new
* aliasname.
*
* If replace == TRUE, then we are replacing the alias
* denoted by to_replace.
*
* Note that even if replace == FALSE, if the user types
* in the name of a current alias then we can still do
* a replacement.
*/
int i, leftoff = 0, tagged = 0;
int is_group = 0;
char aliasname[SLEN], firstname[SLEN], lastname[SLEN];
char address1[LONG_STRING];
char comment[LONG_STRING], ch = *def_ans_no;
char *ch_ptr;
char bufferA[100]; /* TODO: Can remove? */
int ac;
int delay_redraw = 0;
/*
* See if there are any tagged aliases.
*/
ac = get_alias_count(aview);
for (i=0; i < ac; i++) {
struct alias_rec * a = give_alias(aview,i);
if (a &&
ison(a->status, TAGGED)) {
if (tagged == 0) leftoff = i;
tagged++;
}
}
if (tagged == 1) {
char * buffer = NULL;
/*
* There is only on alias tagged. Ask the question
* but the default response is NO.
*/
menu_PutLineX(LOC->prompt_page,1,0, CATGETS(elm_msg_cat,
AliasesSet,
AliasesOneTagged,
"There is 1 alias tagged..."));
menu_CleartoEOLN(LOC->prompt_page);
buffer = elm_message(CATGETS(elm_msg_cat,
AliasesSet, AliasesCreateGroup,
"Create group alias? (%c/%c) "),
*def_ans_yes, *def_ans_no);
ch = want_to(buffer, *def_ans_no, 0, 0, LOC->prompt_page);
free(buffer);
}
else if (tagged > 1) {
char * buffer = NULL;
/*
* If multiple tagged aliases then we assume the user
* wants to create a group alias. The default response
* is YES.
*/
menu_PutLineX(LOC->prompt_page,
1,0, CATGETS(elm_msg_cat,
AliasesSet, AliasesManyTagged,
"There are %d aliases tagged..."),
tagged);
menu_CleartoEOLN(LOC->prompt_page);
buffer = elm_message(CATGETS(elm_msg_cat,
AliasesSet, AliasesCreateGroup,
"Create group alias? (%c/%c) "),
*def_ans_yes, *def_ans_no);
ch = want_to(buffer, *def_ans_yes, 0, 0, LOC->prompt_page);
free(buffer);
}
/*
* Create the group alias address. This is only done
* if one of the above want_to() questions were
* answered YES (and thus there *were* tagged messages
* and the user responded correctly).
*/
if (ch == *def_ans_yes) {
struct alias_rec * a = give_alias(aview,leftoff);
/* TODO: Fix this mess */
strfcpy(address1, a->alias, sizeof address1);
ac = get_alias_count(aview);
for (i=leftoff+1; i < ac; i++) {
struct alias_rec * a = give_alias(aview,i);
if (a &&
ison(a->status, TAGGED)) {
strfcat(address1, ",", sizeof address1);
strfcat(address1, a->alias,
sizeof address1);
}
}
is_group = 1;
}
else {
tagged = 0;
}
/*
* Only ask for an aliasname if we are NOT replacing the
* current alias.
*/
if (replace) {
char buffer[100]; /* TODO: Fix this mess! */
struct alias_rec * a = give_alias(aview,to_replace);
aliasname[0] = '\0';
if (a) {
strfcpy(aliasname, a->alias, sizeof aliasname);
/*
* First, see if what we are replacing is a SYSTEM
* alias. If so, we need to ask a question.
*/
if(a->type & SYSTEM) {
DPRINT(Debug,3,
(&Debug,
"Aliasname [%s] is SYSTEM in add_alias\n",
aliasname));
/*
* If they don't want to superceed the SYSTEM alias
* then just return.
*/
if( ! superceed_system(to_replace, buffer, sizeof buffer,
aview, page, LOC->prompt_page)) {
menu_ClearLine(LOC->prompt_page,1);
return(0);
}
}
}
}
else {
char buffer[100]; /* TODO: Fix this mess! */
strfcpy(buffer, catgets(elm_msg_cat,
AliasesSet, AliasesEnterAliasName,
"Enter alias name: "),
sizeof buffer);
menu_PutLine0(LOC->prompt_page,1,0, buffer);
menu_CleartoEOLN(LOC->prompt_page);
*aliasname = '\0';
replace = get_aliasname(aliasname, buffer, &to_replace,
sizeof aliasname, sizeof buffer,
aview, page,LOC->prompt_page);
while (REDRAW_MARK == replace) {
menu_ClearScreen(page); /* Reset possible redraw flag */
/* Call refresh routines of children */
menu_redraw_children(page);
if (menu_need_redraw(LOC->prompt_page))
menu_ClearScreen(LOC->prompt_page);
delay_redraw++;
menu_PutLine0(LOC->prompt_page,1,0, buffer);
replace = get_aliasname(aliasname, buffer, &to_replace,
sizeof aliasname, sizeof buffer,
aview, page,LOC->prompt_page);
}
if (replace < 0) {
if (delay_redraw)
menu_trigger_redraw(page);
DPRINT(Debug,3,
(&Debug,
"Aliasname [%s] was rejected in add_alias\n", aliasname));
menu_ClearLine(LOC->prompt_page,1);
return(0);
}
}
/*
* If we are replacing an existing alias, we will assume that
* they might want to be just editing most of what is already
* there. So we copy some defaults from the existing alias.
*/
if (replace) {
struct alias_rec * a = give_alias(aview,to_replace);
lastname[0] = '\0';
firstname[0] = '\0';
comment[0] = '\0';
if (a) {
strfcpy(lastname, a->last_name, sizeof lastname);
strfcpy(firstname, a->name, sizeof firstname);
ch_ptr = strstr(firstname, lastname);
if (ch_ptr)
*(ch_ptr-1) = '\0';
strfcpy(comment, a->comment, sizeof comment);
}
}
else {
*lastname = '\0';
*firstname = '\0';
*comment = '\0';
}
/*
* Since there are no tagged aliases, we must ask for an
* address. If we are replacing, a default address is
* presented.
*/
if (tagged == 0) {
char buffer[1000]; /* Fix this mess !!! */
elm_sfprintf(buffer, sizeof buffer,
CATGETS(elm_msg_cat,
AliasesSet, AliasesEnterAddress,
"Enter address for %s: "),
aliasname);
menu_PutLine0(LOC->prompt_page,1,0, buffer);
menu_CleartoEOLN(LOC->prompt_page);
if (replace) {
struct alias_rec * a = give_alias(aview,to_replace);
if (a)
strfcpy(address1, a->address, sizeof address1);
else
address1[0] = '\0';
}
else {
*address1 = '\0';
}
do {
/* FIXME --optionally_enter* should use prompt_page */
int line = menu_GetAbsLine(LOC->prompt_page,1);
int status =
optionally_enter(address1, line, strlen(buffer),
OE_REDRAW_MARK|
OE_SIG_CHAR /* Ctrl-C */, sizeof address1,
page);
while (REDRAW_MARK == status) {
menu_ClearScreen(page); /* Reset possible redraw flag */
delay_redraw++; /* Can't trigger redraw yet... */
/* Call refresh routines of children */
menu_redraw_children(page);
if (menu_need_redraw(LOC->prompt_page))
menu_ClearScreen(LOC->prompt_page);
elm_sfprintf(buffer, sizeof buffer,
CATGETS(elm_msg_cat,
AliasesSet, AliasesEnterAddress,
"Enter address for %s: "),
aliasname);
menu_PutLine0(LOC->prompt_page,1,0, buffer);
status =
optionally_enter(address1, line, strlen(buffer),
OE_REDRAW_MARK|OE_APPEND_CURRENT|
OE_SIG_CHAR /* Ctrl-C */,
sizeof address1,
page);
}
if (0 != status ||
strlen(address1) == 0) {
if (delay_redraw)
menu_trigger_redraw(page);
lib_error(CATGETS(elm_msg_cat, AliasesSet,
AliasesNoAddressSpec,
"No address specified!"));
return(0);
}
} while (check_address(address1) == -1);
clear_error(); /* Just in case */
}
if (!is_group && strchr(address1,',') != NULL)
is_group = 1;
if (!get_realnames(aliasname, firstname, lastname, comment, bufferA,
sizeof firstname, sizeof lastname, sizeof comment,
sizeof bufferA, is_group, page,LOC->prompt_page)) {
if (delay_redraw)
menu_trigger_redraw(page);
return 0;
}
if(ask_accept(aliasname, firstname, lastname, comment, address1,
bufferA, replace, to_replace,
sizeof bufferA, aview, page, LOC)) {
if (delay_redraw)
menu_trigger_redraw(page);
/*
* We can only clear the tags after we know that the
* alias was added. This allows the user to back out
* and rethink without losing the tags.
*/
if (tagged > 0) {
ac = get_alias_count(aview);
for (i=leftoff; i < ac; i++) {
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);
}
}
}
return(1);
}
if (delay_redraw)
menu_trigger_redraw(page);
return(0);
}
static int add_current_alias P_((struct MailboxView *mailbox,
struct AliasView *aview,
struct menu_context *page,
struct screen_parts *LOC));
static int add_current_alias(mailbox,aview, page, LOC)
struct MailboxView *mailbox;
struct AliasView *aview;
struct menu_context *page;
struct screen_parts *LOC;
{
/*
* Alias the current message to the specified name and
* add it to the alias text file, for processing as
* the user leaves the program.
*
* Returns non-zero iff alias actually added to file.
*/
char aliasname[SLEN], firstname[SLEN], lastname[SLEN];
char comment[SLEN], address1[LONG_STRING], buffer[SLEN];
char comment_buff[LONG_STRING];
char *chspace, *bufptr;
struct header_rec *current_header;
static char bad_punc[] = ",.:;";
char *punc_ptr;
int i, match;
int replace, to_replace;
int delay_redraw = 0;
int current_mail_message = get_current(mailbox);
if (current_mail_message == 0) {
DPRINT(Debug,3,
(&Debug,
"Add current alias called without any current message!\n"));
lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesNoMessage,
"No message to alias to!"));
return(0);
}
current_header = give_header(mailbox,current_mail_message - 1);
if (!current_header ||
!current_header->from ||
!current_header->from[0].fullname ||
!current_header->from[0].addr ||
!current_header->from[0].comment)
return 0;
/* TODO: Fix this mess ... */
strfcpy(buffer, catgets(elm_msg_cat, AliasesSet, AliasesCurrentMessage,
"Current message address aliased to: "),
sizeof buffer);
menu_PutLine0(LOC->prompt_page,1,0, buffer);
menu_CleartoEOLN(LOC->prompt_page);
*aliasname = '\0';
replace = get_aliasname(aliasname, buffer, &to_replace,
sizeof aliasname, sizeof buffer,
aview, page,LOC->prompt_page);
while (REDRAW_MARK == replace) {
menu_ClearScreen(page); /* Reset possible redraw flag */
/* Call refresh routines of children */
menu_redraw_children(page);
if (menu_need_redraw(LOC->prompt_page))
menu_ClearScreen(LOC->prompt_page); /* Clear redraw mark from prompt_area*/
/* NOTICE: using menu_trigger_redraw(page) on here
may cause redraw loop!
*/
delay_redraw++;
menu_PutLine0(LOC->prompt_page,1,0, buffer);
replace = get_aliasname(aliasname, buffer, &to_replace,
sizeof aliasname, sizeof buffer,
aview, page,LOC->prompt_page);
}
if (delay_redraw)
menu_trigger_redraw(page);
if (replace < 0) {
DPRINT(Debug,3,
(&Debug,
"Aliasname [%s] was rejected in add_current_alias\n",
aliasname));
menu_ClearLine(LOC->prompt_page,1);
return(0);
}
{
struct string * T =
convert_string(display_charset,
current_header->from[0].fullname,
1);
char * A = us2s(stream_from_string(T,1,NULL));
strfcpy(comment_buff,A,sizeof comment_buff);
free(A);
free_string(&T);
}
/*
* Try to break up the From: comment into firstname, lastname, and
* any other text. This is based on the fact that many address
* comments are pretty straightforward. This will break on many
* situations. Should handle:
* (Robert Howard)
* (Robert L. Howard)
* (Robert Howard, Georgia Tech)
* pretty well. Will break on:
* (The Voice of Reason)
* and others....
*/
*firstname = '\0';
*lastname = '\0';
*comment = '\0';
if (strlen(comment_buff) != 0) { /* There is something. */
bufptr = comment_buff;
while (*bufptr == SPACE) bufptr++; /* Always strip leading WS */
if ((chspace = index(bufptr, (int) SPACE)) != NULL) {
/*
* A space means that there is at least (firstname lastname)
* Get firstname and move bufptr.
*/
*chspace = '\0';
strfcpy(firstname, bufptr, sizeof firstname);
bufptr = chspace + 1; /* Move the pointer */
while (*bufptr == SPACE) bufptr++;
}
above: if ((chspace = index(bufptr, (int) SPACE)) != NULL) {
/*
* Another space means a third+ word. We either have:
* 1. Word 3+ is a comment, or
* 2. Word 2 is a middle initial (word 3 is lastname).
* Check and see.
*/
*chspace = '\0';
if ((strlen(bufptr) == 1) ||
(strlen(bufptr) == 2 && *(bufptr+1) == '.')) {
/*
* If the second word is either a single
* character or a character followed by '.' it was
* probably a middle initial. Add it to firstname
* and shift.
*/
strfcat(firstname, " ", sizeof firstname);
strfcat(firstname, bufptr, sizeof firstname);
bufptr = chspace + 1; /* Move the pointer */
while (*bufptr == SPACE) bufptr++;
goto above;
}
strfcpy(lastname, bufptr, sizeof lastname);
bufptr = chspace + 1; /* Move the pointer */
while (*bufptr == SPACE) bufptr++;
strfcpy(comment, bufptr, sizeof comment);
}
else {
/*
* Only a lastname left.
*/
strfcpy(lastname, bufptr, sizeof lastname);
}
if (!comment[0]) {
struct string * T =
convert_string(display_charset,
current_header->from[0].comment,
1);
char * A = us2s(stream_from_string(T,1,NULL));
strfcpy(comment, A, sizeof comment);
free(A);
free_string(&T);
}
/*
* Finally, get any puctuation characters off the end of
* lastname.
*/
match = TRUE;
for (i = strlen(lastname) - 1; match && i>0; i--) {
match = FALSE;
for (punc_ptr = bad_punc; *punc_ptr != '\0'; punc_ptr++) {
if (lastname[i] == *punc_ptr) {
lastname[i] = '\0';
match = TRUE;
break;
}
}
}
}
if (!get_realnames(aliasname, firstname, lastname, comment, buffer,
sizeof firstname, sizeof lastname, sizeof comment,
sizeof buffer, 0, page,LOC->prompt_page))
return 0;
/* grab the return address of this message */
strfcpy(address1,current_header->from[0].addr,sizeof address1);
return(ask_accept(aliasname, firstname, lastname, comment, address1,
buffer, replace, to_replace, sizeof buffer, aview,
page, LOC));
}
static int add_to_alias_text(aliasname, firstname, lastname, comment, address)
char *aliasname, *firstname, *lastname, *comment, *address;
{
/*
* Add the data to the user alias text file.
*
* Return zero if we succeeded, 1 if not.
*/
FILE *file;
char fname[SLEN];
char buffer[SLEN];
int err;
strfcpy(fname,user_text_file,sizeof fname);
save_file_stats(fname);
err = can_open(fname, "a");
if (err) {
DPRINT(Debug,2,
(&Debug,
"Failure attempting to add alias to file %s within %s (can_open)",
fname, "add_to_alias_text"));
DPRINT(Debug,2,
(&Debug, "** %s **\n", error_description(err)));
lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesCouldntOpenAdd,
"Couldn't open %s to add new alias!"),
fname);
return(1);
}
if ((file = fopen(fname, "a")) == NULL) {
err = errno;
DPRINT(Debug,2,
(&Debug,
"Failure attempting to add alias to file %s within %s",
fname, "add_to_alias_text"));
DPRINT(Debug,2,
(&Debug, "** %s **\n", error_description(err)));
lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesCouldntOpenAdd,
"Couldn't open %s to add new alias!"),
fname);
return(1);
}
if (strlen(firstname) == 0) {
strfcpy(buffer, lastname, sizeof buffer);
}
else {
elm_sfprintf(buffer, sizeof buffer,
FRM("%s; %s"), lastname, firstname);
}
if (strlen(comment) != 0) {
strfcat(buffer, ", ", sizeof buffer);
strfcat(buffer, comment, sizeof buffer);
}
if (fprintf(file,"%s = %s = %s\n", aliasname, buffer, address) == EOF) {
err = errno;
DPRINT(Debug,2,
(&Debug,
"Failure attempting to write alias to file %s within %s",
fname, "add_to_alias_text"));
DPRINT(Debug,2,
(&Debug, "** %s **\n", error_description(err)));
lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesCouldntWrite,
"Couldn't write alias to file %s!"),
fname);
fclose(file);
return(1);
}
fclose(file);
restore_file_stats(fname);
return(0);
}
static int parse_aliases P_((char *, char *, int, int)); /* Prototype */
int delete_from_alias_text(name, num_to_delete)
char **name;
int num_to_delete;
{
/*
* Delete the data from the user alias text file.
*
* Return zero if we succeeded, 1 if not.
*/
FILE *file, *tmp_file;
char fname[SLEN], tmpfname[SLEN];
char line_in_file[LONG_STRING];
char rest_of_line[LONG_STRING];
char *s, *rest;
register int i;
int num_aliases;
int delete_continues;
int err;
delete_continues = FALSE;
strfcpy(fname,user_text_file,sizeof fname);
elm_sfprintf(tmpfname,sizeof tmpfname,
FRM("%s.t"), user_text_file);
save_file_stats(fname);
err = can_open(fname, "r");
if (err) {
DPRINT(Debug,2,
(&Debug,
"Failure attempting to delete alias from file %s within %s (can_open)",
fname, "delete_from_alias_text"));
DPRINT(Debug,2,
(&Debug, "** %s **\n", error_description(err)));
lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesCouldntOpenDelete,
"Couldn't open %s to delete alias!"),
fname);
return(1);
}
if ((file = fopen(fname, "r")) == NULL) {
err = errno;
DPRINT(Debug,2,
(&Debug,
"Failure attempting to delete alias from file %s within %s",
fname, "delete_from_alias_text"));
DPRINT(Debug,2,
(&Debug, "** %s **\n", error_description(err)));
lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesCouldntOpenDelete,
"Couldn't open %s to delete alias!"),
fname);
return(1);
}
err = can_open(tmpfname, "w");
if (err) {
err = errno;
DPRINT(Debug,2,
(&Debug,
"Failure attempting to open temp file %s within %s (can_open)",
tmpfname, "delete_from_alias_text"));
DPRINT(Debug,2,
(&Debug, "** %s **\n", error_description(err)));
lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesCouldntOpenTemp,
"Couldn't open temp file %s to delete alias!"),
tmpfname);
fclose(file);
return(1);
}
if ((tmp_file = fopen(tmpfname, "w")) == NULL) {
err = errno;
DPRINT(Debug,2,
(&Debug,
"Failure attempting to open temp file %s within %s",
tmpfname, "delete_from_alias_text"));
DPRINT(Debug,2,
(&Debug, "** %s **\n", error_description(err)));
lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesCouldntOpenTemp,
"Couldn't open temp file %s to delete alias!"),
tmpfname);
fclose(file);
return(1);
}
while (mail_gets(line_in_file, sizeof(line_in_file), file) != 0)
{
if (! whitespace(line_in_file[0])) {
delete_continues = FALSE;
if (line_in_file[0] != '#') {
if (0 != (num_aliases =
parse_aliases(line_in_file, rest_of_line,
sizeof line_in_file,
sizeof rest_of_line))) {
for (i=0; i < num_to_delete && num_aliases; i++) {
char buf[LONG_STRING];
strfcpy(buf,name[i], sizeof buf);
strfcat(buf,",", sizeof buf);
if ((s = strstr(line_in_file, buf)) != NULL) {
/*
* Collapse the to be deleted alias out of line_in_file
*/
rest = index(s, ',');
for (++rest; *rest; rest++)
*s++ = *rest;
*s = '\0';
num_aliases--;
}
}
if (num_aliases) {
*(line_in_file + strlen(line_in_file) - 1) = ' ';
strfcat(line_in_file, rest_of_line,
sizeof line_in_file);
}
else {
delete_continues = TRUE;
}
}
}
}
if (! delete_continues) {
if (fprintf(tmp_file,"%s", line_in_file) == EOF) {
err = errno;
DPRINT(Debug,2,
(&Debug,
"Failure attempting to write to temp file %s within %s",
tmpfname, "delete_from_alias_text"));
DPRINT(Debug,2,
(&Debug, "** %s **\n", error_description(err)));
lib_error(CATGETS(elm_msg_cat, AliasesSet,
AliasesCouldntWriteTemp,
"Couldn't write to temp file %s!"),
tmpfname);
fclose(file);
fclose(tmp_file);
unlink(tmpfname);
return(1);
}
}
}
fclose(file);
fclose(tmp_file);
if (rename(tmpfname, fname) != 0)
{
lib_error(CATGETS(elm_msg_cat, AliasesSet,
AliasesCouldntRenameTemp,
"Couldn't rename temp file %s after deleting alias!"),
tmpfname);
return(1);
}
restore_file_stats(fname);
return(0);
}
static void set_alias_screen P_((struct menu_context *page,
struct screen_parts *LOC,
struct menu_param *LIST));
static void set_alias_screen(page,LOC, LIST)
struct menu_context *page;
struct screen_parts *LOC;
struct menu_param *LIST;
{
int LINES, COLUMNS;
menu_get_sizes(page,&LINES, &COLUMNS);
/* 1) Title part of screen */
if (! LOC->title_page)
LOC->title_page = new_menu_subpage(page,0,4,sb_update_title,LIST);
else
menu_subpage_relocate(LOC->title_page,page,0,4);
/* 2) menu part */
if (LOC->menu_page)
menu_subpage_relocate(LOC->menu_page,page,LINES-8,4);
else if (mini_menu)
LOC->menu_page = new_menu_subpage(page,LINES-8,4,
sb_alias_menu,LIST);
mailbox_screen_common(page,LOC, LIST);
}
static void check_alias_screen P_((struct screen_parts *LOC,
struct menu_param *list));
static void check_alias_screen(LOC,list)
struct screen_parts *LOC;
struct menu_param *list;
{
/* 1) title page */
if (menu_resized(LOC->title_page)) {
DPRINT(Debug,1, (&Debug, "title page resized\n"));
}
if (menu_need_redraw(LOC->title_page)) {
DPRINT(Debug,1, (&Debug, "title page redraw???\n"));
sb_update_title(LOC->title_page,list);
}
if (LOC->menu_page) {
/* 2) menu page */
if (menu_resized(LOC->menu_page)) {
DPRINT(Debug,1, (&Debug, "menu page resized\n"));
}
if (menu_need_redraw(LOC->menu_page)) {
DPRINT(Debug,1, (&Debug, "menu page redraw???\n"));
sb_show_menu(LOC->menu_page,list);
}
}
/* 3) prompt part */
if (menu_resized(LOC->prompt_page)) {
DPRINT(Debug,1, (&Debug, "prompt page resized\n"));
}
if (menu_need_redraw(LOC->prompt_page)) {
menu_ClearScreen(LOC->prompt_page);
show_last_error(); /* for those operations that have to
* clear the footer except for a message.
*/
}
/* 4) headers part */
if (menu_resized(LOC->header_page)) {
DPRINT(Debug,1, (&Debug, "header page resized\n"));
}
if (menu_need_redraw(LOC->header_page)) {
DPRINT(Debug,1, (&Debug, "header page redraw\n"));
menu_ClearScreen(LOC->header_page);
}
}
void alias(mailbox, aview)
struct MailboxView *mailbox;
struct AliasView *aview;
{
/*
* Work with alias commands...
*/
char name[NLEN], buffer[SLEN];
int ch;
static int newaliases = 0;
int i;
int too_long;
struct menu_context *page = new_menu_context();
struct screen_parts LOC = { NULL, NULL };
struct menu_common MENU;
struct menu_param PARAM[elm_mp_COUNT+1] = {
{ mp_menu_common, 0 },
{ mp_integer, 0 },
{ mp_END,0 }
};
static int first_time = TRUE;
/*
* We're going to try to match the way elm does it at
* he main menu. I probably won't be able to use any
* main menu routines, but I will "borrow" from them. RLH
*/
if (first_time) {
a_group_name = catgets(elm_msg_cat, AliasesSet, AliasesGroup,
" Group");
a_person_name = catgets(elm_msg_cat, AliasesSet, AliasesPerson,
"Person");
a_system_flag = catgets(elm_msg_cat, AliasesSet, AliasesSystemFlag,
"(S)");
a_rev_alias_pad = catgets(elm_msg_cat, AliasesSet, AliasesRevAliasPad,
"Reverse Alias Name ");
a_rev_alias_abr = catgets(elm_msg_cat, AliasesSet, AliasesRevAliasAbr,
"Reverse-Alias");
a_rev_alias_name = catgets(elm_msg_cat, AliasesSet, AliasesRevAliasName,
"Reverse Alias Name");
a_rev_full_pad = catgets(elm_msg_cat, AliasesSet, AliasesRevFullPad,
"Reverse Full (Real) Name");
a_full_abr = catgets(elm_msg_cat, AliasesSet, AliasesRevFullAbr,
"Reverse-Name");
a_rev_full_name = catgets(elm_msg_cat, AliasesSet, AliasesRevFullName,
"Reverse Full (Real) Name");
a_rev_text_pad = catgets(elm_msg_cat, AliasesSet, AliasesRevTextPad,
"Reverse Text File ");
a_text_abr = catgets(elm_msg_cat, AliasesSet, AliasesRevTextAbr,
"Reverse-Text");
a_rev_text_file = catgets(elm_msg_cat, AliasesSet, AliasesRevTextFile,
"Reverse Text File");
a_alias_pad = catgets(elm_msg_cat, AliasesSet, AliasesAliasPad,
"Alias Name ");
a_alias_abr = catgets(elm_msg_cat, AliasesSet, AliasesAliasAbr,
"Alias");
a_alias_name = catgets(elm_msg_cat, AliasesSet, AliasesAliasName,
"Alias Name");
a_full_pad = catgets(elm_msg_cat, AliasesSet, AliasesFullPad,
"Full (Real) Name ");
a_full_abr = catgets(elm_msg_cat, AliasesSet, AliasesFullAbr,
"Name");
a_full_name = catgets(elm_msg_cat, AliasesSet, AliasesFullName,
"Full (Real) Name");
a_text_pad = catgets(elm_msg_cat, AliasesSet, AliasesTextPad,
"Text File ");
a_text_abr = catgets(elm_msg_cat, AliasesSet, AliasesTextAbr,
"Text");
a_text_file = catgets(elm_msg_cat, AliasesSet, AliasesTextFile,
"Text File");
first_time = FALSE;
}
set_mcommon_from_aliasview(&MENU, aview);
mp_list_set_mcommon(PARAM,elm_mp_menu,&MENU);
mp_list_set_integer(PARAM,elm_mp_modified,newaliases);
set_alias_screen(page,&LOC,PARAM);
open_alias_files(aview, &LOC); /* First, read the alias files. RLH */
copy_current(&MENU,LOC.header_page);
alias_screen(aview, page);
/* define_softkeys(ALIAS); */
while (1) {
resize_mark:
menu_set_default(page);
set_mcommon_from_aliasview(&MENU, aview);
if (menu_resized(page)) {
int LINES, COLUMNS;
set_alias_screen(page,&LOC,PARAM);
menu_get_sizes(page,&LINES, &COLUMNS);
menu_trigger_redraw(page);
}
if (menu_need_redraw(page)) { /* Redraw screen if necessary */
DPRINT(Debug,7, (&Debug,
"alias: pending redraw\n"));
mp_list_set_integer(PARAM,elm_mp_modified,newaliases);
alias_screen(aview, page);
}
check_alias_screen(&LOC, PARAM);
{
int lin,col;
menu_PutLineX(LOC.prompt_page,0,0,
FRM("%S"),mcommon_give_item(&MENU, m_Prompt));
menu_GetXYLocation(LOC.prompt_page,&lin,&col);
menu_CleartoEOLN(LOC.prompt_page);
show_last_error();
menu_MoveCursor(LOC.prompt_page,lin,col);
ch = menu_ReadCh(LOC.prompt_page,
REDRAW_MARK|READCH_CURSOR|
READCH_resize);
menu_MoveCursor(LOC.prompt_page,lin,col);
menu_CleartoEOS(LOC.prompt_page);
if (isascii(ch) && isprint(ch)) {
DPRINT(Debug,4,
(&Debug, "-- Alias command: %c [%d]\n",ch,ch));
} else {
DPRINT(Debug,4,
(&Debug, "-- Alias command: [%d]\n",ch));
}
set_error(""); /* clear error buffer */
menu_MoveCursor(LOC.prompt_page,lin,col);
}
switch (ch) {
case RESIZE_MARK:
DPRINT(Debug,4, (&Debug," ... resizing\n"));
goto resize_mark;
case HELP_MARK:
case '?':
alias_help(page,LOC.prompt_page);
break;
case REDRAW_MARK:
case 'L'&31:
menu_trigger_redraw(page);
break;
case '$':
menu_Write_to_screen(LOC.prompt_page,
CATGETS(elm_msg_cat, AliasesSet,
AliasesResync,
"Resynchronize aliases..."));
FlushBuffer();
/*
* Process deletions and then see if we need to
* re-run the "newalias" routine.
*/
if (resync_aliases(newaliases,aview, page, LOC.prompt_page)
>=0) {
install_aliases(aview,&LOC);
newaliases = 0;
menu_trigger_redraw(page);
}
break;
case 'a':
menu_Write_to_screen(LOC.prompt_page,
CATGETS(elm_msg_cat, AliasesSet,
AliasesAddCurrent,
"Add address from current message..."));
FlushBuffer();
clear_error();
if (add_current_alias(mailbox,aview, page, &LOC)) {
newaliases++;
mp_list_set_integer(PARAM,elm_mp_modified,newaliases);
menu_trigger_redraw(LOC.title_page);
}
break;
case 'c': {
int alias_current = get_alias_current(aview);
if (alias_current > 0) {
menu_Write_to_screen(LOC.prompt_page,
CATGETS(elm_msg_cat,
AliasesSet, AliasesReplaceCurrent,
"Replace current alias in database..."));
FlushBuffer();
clear_error();
if (add_alias(TRUE, alias_current-1, aview,
page, &LOC)) {
newaliases++;
mp_list_set_integer(PARAM,elm_mp_modified,newaliases);
menu_trigger_redraw(LOC.title_page);
}
}
else {
lib_error(CATGETS(elm_msg_cat,
AliasesSet, AliasesNoneToReplace,
"Warning: no aliases to replace!"));
}
}
break;
case 'e':
menu_Write_to_screen(LOC.prompt_page,
CATGETS(elm_msg_cat, AliasesSet, AliasesEdit,
"Edit %s..."),
USER_ALIAS_TEXT);
FlushBuffer();
/*
* Process aliases.text for deletions, etc. You
* have to do this *before* checking current because
* all aliases could be marked for deletion.
*/
if (resync_aliases(newaliases,aview, page,
LOC.prompt_page) < 0)
break;
if (edit_aliases_text(aview, page, &LOC)) {
newaliases = 0;
}
menu_trigger_redraw(page);
break;
case 'm':{
int alias_current = get_alias_current(aview);
if (alias_current > 0) {
menu_Write_to_screen(LOC.prompt_page,
CATGETS(elm_msg_cat, AliasesSet, AliasesMail,
"Mail..."));
FlushBuffer();
a_sendmsg(TRUE,allow_forms,
mailbox, aview,
page, &LOC);
}
else {
lib_error(CATGETS(elm_msg_cat,
AliasesSet, AliasesNoneToMail,
"Warning: no aliases to send mail to!"));
}
}
break;
case 'n':
menu_Write_to_screen(LOC.prompt_page,
CATGETS(elm_msg_cat, AliasesSet, AliasesAddNew,
"Add a new alias to database..."));
FlushBuffer();
clear_error();
if (add_alias(FALSE, -1, aview, page, &LOC)) {
newaliases++;
mp_list_set_integer(PARAM,elm_mp_modified,
newaliases);
menu_trigger_redraw(LOC.title_page);
}
break;
case 'q':
case 'Q':
case 'i':
case 'I':
case 'r':
case 'R': {
int r;
menu_Write_to_screen(LOC.prompt_page,
CATGETS(elm_msg_cat, AliasesSet,
AliasesAddReturn,
"Return to main menu..."));
FlushBuffer();
/*
* leaving the alias system. Must check for
* pending deletes, etc. prompt is set to FALSE
* on uppercase letters so that deletions are
* NOT queried.
*/
r = delete_aliases(newaliases, islower(ch), aview, page,
LOC.prompt_page);
if (-1 == r) { /* Ctrl-C */
break;
}
if (r > 0) {
install_aliases(aview,&LOC);
newaliases = 0;
}
clear_error();
goto OUT;
}
case RETURN:
case LINE_FEED:
case SPACE:
case 'v': {
int alias_current = get_alias_current(aview);
if (newaliases) { /* Need this ?? */
int lin,col;
GetXYLocation(&lin,&col);
lib_error(CATGETS(elm_msg_cat,
AliasesSet, AliasesNotInstalled,
"Warning: new aliases not installed yet!"));
MoveCursor(lin,col);
}
if (alias_current > 0) {
struct alias_rec *a = give_alias(aview,
alias_current-1);
if (a) {
if (a->type & GROUP) {
menu_PutLineX(LOC.prompt_page,2, 0,
CATGETS(elm_msg_cat,
AliasesSet,
AliasesGroupAlias,
"Group alias: %-60.60s"),
a->address);
}
else {
menu_PutLineX(LOC.prompt_page,2, 0,
CATGETS(elm_msg_cat,
AliasesSet,
AliasesAliasedAddress,
"Aliased address: %-60.60s"),
a->address);
}
}
} else {
lib_error(CATGETS(elm_msg_cat,
AliasesSet, AliasesNoneToView,
"Warning: no aliases to view!"));
}
}
break;
case 'x':
case 'X':
menu_Write_to_screen(LOC.prompt_page,
CATGETS(elm_msg_cat, AliasesSet,
AliasesAddReturn,
"Return to main menu..."));
FlushBuffer();
exit_alias(aview);
clear_error();
goto OUT;
case 'f':
case 'F': {
int alias_current = get_alias_current(aview);
if (alias_current > 0) {
struct alias_rec *a = give_alias(aview,alias_current-1);
if (a) {
clear_error();
strfcpy(name, a->alias, sizeof name);
if (ch == 'F') {
int status, line;
int delay_redraw = 0;
/* TODO: Fix this mess... */
strfcpy(buffer, catgets(elm_msg_cat,
AliasesSet,
AliasesFullyExpanded,
"Fully expand alias: "),
sizeof buffer);
menu_PutLine0(LOC.prompt_page,1,0, buffer);
menu_CleartoEOS(LOC.prompt_page);
/* FIXME --optionally_enter* should use prompt_page */
line = menu_GetAbsLine(LOC.prompt_page,1);
status = optionally_enter(name, line,
strlen(buffer),
OE_REDRAW_MARK|
OE_SIG_CHAR /* Ctrl-C */,
sizeof name,
page);
while (REDRAW_MARK == status) {
menu_ClearScreen(page); /* Reset possible redraw flag */
delay_redraw++; /* Can't trigger redraw yet... */
menu_PutLine0(LOC.prompt_page,1,0, buffer);
status = optionally_enter(name, line,
strlen(buffer),
OE_REDRAW_MARK|
OE_APPEND_CURRENT|
OE_SIG_CHAR /* Ctrl-C */,
sizeof name,
page);
}
if (delay_redraw)
menu_trigger_redraw(page);
if (0 != status)
break;
}
{
struct addr_item * address;
too_long = FALSE;
address = get_alias_address_l(name, TRUE,
&too_long, NULL,
aview);
if (address != NULL) {
struct menu_context *page2 =
new_menu_context();
struct addr_item *walk ;
redraw2:
walk =address;
while (TRUE) {
int LINES, COLUMNS;
menu_get_sizes(page2,&LINES,&COLUMNS);
menu_ClearScreen(page2);
menu_PutLineX(page2,2,0,
CATGETS(elm_msg_cat,
AliasesSet, AliasesAliasedFull,
"Aliased address for:\t%s\n\r"),
name);
i = 4;
while (i < LINES-3) {
if (walk->addr && walk->fullname) {
if (string_len(walk->fullname) ||
NULL != strchr(walk->addr,'@')) {
menu_PutLineX(page2,
i++, 4, FRM("%S <%s>"),
walk->fullname,walk->addr);
} else
menu_PutLine0(page2,
i++, 4, walk->addr);
walk++;
} else
break;
}
menu_PutLineX(page2,
LINES-2, 0,
CATGETS(elm_msg_cat,
AliasesSet, AliasesPressReturn,
"Press <return> to continue."));
if (REDRAW_MARK == menu_ReadCh(page2,
REDRAW_MARK)) {
menu_ClearScreen(page2); /* Reset possible redraw flag */
goto redraw2;
}
if (walk->addr == NULL) {
break;
}
}
free_addr_items(address);
erase_menu_context(&page2);
menu_trigger_redraw(page);
} else if (! too_long) {
lib_error(CATGETS(elm_msg_cat,
AliasesSet, AliasesNotFound,
"Not found."));
}
}
}
}
else {
lib_error(CATGETS(elm_msg_cat,
AliasesSet, AliasesNoneToView,
"Warning: no aliases to view!"));
}
}
break;
/*
* None of the menu specific commands were chosen, therefore
* it must be a "motion" command (or an error).
*/
default :
ch = motion(ch,&MENU,&LOC, page);
switch (ch) {
case 0: /* OK */
break;
case EOF: leave(0); /* Read failed, control tty died? */
break;
default:
lib_error(CATGETS(elm_msg_cat, ElmSet,
ElmUnknownCommand,
"Unknown command. Use '?' for help."));
}
}
if (menu_need_redraw(page)) { /* Redraw screen if necessary */
DPRINT(Debug,7, (&Debug,
"alias: pending redraw\n"));
mp_list_set_integer(PARAM,elm_mp_modified,newaliases);
alias_screen(aview, page);
}
check_range(&MENU, &LOC);
check_alias_screen(&LOC, PARAM);
} /* BIG while loop... */
OUT:
free_mailbox_screen(&LOC);
erase_menu_context(&page);
return;
}
void install_aliases(aview,LOC)
struct AliasView *aview;
struct screen_parts *LOC;
{
/*
* Run the 'newalias' program and update the
* aliases before going back to the main program!
*
* No return value.....
*/
int na;
char itextfile[SLEN], odatafile[SLEN];
lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesUpdating,
"Updating aliases..."));
strfcpy(itextfile,user_text_file, sizeof itextfile);
strfcpy(odatafile,user_data_file,sizeof odatafile);
/*
* We need to unlimit everything since aliases are
* eing read in from scratch.
*/
set_alias_selected(aview,0);
na = do_newalias(itextfile, odatafile, TRUE, FALSE);
if (na >= 0) {
lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesReReading,
"Processed %d aliases. Re-reading the database..."),
na);
open_alias_files(aview, LOC);
lib_error(CATGETS(elm_msg_cat, AliasesSet, AliasesUpdatedOK,
"Aliases updated successfully."));
}
}
static void alias_help(page,prompt_area)
struct menu_context *page;
struct menu_context *prompt_area;
{
/*
* Help section for the alias menu...
*
* If redraw is needed use menu_trigger_redraw(page)
*/
int ch;
int delay_redraw=0;
redraw:
menu_ClearScreen(prompt_area);
if (mini_menu) {
menu_print_format_center(prompt_area,0,
CATGETS(elm_msg_cat, AliasesSet,
AliasesKeyMenu,
"Press the key you want help for, '?' for a key list, or '.' to exit help"));
}
do {
menu_PutLineX(prompt_area,
2, 0,
CATGETS(elm_msg_cat, AliasesSet, AliasesLongKey,
"Key you want help for: "));
ch = menu_ReadCh(prompt_area,
REDRAW_MARK|READCH_CURSOR|READCH_sig_char);
if (ch == REDRAW_MARK) {
menu_ClearScreen(page); /* Clear possible redraw mark */
/* Call refresh routines of children */
menu_redraw_children(page);
delay_redraw++;
/* This clear redraw mark from prompt_area */
goto redraw;
}
if (ch == '.')
break;
if (ch == TERMCH_interrupt_char)
break;
switch(ch) {
case EOF :
leave(0);
break;
case HELP_MARK:
case '?' :
display_helpfile(ALIAS_HELP);
menu_trigger_redraw(page);
return;
case '$': lib_transient(CATGETS(elm_msg_cat, AliasesSet,
AliasesHelpDollar,
"$ = Force resynchronization of aliases, processing additions and deletions."));
break;
case FIND_MARK:
case '/': lib_transient(CATGETS(elm_msg_cat, AliasesSet,
AliasesHelpSlash,
"/ = Search for specified name or alias in list."));
break;
case RETURN:
case LINE_FEED:
case SPACE:
case 'v': lib_transient(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpv,
"v = View the address for the currently selected alias."));
break;
case 'a':lib_transient(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpa,
"a = Add (return) address of current message to alias database."));
break;
case 'c': lib_transient(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpc,
"c = Change current user alias, modifying alias database at next resync."));
break;
case 'd': lib_transient(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpd,
"d = Mark the current alias for deletion from alias database."));
break;
case ctrl('D'): lib_transient(CATGETS(elm_msg_cat, AliasesSet,
AliasesHelpCtrlD,
"^D = Mark for deletion user aliases matching specified pattern."));
break;
case 'e': lib_transient(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpe,
"e = Edit the alias text file directly (will run newalias)."));
break;
case 'f': lib_transient(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpf,
"f = Display fully expanded address of current alias."));
break;
case 'l': lib_transient(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpl,
"l = Limit displayed aliases on the specified criteria."));
break;
case ctrl('L'): lib_transient(CATGETS(elm_msg_cat, AliasesSet,
AliasesHelpCtrlL,
"^L = Rewrite the screen."));
break;
case 'm': lib_transient(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpm,
"m = Send mail to the current or tagged aliases."));
break;
case 'n': lib_transient(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpn,
"n = Add a new user alias, adding to alias database at next resync."));
break;
case 'r':
case 'q':
case 'i': lib_transient(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpi,
"r,q,i = Return from alias menu (with prompting)."));
break;
case 'R':
case 'Q':
case 'I': lib_transient(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpQ,
"R,Q,I = Return from alias menu (no prompting)."));
break;
case 't': lib_transient(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpt,
"t = Tag current alias for further operations."));
break;
case 'T': lib_transient(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpT,
"T = Tag current alias and go to next alias."));
break;
case ctrl('T'): lib_transient(CATGETS(elm_msg_cat, AliasesSet,
AliasesHelpCtrlT,
"^T = Tag aliases matching specified pattern."));
break;
case 'u': lib_transient(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpu,
"u = Unmark the current alias for deletion from alias database."));
break;
case ctrl('U'): lib_transient(CATGETS(elm_msg_cat, AliasesSet,
AliasesHelpCtrlU,
"^U = Mark for undeletion user aliases matching specified pattern."));
break;
case 'x':
case 'X': lib_transient(CATGETS(elm_msg_cat, AliasesSet, AliasesHelpX,
"x = Exit from alias menu, abandoning any pending deletions."));
break;
default : lib_error(CATGETS(elm_msg_cat, AliasesSet,
AliasesHelpNoHelp,
"That key isn't used in this section."));
break;
}
} while (ch != '.');
if (delay_redraw)
menu_trigger_redraw(page);
menu_trigger_redraw(prompt_area);
return;
}
static int parse_aliases(buffer, remainder, size_buffer, size_remainder)
char *buffer, *remainder;
int size_buffer, size_remainder;
{
/*
* This routine will parse out the individual aliases present
* on the line passed in buffer. This involves:
*
* 1. Testing for an '=' to make sure this is an alias entry.
*
* 2. Setting remainder to point to the rest of the line starting
* at the '=' (for later rewriting if needed).
*
* 3. Parsing the aliases into an string padded with ',' at
* the end.
*
* 4. Returning the number of aliases found (0 if test #1 fails).
*/
char *s;
int number;
/* Check to see if an alias */
if ((s = index(buffer, '=')) == NULL)
return (0);
/* Save the remainder of the line */
strfcpy(remainder, s, size_remainder);
/* Terminate the list of aliases with a ',' */
while (--s >= buffer && whitespace(*s)) ;
if (s < buffer + size_buffer -2) {
*++s = ',';
*++s = '\0';
}
/* Lowercase everything */
s = shift_lower(buffer);
strfcpy(buffer, s, size_buffer);
/* Now, count the aliases */
number = 0;
for (s = buffer; *s; s++)
if (*s == ',')
number++;
return (number);
}
static int get_aliasname(aliasname, buffer, duplicate, size, buffer_size,
aview, page, prompt_area)
char *aliasname, *buffer;
int *duplicate;
int size, buffer_size;
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area;
{
/*
* Have the user enter an aliasname, check to see if it
* is legal, then check for duplicates. If a duplicate
* is found offer to replace existing alias.
*
* Return values:
*
* -1 Either the aliasname was zero length, had bad
* characters and was a duplicate which the user
* chose not to replace.
*
* 0 A new alias was entered successfully.
*
* 1 The entered alias was an existing USER alias
* that the user has chosen to replace. In this
* case the alias to replace is passed back in
* in the variable 'duplicate'.
*
* REDRAW_MARK
*/
int loc;
do {
/* FIXME --optionally_enter* should use prompt_page */
int line = menu_GetAbsLine(prompt_area,1);
int status =
optionally_enter(aliasname, line, strlen(buffer),
OE_REDRAW_MARK|OE_SIG_CHAR, size, page);
if (REDRAW_MARK == status)
return REDRAW_MARK;
/*
* Return if nothing was entered.
*/
if (0 != status || strlen(aliasname) == 0)
return(-1);
} while (check_alias(aliasname) == -1);
clear_error(); /* Just in case */
/*
* Check to see if there is already a USER alias by this name.
*/
if ((loc = find_alias(aliasname, USER, aview)) >= 0) {
struct alias_rec *a = give_alias(aview,loc);
if (a) {
int answer;
int redraw = 0;
DPRINT(Debug,2,
(&Debug,
"Attempt to add a duplicate alias [%s] in get_aliasname\n",
a->alias));
againD:
if (a->type & GROUP )
menu_PutLineX(prompt_area,1,0,
CATGETS(elm_msg_cat,
AliasesSet, AliasesAlreadyGroup,
"Already a group with name %s."),
a->alias);
else
menu_PutLineX(prompt_area,1,0,
CATGETS(elm_msg_cat,
AliasesSet, AliasesAlreadyAlias,
"Already an alias for %s."),
a->alias);
menu_CleartoEOLN(prompt_area);
/*
* If they don't want to replace the alias by that name
* then just return.
*/
answer = prompt_letter(1,"",*def_ans_no,
PROMPT_yesno|PROMPT_redraw_mark|
PROMPT_ctrlL|PROMPT_cancel,
prompt_area,
CATGETS(elm_msg_cat,
AliasesSet, AliasesReplaceExisting,
"Replace existing alias? (%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 (menu_need_redraw(prompt_area))
menu_ClearScreen(prompt_area);
redraw++; /* Can't trigger redraw yet... */
goto againD;
}
if (redraw)
menu_trigger_redraw(page);
if (TERMCH_interrupt_char == answer)
return -1;
if (answer != *def_ans_yes)
return(-1);
*duplicate = loc;
return(1);
}
}
/*
* If they have elected to replace an existing alias then
* we assume that they would also elect to superceed a
* system alias by that name (since they have already
* done so). So we don't even bother to check or ask.
*
* Of course we do check if there was no USER alias match.
*/
if ((loc = find_alias(aliasname, SYSTEM, aview)) >= 0) {
struct alias_rec *a = give_alias(aview,loc);
if (a) {
DPRINT(Debug,2,
(&Debug,
"Attempt to add a duplicate system alias [%s] in get_aliasname\n",
a->address));
if( ! superceed_system(loc, buffer, buffer_size,
aview, page,prompt_area))
return(-1);
}
}
return(0);
}
static int superceed_system(this_alias, buffer, buffer_size, aview,page,prompt_area)
int this_alias;
char *buffer;
int buffer_size;
struct AliasView *aview;
struct menu_context *page;
struct menu_context *prompt_area;
{
struct alias_rec *a = give_alias(aview,this_alias);
if (!a)
return 0;
menu_PutLineX(prompt_area,1, 0,
CATGETS(elm_msg_cat,
AliasesSet, AliasesSystemAlias,
"System (%6s) alias for %s."),
alias_type(a->type), a->alias);
elm_sfprintf(buffer, buffer_size,
CATGETS(elm_msg_cat, AliasesSet, AliasesSuperceed,
"Superceed? (%c/%c) "), *def_ans_yes, *def_ans_no);
/*
* If they don't want to superceed the SYSTEM alias then
* return a FALSE.
*/
return(want_to(buffer, *def_ans_no, 0, 0,
prompt_area) == *def_ans_yes);
}
static int get_realnames(aliasname, firstname, lastname, comment, buffer,
size_first, size_last, size_comment, size_buffer,
is_group, page, prompt_area)
char *aliasname, *firstname, *lastname, *comment, *buffer;
int size_first, size_last, size_comment, size_buffer;
int is_group;
struct menu_context *page;
struct menu_context *prompt_area;
{
int status;
int delay_redraw = 0;
if (is_group) {
lastname[0] = '\0';
firstname[0] = '\0';
} else {
int line;
elm_sfprintf(buffer, size_buffer,
CATGETS(elm_msg_cat, AliasesSet, AliasesEnterLastName,
"Enter last name for %s: "), aliasname);
menu_PutLine0(prompt_area,1,0, buffer);
menu_CleartoEOLN(prompt_area);
/* FIXME --optionally_enter* should use prompt_page */
line = menu_GetAbsLine(prompt_area,1);
status = optionally_enter(lastname, line, strlen(buffer),
OE_REDRAW_MARK|
OE_SIG_CHAR /* Ctrl-C */, size_last, page);
while (REDRAW_MARK == status) {
menu_ClearScreen(page); /* Reset possible redraw flag */
delay_redraw++; /* Can't trigger redraw yet... */
/* Call refresh routines of children */
menu_redraw_children(page);
if (menu_need_redraw(prompt_area))
menu_ClearScreen(prompt_area);
/* FIXME --optionally_enter* should use prompt_page */
line = menu_GetAbsLine(prompt_area,1);
menu_PutLine0(prompt_area,1,0, buffer);
status = optionally_enter(lastname, line, strlen(buffer),
OE_REDRAW_MARK|OE_APPEND_CURRENT|
OE_SIG_CHAR /* Ctrl-C */,
size_last, page);
}
if (status != 0) { /* Error or Ctrl-C */
if (delay_redraw)
menu_trigger_redraw(page);
return 0;
}
{
int line;
elm_sfprintf(buffer, size_buffer,
CATGETS(elm_msg_cat, AliasesSet, AliasesEnterFirstName,
"Enter first name for %s: "), aliasname);
menu_PutLine0(prompt_area,1,0, buffer);
menu_CleartoEOLN(prompt_area);
/* FIXME --optionally_enter* should use prompt_page */
line = menu_GetAbsLine(prompt_area,1);
status = optionally_enter(firstname, line, strlen(buffer),
OE_REDRAW_MARK|
OE_SIG_CHAR /* Ctrl-C */, size_first, page);
while (REDRAW_MARK == status) {
menu_ClearScreen(page); /* Reset possible redraw flag */
delay_redraw++; /* Can't trigger redraw yet... */
/* Call refresh routines of children */
menu_redraw_children(page);
if (menu_need_redraw(prompt_area))
menu_ClearScreen(prompt_area);
/* FIXME --optionally_enter* should use prompt_page */
line = menu_GetAbsLine(prompt_area,1);
menu_PutLine0(prompt_area,1,0, buffer);
status = optionally_enter(firstname, line, strlen(buffer),
OE_REDRAW_MARK|OE_APPEND_CURRENT|
OE_SIG_CHAR /* Ctrl-C */,
size_first, page);
}
}
if (0 != status) { /* Ctrl-C or error */
if (delay_redraw)
menu_trigger_redraw(page);
return 0;
}
if (strlen(lastname) == 0) {
strfcpy(lastname, firstname, size_last);
*firstname = '\0';
}
}
{
int line;
elm_sfprintf(buffer, size_buffer,
CATGETS(elm_msg_cat, AliasesSet, AliasesEnterComment,
"Enter optional comment for %s: "), aliasname);
menu_PutLine0(prompt_area,1,0, buffer);
/* FIXME --optionally_enter* should use prompt_page */
line = menu_GetAbsLine(prompt_area,1);
status = optionally_enter(comment, line, strlen(buffer),
OE_REDRAW_MARK|
OE_SIG_CHAR /* Ctrl-C */, size_comment, page);
while (status == REDRAW_MARK) {
menu_ClearScreen(page); /* Reset possible redraw flag */
delay_redraw++; /* Can't trigger redraw yet... */
/* Call refresh routines of children */
menu_redraw_children(page);
if (menu_need_redraw(prompt_area))
menu_ClearScreen(prompt_area);
menu_PutLine0(prompt_area,1,0, buffer);
status = optionally_enter(comment, line, strlen(buffer),
OE_REDRAW_MARK|OE_APPEND_CURRENT|
OE_SIG_CHAR /* Ctrl-C */,
size_comment, page);
}
}
if (delay_redraw)
menu_trigger_redraw(page);
if (0 != status) /* Ctrl-C or error */
return 0;
return 1;
}
static int ask_accept(aliasname, firstname, lastname, comment, address, buffer,
replace, replacement, size_buffer, aview,
page,LOC)
char *aliasname, *firstname, *lastname, *comment, *address, *buffer;
int replace, replacement;
int size_buffer;
struct AliasView *aview;
struct menu_context *page;
struct screen_parts *LOC;
{
int delay_redraw = 0;
int answer = 0;
char *(old_alias[1]);
again:
/*
* If firstname == lastname, they probably just took all
* the deafaults. We *assume* they don't want lastname
* entered twice, so we will truncate it.
*/
if (strcmp(firstname, lastname) == 0) {
*firstname = '\0';
}
if (strlen(lastname) == 0) {
menu_PutLineX(LOC->prompt_page,
2,0, CATGETS(elm_msg_cat, AliasesSet,
AliasesAddressAs1,
"Messages addressed as: %s"),
address);
strfcpy(buffer, aliasname, size_buffer);
} else {
if (strlen(firstname) == 0) {
strfcpy(buffer, lastname, size_buffer);
}
else {
elm_sfprintf(buffer, size_buffer,
FRM("%s %s"), firstname, lastname);
}
menu_PutLineX(LOC->prompt_page,
2,0,
CATGETS(elm_msg_cat, AliasesSet,
AliasesAddressAs,
"Messages addressed as: %s <%s>"),
buffer,address);
}
if (strlen(comment) != 0) {
strfcat(buffer, ", ", size_buffer);
strfcat(buffer, comment, size_buffer);
}
menu_PutLineX(LOC->prompt_page,1,0,
CATGETS(elm_msg_cat, AliasesSet,
AliasesAddressTo,
"New alias: %s is '%s'."),
aliasname, buffer);
menu_CleartoEOLN(LOC->prompt_page);
/*
* Kludge Alert: Spaces are padded to the front of the prompt
* to write over the previous question. Should probably record
* the end of the line, move to it, and CleartoEOLN() it.
*/
answer = prompt_letter(1,"",*def_ans_no,
PROMPT_yesno|PROMPT_redraw_mark|
PROMPT_ctrlL|PROMPT_cancel,
LOC->prompt_page,
CATGETS(elm_msg_cat, AliasesSet, AliasesAcceptNew,
" Accept new alias? (%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 (menu_need_redraw(LOC->prompt_page))
menu_ClearScreen(LOC->prompt_page);
delay_redraw++; /* Can't trigger redraw yet... */
goto again;
}
if (delay_redraw)
menu_trigger_redraw(page);
if (TERMCH_interrupt_char == answer)
goto clean;
if(answer == *def_ans_yes) {
if (replace) {
struct alias_rec *a = give_alias(aview,replacement);
if (a) {
old_alias[0] = a->alias;
/*
* First, clear flag if this is marked to be deleted.
* This prevents the problem where they marked it for
* deletion and then figured out that it could be
* c)hanged but didn't explicitly U)ndelete it. Without
* this test, the resync action would then delete
* the new alias we just so carefully added to the
* text file.
*/
if (ison(a->status, DELETED)) {
clearit(a->status, DELETED);
}
/*
* Changed aliases are given the NEW flag.
*/
setit(a->status, NEW);
{
struct menu_common MENU;
int vis;
set_mcommon_from_aliasview(&MENU,aview);
vis = compute_visible(replacement+1, &MENU);
menu_header_status_update(LOC->header_page,vis-1);
}
/*
* Now we can delete it...
*/
delete_from_alias_text(old_alias, 1);
}
}
add_to_alias_text(aliasname, firstname, lastname, comment, address);
}
clean:
menu_ClearLine(LOC->prompt_page,1);
menu_ClearLine(LOC->prompt_page,2);
return(answer == *def_ans_yes ? 1 : 0);
}
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1