xref: /netbsd-src/external/ibm-public/postfix/dist/src/global/strip_addr.c (revision 67b9b338a7386232ac596b5fd0cd5a9cc8a03c71)
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