xref: /netbsd-src/external/ibm-public/postfix/dist/src/global/strip_addr.c (revision cef8759bd76c1b621f8eab8faa6f208faabc2e15)
1 /*	$NetBSD: strip_addr.c,v 1.3 2020/03/18 19:05:16 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 
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 
120 char   *var_double_bounce_sender = DEF_DOUBLE_BOUNCE;
121 
122 int     main(int unused_argc, char **unused_argv)
123 {
124     char   *extension;
125     char   *stripped;
126     char   *delim = "+-";
127 
128 #define NO_DELIM	""
129 
130     /*
131      * Incredible. This function takes only three arguments, and the tests
132      * already take more lines of code than the code being tested.
133      */
134     stripped = strip_addr_internal("foo", (char **) 0, NO_DELIM);
135     if (stripped != 0)
136 	msg_panic("strip_addr botch 1");
137 
138     stripped = strip_addr_internal("foo", &extension, NO_DELIM);
139     if (stripped != 0)
140 	msg_panic("strip_addr botch 2");
141     if (extension != 0)
142 	msg_panic("strip_addr botch 3");
143 
144     stripped = strip_addr_internal("foo", (char **) 0, delim);
145     if (stripped != 0)
146 	msg_panic("strip_addr botch 4");
147 
148     stripped = strip_addr_internal("foo", &extension, delim);
149     if (stripped != 0)
150 	msg_panic("strip_addr botch 5");
151     if (extension != 0)
152 	msg_panic("strip_addr botch 6");
153 
154     stripped = strip_addr_internal("foo@bar", (char **) 0, NO_DELIM);
155     if (stripped != 0)
156 	msg_panic("strip_addr botch 7");
157 
158     stripped = strip_addr_internal("foo@bar", &extension, NO_DELIM);
159     if (stripped != 0)
160 	msg_panic("strip_addr botch 8");
161     if (extension != 0)
162 	msg_panic("strip_addr botch 9");
163 
164     stripped = strip_addr_internal("foo@bar", (char **) 0, delim);
165     if (stripped != 0)
166 	msg_panic("strip_addr botch 10");
167 
168     stripped = strip_addr_internal("foo@bar", &extension, delim);
169     if (stripped != 0)
170 	msg_panic("strip_addr botch 11");
171     if (extension != 0)
172 	msg_panic("strip_addr botch 12");
173 
174     stripped = strip_addr_internal("foo-ext", (char **) 0, NO_DELIM);
175     if (stripped != 0)
176 	msg_panic("strip_addr botch 13");
177 
178     stripped = strip_addr_internal("foo-ext", &extension, NO_DELIM);
179     if (stripped != 0)
180 	msg_panic("strip_addr botch 14");
181     if (extension != 0)
182 	msg_panic("strip_addr botch 15");
183 
184     stripped = strip_addr_internal("foo-ext", (char **) 0, delim);
185     if (stripped == 0)
186 	msg_panic("strip_addr botch 16");
187     msg_info("wanted:    foo-ext -> %s", "foo");
188     msg_info("strip_addr foo-ext -> %s", stripped);
189     myfree(stripped);
190 
191     stripped = strip_addr_internal("foo-ext", &extension, delim);
192     if (stripped == 0)
193 	msg_panic("strip_addr botch 17");
194     if (extension == 0)
195 	msg_panic("strip_addr botch 18");
196     msg_info("wanted:    foo-ext -> %s %s", "foo", "-ext");
197     msg_info("strip_addr foo-ext -> %s %s", stripped, extension);
198     myfree(stripped);
199     myfree(extension);
200 
201     stripped = strip_addr_internal("foo-ext@bar", (char **) 0, NO_DELIM);
202     if (stripped != 0)
203 	msg_panic("strip_addr botch 19");
204 
205     stripped = strip_addr_internal("foo-ext@bar", &extension, NO_DELIM);
206     if (stripped != 0)
207 	msg_panic("strip_addr botch 20");
208     if (extension != 0)
209 	msg_panic("strip_addr botch 21");
210 
211     stripped = strip_addr_internal("foo-ext@bar", (char **) 0, delim);
212     if (stripped == 0)
213 	msg_panic("strip_addr botch 22");
214     msg_info("wanted:    foo-ext@bar -> %s", "foo@bar");
215     msg_info("strip_addr foo-ext@bar -> %s", stripped);
216     myfree(stripped);
217 
218     stripped = strip_addr_internal("foo-ext@bar", &extension, delim);
219     if (stripped == 0)
220 	msg_panic("strip_addr botch 23");
221     if (extension == 0)
222 	msg_panic("strip_addr botch 24");
223     msg_info("wanted:    foo-ext@bar -> %s %s", "foo@bar", "-ext");
224     msg_info("strip_addr foo-ext@bar -> %s %s", stripped, extension);
225     myfree(stripped);
226     myfree(extension);
227 
228     stripped = strip_addr_internal("foo+ext@bar", &extension, delim);
229     if (stripped == 0)
230 	msg_panic("strip_addr botch 25");
231     if (extension == 0)
232 	msg_panic("strip_addr botch 26");
233     msg_info("wanted:    foo+ext@bar -> %s %s", "foo@bar", "+ext");
234     msg_info("strip_addr foo+ext@bar -> %s %s", stripped, extension);
235     myfree(stripped);
236     myfree(extension);
237 
238     stripped = strip_addr_internal("foo bar+ext", &extension, delim);
239     if (stripped == 0)
240 	msg_panic("strip_addr botch 27");
241     if (extension == 0)
242 	msg_panic("strip_addr botch 28");
243     msg_info("wanted:    foo bar+ext -> %s %s", "foo bar", "+ext");
244     msg_info("strip_addr foo bar+ext -> %s %s", stripped, extension);
245     myfree(stripped);
246     myfree(extension);
247 
248     return (0);
249 }
250 
251 #endif
252