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