home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
APPS
/
elm.lzh
/
ELM
/
SRC
/
ALIAS.C
< prev
next >
Wrap
Text File
|
1991-01-11
|
19KB
|
732 lines
static char rcsid[] = "@(#)$Id: alias.c,v 4.1.1.1 90/06/05 21:20:26 syd Exp $";
/*******************************************************************************
* The Elm Mail System - $Revision: 4.1.1.1 $ $State: Exp $
*
* Copyright (c) 1986, 1987 Dave Taylor
* Copyright (c) 1988, 1989, 1990 USENET Community Trust
*******************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Syd Weinstein, Elm Coordinator
* elm@DSI.COM dsinc!elm
*
*******************************************************************************
* $Log: alias.c,v $
* Revision 4.1.1.1 90/06/05 21:20:26 syd
* Make temp file name less than 14 chars to allow deleting
* aliases on a 14 char limit file system
* From: Syd
*
* Revision 4.1 90/04/28 22:42:25 syd
* checkin of Elm 2.3 as of Release PL0
*
*
******************************************************************************/
/** This file contains alias stuff
**/
#include "headers.h"
#include <errno.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef BSD
#undef tolower
#endif
#define ECHOIT 1 /* echo on for prompting */
char *get_alias_address();
char *error_name(), *error_description(), *strip_parens(), *index();
extern int errno;
#ifndef DONT_TOUCH_ADDRESSES
char *expand_system();
extern int findnode_has_been_initialized;
#endif
int
ok_alias_name(name)
char *name;
{
while ( *name != '\0' && ok_alias_char(*name) )
++name;
return ( *name == '\0' );
}
read_alias_files()
{
/** read the system and user alias files, if present, and if they
have changed since last we read them.
**/
read_system_aliases();
read_user_aliases();
}
read_system_aliases()
{
/** read the system alias file, if present,
and if it has changed since last we read it.
**/
struct stat hst;
static time_t system_ctime, system_mtime;
/* If hash file hasn't changed, don't bother re-reading. */
if (system_data != -1
&& stat(system_hash_file, &hst) == 0
&& hst.st_ctime == system_ctime
&& hst.st_mtime == system_mtime)
return;
/* Close system data file if it was open. */
if (system_data != -1) {
close(system_data);
system_data = -1;
}
/* Read system hash table. If we can't, just return. */
if (read_hash_file(system_hash_file, (char *) system_hash_table,
sizeof system_hash_table) < 0)
return;
/* Open system data table. */
if ((system_data = open(system_data_file, O_RDONLY)) == -1) {
dprint(1, (debugfile,
"Warning: Can't open system alias data file %s\n",
system_data_file));
return;
}
/* Remember hash file times. */
system_ctime = hst.st_ctime;
system_mtime = hst.st_mtime;
}
read_user_aliases()
{
/** read the system alias file, if present,
and if it has changed since last we read it.
**/
struct stat hst;
char fname[SLEN];
static time_t user_ctime, user_mtime;
/* If hash file hasn't changed, don't bother re-reading. */
sprintf(fname, "%s/%s", home, ALIAS_HASH);
if (user_data != -1
&& stat(fname, &hst) == 0
&& hst.st_ctime == user_ctime
&& hst.st_mtime == user_mtime)
return;
/* Close user data file if it was open. */
if (user_data != -1) {
close(user_data);
user_data = -1;
}
/* Read user hash table. If we can't, just return. */
if (read_hash_file(fname, (char *) user_hash_table,
sizeof user_hash_table) < 0)
return;
/* Open user data table. */
sprintf(fname, "%s/%s", home, ALIAS_DATA);
if ((user_data = open(fname, O_RDONLY)) == -1) {
dprint(1, (debugfile,
"Warning: Can't open user alias data file %s\n", fname));
return;
}
/* Remember hash file times. */
user_ctime = hst.st_ctime;
user_mtime = hst.st_mtime;
}
int
read_hash_file(file, table, table_size)
char *file, *table;
int table_size;
{
/** read the specified alias hash file into the specified table.
it must be _exactly_ the right size or forget it.
**/
struct stat st;
int hash;
/* Open the hash file. */
if ((hash = open(file, O_RDONLY)) == -1) {
dprint(2, (debugfile,
"Warning: Can't open alias hash file %s\n", file));
return -1;
}
/* Be sure the hash file is the correct size. */
if (fstat(hash, &st) == 0 && st.st_size != table_size) {
dprint(2, (debugfile,
"Warning: Alias hash file %s is wrong size (%ld/%d)\n",
file, st.st_size, table_size));
close(hash);
return -1;
}
/* Read the hash file into memory. */
if (read(hash, (char *) table, table_size) != table_size) {
dprint(2, (debugfile,
"Warning: Can't read alias hash file %s\n", file));
close(hash);
return -1;
}
/* Close the hash file; return success. */
close(hash);
return 0;
}
int
add_alias()
{
/** add an alias to the user alias text file. Return zero
if alias not added in actuality **/
char name[SLEN], *address, address1[LONG_STRING], buffer[LONG_STRING];
char comment[SLEN], ch;
char *strcpy();
strcpy(buffer, "Enter alias name: ");
PutLine0(LINES-2,0, buffer);
CleartoEOLN();
*name = '\0';
optionally_enter(name, LINES-2, strlen(buffer), FALSE, FALSE);
if (strlen(name) == 0)
return(0);
if ( !ok_alias_name(name) ) {
error1("Bad character(s) in alias name %s.", name);
return(0);
}
if ((address = get_alias_address(name, FALSE)) != NULL) {
dprint(3, (debugfile,
"Attempt to add a duplicate alias [%s] in add_alias\n",
address));
if (address[0] == '!') {
address[0] = ' ';
error1("Already a group with name %s.", address);
}
else
error1("Already an alias for %s.", address);
return(0);
}
sprintf(buffer, "Enter full name for %s: ", name);
PutLine0(LINES-2,0, buffer);
CleartoEOLN();
*comment = '\0';
optionally_enter(comment, LINES-2, strlen(buffer), FALSE, FALSE);
if (strlen(comment) == 0) strcpy(comment, name);
sprintf(buffer, "Enter address for %s: ", name);
PutLine0(LINES-2,0, buffer);
CleartoEOLN();
*address1 = '\0';
optionally_enter(address1, LINES-2, strlen(buffer), FALSE, FALSE);
Raw(ON);
if (strlen(address1) == 0) {
error("No address specified!");
return(0);
}
PutLine3(LINES-2,0,"%s (%s) = %s", comment, name, address1);
CleartoEOLN();
if((ch = want_to("Accept new alias? (y/n) ",'y')) == 'y')
add_to_alias_text(name, comment, address1);
ClearLine(LINES-2);
return(ch == 'y' ? 1 : 0);
}
int
delete_alias()
{
/** delete an alias from the user alias text file. Return zero
if alias not deleted in actuality **/
char name[SLEN], *address, buffer[LONG_STRING];
char *strcpy();
strcpy(buffer, "Enter alias name for deletion: ");
PutLine0(LINES-2,0, buffer);
CleartoEOLN();
*name = '\0';
optionally_enter(name, LINES-2, strlen(buffer), FALSE, FALSE);
if (strlen(name) == 0)
return(0);
if ((address = get_alias_address(name, FALSE))!=NULL)
{
if (address[0] == '!')
{
address[0] = ' ';
PutLine1(LINES-1,0,"Group alias: %-60.60s", address);
CleartoEOLN();
}
else
PutLine1(LINES-1,0,"Aliased address: %-60.60s", address);
}
else
{
dprint(3, (debugfile,
"Attempt to delete a non-existent alias [%s] in delete_alias\n",
name));
error1("No alias for %s.", name);
return(0);
}
if (want_to("Delete this alias? (y/n) ", 'y') == 'y')
{
if (!delete_from_alias_text(name))
{
CleartoEOS();
return(1);
}
}
CleartoEOS();
return(0);
}
int
add_current_alias()
{
/** 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 name[SLEN], address1[LONG_STRING], buffer[LONG_STRING], *address;
char comment[SLEN], ch;
struct header_rec *current_header;
if (current == 0) {
dprint(4, (debugfile,
"Add current alias called without any current message!\n"));
error("No message to alias to!");
return(0);
}
current_header = headers[current - 1];
strcpy(buffer, "Current message address aliased to: ");
PutLine0(LINES-2,0, buffer);
CleartoEOLN();
*name = '\0';
optionally_enter(name, LINES-2, strlen(buffer), FALSE, FALSE);
if (strlen(name) == 0) /* cancelled... */
return(0);
if ( !ok_alias_name(name) ) {
error1("Bad character(s) in alias name %s.", name);
return(0);
}
if ((address = get_alias_address(name, FALSE)) != NULL) {
dprint(3, (debugfile,
"Attempt to add a duplicate alias [%s] in add_current_alias\n",
address));
if (address[1] == '!') {
address[0] = ' ';
error1("Already a group with name %s.", address);
}
else
error1("Already an alias for %s.", address);
return(0);
}
sprintf(buffer, "Enter full name for %s: ", name);
PutLine0(LINES-2,0, buffer);
CleartoEOLN();
/* use full name in current message for default comment */
tail_of(current_header->from, comment, current_header->to);
if(index(comment, '!') || index(comment, '@'))
/* never mind - it's an address not a full name */
*comment = '\0';
optionally_enter(comment, LINES-2, strlen(buffer), FALSE, FALSE);
/* grab the return address of this message */
get_return(address1, current-1);
strcpy(address1, strip_parens(address1)); /* remove parens! */
#ifdef OPTIMIZE_RETURN
optimize_return(address1);
#endif
PutLine3(LINES-2,0,"%s (%s) = %s", comment, name, address1);
CleartoEOLN();
if((ch = want_to("Accept new alias? (y/n) ",'y')) == 'y')
add_to_alias_text(name, comment, address1);
ClearLine(LINES-2);
return(ch == 'y' ? 1 : 0);
}
add_to_alias_text(name, comment, address)
char *name, *comment, *address;
{
/** Add the data to the user alias text file. Return zero if we
succeeded, 1 if not **/
FILE *file;
char fname[SLEN];
sprintf(fname,"%s/%s", home, ALIAS_TEXT);
save_file_stats(fname);
if ((file = fopen(fname, "a")) == NULL) {
dprint(2, (debugfile,
"Failure attempting to add alias to file %s within %s",
fname, "add_to_alias_text"));
dprint(2, (debugfile, "** %s - %s **\n", error_name(errno),
error_description(errno)));
error1("Couldn't open %s to add new alias!", fname);
return(1);
}
if (fprintf(file,"%s = %s = %s\n", name, comment, address) == EOF) {
dprint(2, (debugfile,
"Failure attempting to write alias to file within %s",
fname, "add_to_alias_text"));
dprint(2, (debugfile, "** %s - %s **\n", error_name(errno),
error_description(errno)));
error1("Couldn't write alias to file %s!", fname);
fclose(file);
return(1);
}
fclose(file);
restore_file_stats(fname);
return(0);
}
delete_from_alias_text(name)
char *name;
{
/** 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[SLEN+3+SLEN+3+LONG_STRING]; /* name = comment = address */
char name_with_equals[SLEN+2];
strcpy(name_with_equals, name);
strcat(name_with_equals, " =");
sprintf(fname,"%s/%s", home, ALIAS_TEXT);
sprintf(tmpfname,"%s/%s.t", home, ALIAS_TEXT);
save_file_stats(fname);
if ((file = fopen(fname, "r")) == NULL) {
dprint(2, (debugfile,
"Failure attempting to delete alias from file %s within %s",
fname, "delete_from_alias_text"));
dprint(2, (debugfile, "** %s - %s **\n", error_name(errno),
error_description(errno)));
error1("Couldn't open %s to delete alias!", fname);
return(1);
}
if ((tmp_file = fopen(tmpfname, "w")) == NULL) {
dprint(2, (debugfile,
"Failure attempting to open temp file %s within %s",
tmpfname, "delete_from_alias_text"));
dprint(2, (debugfile, "** %s - %s **\n", error_name(errno),
error_description(errno)));
error1("Couldn't open tempfile %s to delete alias!", tmpfname);
return(1);
}
while (fgets(line_in_file, sizeof(line_in_file), file) != (char *)NULL)
{
if (strncmp(name_with_equals, line_in_file,
strlen(name_with_equals)) != 0)
if (fprintf(tmp_file,"%s", line_in_file) == EOF) {
dprint(2, (debugfile,
"Failure attempting to write to temp file %s within %s",
tmpfname, "delete_from_alias_text"));
dprint(2, (debugfile, "** %s - %s **\n", error_name(errno),
error_description(errno)));
error1("Couldn't write to tempfile %s!", tmpfname);
fclose(file);
fclose(tmp_file);
unlink(tmpfname);
return(1);
}
}
fclose(file);
fclose(tmp_file);
unlink(fname); /* ?? */
if (rename(tmpfname, fname) != 0)
{
error1("Couldn't rename tempfile %s after deleting alias!", tmpfname);
return(1);
}
restore_file_stats(fname);
return(0);
}
show_alias_menu()
{
MoveCursor(LINES-7,0); CleartoEOS();
PutLine0(LINES-7,COLUMNS-45, "Alias commands");
Centerline(LINES-6,
"a)lias current message, d)elete an alias, check a p)erson or s)ystem,");
Centerline(LINES-5,
"l)ist existing aliases, m)ake new alias, or r)eturn");
}
alias()
{
/** work with alias commands... **/
/** return non-0 if main part of screen overwritten, else 0 **/
char name[NLEN], *address, ch, buffer[SLEN];
int newaliases = 0, redraw = 0;
if (mini_menu)
show_alias_menu();
/** now let's ensure that we've initialized everything! **/
#ifndef DONT_TOUCH_ADDRESSES
if (! findnode_has_been_initialized) {
if (warnings)
error("Initializing internal tables...");
#ifndef USE_DBM
get_connections();
open_domain_file();
#endif
init_findnode();
clear_error();
findnode_has_been_initialized = TRUE;
}
#endif
define_softkeys(ALIAS);
while (1) {
prompt("Alias: ");
CleartoEOLN();
ch = ReadCh();
MoveCursor(LINES-1,0); CleartoEOS();
dprint(3, (debugfile, "\n-- Alias command: %c\n\n", ch));
switch (tolower(ch)) {
case '?': redraw += alias_help(); break;
case 'a': newaliases += add_current_alias(); break;
case 'd': if (delete_alias()) install_aliases(); break;
case 'l': display_aliases();
redraw++;
if (mini_menu) show_alias_menu();
break;
case 'm': newaliases += add_alias(); break;
case RETURN:
case LINE_FEED:
case 'q':
case 'x':
case 'r': if (newaliases) install_aliases();
clear_error();
return(redraw);
case 'p': if (newaliases)
error("Warning: new aliases not installed yet!");
strcpy(buffer, "Check for person: ");
PutLine0(LINES-2,0, buffer);
CleartoEOLN();
*name = '\0';
optionally_enter(name, LINES-2, strlen(buffer),
FALSE, FALSE);
if ((address = get_alias_address(name, FALSE))!=NULL) {
if (address[0] == '!') {
address[0] = ' ';
PutLine1(LINES-1,0,"Group alias:%-60.60s", address);
CleartoEOLN();
}
else
PutLine1(LINES-1,0,"Aliased address: %-60.60s",
address);
}
else
error("Not found.");
break;
case 's': strcpy(buffer, "Check for system: ");
PutLine0(LINES-2,0, buffer);
CleartoEOLN();
*name = '\0';
optionally_enter(name, LINES-2, strlen(buffer),
FALSE, FALSE);
if (talk_to(name))
#ifdef INTERNET
PutLine1(LINES-1,0,
"You have a direct connection. The address is USER@%s.",
name);
#else
PutLine1(LINES-1,0,
"You have a direct connection. The address is %s!USER.",
name);
#endif
else {
sprintf(buffer, "USER@%s", name);
#ifdef DONT_TOUCH_ADDRESSES
address = buffer;
#else
address = expand_system(buffer, FALSE);
#endif
if (strlen(address) > strlen(name) + 7)
PutLine1(LINES-1,0,"Address is: %.65s", address);
else
error1("Couldn't expand system %s.", name);
}
break;
case '@': strcpy(buffer, "Fully expand alias: ");
PutLine0(LINES-2,0, buffer);
CleartoEOS();
*name = '\0';
optionally_enter(name, LINES-2, strlen(buffer),
FALSE, FALSE);
if ((address = get_alias_address(name, TRUE)) != NULL) {
ClearScreen();
PutLine1(3,0,"Aliased address:\l\r%s", address);
PutLine0(LINES-1,0,"Press <return> to continue.");
/* (void) getchar(); */
ReadCh();
redraw++;
}
else
error("Not found.");
if (mini_menu) show_alias_menu();
break;
default : error("Invalid input!");
}
}
}
install_aliases()
{
/** run the 'newalias' program and update the
aliases before going back to the main program!
**/
error("Updating aliases...");
sleep(2);
if (system_call(newalias, SH, FALSE, FALSE) == 0) {
error("Re-reading the database in...");
sleep(2);
read_alias_files();
set_error("Aliases updated successfully.");
}
else
set_error("'Newalias' failed. Please check alias_text.");
}
alias_help()
{
/** help section for the alias menu... **/
/** return non-0 if main part of screen overwritten, else 0 */
char ch;
int redraw=0;
char *alias_prompt = mini_menu ? "Key: " : "Key you want help for: ";
MoveCursor(LINES-3, 0); CleartoEOS();
if (mini_menu) {
Centerline(LINES-3,
"Press the key you want help for, '?' for a key list, or '.' to exit help");
}
lower_prompt(alias_prompt);
while ((ch = ReadCh()) != '.') {
ch = tolower(ch);
switch(ch) {
case '?' : display_helpfile(ALIAS_HELP);
redraw++;
if (mini_menu) show_alias_menu();
return(redraw);
case 'a': error(
"a = Add (return) address of current message to alias database.");
break;
case 'd': error("d = Delete a user alias from alias database.");
break;
case 'l': error("l = List all aliases in database.");
break;
case 'm': error(
"m = Make a new user alias, adding to alias database when done.");
break;
case RETURN:
case LINE_FEED:
case 'q':
case 'x':
case 'r': error("Return from alias menu.");
break;
case 'p': error("p = Check for a person in the alias database.");
break;
case 's': error(
"s = Check for a system in the host routing/domain database.");
break;
default : error("That key isn't used in this section.");
break;
}
lower_prompt(alias_prompt);
}
return(redraw);
}
display_aliases()
{
char fname[SLEN];
sprintf(fname,"%s/%s", home, ALIAS_TEXT);
display_file(fname);
ClearScreen();
return;
}