174 lines
4.0 KiB
C
174 lines
4.0 KiB
C
/*++
|
|
/* NAME
|
|
/* mail_addr_map 3
|
|
/* SUMMARY
|
|
/* generic address mapping
|
|
/* SYNOPSIS
|
|
/* #include <mail_addr_map.h>
|
|
/*
|
|
/* ARGV *mail_addr_map(path, address, propagate)
|
|
/* MAPS *path;
|
|
/* const char *address;
|
|
/* int propagate;
|
|
/* DESCRIPTION
|
|
/* mail_addr_map() returns the translation for the named address,
|
|
/* or a null pointer if none is found. The result is in canonical
|
|
/* external (quoted) form. The search is case insensitive.
|
|
/*
|
|
/* When the \fBpropagate\fR argument is non-zero,
|
|
/* address extensions that aren't explicitly matched in the lookup
|
|
/* table are propagated to the result addresses. The caller is
|
|
/* expected to pass the result to argv_free().
|
|
/*
|
|
/* Lookups are performed by mail_addr_find(). When the result has the
|
|
/* form \fI@otherdomain\fR, the result is the original user in
|
|
/* \fIotherdomain\fR.
|
|
/*
|
|
/* Arguments:
|
|
/* .IP path
|
|
/* Dictionary search path (see maps(3)).
|
|
/* .IP address
|
|
/* The address to be looked up.
|
|
/* DIAGNOSTICS
|
|
/* The global \fIdict_errno\fR is non-zero when the lookup
|
|
/* should be tried again.
|
|
/* SEE ALSO
|
|
/* mail_addr_find(3), mail address matching
|
|
/* mail_addr_crunch(3), mail address parsing and rewriting
|
|
/* 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 <string.h>
|
|
|
|
/* Utility library. */
|
|
|
|
#include <msg.h>
|
|
#include <vstring.h>
|
|
#include <dict.h>
|
|
#include <argv.h>
|
|
#include <mymalloc.h>
|
|
|
|
/* Global library. */
|
|
|
|
#include <mail_addr_find.h>
|
|
#include <mail_addr_crunch.h>
|
|
#include <mail_addr_map.h>
|
|
|
|
/* Application-specific. */
|
|
|
|
#define STR vstring_str
|
|
|
|
/* mail_addr_map - map a canonical address */
|
|
|
|
ARGV *mail_addr_map(MAPS *path, const char *address, int propagate)
|
|
{
|
|
VSTRING *buffer = 0;
|
|
char *myname = "mail_addr_map";
|
|
const char *string;
|
|
char *ratsign;
|
|
char *extension = 0;
|
|
ARGV *argv = 0;
|
|
int i;
|
|
|
|
/*
|
|
* Look up the full address; if no match is found, look up the address
|
|
* with the extension stripped off, and remember the unmatched extension.
|
|
*/
|
|
if ((string = mail_addr_find(path, address, &extension)) != 0) {
|
|
|
|
/*
|
|
* Prepend the original user to @otherdomain.
|
|
*/
|
|
if (*string == '@') {
|
|
buffer = vstring_alloc(100);
|
|
if ((ratsign = strchr(address, '@')) != 0)
|
|
vstring_strncpy(buffer, address, ratsign - address);
|
|
else
|
|
vstring_strcpy(buffer, address);
|
|
vstring_strcat(buffer, string);
|
|
string = STR(buffer);
|
|
}
|
|
|
|
/*
|
|
* Canonicalize and externalize the result, and propagate the
|
|
* unmatched extension to each address found.
|
|
*/
|
|
argv = mail_addr_crunch(string, propagate ? extension : 0);
|
|
if (buffer)
|
|
vstring_free(buffer);
|
|
if (msg_verbose)
|
|
for (i = 0; i < argv->argc; i++)
|
|
msg_info("%s: %s -> %d: %s", myname, address, i, argv->argv[i]);
|
|
}
|
|
|
|
/*
|
|
* No match found.
|
|
*/
|
|
else {
|
|
if (msg_verbose)
|
|
msg_info("%s: %s -> %s", myname, address,
|
|
dict_errno ? "(try again)" : "(not found)");
|
|
}
|
|
|
|
/*
|
|
* Cleanup.
|
|
*/
|
|
if (extension)
|
|
myfree(extension);
|
|
|
|
return (argv);
|
|
}
|
|
|
|
#ifdef TEST
|
|
|
|
/*
|
|
* Proof-of-concept test program. Read an address from stdin, and spit out
|
|
* the lookup result.
|
|
*/
|
|
#include <unistd.h>
|
|
#include <mail_conf.h>
|
|
#include <vstream.h>
|
|
#include <vstring_vstream.h>
|
|
#include <mail_params.h>
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
VSTRING *buffer = vstring_alloc(100);
|
|
MAPS *path;
|
|
ARGV *result;
|
|
|
|
/*
|
|
* Parse JCL.
|
|
*/
|
|
if (argc != 2)
|
|
msg_fatal("usage: %s database", argv[0]);
|
|
|
|
/*
|
|
* Initialize.
|
|
*/
|
|
mail_conf_read();
|
|
msg_verbose = 1;
|
|
if (chdir(var_queue_dir) < 0)
|
|
msg_fatal("chdir %s: %m", var_queue_dir);
|
|
path = maps_create(argv[0], argv[1], DICT_FLAG_LOCK);
|
|
while (vstring_fgets_nonl(buffer, VSTREAM_IN)) {
|
|
if ((result = mail_addr_map(path, STR(buffer), 1)) != 0)
|
|
argv_free(result);
|
|
}
|
|
vstring_free(buffer);
|
|
maps_free(path);
|
|
}
|
|
|
|
#endif
|