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