diff options
Diffstat (limited to 'src/global/strip_addr.c')
-rw-r--r-- | src/global/strip_addr.c | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/src/global/strip_addr.c b/src/global/strip_addr.c new file mode 100644 index 0000000..c4c39b0 --- /dev/null +++ b/src/global/strip_addr.c @@ -0,0 +1,252 @@ +/*++ +/* NAME +/* strip_addr 3 +/* SUMMARY +/* strip extension from full or localpart-only address +/* SYNOPSIS +/* #include <strip_addr.h> +/* +/* char *strip_addr_internal(address, extension, delimiter_set) +/* const char *address; +/* char **extension; +/* const char *delimiter_set; +/* LEGACY SUPPORT +/* char *strip_addr(address, extension, delimiter_set) +/* const char *address; +/* char **extension; +/* const char *delimiter_set; +/* DESCRIPTION +/* strip_addr*() takes an address and either returns a null +/* pointer when the address contains no address extension, +/* or returns a copy of the address without address extension. +/* The caller is expected to pass the copy to myfree(). +/* +/* With strip_addr_internal(), the input and result are in +/* internal form. +/* +/* strip_addr() is a backwards-compatible form for legacy code. +/* +/* Arguments: +/* .IP address +/* Address localpart or user@domain form. +/* .IP extension +/* A null pointer, or the address of a pointer that is set to +/* the address of a dynamic memory copy of the address extension +/* that had to be chopped off. +/* The copy includes the recipient address delimiter. +/* The caller is expected to pass the copy to myfree(). +/* .IP delimiter_set +/* Set of recipient address delimiter characters. +/* SEE ALSO +/* split_addr(3) strip extension from localpart +/* 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 +/* +/* Wietse Venema +/* Google, Inc. +/* 111 8th Avenue +/* New York, NY 10011, USA +/*--*/ + +/* System library. */ + +#include <sys_defs.h> +#include <string.h> + +/* Utility library. */ + +#include <mymalloc.h> + +/* Global library. */ + +#include <split_addr.h> +#include <strip_addr.h> + +/* strip_addr - strip extension from address */ + +char *strip_addr_internal(const char *full, char **extension, + const char *delimiter_set) +{ + char *ratsign; + char *extent; + char *saved_ext; + char *stripped; + + /* + * A quick test to eliminate inputs without delimiter anywhere. + */ + if (*delimiter_set == 0 || full[strcspn(full, delimiter_set)] == 0) { + stripped = saved_ext = 0; + } else { + stripped = mystrdup(full); + if ((ratsign = strrchr(stripped, '@')) != 0) + *ratsign = 0; + if ((extent = split_addr(stripped, delimiter_set)) != 0) { + extent -= 1; + if (extension) { + *extent = full[strlen(stripped)]; + saved_ext = mystrdup(extent); + *extent = 0; + } else + saved_ext = 0; + if (ratsign != 0) { + *ratsign = '@'; + memmove(extent, ratsign, strlen(ratsign) + 1); + } + } else { + myfree(stripped); + stripped = saved_ext = 0; + } + } + if (extension) + *extension = saved_ext; + return (stripped); +} + +#ifdef TEST + +#include <msg.h> +#include <mail_params.h> + +int main(int unused_argc, char **unused_argv) +{ + char *extension; + char *stripped; + char *delim = "+-"; + +#define NO_DELIM "" + + /* + * No static initializer, because this is owned by a library. + */ + var_double_bounce_sender = DEF_DOUBLE_BOUNCE; + + /* + * Incredible. This function takes only three arguments, and the tests + * already take more lines of code than the code being tested. + */ + stripped = strip_addr_internal("foo", (char **) 0, NO_DELIM); + if (stripped != 0) + msg_panic("strip_addr botch 1"); + + stripped = strip_addr_internal("foo", &extension, NO_DELIM); + if (stripped != 0) + msg_panic("strip_addr botch 2"); + if (extension != 0) + msg_panic("strip_addr botch 3"); + + stripped = strip_addr_internal("foo", (char **) 0, delim); + if (stripped != 0) + msg_panic("strip_addr botch 4"); + + stripped = strip_addr_internal("foo", &extension, delim); + if (stripped != 0) + msg_panic("strip_addr botch 5"); + if (extension != 0) + msg_panic("strip_addr botch 6"); + + stripped = strip_addr_internal("foo@bar", (char **) 0, NO_DELIM); + if (stripped != 0) + msg_panic("strip_addr botch 7"); + + stripped = strip_addr_internal("foo@bar", &extension, NO_DELIM); + if (stripped != 0) + msg_panic("strip_addr botch 8"); + if (extension != 0) + msg_panic("strip_addr botch 9"); + + stripped = strip_addr_internal("foo@bar", (char **) 0, delim); + if (stripped != 0) + msg_panic("strip_addr botch 10"); + + stripped = strip_addr_internal("foo@bar", &extension, delim); + if (stripped != 0) + msg_panic("strip_addr botch 11"); + if (extension != 0) + msg_panic("strip_addr botch 12"); + + stripped = strip_addr_internal("foo-ext", (char **) 0, NO_DELIM); + if (stripped != 0) + msg_panic("strip_addr botch 13"); + + stripped = strip_addr_internal("foo-ext", &extension, NO_DELIM); + if (stripped != 0) + msg_panic("strip_addr botch 14"); + if (extension != 0) + msg_panic("strip_addr botch 15"); + + stripped = strip_addr_internal("foo-ext", (char **) 0, delim); + if (stripped == 0) + msg_panic("strip_addr botch 16"); + msg_info("wanted: foo-ext -> %s", "foo"); + msg_info("strip_addr foo-ext -> %s", stripped); + myfree(stripped); + + stripped = strip_addr_internal("foo-ext", &extension, delim); + if (stripped == 0) + msg_panic("strip_addr botch 17"); + if (extension == 0) + msg_panic("strip_addr botch 18"); + msg_info("wanted: foo-ext -> %s %s", "foo", "-ext"); + msg_info("strip_addr foo-ext -> %s %s", stripped, extension); + myfree(stripped); + myfree(extension); + + stripped = strip_addr_internal("foo-ext@bar", (char **) 0, NO_DELIM); + if (stripped != 0) + msg_panic("strip_addr botch 19"); + + stripped = strip_addr_internal("foo-ext@bar", &extension, NO_DELIM); + if (stripped != 0) + msg_panic("strip_addr botch 20"); + if (extension != 0) + msg_panic("strip_addr botch 21"); + + stripped = strip_addr_internal("foo-ext@bar", (char **) 0, delim); + if (stripped == 0) + msg_panic("strip_addr botch 22"); + msg_info("wanted: foo-ext@bar -> %s", "foo@bar"); + msg_info("strip_addr foo-ext@bar -> %s", stripped); + myfree(stripped); + + stripped = strip_addr_internal("foo-ext@bar", &extension, delim); + if (stripped == 0) + msg_panic("strip_addr botch 23"); + if (extension == 0) + msg_panic("strip_addr botch 24"); + msg_info("wanted: foo-ext@bar -> %s %s", "foo@bar", "-ext"); + msg_info("strip_addr foo-ext@bar -> %s %s", stripped, extension); + myfree(stripped); + myfree(extension); + + stripped = strip_addr_internal("foo+ext@bar", &extension, delim); + if (stripped == 0) + msg_panic("strip_addr botch 25"); + if (extension == 0) + msg_panic("strip_addr botch 26"); + msg_info("wanted: foo+ext@bar -> %s %s", "foo@bar", "+ext"); + msg_info("strip_addr foo+ext@bar -> %s %s", stripped, extension); + myfree(stripped); + myfree(extension); + + stripped = strip_addr_internal("foo bar+ext", &extension, delim); + if (stripped == 0) + msg_panic("strip_addr botch 27"); + if (extension == 0) + msg_panic("strip_addr botch 28"); + msg_info("wanted: foo bar+ext -> %s %s", "foo bar", "+ext"); + msg_info("strip_addr foo bar+ext -> %s %s", stripped, extension); + myfree(stripped); + myfree(extension); + + return (0); +} + +#endif |