/*++ /* NAME /* strip_addr 3 /* SUMMARY /* strip extension from full or localpart-only address /* SYNOPSIS /* #include /* /* 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 #include /* Utility library. */ #include /* Global library. */ #include #include /* 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 #include 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