1 /* $NetBSD: strip_addr.c,v 1.2 2017/02/14 01:16:45 christos Exp $ */ 2 3 /*++ 4 /* NAME 5 /* strip_addr 3 6 /* SUMMARY 7 /* strip extension from full or localpart-only address 8 /* SYNOPSIS 9 /* #include <strip_addr.h> 10 /* 11 /* char *strip_addr(address, extension, delimiter_set) 12 /* const char *address; 13 /* char **extension; 14 /* const char *delimiter_set; 15 /* DESCRIPTION 16 /* strip_addr() takes an address and either returns a null 17 /* pointer when the address contains no address extension, 18 /* or returns a copy of the address without address extension. 19 /* The caller is expected to pass the copy to myfree(). 20 /* 21 /* Arguments: 22 /* .IP address 23 /* Address localpart or user@domain form. 24 /* .IP extension 25 /* A null pointer, or the address of a pointer that is set to 26 /* the address of a dynamic memory copy of the address extension 27 /* that had to be chopped off. 28 /* The copy includes the recipient address delimiter. 29 /* The caller is expected to pass the copy to myfree(). 30 /* .IP delimiter_set 31 /* Set of recipient address delimiter characters. 32 /* SEE ALSO 33 /* split_addr(3) strip extension from localpart 34 /* LICENSE 35 /* .ad 36 /* .fi 37 /* The Secure Mailer license must be distributed with this software. 38 /* AUTHOR(S) 39 /* Wietse Venema 40 /* IBM T.J. Watson Research 41 /* P.O. Box 704 42 /* Yorktown Heights, NY 10598, USA 43 /*--*/ 44 45 /* System library. */ 46 47 #include <sys_defs.h> 48 #include <string.h> 49 50 /* Utility library. */ 51 52 #include <mymalloc.h> 53 54 /* Global library. */ 55 56 #include <split_addr.h> 57 #include <strip_addr.h> 58 59 /* strip_addr - strip extension from address */ 60 61 char *strip_addr(const char *full, char **extension, const char *delimiter_set) 62 { 63 char *ratsign; 64 char *extent; 65 char *saved_ext; 66 char *stripped; 67 68 /* 69 * A quick test to eliminate inputs without delimiter anywhere. 70 */ 71 if (*delimiter_set == 0 || full[strcspn(full, delimiter_set)] == 0) { 72 stripped = saved_ext = 0; 73 } else { 74 stripped = mystrdup(full); 75 if ((ratsign = strrchr(stripped, '@')) != 0) 76 *ratsign = 0; 77 if ((extent = split_addr(stripped, delimiter_set)) != 0) { 78 extent -= 1; 79 if (extension) { 80 *extent = full[strlen(stripped)]; 81 saved_ext = mystrdup(extent); 82 *extent = 0; 83 } else 84 saved_ext = 0; 85 if (ratsign != 0) { 86 *ratsign = '@'; 87 memmove(extent, ratsign, strlen(ratsign) + 1); 88 } 89 } else { 90 myfree(stripped); 91 stripped = saved_ext = 0; 92 } 93 } 94 if (extension) 95 *extension = saved_ext; 96 return (stripped); 97 } 98 99 #ifdef TEST 100 101 #include <msg.h> 102 #include <mail_params.h> 103 104 char *var_double_bounce_sender = DEF_DOUBLE_BOUNCE; 105 106 int main(int unused_argc, char **unused_argv) 107 { 108 char *extension; 109 char *stripped; 110 char *delim = "+-"; 111 112 #define NO_DELIM "" 113 114 /* 115 * Incredible. This function takes only three arguments, and the tests 116 * already take more lines of code than the code being tested. 117 */ 118 stripped = strip_addr("foo", (char **) 0, NO_DELIM); 119 if (stripped != 0) 120 msg_panic("strip_addr botch 1"); 121 122 stripped = strip_addr("foo", &extension, NO_DELIM); 123 if (stripped != 0) 124 msg_panic("strip_addr botch 2"); 125 if (extension != 0) 126 msg_panic("strip_addr botch 3"); 127 128 stripped = strip_addr("foo", (char **) 0, delim); 129 if (stripped != 0) 130 msg_panic("strip_addr botch 4"); 131 132 stripped = strip_addr("foo", &extension, delim); 133 if (stripped != 0) 134 msg_panic("strip_addr botch 5"); 135 if (extension != 0) 136 msg_panic("strip_addr botch 6"); 137 138 stripped = strip_addr("foo@bar", (char **) 0, NO_DELIM); 139 if (stripped != 0) 140 msg_panic("strip_addr botch 7"); 141 142 stripped = strip_addr("foo@bar", &extension, NO_DELIM); 143 if (stripped != 0) 144 msg_panic("strip_addr botch 8"); 145 if (extension != 0) 146 msg_panic("strip_addr botch 9"); 147 148 stripped = strip_addr("foo@bar", (char **) 0, delim); 149 if (stripped != 0) 150 msg_panic("strip_addr botch 10"); 151 152 stripped = strip_addr("foo@bar", &extension, delim); 153 if (stripped != 0) 154 msg_panic("strip_addr botch 11"); 155 if (extension != 0) 156 msg_panic("strip_addr botch 12"); 157 158 stripped = strip_addr("foo-ext", (char **) 0, NO_DELIM); 159 if (stripped != 0) 160 msg_panic("strip_addr botch 13"); 161 162 stripped = strip_addr("foo-ext", &extension, NO_DELIM); 163 if (stripped != 0) 164 msg_panic("strip_addr botch 14"); 165 if (extension != 0) 166 msg_panic("strip_addr botch 15"); 167 168 stripped = strip_addr("foo-ext", (char **) 0, delim); 169 if (stripped == 0) 170 msg_panic("strip_addr botch 16"); 171 msg_info("wanted: foo-ext -> %s", "foo"); 172 msg_info("strip_addr foo-ext -> %s", stripped); 173 myfree(stripped); 174 175 stripped = strip_addr("foo-ext", &extension, delim); 176 if (stripped == 0) 177 msg_panic("strip_addr botch 17"); 178 if (extension == 0) 179 msg_panic("strip_addr botch 18"); 180 msg_info("wanted: foo-ext -> %s %s", "foo", "-ext"); 181 msg_info("strip_addr foo-ext -> %s %s", stripped, extension); 182 myfree(stripped); 183 myfree(extension); 184 185 stripped = strip_addr("foo-ext@bar", (char **) 0, NO_DELIM); 186 if (stripped != 0) 187 msg_panic("strip_addr botch 19"); 188 189 stripped = strip_addr("foo-ext@bar", &extension, NO_DELIM); 190 if (stripped != 0) 191 msg_panic("strip_addr botch 20"); 192 if (extension != 0) 193 msg_panic("strip_addr botch 21"); 194 195 stripped = strip_addr("foo-ext@bar", (char **) 0, delim); 196 if (stripped == 0) 197 msg_panic("strip_addr botch 22"); 198 msg_info("wanted: foo-ext@bar -> %s", "foo@bar"); 199 msg_info("strip_addr foo-ext@bar -> %s", stripped); 200 myfree(stripped); 201 202 stripped = strip_addr("foo-ext@bar", &extension, delim); 203 if (stripped == 0) 204 msg_panic("strip_addr botch 23"); 205 if (extension == 0) 206 msg_panic("strip_addr botch 24"); 207 msg_info("wanted: foo-ext@bar -> %s %s", "foo@bar", "-ext"); 208 msg_info("strip_addr foo-ext@bar -> %s %s", stripped, extension); 209 myfree(stripped); 210 myfree(extension); 211 212 stripped = strip_addr("foo+ext@bar", &extension, delim); 213 if (stripped == 0) 214 msg_panic("strip_addr botch 25"); 215 if (extension == 0) 216 msg_panic("strip_addr botch 26"); 217 msg_info("wanted: foo+ext@bar -> %s %s", "foo@bar", "+ext"); 218 msg_info("strip_addr foo+ext@bar -> %s %s", stripped, extension); 219 myfree(stripped); 220 myfree(extension); 221 222 return (0); 223 } 224 225 #endif 226