208 lines
5.7 KiB
C
208 lines
5.7 KiB
C
/*++
|
|
/* NAME
|
|
/* token 3
|
|
/* SUMMARY
|
|
/* tokenize alias/include/.forward entries and deliver
|
|
/* SYNOPSIS
|
|
/* #include "local.h"
|
|
/*
|
|
/* int deliver_token(state, usr_attr, addr)
|
|
/* LOCAL_STATE state;
|
|
/* USER_ATTR usr_attr;
|
|
/* TOK822 *addr;
|
|
/*
|
|
/* int deliver_token_string(state, usr_attr, string, addr_count)
|
|
/* LOCAL_STATE state;
|
|
/* USER_ATTR usr_attr;
|
|
/* char *string;
|
|
/* int *addr_count;
|
|
/*
|
|
/* int deliver_token_stream(state, usr_attr, fp, addr_count)
|
|
/* LOCAL_STATE state;
|
|
/* USER_ATTR usr_attr;
|
|
/* VSTREAM *fp;
|
|
/* int *addr_count;
|
|
/* DESCRIPTION
|
|
/* This module delivers to addresses listed in an alias database
|
|
/* entry, in an include file, or in a .forward file.
|
|
/*
|
|
/* deliver_token() delivers to the address in the given token:
|
|
/* an absolute /path/name, a ~/path/name relative to the recipient's
|
|
/* home directory, an :include:/path/name request, an external
|
|
/* "|command", or a mail address.
|
|
/*
|
|
/* deliver_token_string() delivers to all addresses listed in
|
|
/* the specified string.
|
|
/*
|
|
/* deliver_token_stream() delivers to all addresses listed in
|
|
/* the specified stream. Input records > \fIline_length_limit\fR
|
|
/* are broken up into multiple records, to prevent the mail
|
|
/* system from using unreasonable amounts of memory.
|
|
/*
|
|
/* Arguments:
|
|
/* .IP state
|
|
/* The attributes that specify the message, recipient and more.
|
|
/* Attributes describing alias, include or forward expansion.
|
|
/* A table with the results from expanding aliases or lists.
|
|
/* A table with delivered-to: addresses taken from the message.
|
|
/* .IP usr_attr
|
|
/* Attributes describing user rights and environment.
|
|
/* .IP addr
|
|
/* A parsed address from an include file, alias file or .forward file.
|
|
/* .IP string
|
|
/* A null-terminated string.
|
|
/* .IP fp
|
|
/* A readable stream.
|
|
/* .IP addr_count
|
|
/* Null pointer, or the address of a counter that is incremented
|
|
/* by the number of destinations found by the tokenizer.
|
|
/* DIAGNOSTICS
|
|
/* Fatal errors: out of memory. The result is non-zero when the
|
|
/* operation should be tried again. Warnings: malformed address.
|
|
/* SEE ALSO
|
|
/* list_token(3) tokenize list
|
|
/* LICENSE
|
|
/* .ad
|
|
/* .fi
|
|
/* The Secure Mailer license must be distributed with this software.
|
|
/* AUTHOR(S)
|
|
/* Wietse Venema
|
|
/* IBM T.J. Watson Research
|
|
/* P.O. Box 704
|
|
/* Yorktown Heights, NY 10598, USA
|
|
/*--*/
|
|
|
|
/* System library. */
|
|
|
|
#include <sys_defs.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
|
|
#ifdef STRCASECMP_IN_STRINGS_H
|
|
#include <strings.h>
|
|
#endif
|
|
|
|
/* Utility library. */
|
|
|
|
#include <msg.h>
|
|
#include <vstring.h>
|
|
#include <vstream.h>
|
|
#include <htable.h>
|
|
#include <readlline.h>
|
|
#include <mymalloc.h>
|
|
#include <vstring_vstream.h>
|
|
#include <stringops.h>
|
|
|
|
/* Global library. */
|
|
|
|
#include <tok822.h>
|
|
#include <mail_params.h>
|
|
#include <bounce.h>
|
|
|
|
/* Application-specific. */
|
|
|
|
#include "local.h"
|
|
|
|
/* deliver_token_home - expand ~token */
|
|
|
|
static int deliver_token_home(LOCAL_STATE state, USER_ATTR usr_attr, char *addr)
|
|
{
|
|
char *full_path;
|
|
int status;
|
|
|
|
if (addr[1] != '/') { /* disallow ~user */
|
|
status = bounce_append(BOUNCE_FLAG_KEEP,
|
|
BOUNCE_ATTR(state.msg_attr),
|
|
"bad home directory syntax for: %s", addr);
|
|
} else if (usr_attr.home == 0) { /* require user context */
|
|
status = bounce_append(BOUNCE_FLAG_KEEP,
|
|
BOUNCE_ATTR(state.msg_attr),
|
|
"unknown home directory for: %s", addr);
|
|
} else if (usr_attr.home[0] == '/' && usr_attr.home[1] == 0) {
|
|
status = deliver_file(state, usr_attr, addr + 1);
|
|
} else { /* expand ~ to home */
|
|
full_path = concatenate(usr_attr.home, addr + 1, (char *) 0);
|
|
status = deliver_file(state, usr_attr, full_path);
|
|
myfree(full_path);
|
|
}
|
|
return (status);
|
|
}
|
|
|
|
/* deliver_token - deliver to expansion of include file or alias */
|
|
|
|
int deliver_token(LOCAL_STATE state, USER_ATTR usr_attr, TOK822 *addr)
|
|
{
|
|
VSTRING *addr_buf = vstring_alloc(100);
|
|
static char include[] = ":include:";
|
|
int status;
|
|
char *path;
|
|
|
|
#define STR vstring_str
|
|
|
|
tok822_internalize(addr_buf, addr->head, TOK822_STR_DEFL);
|
|
if (msg_verbose)
|
|
msg_info("deliver_token: %s", STR(addr_buf));
|
|
|
|
if (*STR(addr_buf) == '/') {
|
|
status = deliver_file(state, usr_attr, STR(addr_buf));
|
|
} else if (*STR(addr_buf) == '~') {
|
|
status = deliver_token_home(state, usr_attr, STR(addr_buf));
|
|
} else if (*STR(addr_buf) == '|') {
|
|
status = deliver_command(state, usr_attr, STR(addr_buf) + 1);
|
|
} else if (strncasecmp(STR(addr_buf), include, sizeof(include) - 1) == 0) {
|
|
path = STR(addr_buf) + sizeof(include) - 1;
|
|
status = deliver_include(state, usr_attr, path);
|
|
} else {
|
|
status = deliver_resolve_tree(state, usr_attr, addr);
|
|
}
|
|
vstring_free(addr_buf);
|
|
|
|
return (status);
|
|
}
|
|
|
|
/* deliver_token_string - tokenize string and deliver */
|
|
|
|
int deliver_token_string(LOCAL_STATE state, USER_ATTR usr_attr,
|
|
char *string, int *addr_count)
|
|
{
|
|
TOK822 *tree;
|
|
TOK822 *addr;
|
|
int status = 0;
|
|
|
|
if (msg_verbose)
|
|
msg_info("deliver_token_string: %s", string);
|
|
|
|
tree = tok822_parse(string);
|
|
for (addr = tree; addr != 0; addr = addr->next) {
|
|
if (addr->type == TOK822_ADDR) {
|
|
if (addr_count)
|
|
(*addr_count)++;
|
|
status |= deliver_token(state, usr_attr, addr);
|
|
}
|
|
}
|
|
tok822_free_tree(tree);
|
|
return (status);
|
|
}
|
|
|
|
/* deliver_token_stream - tokenize stream and deliver */
|
|
|
|
int deliver_token_stream(LOCAL_STATE state, USER_ATTR usr_attr,
|
|
VSTREAM *fp, int *addr_count)
|
|
{
|
|
VSTRING *buf = vstring_alloc(100);
|
|
int status = 0;
|
|
|
|
if (msg_verbose)
|
|
msg_info("deliver_token_stream: %s", VSTREAM_PATH(fp));
|
|
|
|
while (vstring_fgets_bound(buf, fp, var_line_limit)) {
|
|
if (*STR(buf) != '#') {
|
|
status = deliver_token_string(state, usr_attr, STR(buf), addr_count);
|
|
if (status != 0)
|
|
break;
|
|
}
|
|
}
|
|
vstring_free(buf);
|
|
return (status);
|
|
}
|