xref: /minix3/external/bsd/bind/dist/contrib/idn/idnkit-1.0-src/lib/resconf.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: resconf.c,v 1.4 2014/12/10 04:37:55 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek #ifndef lint
4*00b67f09SDavid van Moolenbroek static char *rcsid = "Id: resconf.c,v 1.1 2003/06/04 00:26:12 marka Exp ";
5*00b67f09SDavid van Moolenbroek #endif
6*00b67f09SDavid van Moolenbroek 
7*00b67f09SDavid van Moolenbroek /*
8*00b67f09SDavid van Moolenbroek  * Copyright (c) 2000 Japan Network Information Center.  All rights reserved.
9*00b67f09SDavid van Moolenbroek  *
10*00b67f09SDavid van Moolenbroek  * By using this file, you agree to the terms and conditions set forth bellow.
11*00b67f09SDavid van Moolenbroek  *
12*00b67f09SDavid van Moolenbroek  * 			LICENSE TERMS AND CONDITIONS
13*00b67f09SDavid van Moolenbroek  *
14*00b67f09SDavid van Moolenbroek  * The following License Terms and Conditions apply, unless a different
15*00b67f09SDavid van Moolenbroek  * license is obtained from Japan Network Information Center ("JPNIC"),
16*00b67f09SDavid van Moolenbroek  * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
17*00b67f09SDavid van Moolenbroek  * Chiyoda-ku, Tokyo 101-0047, Japan.
18*00b67f09SDavid van Moolenbroek  *
19*00b67f09SDavid van Moolenbroek  * 1. Use, Modification and Redistribution (including distribution of any
20*00b67f09SDavid van Moolenbroek  *    modified or derived work) in source and/or binary forms is permitted
21*00b67f09SDavid van Moolenbroek  *    under this License Terms and Conditions.
22*00b67f09SDavid van Moolenbroek  *
23*00b67f09SDavid van Moolenbroek  * 2. Redistribution of source code must retain the copyright notices as they
24*00b67f09SDavid van Moolenbroek  *    appear in each source code file, this License Terms and Conditions.
25*00b67f09SDavid van Moolenbroek  *
26*00b67f09SDavid van Moolenbroek  * 3. Redistribution in binary form must reproduce the Copyright Notice,
27*00b67f09SDavid van Moolenbroek  *    this License Terms and Conditions, in the documentation and/or other
28*00b67f09SDavid van Moolenbroek  *    materials provided with the distribution.  For the purposes of binary
29*00b67f09SDavid van Moolenbroek  *    distribution the "Copyright Notice" refers to the following language:
30*00b67f09SDavid van Moolenbroek  *    "Copyright (c) 2000-2002 Japan Network Information Center.  All rights reserved."
31*00b67f09SDavid van Moolenbroek  *
32*00b67f09SDavid van Moolenbroek  * 4. The name of JPNIC may not be used to endorse or promote products
33*00b67f09SDavid van Moolenbroek  *    derived from this Software without specific prior written approval of
34*00b67f09SDavid van Moolenbroek  *    JPNIC.
35*00b67f09SDavid van Moolenbroek  *
36*00b67f09SDavid van Moolenbroek  * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
37*00b67f09SDavid van Moolenbroek  *    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
38*00b67f09SDavid van Moolenbroek  *    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
39*00b67f09SDavid van Moolenbroek  *    PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL JPNIC BE LIABLE
40*00b67f09SDavid van Moolenbroek  *    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
41*00b67f09SDavid van Moolenbroek  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
42*00b67f09SDavid van Moolenbroek  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43*00b67f09SDavid van Moolenbroek  *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44*00b67f09SDavid van Moolenbroek  *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45*00b67f09SDavid van Moolenbroek  *    OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
46*00b67f09SDavid van Moolenbroek  *    ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
47*00b67f09SDavid van Moolenbroek  */
48*00b67f09SDavid van Moolenbroek 
49*00b67f09SDavid van Moolenbroek #include <config.h>
50*00b67f09SDavid van Moolenbroek 
51*00b67f09SDavid van Moolenbroek #include <stddef.h>
52*00b67f09SDavid van Moolenbroek #include <stdarg.h>
53*00b67f09SDavid van Moolenbroek #include <stdlib.h>
54*00b67f09SDavid van Moolenbroek #include <stdio.h>
55*00b67f09SDavid van Moolenbroek #include <string.h>
56*00b67f09SDavid van Moolenbroek #include <ctype.h>
57*00b67f09SDavid van Moolenbroek #include <errno.h>
58*00b67f09SDavid van Moolenbroek #ifdef HAVE_UNISTD_H
59*00b67f09SDavid van Moolenbroek #include <unistd.h>
60*00b67f09SDavid van Moolenbroek #endif
61*00b67f09SDavid van Moolenbroek #ifdef HAVE_PWD_H
62*00b67f09SDavid van Moolenbroek #include <pwd.h>
63*00b67f09SDavid van Moolenbroek #endif
64*00b67f09SDavid van Moolenbroek 
65*00b67f09SDavid van Moolenbroek #include <idn/result.h>
66*00b67f09SDavid van Moolenbroek #include <idn/assert.h>
67*00b67f09SDavid van Moolenbroek #include <idn/logmacro.h>
68*00b67f09SDavid van Moolenbroek #include <idn/converter.h>
69*00b67f09SDavid van Moolenbroek #include <idn/nameprep.h>
70*00b67f09SDavid van Moolenbroek #include <idn/normalizer.h>
71*00b67f09SDavid van Moolenbroek #include <idn/checker.h>
72*00b67f09SDavid van Moolenbroek #include <idn/mapper.h>
73*00b67f09SDavid van Moolenbroek #include <idn/mapselector.h>
74*00b67f09SDavid van Moolenbroek #include <idn/delimitermap.h>
75*00b67f09SDavid van Moolenbroek #include <idn/localencoding.h>
76*00b67f09SDavid van Moolenbroek #include <idn/resconf.h>
77*00b67f09SDavid van Moolenbroek #include <idn/debug.h>
78*00b67f09SDavid van Moolenbroek #include <idn/util.h>
79*00b67f09SDavid van Moolenbroek 
80*00b67f09SDavid van Moolenbroek #ifdef WIN32
81*00b67f09SDavid van Moolenbroek #define MAX_PATH_SIZE		500	/* a good longer than MAX_PATH */
82*00b67f09SDavid van Moolenbroek #define IDNVAL_CONFFILE		"ConfFile"
83*00b67f09SDavid van Moolenbroek #else /* WIN32 */
84*00b67f09SDavid van Moolenbroek 
85*00b67f09SDavid van Moolenbroek #ifndef IDN_RESCONF_DIR
86*00b67f09SDavid van Moolenbroek #define IDN_RESCONF_DIR		"/etc"
87*00b67f09SDavid van Moolenbroek #endif
88*00b67f09SDavid van Moolenbroek #define IDN_RESCONF_FILE	IDN_RESCONF_DIR "/idn.conf"
89*00b67f09SDavid van Moolenbroek #define IDN_USER_RESCONF_FILE	"/.idnrc"
90*00b67f09SDavid van Moolenbroek 
91*00b67f09SDavid van Moolenbroek #endif /* WIN32 */
92*00b67f09SDavid van Moolenbroek 
93*00b67f09SDavid van Moolenbroek #define MAX_CONF_LINE_LENGTH	255
94*00b67f09SDavid van Moolenbroek #define MAX_CONF_LINE_ARGS	63
95*00b67f09SDavid van Moolenbroek 
96*00b67f09SDavid van Moolenbroek #define DEFAULT_CONF_NAMEPREP		0x0001
97*00b67f09SDavid van Moolenbroek #define DEFAULT_CONF_IDN_ENCODING	0x0010
98*00b67f09SDavid van Moolenbroek #define DEFAULT_CONF_ALL		(DEFAULT_CONF_NAMEPREP | \
99*00b67f09SDavid van Moolenbroek 					DEFAULT_CONF_IDN_ENCODING)
100*00b67f09SDavid van Moolenbroek 
101*00b67f09SDavid van Moolenbroek #define IDN_ENCODING_CURRENT	"Punycode"
102*00b67f09SDavid van Moolenbroek 
103*00b67f09SDavid van Moolenbroek #ifdef ENABLE_MDNKIT_COMPAT
104*00b67f09SDavid van Moolenbroek #define MDN_RESCONF_FILE	IDN_RESCONF_DIR "/mdn.conf"
105*00b67f09SDavid van Moolenbroek #endif
106*00b67f09SDavid van Moolenbroek 
107*00b67f09SDavid van Moolenbroek struct idn_resconf {
108*00b67f09SDavid van Moolenbroek 	int local_converter_is_static;
109*00b67f09SDavid van Moolenbroek 	idn_converter_t local_converter;
110*00b67f09SDavid van Moolenbroek 	idn_converter_t idn_converter;
111*00b67f09SDavid van Moolenbroek         idn_converter_t aux_idn_converter;
112*00b67f09SDavid van Moolenbroek 	idn_normalizer_t normalizer;
113*00b67f09SDavid van Moolenbroek 	idn_checker_t prohibit_checker;
114*00b67f09SDavid van Moolenbroek 	idn_checker_t unassigned_checker;
115*00b67f09SDavid van Moolenbroek 	idn_checker_t bidi_checker;
116*00b67f09SDavid van Moolenbroek 	idn_mapper_t mapper;
117*00b67f09SDavid van Moolenbroek 	idn_mapselector_t local_mapper;
118*00b67f09SDavid van Moolenbroek 	idn_delimitermap_t delimiter_mapper;
119*00b67f09SDavid van Moolenbroek 	int reference_count;
120*00b67f09SDavid van Moolenbroek };
121*00b67f09SDavid van Moolenbroek 
122*00b67f09SDavid van Moolenbroek static int initialized;
123*00b67f09SDavid van Moolenbroek 
124*00b67f09SDavid van Moolenbroek #ifndef WIN32
125*00b67f09SDavid van Moolenbroek static const char *	userhomedir(void);
126*00b67f09SDavid van Moolenbroek #endif
127*00b67f09SDavid van Moolenbroek static idn_result_t	open_userdefaultfile(FILE **fpp);
128*00b67f09SDavid van Moolenbroek static idn_result_t	open_defaultfile(FILE **fpp);
129*00b67f09SDavid van Moolenbroek static idn_result_t	parse_conf(idn_resconf_t ctx, FILE *fp);
130*00b67f09SDavid van Moolenbroek static idn_result_t	parse_idn_encoding(idn_resconf_t ctx, char *args,
131*00b67f09SDavid van Moolenbroek 					   int lineno);
132*00b67f09SDavid van Moolenbroek static idn_result_t	parse_local_map(idn_resconf_t ctx, char *args,
133*00b67f09SDavid van Moolenbroek 					int lineno);
134*00b67f09SDavid van Moolenbroek static idn_result_t	parse_nameprep(idn_resconf_t ctx, char *args,
135*00b67f09SDavid van Moolenbroek 				       int lineno);
136*00b67f09SDavid van Moolenbroek static int		split_args(char *s, char **av, int max_ac);
137*00b67f09SDavid van Moolenbroek static void		resetconf(idn_resconf_t ctx);
138*00b67f09SDavid van Moolenbroek #ifndef WITHOUT_ICONV
139*00b67f09SDavid van Moolenbroek static idn_result_t	update_local_converter(idn_resconf_t ctx);
140*00b67f09SDavid van Moolenbroek #endif
141*00b67f09SDavid van Moolenbroek static idn_result_t	setdefaults_body(idn_resconf_t ctx, int conf_mask);
142*00b67f09SDavid van Moolenbroek 
143*00b67f09SDavid van Moolenbroek idn_result_t
idn_resconf_initialize(void)144*00b67f09SDavid van Moolenbroek idn_resconf_initialize(void) {
145*00b67f09SDavid van Moolenbroek 	idn_result_t r;
146*00b67f09SDavid van Moolenbroek 
147*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_initialize()\n"));
148*00b67f09SDavid van Moolenbroek 
149*00b67f09SDavid van Moolenbroek 	if (initialized) {
150*00b67f09SDavid van Moolenbroek 		r = idn_success;
151*00b67f09SDavid van Moolenbroek 		goto ret;
152*00b67f09SDavid van Moolenbroek 	}
153*00b67f09SDavid van Moolenbroek 
154*00b67f09SDavid van Moolenbroek 	/*
155*00b67f09SDavid van Moolenbroek 	 * Initialize sub modules.
156*00b67f09SDavid van Moolenbroek 	 */
157*00b67f09SDavid van Moolenbroek 	if ((r = idn_converter_initialize()) != idn_success)
158*00b67f09SDavid van Moolenbroek 		goto ret;
159*00b67f09SDavid van Moolenbroek 	if ((r = idn_normalizer_initialize()) != idn_success)
160*00b67f09SDavid van Moolenbroek 		goto ret;
161*00b67f09SDavid van Moolenbroek 	if ((r = idn_checker_initialize()) != idn_success)
162*00b67f09SDavid van Moolenbroek 		goto ret;
163*00b67f09SDavid van Moolenbroek 	if ((r = idn_mapselector_initialize()) != idn_success)
164*00b67f09SDavid van Moolenbroek 		goto ret;
165*00b67f09SDavid van Moolenbroek 	if ((r = idn_mapper_initialize()) != idn_success)
166*00b67f09SDavid van Moolenbroek 		goto ret;
167*00b67f09SDavid van Moolenbroek 
168*00b67f09SDavid van Moolenbroek 	r = idn_success;
169*00b67f09SDavid van Moolenbroek 	initialized = 1;
170*00b67f09SDavid van Moolenbroek ret:
171*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_initialize(): %s\n", idn_result_tostring(r)));
172*00b67f09SDavid van Moolenbroek 	return (r);
173*00b67f09SDavid van Moolenbroek }
174*00b67f09SDavid van Moolenbroek 
175*00b67f09SDavid van Moolenbroek idn_result_t
idn_resconf_create(idn_resconf_t * ctxp)176*00b67f09SDavid van Moolenbroek idn_resconf_create(idn_resconf_t *ctxp) {
177*00b67f09SDavid van Moolenbroek 	idn_resconf_t ctx = NULL;
178*00b67f09SDavid van Moolenbroek 	idn_result_t r;
179*00b67f09SDavid van Moolenbroek 
180*00b67f09SDavid van Moolenbroek 	assert(ctxp != NULL);
181*00b67f09SDavid van Moolenbroek 
182*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_create()\n"));
183*00b67f09SDavid van Moolenbroek 
184*00b67f09SDavid van Moolenbroek 	if (!initialized) {
185*00b67f09SDavid van Moolenbroek 		r = idn_failure;
186*00b67f09SDavid van Moolenbroek 		goto ret;
187*00b67f09SDavid van Moolenbroek 	}
188*00b67f09SDavid van Moolenbroek 	if ((ctx = malloc(sizeof(*ctx))) == NULL) {
189*00b67f09SDavid van Moolenbroek 		r = idn_nomemory;
190*00b67f09SDavid van Moolenbroek 		goto ret;
191*00b67f09SDavid van Moolenbroek 	}
192*00b67f09SDavid van Moolenbroek 
193*00b67f09SDavid van Moolenbroek 	ctx->local_converter_is_static = 0;
194*00b67f09SDavid van Moolenbroek 	ctx->local_converter = NULL;
195*00b67f09SDavid van Moolenbroek 	ctx->idn_converter = NULL;
196*00b67f09SDavid van Moolenbroek 	ctx->aux_idn_converter = NULL;
197*00b67f09SDavid van Moolenbroek 	ctx->normalizer = NULL;
198*00b67f09SDavid van Moolenbroek 	ctx->prohibit_checker = NULL;
199*00b67f09SDavid van Moolenbroek 	ctx->unassigned_checker = NULL;
200*00b67f09SDavid van Moolenbroek 	ctx->bidi_checker = NULL;
201*00b67f09SDavid van Moolenbroek 	ctx->mapper = NULL;
202*00b67f09SDavid van Moolenbroek 	ctx->local_mapper = NULL;
203*00b67f09SDavid van Moolenbroek 	ctx->reference_count = 1;
204*00b67f09SDavid van Moolenbroek 
205*00b67f09SDavid van Moolenbroek 	r = idn_delimitermap_create(&ctx->delimiter_mapper);
206*00b67f09SDavid van Moolenbroek 	if (r != idn_success)
207*00b67f09SDavid van Moolenbroek 		goto ret;
208*00b67f09SDavid van Moolenbroek 
209*00b67f09SDavid van Moolenbroek 	*ctxp = ctx;
210*00b67f09SDavid van Moolenbroek 	r = idn_success;
211*00b67f09SDavid van Moolenbroek ret:
212*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_create(): %s\n", idn_result_tostring(r)));
213*00b67f09SDavid van Moolenbroek 	return (r);
214*00b67f09SDavid van Moolenbroek }
215*00b67f09SDavid van Moolenbroek 
216*00b67f09SDavid van Moolenbroek char *
idn_resconf_defaultfile()217*00b67f09SDavid van Moolenbroek idn_resconf_defaultfile() {
218*00b67f09SDavid van Moolenbroek #ifdef WIN32
219*00b67f09SDavid van Moolenbroek 	static char default_path[MAX_PATH_SIZE];
220*00b67f09SDavid van Moolenbroek 
221*00b67f09SDavid van Moolenbroek 	if (idn__util_getregistrystring(idn__util_hkey_localmachine,
222*00b67f09SDavid van Moolenbroek 					IDNVAL_CONFFILE, default_path,
223*00b67f09SDavid van Moolenbroek 					sizeof(default_path))) {
224*00b67f09SDavid van Moolenbroek 		return (default_path);
225*00b67f09SDavid van Moolenbroek 	} else {
226*00b67f09SDavid van Moolenbroek 		return (NULL);
227*00b67f09SDavid van Moolenbroek 	}
228*00b67f09SDavid van Moolenbroek #else
229*00b67f09SDavid van Moolenbroek 	return (IDN_RESCONF_FILE);
230*00b67f09SDavid van Moolenbroek #endif
231*00b67f09SDavid van Moolenbroek }
232*00b67f09SDavid van Moolenbroek 
233*00b67f09SDavid van Moolenbroek #ifndef WIN32
234*00b67f09SDavid van Moolenbroek static const char *
userhomedir()235*00b67f09SDavid van Moolenbroek userhomedir() {
236*00b67f09SDavid van Moolenbroek 	uid_t uid;
237*00b67f09SDavid van Moolenbroek 	struct passwd *pwd;
238*00b67f09SDavid van Moolenbroek 
239*00b67f09SDavid van Moolenbroek 	uid = getuid();
240*00b67f09SDavid van Moolenbroek 	pwd = getpwuid(uid);
241*00b67f09SDavid van Moolenbroek 	if (pwd == NULL) {
242*00b67f09SDavid van Moolenbroek 		return (NULL);
243*00b67f09SDavid van Moolenbroek 	}
244*00b67f09SDavid van Moolenbroek 
245*00b67f09SDavid van Moolenbroek 	return (pwd->pw_dir);
246*00b67f09SDavid van Moolenbroek }
247*00b67f09SDavid van Moolenbroek #endif
248*00b67f09SDavid van Moolenbroek 
249*00b67f09SDavid van Moolenbroek static idn_result_t
open_userdefaultfile(FILE ** fpp)250*00b67f09SDavid van Moolenbroek open_userdefaultfile(FILE **fpp) {
251*00b67f09SDavid van Moolenbroek #ifdef WIN32
252*00b67f09SDavid van Moolenbroek 	char user_path[MAX_PATH_SIZE];
253*00b67f09SDavid van Moolenbroek 
254*00b67f09SDavid van Moolenbroek 	TRACE(("open_userdefaultfile()\n"));
255*00b67f09SDavid van Moolenbroek 
256*00b67f09SDavid van Moolenbroek 	if (idn__util_getregistrystring(idn__util_hkey_currentuser,
257*00b67f09SDavid van Moolenbroek 					IDNVAL_CONFFILE, user_path,
258*00b67f09SDavid van Moolenbroek 					sizeof(user_path)) == 0) {
259*00b67f09SDavid van Moolenbroek 		return (idn_nofile);
260*00b67f09SDavid van Moolenbroek 	}
261*00b67f09SDavid van Moolenbroek 	*fpp = fopen(user_path, "r");
262*00b67f09SDavid van Moolenbroek 	if (*fpp == NULL) {
263*00b67f09SDavid van Moolenbroek 		return (idn_nofile);
264*00b67f09SDavid van Moolenbroek 	}
265*00b67f09SDavid van Moolenbroek 	return (idn_success);
266*00b67f09SDavid van Moolenbroek #else /* WIN32 */
267*00b67f09SDavid van Moolenbroek 	const char *homedir;
268*00b67f09SDavid van Moolenbroek 	char *file;
269*00b67f09SDavid van Moolenbroek 	int len;
270*00b67f09SDavid van Moolenbroek 
271*00b67f09SDavid van Moolenbroek 	TRACE(("open_userdefaultfile()\n"));
272*00b67f09SDavid van Moolenbroek 
273*00b67f09SDavid van Moolenbroek 	homedir = userhomedir();
274*00b67f09SDavid van Moolenbroek 	len = strlen(IDN_USER_RESCONF_FILE) + 1;
275*00b67f09SDavid van Moolenbroek 	if (homedir != NULL) {
276*00b67f09SDavid van Moolenbroek 		len += strlen(homedir);
277*00b67f09SDavid van Moolenbroek 	} else {
278*00b67f09SDavid van Moolenbroek 		return (idn_notfound);
279*00b67f09SDavid van Moolenbroek 	}
280*00b67f09SDavid van Moolenbroek 
281*00b67f09SDavid van Moolenbroek 	file = (char *)malloc(sizeof(char) * len);
282*00b67f09SDavid van Moolenbroek 	if (file == NULL) {
283*00b67f09SDavid van Moolenbroek 		WARNING(("open_userdefaultfile(): malloc failed\n"));
284*00b67f09SDavid van Moolenbroek 		return (idn_nomemory);
285*00b67f09SDavid van Moolenbroek 	}
286*00b67f09SDavid van Moolenbroek 
287*00b67f09SDavid van Moolenbroek 	(void)strcpy(file, homedir);
288*00b67f09SDavid van Moolenbroek 	strcat(file, IDN_USER_RESCONF_FILE);
289*00b67f09SDavid van Moolenbroek 
290*00b67f09SDavid van Moolenbroek 	*fpp = fopen(file, "r");
291*00b67f09SDavid van Moolenbroek 	free(file);
292*00b67f09SDavid van Moolenbroek 	if (*fpp == NULL) {
293*00b67f09SDavid van Moolenbroek 		return (idn_nofile);
294*00b67f09SDavid van Moolenbroek 	}
295*00b67f09SDavid van Moolenbroek 
296*00b67f09SDavid van Moolenbroek 	return (idn_success);
297*00b67f09SDavid van Moolenbroek #endif /* WIN32 */
298*00b67f09SDavid van Moolenbroek }
299*00b67f09SDavid van Moolenbroek 
300*00b67f09SDavid van Moolenbroek static idn_result_t
open_defaultfile(FILE ** fpp)301*00b67f09SDavid van Moolenbroek open_defaultfile(FILE **fpp) {
302*00b67f09SDavid van Moolenbroek 	idn_result_t r;
303*00b67f09SDavid van Moolenbroek 	const char *file;
304*00b67f09SDavid van Moolenbroek 
305*00b67f09SDavid van Moolenbroek 	r = open_userdefaultfile(fpp);
306*00b67f09SDavid van Moolenbroek 	if (r == idn_nofile || r == idn_notfound) {
307*00b67f09SDavid van Moolenbroek 		TRACE(("open_defaultfile: "
308*00b67f09SDavid van Moolenbroek 		       "cannot open user configuration file\n"));
309*00b67f09SDavid van Moolenbroek 		file = idn_resconf_defaultfile();
310*00b67f09SDavid van Moolenbroek 		*fpp = fopen(file, "r");
311*00b67f09SDavid van Moolenbroek #ifdef ENABLE_MDNKIT_COMPAT
312*00b67f09SDavid van Moolenbroek 		if (*fpp == NULL)
313*00b67f09SDavid van Moolenbroek 			*fpp = fopen(MDN_RESCONF_FILE, "r");
314*00b67f09SDavid van Moolenbroek #endif
315*00b67f09SDavid van Moolenbroek 		if (*fpp == NULL) {
316*00b67f09SDavid van Moolenbroek 			TRACE(("open_defaultfile: "
317*00b67f09SDavid van Moolenbroek 			       "cannot open system configuration file\n"));
318*00b67f09SDavid van Moolenbroek 			return (idn_nofile);
319*00b67f09SDavid van Moolenbroek 		}
320*00b67f09SDavid van Moolenbroek 	} else if (r != idn_success) {
321*00b67f09SDavid van Moolenbroek 		return (r);
322*00b67f09SDavid van Moolenbroek 	}
323*00b67f09SDavid van Moolenbroek 
324*00b67f09SDavid van Moolenbroek 	return (idn_success);
325*00b67f09SDavid van Moolenbroek }
326*00b67f09SDavid van Moolenbroek 
327*00b67f09SDavid van Moolenbroek idn_result_t
idn_resconf_loadfile(idn_resconf_t ctx,const char * file)328*00b67f09SDavid van Moolenbroek idn_resconf_loadfile(idn_resconf_t ctx, const char *file) {
329*00b67f09SDavid van Moolenbroek 	FILE *fp = NULL;
330*00b67f09SDavid van Moolenbroek 	idn_result_t r;
331*00b67f09SDavid van Moolenbroek 
332*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
333*00b67f09SDavid van Moolenbroek 
334*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_loadfile(file=%s)\n",
335*00b67f09SDavid van Moolenbroek 	      file == NULL ? "<null>" : file));
336*00b67f09SDavid van Moolenbroek 
337*00b67f09SDavid van Moolenbroek 	resetconf(ctx);
338*00b67f09SDavid van Moolenbroek 	r = idn_delimitermap_create(&ctx->delimiter_mapper);
339*00b67f09SDavid van Moolenbroek 	if (r != idn_success) {
340*00b67f09SDavid van Moolenbroek 		goto ret;
341*00b67f09SDavid van Moolenbroek 	}
342*00b67f09SDavid van Moolenbroek 
343*00b67f09SDavid van Moolenbroek 	if (file == NULL) {
344*00b67f09SDavid van Moolenbroek 		r = open_defaultfile(&fp);
345*00b67f09SDavid van Moolenbroek 		if (r == idn_nofile || r == idn_notfound) {
346*00b67f09SDavid van Moolenbroek 			r = setdefaults_body(ctx, 0);
347*00b67f09SDavid van Moolenbroek 			goto ret;
348*00b67f09SDavid van Moolenbroek 		} else if (r != idn_success) {
349*00b67f09SDavid van Moolenbroek 			goto ret;
350*00b67f09SDavid van Moolenbroek 		}
351*00b67f09SDavid van Moolenbroek 	} else {
352*00b67f09SDavid van Moolenbroek 		fp = fopen(file, "r");
353*00b67f09SDavid van Moolenbroek 		if (fp == NULL) {
354*00b67f09SDavid van Moolenbroek 			TRACE(("idn_resconf_loadfile: cannot open %-.40s\n",
355*00b67f09SDavid van Moolenbroek 			       file));
356*00b67f09SDavid van Moolenbroek 			r = idn_nofile;
357*00b67f09SDavid van Moolenbroek 			goto ret;
358*00b67f09SDavid van Moolenbroek 		}
359*00b67f09SDavid van Moolenbroek 	}
360*00b67f09SDavid van Moolenbroek 
361*00b67f09SDavid van Moolenbroek 	r = parse_conf(ctx, fp);
362*00b67f09SDavid van Moolenbroek 	fclose(fp);
363*00b67f09SDavid van Moolenbroek 
364*00b67f09SDavid van Moolenbroek ret:
365*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_loadfile(): %s\n", idn_result_tostring(r)));
366*00b67f09SDavid van Moolenbroek 	return (r);
367*00b67f09SDavid van Moolenbroek }
368*00b67f09SDavid van Moolenbroek 
369*00b67f09SDavid van Moolenbroek void
idn_resconf_destroy(idn_resconf_t ctx)370*00b67f09SDavid van Moolenbroek idn_resconf_destroy(idn_resconf_t ctx) {
371*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
372*00b67f09SDavid van Moolenbroek 
373*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_destroy()\n"));
374*00b67f09SDavid van Moolenbroek 
375*00b67f09SDavid van Moolenbroek 	ctx->reference_count--;
376*00b67f09SDavid van Moolenbroek 	if (ctx->reference_count <= 0) {
377*00b67f09SDavid van Moolenbroek 		resetconf(ctx);
378*00b67f09SDavid van Moolenbroek 		free(ctx);
379*00b67f09SDavid van Moolenbroek 		TRACE(("idn_resconf_destroy: the object is destroyed\n"));
380*00b67f09SDavid van Moolenbroek 	} else {
381*00b67f09SDavid van Moolenbroek 		TRACE(("idn_resconf_destroy(): "
382*00b67f09SDavid van Moolenbroek 		       "update reference count (%d->%d)\n",
383*00b67f09SDavid van Moolenbroek 		       ctx->reference_count + 1, ctx->reference_count));
384*00b67f09SDavid van Moolenbroek 	}
385*00b67f09SDavid van Moolenbroek }
386*00b67f09SDavid van Moolenbroek 
387*00b67f09SDavid van Moolenbroek void
idn_resconf_incrref(idn_resconf_t ctx)388*00b67f09SDavid van Moolenbroek idn_resconf_incrref(idn_resconf_t ctx) {
389*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
390*00b67f09SDavid van Moolenbroek 
391*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_incrref()\n"));
392*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_incrref: update reference count (%d->%d)\n",
393*00b67f09SDavid van Moolenbroek 		ctx->reference_count, ctx->reference_count + 1));
394*00b67f09SDavid van Moolenbroek 
395*00b67f09SDavid van Moolenbroek 	ctx->reference_count++;
396*00b67f09SDavid van Moolenbroek }
397*00b67f09SDavid van Moolenbroek 
398*00b67f09SDavid van Moolenbroek idn_converter_t
idn_resconf_getalternateconverter(idn_resconf_t ctx)399*00b67f09SDavid van Moolenbroek idn_resconf_getalternateconverter(idn_resconf_t ctx) {
400*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
401*00b67f09SDavid van Moolenbroek 
402*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_getalternateconverter()\n"));
403*00b67f09SDavid van Moolenbroek 
404*00b67f09SDavid van Moolenbroek 	return (idn_resconf_getidnconverter(ctx));
405*00b67f09SDavid van Moolenbroek }
406*00b67f09SDavid van Moolenbroek 
407*00b67f09SDavid van Moolenbroek idn_delimitermap_t
idn_resconf_getdelimitermap(idn_resconf_t ctx)408*00b67f09SDavid van Moolenbroek idn_resconf_getdelimitermap(idn_resconf_t ctx) {
409*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
410*00b67f09SDavid van Moolenbroek 
411*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_getdelimitermap()\n"));
412*00b67f09SDavid van Moolenbroek 
413*00b67f09SDavid van Moolenbroek 	if (ctx->delimiter_mapper != NULL)
414*00b67f09SDavid van Moolenbroek 		idn_delimitermap_incrref(ctx->delimiter_mapper);
415*00b67f09SDavid van Moolenbroek 	return (ctx->delimiter_mapper);
416*00b67f09SDavid van Moolenbroek }
417*00b67f09SDavid van Moolenbroek 
418*00b67f09SDavid van Moolenbroek idn_converter_t
idn_resconf_getidnconverter(idn_resconf_t ctx)419*00b67f09SDavid van Moolenbroek idn_resconf_getidnconverter(idn_resconf_t ctx) {
420*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
421*00b67f09SDavid van Moolenbroek 
422*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_getidnconverter()\n"));
423*00b67f09SDavid van Moolenbroek 
424*00b67f09SDavid van Moolenbroek 	if (ctx->idn_converter != NULL)
425*00b67f09SDavid van Moolenbroek 		idn_converter_incrref(ctx->idn_converter);
426*00b67f09SDavid van Moolenbroek 	return (ctx->idn_converter);
427*00b67f09SDavid van Moolenbroek }
428*00b67f09SDavid van Moolenbroek 
429*00b67f09SDavid van Moolenbroek idn_converter_t
idn_resconf_getauxidnconverter(idn_resconf_t ctx)430*00b67f09SDavid van Moolenbroek idn_resconf_getauxidnconverter(idn_resconf_t ctx) {
431*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
432*00b67f09SDavid van Moolenbroek 
433*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_getauxidnconverter()\n"));
434*00b67f09SDavid van Moolenbroek 
435*00b67f09SDavid van Moolenbroek 	if (ctx->aux_idn_converter != NULL)
436*00b67f09SDavid van Moolenbroek 		idn_converter_incrref(ctx->aux_idn_converter);
437*00b67f09SDavid van Moolenbroek 	return (ctx->aux_idn_converter);
438*00b67f09SDavid van Moolenbroek }
439*00b67f09SDavid van Moolenbroek 
440*00b67f09SDavid van Moolenbroek idn_converter_t
idn_resconf_getlocalconverter(idn_resconf_t ctx)441*00b67f09SDavid van Moolenbroek idn_resconf_getlocalconverter(idn_resconf_t ctx) {
442*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
443*00b67f09SDavid van Moolenbroek 
444*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_getlocalconverter()\n"));
445*00b67f09SDavid van Moolenbroek 
446*00b67f09SDavid van Moolenbroek #ifdef WITHOUT_ICONV
447*00b67f09SDavid van Moolenbroek 	return NULL;
448*00b67f09SDavid van Moolenbroek 
449*00b67f09SDavid van Moolenbroek #else /* WITHOUT_ICONV */
450*00b67f09SDavid van Moolenbroek 	if (update_local_converter(ctx) != idn_success)
451*00b67f09SDavid van Moolenbroek 		return (NULL);
452*00b67f09SDavid van Moolenbroek 
453*00b67f09SDavid van Moolenbroek 	idn_converter_incrref(ctx->local_converter);
454*00b67f09SDavid van Moolenbroek 	return (ctx->local_converter);
455*00b67f09SDavid van Moolenbroek 
456*00b67f09SDavid van Moolenbroek #endif /* WITHOUT_ICONV */
457*00b67f09SDavid van Moolenbroek }
458*00b67f09SDavid van Moolenbroek 
459*00b67f09SDavid van Moolenbroek idn_mapselector_t
idn_resconf_getlocalmapselector(idn_resconf_t ctx)460*00b67f09SDavid van Moolenbroek idn_resconf_getlocalmapselector(idn_resconf_t ctx) {
461*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
462*00b67f09SDavid van Moolenbroek 
463*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_getlocalmapselector()\n"));
464*00b67f09SDavid van Moolenbroek 
465*00b67f09SDavid van Moolenbroek 	if (ctx->local_mapper != NULL)
466*00b67f09SDavid van Moolenbroek 		idn_mapselector_incrref(ctx->local_mapper);
467*00b67f09SDavid van Moolenbroek 	return (ctx->local_mapper);
468*00b67f09SDavid van Moolenbroek }
469*00b67f09SDavid van Moolenbroek 
470*00b67f09SDavid van Moolenbroek idn_mapper_t
idn_resconf_getmapper(idn_resconf_t ctx)471*00b67f09SDavid van Moolenbroek idn_resconf_getmapper(idn_resconf_t ctx) {
472*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
473*00b67f09SDavid van Moolenbroek 
474*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_getmapper()\n"));
475*00b67f09SDavid van Moolenbroek 
476*00b67f09SDavid van Moolenbroek 	if (ctx->mapper != NULL)
477*00b67f09SDavid van Moolenbroek 		idn_mapper_incrref(ctx->mapper);
478*00b67f09SDavid van Moolenbroek 	return (ctx->mapper);
479*00b67f09SDavid van Moolenbroek }
480*00b67f09SDavid van Moolenbroek 
481*00b67f09SDavid van Moolenbroek idn_normalizer_t
idn_resconf_getnormalizer(idn_resconf_t ctx)482*00b67f09SDavid van Moolenbroek idn_resconf_getnormalizer(idn_resconf_t ctx) {
483*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
484*00b67f09SDavid van Moolenbroek 
485*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_getnormalizer()\n"));
486*00b67f09SDavid van Moolenbroek 
487*00b67f09SDavid van Moolenbroek 	if (ctx->normalizer != NULL)
488*00b67f09SDavid van Moolenbroek 		idn_normalizer_incrref(ctx->normalizer);
489*00b67f09SDavid van Moolenbroek 	return (ctx->normalizer);
490*00b67f09SDavid van Moolenbroek }
491*00b67f09SDavid van Moolenbroek 
492*00b67f09SDavid van Moolenbroek idn_checker_t
idn_resconf_getprohibitchecker(idn_resconf_t ctx)493*00b67f09SDavid van Moolenbroek idn_resconf_getprohibitchecker(idn_resconf_t ctx) {
494*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
495*00b67f09SDavid van Moolenbroek 
496*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_getprohibitchecker()\n"));
497*00b67f09SDavid van Moolenbroek 
498*00b67f09SDavid van Moolenbroek 	if (ctx->prohibit_checker != NULL)
499*00b67f09SDavid van Moolenbroek 		idn_checker_incrref(ctx->prohibit_checker);
500*00b67f09SDavid van Moolenbroek 	return (ctx->prohibit_checker);
501*00b67f09SDavid van Moolenbroek }
502*00b67f09SDavid van Moolenbroek 
503*00b67f09SDavid van Moolenbroek idn_checker_t
idn_resconf_getunassignedchecker(idn_resconf_t ctx)504*00b67f09SDavid van Moolenbroek idn_resconf_getunassignedchecker(idn_resconf_t ctx) {
505*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
506*00b67f09SDavid van Moolenbroek 
507*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_getunassignedchecker()\n"));
508*00b67f09SDavid van Moolenbroek 
509*00b67f09SDavid van Moolenbroek 	if (ctx->unassigned_checker != NULL)
510*00b67f09SDavid van Moolenbroek 		idn_checker_incrref(ctx->unassigned_checker);
511*00b67f09SDavid van Moolenbroek 	return (ctx->unassigned_checker);
512*00b67f09SDavid van Moolenbroek }
513*00b67f09SDavid van Moolenbroek 
514*00b67f09SDavid van Moolenbroek idn_checker_t
idn_resconf_getbidichecker(idn_resconf_t ctx)515*00b67f09SDavid van Moolenbroek idn_resconf_getbidichecker(idn_resconf_t ctx) {
516*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
517*00b67f09SDavid van Moolenbroek 
518*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_getbidichecker()\n"));
519*00b67f09SDavid van Moolenbroek 
520*00b67f09SDavid van Moolenbroek 	if (ctx->bidi_checker != NULL)
521*00b67f09SDavid van Moolenbroek 		idn_checker_incrref(ctx->bidi_checker);
522*00b67f09SDavid van Moolenbroek 	return (ctx->bidi_checker);
523*00b67f09SDavid van Moolenbroek }
524*00b67f09SDavid van Moolenbroek 
525*00b67f09SDavid van Moolenbroek void
idn_resconf_setalternateconverter(idn_resconf_t ctx,idn_converter_t alternate_converter)526*00b67f09SDavid van Moolenbroek idn_resconf_setalternateconverter(idn_resconf_t ctx,
527*00b67f09SDavid van Moolenbroek 				  idn_converter_t alternate_converter) {
528*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
529*00b67f09SDavid van Moolenbroek 
530*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_setalternateconverter()\n"));
531*00b67f09SDavid van Moolenbroek }
532*00b67f09SDavid van Moolenbroek 
533*00b67f09SDavid van Moolenbroek void
idn_resconf_setdelimitermap(idn_resconf_t ctx,idn_delimitermap_t delimiter_mapper)534*00b67f09SDavid van Moolenbroek idn_resconf_setdelimitermap(idn_resconf_t ctx,
535*00b67f09SDavid van Moolenbroek 			    idn_delimitermap_t delimiter_mapper) {
536*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
537*00b67f09SDavid van Moolenbroek 
538*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_setdelimitermap()\n"));
539*00b67f09SDavid van Moolenbroek 
540*00b67f09SDavid van Moolenbroek 	if (ctx->delimiter_mapper != NULL)
541*00b67f09SDavid van Moolenbroek 		idn_delimitermap_destroy(ctx->delimiter_mapper);
542*00b67f09SDavid van Moolenbroek 	ctx->delimiter_mapper = delimiter_mapper;
543*00b67f09SDavid van Moolenbroek 	if (delimiter_mapper != NULL)
544*00b67f09SDavid van Moolenbroek 		idn_delimitermap_incrref(ctx->delimiter_mapper);
545*00b67f09SDavid van Moolenbroek }
546*00b67f09SDavid van Moolenbroek 
547*00b67f09SDavid van Moolenbroek void
idn_resconf_setidnconverter(idn_resconf_t ctx,idn_converter_t idn_converter)548*00b67f09SDavid van Moolenbroek idn_resconf_setidnconverter(idn_resconf_t ctx,
549*00b67f09SDavid van Moolenbroek 			    idn_converter_t idn_converter) {
550*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
551*00b67f09SDavid van Moolenbroek 
552*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_setidnconverter()\n"));
553*00b67f09SDavid van Moolenbroek 
554*00b67f09SDavid van Moolenbroek 	if (ctx->idn_converter != NULL)
555*00b67f09SDavid van Moolenbroek 		idn_converter_destroy(ctx->idn_converter);
556*00b67f09SDavid van Moolenbroek 	ctx->idn_converter = idn_converter;
557*00b67f09SDavid van Moolenbroek 	if (idn_converter != NULL)
558*00b67f09SDavid van Moolenbroek 		idn_converter_incrref(ctx->idn_converter);
559*00b67f09SDavid van Moolenbroek }
560*00b67f09SDavid van Moolenbroek 
561*00b67f09SDavid van Moolenbroek void
idn_resconf_setauxidnconverter(idn_resconf_t ctx,idn_converter_t aux_idn_converter)562*00b67f09SDavid van Moolenbroek idn_resconf_setauxidnconverter(idn_resconf_t ctx,
563*00b67f09SDavid van Moolenbroek 				idn_converter_t aux_idn_converter) {
564*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
565*00b67f09SDavid van Moolenbroek 
566*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_setauxidnconverter()\n"));
567*00b67f09SDavid van Moolenbroek 
568*00b67f09SDavid van Moolenbroek 	if (ctx->aux_idn_converter != NULL)
569*00b67f09SDavid van Moolenbroek 		idn_converter_destroy(ctx->aux_idn_converter);
570*00b67f09SDavid van Moolenbroek 	ctx->aux_idn_converter = aux_idn_converter;
571*00b67f09SDavid van Moolenbroek 	if (aux_idn_converter != NULL)
572*00b67f09SDavid van Moolenbroek 		idn_converter_incrref(ctx->aux_idn_converter);
573*00b67f09SDavid van Moolenbroek }
574*00b67f09SDavid van Moolenbroek 
575*00b67f09SDavid van Moolenbroek void
idn_resconf_setlocalconverter(idn_resconf_t ctx,idn_converter_t local_converter)576*00b67f09SDavid van Moolenbroek idn_resconf_setlocalconverter(idn_resconf_t ctx,
577*00b67f09SDavid van Moolenbroek 			      idn_converter_t local_converter) {
578*00b67f09SDavid van Moolenbroek #ifndef WITHOUT_ICONV
579*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
580*00b67f09SDavid van Moolenbroek 
581*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_setlocalconverter()\n"));
582*00b67f09SDavid van Moolenbroek 
583*00b67f09SDavid van Moolenbroek 	if (ctx->local_converter != NULL) {
584*00b67f09SDavid van Moolenbroek 		idn_converter_destroy(ctx->local_converter);
585*00b67f09SDavid van Moolenbroek 		ctx->local_converter = NULL;
586*00b67f09SDavid van Moolenbroek 	}
587*00b67f09SDavid van Moolenbroek 
588*00b67f09SDavid van Moolenbroek 	if (local_converter == NULL)
589*00b67f09SDavid van Moolenbroek 		ctx->local_converter_is_static = 0;
590*00b67f09SDavid van Moolenbroek 	else {
591*00b67f09SDavid van Moolenbroek 		ctx->local_converter = local_converter;
592*00b67f09SDavid van Moolenbroek 		idn_converter_incrref(local_converter);
593*00b67f09SDavid van Moolenbroek 		ctx->local_converter_is_static = 1;
594*00b67f09SDavid van Moolenbroek 	}
595*00b67f09SDavid van Moolenbroek #endif /* WITHOUT_ICONV */
596*00b67f09SDavid van Moolenbroek }
597*00b67f09SDavid van Moolenbroek 
598*00b67f09SDavid van Moolenbroek void
idn_resconf_setlocalmapselector(idn_resconf_t ctx,idn_mapselector_t local_mapper)599*00b67f09SDavid van Moolenbroek idn_resconf_setlocalmapselector(idn_resconf_t ctx,
600*00b67f09SDavid van Moolenbroek 				idn_mapselector_t local_mapper) {
601*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
602*00b67f09SDavid van Moolenbroek 
603*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_setlocalmapselector()\n"));
604*00b67f09SDavid van Moolenbroek 
605*00b67f09SDavid van Moolenbroek 	if (ctx->local_mapper != NULL)
606*00b67f09SDavid van Moolenbroek 		idn_mapselector_destroy(ctx->local_mapper);
607*00b67f09SDavid van Moolenbroek 	ctx->local_mapper = local_mapper;
608*00b67f09SDavid van Moolenbroek 	if (local_mapper != NULL)
609*00b67f09SDavid van Moolenbroek 		idn_mapselector_incrref(ctx->local_mapper);
610*00b67f09SDavid van Moolenbroek }
611*00b67f09SDavid van Moolenbroek 
612*00b67f09SDavid van Moolenbroek void
idn_resconf_setmapper(idn_resconf_t ctx,idn_mapper_t mapper)613*00b67f09SDavid van Moolenbroek idn_resconf_setmapper(idn_resconf_t ctx, idn_mapper_t mapper) {
614*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
615*00b67f09SDavid van Moolenbroek 
616*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_setmapper()\n"));
617*00b67f09SDavid van Moolenbroek 
618*00b67f09SDavid van Moolenbroek 	if (ctx->mapper != NULL)
619*00b67f09SDavid van Moolenbroek 		idn_mapper_destroy(ctx->mapper);
620*00b67f09SDavid van Moolenbroek 	ctx->mapper = mapper;
621*00b67f09SDavid van Moolenbroek 	if (mapper != NULL)
622*00b67f09SDavid van Moolenbroek 		idn_mapper_incrref(ctx->mapper);
623*00b67f09SDavid van Moolenbroek }
624*00b67f09SDavid van Moolenbroek 
625*00b67f09SDavid van Moolenbroek void
idn_resconf_setnormalizer(idn_resconf_t ctx,idn_normalizer_t normalizer)626*00b67f09SDavid van Moolenbroek idn_resconf_setnormalizer(idn_resconf_t ctx, idn_normalizer_t normalizer) {
627*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
628*00b67f09SDavid van Moolenbroek 
629*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_setnormalizer()\n"));
630*00b67f09SDavid van Moolenbroek 
631*00b67f09SDavid van Moolenbroek 	if (ctx->normalizer != NULL)
632*00b67f09SDavid van Moolenbroek 		idn_normalizer_destroy(ctx->normalizer);
633*00b67f09SDavid van Moolenbroek 	ctx->normalizer = normalizer;
634*00b67f09SDavid van Moolenbroek 	if (normalizer != NULL)
635*00b67f09SDavid van Moolenbroek 		idn_normalizer_incrref(ctx->normalizer);
636*00b67f09SDavid van Moolenbroek }
637*00b67f09SDavid van Moolenbroek 
638*00b67f09SDavid van Moolenbroek void
idn_resconf_setprohibitchecker(idn_resconf_t ctx,idn_checker_t prohibit_checker)639*00b67f09SDavid van Moolenbroek idn_resconf_setprohibitchecker(idn_resconf_t ctx,
640*00b67f09SDavid van Moolenbroek 			       idn_checker_t prohibit_checker) {
641*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
642*00b67f09SDavid van Moolenbroek 
643*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_setprohibitchecker()\n"));
644*00b67f09SDavid van Moolenbroek 
645*00b67f09SDavid van Moolenbroek 	if (ctx->prohibit_checker != NULL)
646*00b67f09SDavid van Moolenbroek 		idn_checker_destroy(ctx->prohibit_checker);
647*00b67f09SDavid van Moolenbroek 	ctx->prohibit_checker = prohibit_checker;
648*00b67f09SDavid van Moolenbroek 	if (prohibit_checker != NULL)
649*00b67f09SDavid van Moolenbroek 		idn_checker_incrref(ctx->prohibit_checker);
650*00b67f09SDavid van Moolenbroek }
651*00b67f09SDavid van Moolenbroek 
652*00b67f09SDavid van Moolenbroek void
idn_resconf_setunassignedchecker(idn_resconf_t ctx,idn_checker_t unassigned_checker)653*00b67f09SDavid van Moolenbroek idn_resconf_setunassignedchecker(idn_resconf_t ctx,
654*00b67f09SDavid van Moolenbroek 				 idn_checker_t unassigned_checker) {
655*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
656*00b67f09SDavid van Moolenbroek 
657*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_setunassignedchecker()\n"));
658*00b67f09SDavid van Moolenbroek 
659*00b67f09SDavid van Moolenbroek 	if (ctx->unassigned_checker != NULL)
660*00b67f09SDavid van Moolenbroek 		idn_checker_destroy(ctx->unassigned_checker);
661*00b67f09SDavid van Moolenbroek 	ctx->unassigned_checker = unassigned_checker;
662*00b67f09SDavid van Moolenbroek 	if (unassigned_checker != NULL)
663*00b67f09SDavid van Moolenbroek 		idn_checker_incrref(ctx->unassigned_checker);
664*00b67f09SDavid van Moolenbroek }
665*00b67f09SDavid van Moolenbroek 
666*00b67f09SDavid van Moolenbroek void
idn_resconf_setbidichecker(idn_resconf_t ctx,idn_checker_t bidi_checker)667*00b67f09SDavid van Moolenbroek idn_resconf_setbidichecker(idn_resconf_t ctx,
668*00b67f09SDavid van Moolenbroek 			   idn_checker_t bidi_checker) {
669*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
670*00b67f09SDavid van Moolenbroek 
671*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_setbidichecker()\n"));
672*00b67f09SDavid van Moolenbroek 
673*00b67f09SDavid van Moolenbroek 	if (ctx->bidi_checker != NULL)
674*00b67f09SDavid van Moolenbroek 		idn_checker_destroy(ctx->bidi_checker);
675*00b67f09SDavid van Moolenbroek 	ctx->bidi_checker = bidi_checker;
676*00b67f09SDavid van Moolenbroek 	if (bidi_checker != NULL)
677*00b67f09SDavid van Moolenbroek 		idn_checker_incrref(ctx->bidi_checker);
678*00b67f09SDavid van Moolenbroek }
679*00b67f09SDavid van Moolenbroek 
680*00b67f09SDavid van Moolenbroek idn_result_t
idn_resconf_setnameprepversion(idn_resconf_t ctx,const char * version)681*00b67f09SDavid van Moolenbroek idn_resconf_setnameprepversion(idn_resconf_t ctx, const char *version)
682*00b67f09SDavid van Moolenbroek {
683*00b67f09SDavid van Moolenbroek 	char prohibit_scheme_name[MAX_CONF_LINE_LENGTH + 1];
684*00b67f09SDavid van Moolenbroek 	char unassigned_scheme_name[MAX_CONF_LINE_LENGTH + 1];
685*00b67f09SDavid van Moolenbroek 	char bidi_scheme_name[MAX_CONF_LINE_LENGTH + 1];
686*00b67f09SDavid van Moolenbroek 	idn_mapper_t mapper = NULL;
687*00b67f09SDavid van Moolenbroek 	idn_normalizer_t normalizer = NULL;
688*00b67f09SDavid van Moolenbroek 	idn_checker_t prohibit_checker = NULL;
689*00b67f09SDavid van Moolenbroek 	idn_checker_t unassigned_checker = NULL;
690*00b67f09SDavid van Moolenbroek 	idn_checker_t bidi_checker = NULL;
691*00b67f09SDavid van Moolenbroek 	idn_result_t r;
692*00b67f09SDavid van Moolenbroek 
693*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL && version != NULL);
694*00b67f09SDavid van Moolenbroek 
695*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_setnameprepversion()\n"));
696*00b67f09SDavid van Moolenbroek 
697*00b67f09SDavid van Moolenbroek 	/*
698*00b67f09SDavid van Moolenbroek 	 * Set canonical scheme names.
699*00b67f09SDavid van Moolenbroek 	 */
700*00b67f09SDavid van Moolenbroek 	if (strlen(version) + strlen(IDN_CHECKER_PROHIBIT_PREFIX)
701*00b67f09SDavid van Moolenbroek 	    > MAX_CONF_LINE_LENGTH) {
702*00b67f09SDavid van Moolenbroek 		r = idn_invalid_name;
703*00b67f09SDavid van Moolenbroek 		goto failure;
704*00b67f09SDavid van Moolenbroek 	}
705*00b67f09SDavid van Moolenbroek 	sprintf(prohibit_scheme_name, "%s%s",
706*00b67f09SDavid van Moolenbroek 	        IDN_CHECKER_PROHIBIT_PREFIX, version);
707*00b67f09SDavid van Moolenbroek 
708*00b67f09SDavid van Moolenbroek 	if (strlen(version) + strlen(IDN_CHECKER_UNASSIGNED_PREFIX)
709*00b67f09SDavid van Moolenbroek 	    > MAX_CONF_LINE_LENGTH) {
710*00b67f09SDavid van Moolenbroek 		r = idn_invalid_name;
711*00b67f09SDavid van Moolenbroek 		goto failure;
712*00b67f09SDavid van Moolenbroek 	}
713*00b67f09SDavid van Moolenbroek 	sprintf(unassigned_scheme_name, "%s%s",
714*00b67f09SDavid van Moolenbroek 	        IDN_CHECKER_UNASSIGNED_PREFIX, version);
715*00b67f09SDavid van Moolenbroek 
716*00b67f09SDavid van Moolenbroek 	if (strlen(version) + strlen(IDN_CHECKER_BIDI_PREFIX)
717*00b67f09SDavid van Moolenbroek 	    > MAX_CONF_LINE_LENGTH) {
718*00b67f09SDavid van Moolenbroek 		r = idn_invalid_name;
719*00b67f09SDavid van Moolenbroek 		goto failure;
720*00b67f09SDavid van Moolenbroek 	}
721*00b67f09SDavid van Moolenbroek 	sprintf(bidi_scheme_name, "%s%s",
722*00b67f09SDavid van Moolenbroek 	        IDN_CHECKER_BIDI_PREFIX, version);
723*00b67f09SDavid van Moolenbroek 
724*00b67f09SDavid van Moolenbroek 	/*
725*00b67f09SDavid van Moolenbroek 	 * Create objects.
726*00b67f09SDavid van Moolenbroek 	 */
727*00b67f09SDavid van Moolenbroek 	r = idn_mapper_create(&mapper);
728*00b67f09SDavid van Moolenbroek 	if (r != idn_success)
729*00b67f09SDavid van Moolenbroek 		goto failure;
730*00b67f09SDavid van Moolenbroek 	r = idn_normalizer_create(&normalizer);
731*00b67f09SDavid van Moolenbroek 	if (r != idn_success)
732*00b67f09SDavid van Moolenbroek 		goto failure;
733*00b67f09SDavid van Moolenbroek 	r = idn_checker_create(&prohibit_checker);
734*00b67f09SDavid van Moolenbroek 	if (r != idn_success)
735*00b67f09SDavid van Moolenbroek 		goto failure;
736*00b67f09SDavid van Moolenbroek 	r = idn_checker_create(&unassigned_checker);
737*00b67f09SDavid van Moolenbroek 	if (r != idn_success)
738*00b67f09SDavid van Moolenbroek 		goto failure;
739*00b67f09SDavid van Moolenbroek 	r = idn_checker_create(&bidi_checker);
740*00b67f09SDavid van Moolenbroek 	if (r != idn_success)
741*00b67f09SDavid van Moolenbroek 		goto failure;
742*00b67f09SDavid van Moolenbroek 
743*00b67f09SDavid van Moolenbroek 	r = idn_mapper_add(mapper, version);
744*00b67f09SDavid van Moolenbroek 	if (r != idn_success)
745*00b67f09SDavid van Moolenbroek 		goto failure;
746*00b67f09SDavid van Moolenbroek 	r = idn_normalizer_add(normalizer, version);
747*00b67f09SDavid van Moolenbroek 	if (r != idn_success)
748*00b67f09SDavid van Moolenbroek 		goto failure;
749*00b67f09SDavid van Moolenbroek 	r = idn_checker_add(prohibit_checker, prohibit_scheme_name);
750*00b67f09SDavid van Moolenbroek 	if (r != idn_success)
751*00b67f09SDavid van Moolenbroek 		goto failure;
752*00b67f09SDavid van Moolenbroek 	r = idn_checker_add(unassigned_checker, unassigned_scheme_name);
753*00b67f09SDavid van Moolenbroek 	if (r != idn_success)
754*00b67f09SDavid van Moolenbroek 		goto failure;
755*00b67f09SDavid van Moolenbroek 	r = idn_checker_add(bidi_checker, bidi_scheme_name);
756*00b67f09SDavid van Moolenbroek 	if (r != idn_success)
757*00b67f09SDavid van Moolenbroek 		goto failure;
758*00b67f09SDavid van Moolenbroek 
759*00b67f09SDavid van Moolenbroek 	/*
760*00b67f09SDavid van Moolenbroek 	 * Set the objects.
761*00b67f09SDavid van Moolenbroek 	 */
762*00b67f09SDavid van Moolenbroek 	idn_resconf_setmapper(ctx, mapper);
763*00b67f09SDavid van Moolenbroek 	idn_resconf_setnormalizer(ctx, normalizer);
764*00b67f09SDavid van Moolenbroek 	idn_resconf_setprohibitchecker(ctx, prohibit_checker);
765*00b67f09SDavid van Moolenbroek 	idn_resconf_setunassignedchecker(ctx, unassigned_checker);
766*00b67f09SDavid van Moolenbroek 	idn_resconf_setbidichecker(ctx, bidi_checker);
767*00b67f09SDavid van Moolenbroek 
768*00b67f09SDavid van Moolenbroek 	/*
769*00b67f09SDavid van Moolenbroek 	 * Destroy the objects.
770*00b67f09SDavid van Moolenbroek 	 */
771*00b67f09SDavid van Moolenbroek 	idn_mapper_destroy(mapper);
772*00b67f09SDavid van Moolenbroek 	idn_normalizer_destroy(normalizer);
773*00b67f09SDavid van Moolenbroek 	idn_checker_destroy(prohibit_checker);
774*00b67f09SDavid van Moolenbroek 	idn_checker_destroy(unassigned_checker);
775*00b67f09SDavid van Moolenbroek 	idn_checker_destroy(bidi_checker);
776*00b67f09SDavid van Moolenbroek 
777*00b67f09SDavid van Moolenbroek 	return (idn_success);
778*00b67f09SDavid van Moolenbroek 
779*00b67f09SDavid van Moolenbroek failure:
780*00b67f09SDavid van Moolenbroek 	if (mapper != NULL)
781*00b67f09SDavid van Moolenbroek 		idn_mapper_destroy(mapper);
782*00b67f09SDavid van Moolenbroek 	if (normalizer != NULL)
783*00b67f09SDavid van Moolenbroek 		idn_normalizer_destroy(normalizer);
784*00b67f09SDavid van Moolenbroek 	if (prohibit_checker != NULL)
785*00b67f09SDavid van Moolenbroek 		idn_checker_destroy(prohibit_checker);
786*00b67f09SDavid van Moolenbroek 	if (unassigned_checker != NULL)
787*00b67f09SDavid van Moolenbroek 		idn_checker_destroy(unassigned_checker);
788*00b67f09SDavid van Moolenbroek 	if (bidi_checker != NULL)
789*00b67f09SDavid van Moolenbroek 		idn_checker_destroy(bidi_checker);
790*00b67f09SDavid van Moolenbroek 
791*00b67f09SDavid van Moolenbroek 	return (r);
792*00b67f09SDavid van Moolenbroek }
793*00b67f09SDavid van Moolenbroek 
794*00b67f09SDavid van Moolenbroek idn_result_t
idn_resconf_setalternateconvertername(idn_resconf_t ctx,const char * name,int flags)795*00b67f09SDavid van Moolenbroek idn_resconf_setalternateconvertername(idn_resconf_t ctx, const char *name,
796*00b67f09SDavid van Moolenbroek 				      int flags) {
797*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL && name != NULL);
798*00b67f09SDavid van Moolenbroek 
799*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_setalternateconvertername(name=%s, flags=%d)\n",
800*00b67f09SDavid van Moolenbroek 	      name, flags));
801*00b67f09SDavid van Moolenbroek 
802*00b67f09SDavid van Moolenbroek 	return (idn_success);
803*00b67f09SDavid van Moolenbroek }
804*00b67f09SDavid van Moolenbroek 
805*00b67f09SDavid van Moolenbroek idn_result_t
idn_resconf_setidnconvertername(idn_resconf_t ctx,const char * name,int flags)806*00b67f09SDavid van Moolenbroek idn_resconf_setidnconvertername(idn_resconf_t ctx, const char *name,
807*00b67f09SDavid van Moolenbroek 				int flags) {
808*00b67f09SDavid van Moolenbroek 	idn_converter_t idn_converter;
809*00b67f09SDavid van Moolenbroek 	idn_result_t r;
810*00b67f09SDavid van Moolenbroek 
811*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL && name != NULL);
812*00b67f09SDavid van Moolenbroek 
813*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_setidnconvertername(name=%s, flags=%d)\n",
814*00b67f09SDavid van Moolenbroek 	      name, flags));
815*00b67f09SDavid van Moolenbroek 
816*00b67f09SDavid van Moolenbroek 	r = idn_converter_create(name, &idn_converter, flags);
817*00b67f09SDavid van Moolenbroek 	if (r != idn_success)
818*00b67f09SDavid van Moolenbroek 		return (r);
819*00b67f09SDavid van Moolenbroek 
820*00b67f09SDavid van Moolenbroek 	if (ctx->idn_converter != NULL)
821*00b67f09SDavid van Moolenbroek 		idn_converter_destroy(ctx->idn_converter);
822*00b67f09SDavid van Moolenbroek 	ctx->idn_converter = idn_converter;
823*00b67f09SDavid van Moolenbroek 
824*00b67f09SDavid van Moolenbroek 	return (idn_success);
825*00b67f09SDavid van Moolenbroek }
826*00b67f09SDavid van Moolenbroek 
827*00b67f09SDavid van Moolenbroek idn_result_t
idn_resconf_setauxidnconvertername(idn_resconf_t ctx,const char * name,int flags)828*00b67f09SDavid van Moolenbroek idn_resconf_setauxidnconvertername(idn_resconf_t ctx, const char *name,
829*00b67f09SDavid van Moolenbroek 				    int flags) {
830*00b67f09SDavid van Moolenbroek 	idn_converter_t aux_idn_converter;
831*00b67f09SDavid van Moolenbroek 	const char *old_name;
832*00b67f09SDavid van Moolenbroek 	idn_result_t r;
833*00b67f09SDavid van Moolenbroek 
834*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL && name != NULL);
835*00b67f09SDavid van Moolenbroek 
836*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_setauxidnconvertername(name=%s, flags=%d)\n",
837*00b67f09SDavid van Moolenbroek 	      name, flags));
838*00b67f09SDavid van Moolenbroek 
839*00b67f09SDavid van Moolenbroek 	if (ctx->aux_idn_converter != NULL) {
840*00b67f09SDavid van Moolenbroek 	    old_name = idn_converter_localencoding(ctx->aux_idn_converter);
841*00b67f09SDavid van Moolenbroek 	    if (old_name != NULL && strcmp(old_name, name) == 0)
842*00b67f09SDavid van Moolenbroek 		return (idn_success);
843*00b67f09SDavid van Moolenbroek 	}
844*00b67f09SDavid van Moolenbroek 
845*00b67f09SDavid van Moolenbroek 	r = idn_converter_create(name, &aux_idn_converter, flags);
846*00b67f09SDavid van Moolenbroek 	if (r != idn_success)
847*00b67f09SDavid van Moolenbroek 		return (r);
848*00b67f09SDavid van Moolenbroek 
849*00b67f09SDavid van Moolenbroek 	if (ctx->aux_idn_converter != NULL)
850*00b67f09SDavid van Moolenbroek 		idn_converter_destroy(ctx->aux_idn_converter);
851*00b67f09SDavid van Moolenbroek 	ctx->aux_idn_converter = aux_idn_converter;
852*00b67f09SDavid van Moolenbroek 
853*00b67f09SDavid van Moolenbroek 	return (idn_success);
854*00b67f09SDavid van Moolenbroek }
855*00b67f09SDavid van Moolenbroek 
856*00b67f09SDavid van Moolenbroek idn_result_t
idn_resconf_setlocalconvertername(idn_resconf_t ctx,const char * name,int flags)857*00b67f09SDavid van Moolenbroek idn_resconf_setlocalconvertername(idn_resconf_t ctx, const char *name,
858*00b67f09SDavid van Moolenbroek 				  int flags) {
859*00b67f09SDavid van Moolenbroek #ifdef WITHOUT_ICONV
860*00b67f09SDavid van Moolenbroek 	return idn_failure;
861*00b67f09SDavid van Moolenbroek 
862*00b67f09SDavid van Moolenbroek #else /* WITHOUT_ICONV */
863*00b67f09SDavid van Moolenbroek 	idn_converter_t local_converter;
864*00b67f09SDavid van Moolenbroek 	idn_result_t r;
865*00b67f09SDavid van Moolenbroek 
866*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
867*00b67f09SDavid van Moolenbroek 
868*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_setlocalconvertername(name=%s, flags=%d)\n",
869*00b67f09SDavid van Moolenbroek 	      name == NULL ? "<null>" : name, flags));
870*00b67f09SDavid van Moolenbroek 
871*00b67f09SDavid van Moolenbroek 	if (ctx->local_converter != NULL) {
872*00b67f09SDavid van Moolenbroek 		idn_converter_destroy(ctx->local_converter);
873*00b67f09SDavid van Moolenbroek 		ctx->local_converter = NULL;
874*00b67f09SDavid van Moolenbroek 	}
875*00b67f09SDavid van Moolenbroek 	ctx->local_converter_is_static = 0;
876*00b67f09SDavid van Moolenbroek 
877*00b67f09SDavid van Moolenbroek 	if (name != NULL) {
878*00b67f09SDavid van Moolenbroek 		r = idn_converter_create(name, &local_converter, flags);
879*00b67f09SDavid van Moolenbroek 		if (r != idn_success)
880*00b67f09SDavid van Moolenbroek 			return (r);
881*00b67f09SDavid van Moolenbroek 		ctx->local_converter = local_converter;
882*00b67f09SDavid van Moolenbroek 		ctx->local_converter_is_static = 1;
883*00b67f09SDavid van Moolenbroek 	}
884*00b67f09SDavid van Moolenbroek 
885*00b67f09SDavid van Moolenbroek 	return (idn_success);
886*00b67f09SDavid van Moolenbroek 
887*00b67f09SDavid van Moolenbroek #endif /* WITHOUT_ICONV */
888*00b67f09SDavid van Moolenbroek }
889*00b67f09SDavid van Moolenbroek 
890*00b67f09SDavid van Moolenbroek idn_result_t
idn_resconf_addalldelimitermapucs(idn_resconf_t ctx,unsigned long * v,int nv)891*00b67f09SDavid van Moolenbroek idn_resconf_addalldelimitermapucs(idn_resconf_t ctx, unsigned long *v,
892*00b67f09SDavid van Moolenbroek 				  int nv) {
893*00b67f09SDavid van Moolenbroek 	idn_result_t r;
894*00b67f09SDavid van Moolenbroek 
895*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_addalldelimitermapucs(nv=%d)\n", nv));
896*00b67f09SDavid van Moolenbroek 
897*00b67f09SDavid van Moolenbroek 	if (ctx->delimiter_mapper == NULL) {
898*00b67f09SDavid van Moolenbroek 		r = idn_delimitermap_create(&(ctx->delimiter_mapper));
899*00b67f09SDavid van Moolenbroek 		if (r != idn_success)
900*00b67f09SDavid van Moolenbroek 			return (r);
901*00b67f09SDavid van Moolenbroek 	}
902*00b67f09SDavid van Moolenbroek 
903*00b67f09SDavid van Moolenbroek 	r = idn_delimitermap_addall(ctx->delimiter_mapper, v, nv);
904*00b67f09SDavid van Moolenbroek 	return (r);
905*00b67f09SDavid van Moolenbroek }
906*00b67f09SDavid van Moolenbroek 
907*00b67f09SDavid van Moolenbroek idn_result_t
idn_resconf_addalllocalmapselectornames(idn_resconf_t ctx,const char * tld,const char ** names,int nnames)908*00b67f09SDavid van Moolenbroek idn_resconf_addalllocalmapselectornames(idn_resconf_t ctx, const char *tld,
909*00b67f09SDavid van Moolenbroek 					const char **names, int nnames) {
910*00b67f09SDavid van Moolenbroek 	idn_result_t r;
911*00b67f09SDavid van Moolenbroek 
912*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL && names != NULL && tld != NULL);
913*00b67f09SDavid van Moolenbroek 
914*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_addalllocalmapselectorname(tld=%s, nnames=%d)\n",
915*00b67f09SDavid van Moolenbroek 	      tld, nnames));
916*00b67f09SDavid van Moolenbroek 
917*00b67f09SDavid van Moolenbroek 	if (ctx->local_mapper == NULL) {
918*00b67f09SDavid van Moolenbroek 		r = idn_mapselector_create(&(ctx->local_mapper));
919*00b67f09SDavid van Moolenbroek 		if (r != idn_success)
920*00b67f09SDavid van Moolenbroek 			return (r);
921*00b67f09SDavid van Moolenbroek 	}
922*00b67f09SDavid van Moolenbroek 
923*00b67f09SDavid van Moolenbroek 	r = idn_mapselector_addall(ctx->local_mapper, tld, names, nnames);
924*00b67f09SDavid van Moolenbroek 	return (r);
925*00b67f09SDavid van Moolenbroek }
926*00b67f09SDavid van Moolenbroek 
927*00b67f09SDavid van Moolenbroek idn_result_t
idn_resconf_addallmappernames(idn_resconf_t ctx,const char ** names,int nnames)928*00b67f09SDavid van Moolenbroek idn_resconf_addallmappernames(idn_resconf_t ctx, const char **names,
929*00b67f09SDavid van Moolenbroek 			      int nnames) {
930*00b67f09SDavid van Moolenbroek 	idn_result_t r;
931*00b67f09SDavid van Moolenbroek 
932*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL && names != NULL);
933*00b67f09SDavid van Moolenbroek 
934*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_addallmappername()\n"));
935*00b67f09SDavid van Moolenbroek 
936*00b67f09SDavid van Moolenbroek 	if (ctx->mapper == NULL) {
937*00b67f09SDavid van Moolenbroek 		r = idn_mapper_create(&(ctx->mapper));
938*00b67f09SDavid van Moolenbroek 		if (r != idn_success)
939*00b67f09SDavid van Moolenbroek 			return (r);
940*00b67f09SDavid van Moolenbroek 	}
941*00b67f09SDavid van Moolenbroek 
942*00b67f09SDavid van Moolenbroek 	r = idn_mapper_addall(ctx->mapper, names, nnames);
943*00b67f09SDavid van Moolenbroek 	return (r);
944*00b67f09SDavid van Moolenbroek }
945*00b67f09SDavid van Moolenbroek 
946*00b67f09SDavid van Moolenbroek idn_result_t
idn_resconf_addallnormalizernames(idn_resconf_t ctx,const char ** names,int nnames)947*00b67f09SDavid van Moolenbroek idn_resconf_addallnormalizernames(idn_resconf_t ctx, const char **names,
948*00b67f09SDavid van Moolenbroek 				  int nnames) {
949*00b67f09SDavid van Moolenbroek 	idn_result_t r;
950*00b67f09SDavid van Moolenbroek 
951*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL && names != NULL);
952*00b67f09SDavid van Moolenbroek 
953*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_addallnormalizername(nnames=%d)\n", nnames));
954*00b67f09SDavid van Moolenbroek 
955*00b67f09SDavid van Moolenbroek 	if (ctx->normalizer == NULL) {
956*00b67f09SDavid van Moolenbroek 		r = idn_normalizer_create(&(ctx->normalizer));
957*00b67f09SDavid van Moolenbroek 		if (r != idn_success)
958*00b67f09SDavid van Moolenbroek 			return (r);
959*00b67f09SDavid van Moolenbroek 	}
960*00b67f09SDavid van Moolenbroek 
961*00b67f09SDavid van Moolenbroek 	r = idn_normalizer_addall(ctx->normalizer, names, nnames);
962*00b67f09SDavid van Moolenbroek 	return (r);
963*00b67f09SDavid van Moolenbroek }
964*00b67f09SDavid van Moolenbroek 
965*00b67f09SDavid van Moolenbroek idn_result_t
idn_resconf_addallprohibitcheckernames(idn_resconf_t ctx,const char ** names,int nnames)966*00b67f09SDavid van Moolenbroek idn_resconf_addallprohibitcheckernames(idn_resconf_t ctx, const char **names,
967*00b67f09SDavid van Moolenbroek 				       int nnames) {
968*00b67f09SDavid van Moolenbroek 	char long_name[MAX_CONF_LINE_LENGTH + 1];
969*00b67f09SDavid van Moolenbroek 	idn_result_t r;
970*00b67f09SDavid van Moolenbroek 	int i;
971*00b67f09SDavid van Moolenbroek 
972*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL && names != NULL);
973*00b67f09SDavid van Moolenbroek 
974*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_addallprohibitcheckername(nnames=%d)\n", nnames));
975*00b67f09SDavid van Moolenbroek 
976*00b67f09SDavid van Moolenbroek 	if (ctx->prohibit_checker == NULL) {
977*00b67f09SDavid van Moolenbroek 		r = idn_checker_create(&(ctx->prohibit_checker));
978*00b67f09SDavid van Moolenbroek 		if (r != idn_success)
979*00b67f09SDavid van Moolenbroek 			return (r);
980*00b67f09SDavid van Moolenbroek 	}
981*00b67f09SDavid van Moolenbroek 
982*00b67f09SDavid van Moolenbroek 	for (i = 0; i < nnames; i++, names++) {
983*00b67f09SDavid van Moolenbroek 		if (strlen(*names) + strlen(IDN_CHECKER_PROHIBIT_PREFIX)
984*00b67f09SDavid van Moolenbroek 			> MAX_CONF_LINE_LENGTH) {
985*00b67f09SDavid van Moolenbroek 			return (idn_invalid_name);
986*00b67f09SDavid van Moolenbroek 		}
987*00b67f09SDavid van Moolenbroek 		strcpy(long_name, IDN_CHECKER_PROHIBIT_PREFIX);
988*00b67f09SDavid van Moolenbroek 		strcat(long_name, *names);
989*00b67f09SDavid van Moolenbroek 
990*00b67f09SDavid van Moolenbroek 		r = idn_checker_add(ctx->prohibit_checker, long_name);
991*00b67f09SDavid van Moolenbroek 		if (r != idn_success)
992*00b67f09SDavid van Moolenbroek 			return (r);
993*00b67f09SDavid van Moolenbroek 	}
994*00b67f09SDavid van Moolenbroek 
995*00b67f09SDavid van Moolenbroek 	return (idn_success);
996*00b67f09SDavid van Moolenbroek }
997*00b67f09SDavid van Moolenbroek 
998*00b67f09SDavid van Moolenbroek idn_result_t
idn_resconf_addallunassignedcheckernames(idn_resconf_t ctx,const char ** names,int nnames)999*00b67f09SDavid van Moolenbroek idn_resconf_addallunassignedcheckernames(idn_resconf_t ctx, const char **names,
1000*00b67f09SDavid van Moolenbroek 					 int nnames) {
1001*00b67f09SDavid van Moolenbroek 	char long_name[MAX_CONF_LINE_LENGTH + 1];
1002*00b67f09SDavid van Moolenbroek 	idn_result_t r;
1003*00b67f09SDavid van Moolenbroek 	int i;
1004*00b67f09SDavid van Moolenbroek 
1005*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL && names != NULL);
1006*00b67f09SDavid van Moolenbroek 
1007*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_addallunassignedcheckername(nnames=%d)\n",
1008*00b67f09SDavid van Moolenbroek 	      nnames));
1009*00b67f09SDavid van Moolenbroek 
1010*00b67f09SDavid van Moolenbroek 	if (ctx->unassigned_checker == NULL) {
1011*00b67f09SDavid van Moolenbroek 		r = idn_checker_create(&(ctx->unassigned_checker));
1012*00b67f09SDavid van Moolenbroek 		if (r != idn_success)
1013*00b67f09SDavid van Moolenbroek 			return (r);
1014*00b67f09SDavid van Moolenbroek 	}
1015*00b67f09SDavid van Moolenbroek 
1016*00b67f09SDavid van Moolenbroek 	for (i = 0; i < nnames; i++, names++) {
1017*00b67f09SDavid van Moolenbroek 		if (strlen(*names) + strlen(IDN_CHECKER_UNASSIGNED_PREFIX)
1018*00b67f09SDavid van Moolenbroek 			> MAX_CONF_LINE_LENGTH) {
1019*00b67f09SDavid van Moolenbroek 			return (idn_invalid_name);
1020*00b67f09SDavid van Moolenbroek 		}
1021*00b67f09SDavid van Moolenbroek 		strcpy(long_name, IDN_CHECKER_UNASSIGNED_PREFIX);
1022*00b67f09SDavid van Moolenbroek 		strcat(long_name, *names);
1023*00b67f09SDavid van Moolenbroek 
1024*00b67f09SDavid van Moolenbroek 		r = idn_checker_add(ctx->unassigned_checker, long_name);
1025*00b67f09SDavid van Moolenbroek 		if (r != idn_success)
1026*00b67f09SDavid van Moolenbroek 			return (r);
1027*00b67f09SDavid van Moolenbroek 	}
1028*00b67f09SDavid van Moolenbroek 
1029*00b67f09SDavid van Moolenbroek 	return (idn_success);
1030*00b67f09SDavid van Moolenbroek }
1031*00b67f09SDavid van Moolenbroek 
1032*00b67f09SDavid van Moolenbroek idn_result_t
idn_resconf_addallbidicheckernames(idn_resconf_t ctx,const char ** names,int nnames)1033*00b67f09SDavid van Moolenbroek idn_resconf_addallbidicheckernames(idn_resconf_t ctx, const char **names,
1034*00b67f09SDavid van Moolenbroek 				   int nnames) {
1035*00b67f09SDavid van Moolenbroek 	char long_name[MAX_CONF_LINE_LENGTH + 1];
1036*00b67f09SDavid van Moolenbroek 	idn_result_t r;
1037*00b67f09SDavid van Moolenbroek 	int i;
1038*00b67f09SDavid van Moolenbroek 
1039*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL && names != NULL);
1040*00b67f09SDavid van Moolenbroek 
1041*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_addallbidicheckername(nnames=%d)\n", nnames));
1042*00b67f09SDavid van Moolenbroek 
1043*00b67f09SDavid van Moolenbroek 	if (ctx->bidi_checker == NULL) {
1044*00b67f09SDavid van Moolenbroek 		r = idn_checker_create(&(ctx->bidi_checker));
1045*00b67f09SDavid van Moolenbroek 		if (r != idn_success)
1046*00b67f09SDavid van Moolenbroek 			return (r);
1047*00b67f09SDavid van Moolenbroek 	}
1048*00b67f09SDavid van Moolenbroek 
1049*00b67f09SDavid van Moolenbroek 	for (i = 0; i < nnames; i++, names++) {
1050*00b67f09SDavid van Moolenbroek 		if (strlen(*names) + strlen(IDN_CHECKER_BIDI_PREFIX)
1051*00b67f09SDavid van Moolenbroek 			> MAX_CONF_LINE_LENGTH) {
1052*00b67f09SDavid van Moolenbroek 			return (idn_invalid_name);
1053*00b67f09SDavid van Moolenbroek 		}
1054*00b67f09SDavid van Moolenbroek 		strcpy(long_name, IDN_CHECKER_BIDI_PREFIX);
1055*00b67f09SDavid van Moolenbroek 		strcat(long_name, *names);
1056*00b67f09SDavid van Moolenbroek 
1057*00b67f09SDavid van Moolenbroek 		r = idn_checker_add(ctx->bidi_checker, long_name);
1058*00b67f09SDavid van Moolenbroek 		if (r != idn_success)
1059*00b67f09SDavid van Moolenbroek 			return (r);
1060*00b67f09SDavid van Moolenbroek 	}
1061*00b67f09SDavid van Moolenbroek 
1062*00b67f09SDavid van Moolenbroek 	return (idn_success);
1063*00b67f09SDavid van Moolenbroek }
1064*00b67f09SDavid van Moolenbroek 
1065*00b67f09SDavid van Moolenbroek static idn_result_t
parse_conf(idn_resconf_t ctx,FILE * fp)1066*00b67f09SDavid van Moolenbroek parse_conf(idn_resconf_t ctx, FILE *fp) {
1067*00b67f09SDavid van Moolenbroek 	char line[MAX_CONF_LINE_LENGTH + 1];
1068*00b67f09SDavid van Moolenbroek 	int lineno = 0;
1069*00b67f09SDavid van Moolenbroek 	char *argv[3];
1070*00b67f09SDavid van Moolenbroek 	int argc;
1071*00b67f09SDavid van Moolenbroek 	idn_result_t r;
1072*00b67f09SDavid van Moolenbroek 	int conf_mask = 0;
1073*00b67f09SDavid van Moolenbroek 
1074*00b67f09SDavid van Moolenbroek 	TRACE(("parse_conf()\n"));
1075*00b67f09SDavid van Moolenbroek 
1076*00b67f09SDavid van Moolenbroek 	/*
1077*00b67f09SDavid van Moolenbroek 	 * Parse config file.  parsing of 'idn-encoding' line is
1078*00b67f09SDavid van Moolenbroek 	 * postponed because 'alias-file' line must be processed
1079*00b67f09SDavid van Moolenbroek 	 * before them.
1080*00b67f09SDavid van Moolenbroek 	 */
1081*00b67f09SDavid van Moolenbroek 	while (fgets(line, sizeof(line), fp) != NULL) {
1082*00b67f09SDavid van Moolenbroek 		char *newline;
1083*00b67f09SDavid van Moolenbroek 
1084*00b67f09SDavid van Moolenbroek 		lineno++;
1085*00b67f09SDavid van Moolenbroek 		newline = strpbrk(line, "\r\n");
1086*00b67f09SDavid van Moolenbroek 		if (newline != NULL)
1087*00b67f09SDavid van Moolenbroek 			*newline = '\0';
1088*00b67f09SDavid van Moolenbroek 		else if (fgetc(fp) != EOF) {
1089*00b67f09SDavid van Moolenbroek 			ERROR(("libidnkit: too long line \"%-.30s\", "
1090*00b67f09SDavid van Moolenbroek 			       "line %d\n", line, lineno));
1091*00b67f09SDavid van Moolenbroek 			return (idn_invalid_syntax);
1092*00b67f09SDavid van Moolenbroek 		}
1093*00b67f09SDavid van Moolenbroek 
1094*00b67f09SDavid van Moolenbroek 		argc = split_args(line, argv, 2);
1095*00b67f09SDavid van Moolenbroek 		if (argc == -1) {
1096*00b67f09SDavid van Moolenbroek 			ERROR(("libidnkit: syntax error, line %d\n", lineno));
1097*00b67f09SDavid van Moolenbroek 			return (idn_invalid_syntax);
1098*00b67f09SDavid van Moolenbroek 		} else if (argc == 0 || argv[0][0] == '#') {
1099*00b67f09SDavid van Moolenbroek 			continue;
1100*00b67f09SDavid van Moolenbroek 		} else if (argc == 1) {
1101*00b67f09SDavid van Moolenbroek 			ERROR(("libidnkit: syntax error, line %d\n", lineno));
1102*00b67f09SDavid van Moolenbroek 			return (idn_invalid_syntax);
1103*00b67f09SDavid van Moolenbroek 		}
1104*00b67f09SDavid van Moolenbroek 
1105*00b67f09SDavid van Moolenbroek 		if (strcmp(argv[0], "idn-encoding") == 0) {
1106*00b67f09SDavid van Moolenbroek 			if (conf_mask & DEFAULT_CONF_IDN_ENCODING) {
1107*00b67f09SDavid van Moolenbroek 				ERROR(("libidnkit: \"%s\" redefined, "
1108*00b67f09SDavid van Moolenbroek 				       "line %d\n", argv[0], lineno));
1109*00b67f09SDavid van Moolenbroek 				r = idn_invalid_syntax;
1110*00b67f09SDavid van Moolenbroek 			} else {
1111*00b67f09SDavid van Moolenbroek 				conf_mask |= DEFAULT_CONF_IDN_ENCODING;
1112*00b67f09SDavid van Moolenbroek 				r = parse_idn_encoding(ctx, argv[1], lineno);
1113*00b67f09SDavid van Moolenbroek 			}
1114*00b67f09SDavid van Moolenbroek 		} else if (strcmp(argv[0], "local-map") == 0) {
1115*00b67f09SDavid van Moolenbroek 			r = parse_local_map(ctx, argv[1], lineno);
1116*00b67f09SDavid van Moolenbroek 
1117*00b67f09SDavid van Moolenbroek 		} else if (strcmp(argv[0], "nameprep") == 0) {
1118*00b67f09SDavid van Moolenbroek 			if (conf_mask & DEFAULT_CONF_NAMEPREP) {
1119*00b67f09SDavid van Moolenbroek 				ERROR(("libidnkit: \"%s\" redefined, "
1120*00b67f09SDavid van Moolenbroek 				       "line %d\n", argv[0], lineno));
1121*00b67f09SDavid van Moolenbroek 				r = idn_invalid_syntax;
1122*00b67f09SDavid van Moolenbroek 			} else {
1123*00b67f09SDavid van Moolenbroek 				conf_mask |= DEFAULT_CONF_NAMEPREP;
1124*00b67f09SDavid van Moolenbroek 				r = parse_nameprep(ctx, argv[1], lineno);
1125*00b67f09SDavid van Moolenbroek 			}
1126*00b67f09SDavid van Moolenbroek 		} else if (strcmp(argv[0], "nameprep-map") == 0 ||
1127*00b67f09SDavid van Moolenbroek 			   strcmp(argv[0], "nameprep-normalize") == 0 ||
1128*00b67f09SDavid van Moolenbroek 			   strcmp(argv[0], "nameprep-prohibit") == 0 ||
1129*00b67f09SDavid van Moolenbroek 			   strcmp(argv[0], "nameprep-unassigned") == 0 ||
1130*00b67f09SDavid van Moolenbroek 			   strcmp(argv[0], "alias-file") == 0 ||
1131*00b67f09SDavid van Moolenbroek 			   strcmp(argv[0], "encoding-alias-file") == 0 ||
1132*00b67f09SDavid van Moolenbroek 			   strcmp(argv[0], "normalize") == 0 ||
1133*00b67f09SDavid van Moolenbroek 			   strcmp(argv[0], "server-encoding") == 0 ||
1134*00b67f09SDavid van Moolenbroek 		           strcmp(argv[0], "alternate-encoding") == 0 ||
1135*00b67f09SDavid van Moolenbroek 			   strcmp(argv[0], "delimiter-map") == 0) {
1136*00b67f09SDavid van Moolenbroek 			WARNING(("libidnkit: obsolete command \"%s\", line %d "
1137*00b67f09SDavid van Moolenbroek 			         "(ignored)\n", argv[0], lineno));
1138*00b67f09SDavid van Moolenbroek 			r = idn_success;
1139*00b67f09SDavid van Moolenbroek 		} else {
1140*00b67f09SDavid van Moolenbroek 			ERROR(("libidnkit: unknown command \"%-.30s\", "
1141*00b67f09SDavid van Moolenbroek 			       "line %d\n", argv[0], lineno));
1142*00b67f09SDavid van Moolenbroek 			r = idn_invalid_syntax;
1143*00b67f09SDavid van Moolenbroek 		}
1144*00b67f09SDavid van Moolenbroek 		if (r != idn_success)
1145*00b67f09SDavid van Moolenbroek 			return (r);
1146*00b67f09SDavid van Moolenbroek 	}
1147*00b67f09SDavid van Moolenbroek 
1148*00b67f09SDavid van Moolenbroek 	lineno++;
1149*00b67f09SDavid van Moolenbroek 
1150*00b67f09SDavid van Moolenbroek 	if (conf_mask != DEFAULT_CONF_ALL) {
1151*00b67f09SDavid van Moolenbroek 		return setdefaults_body(ctx, conf_mask);
1152*00b67f09SDavid van Moolenbroek 	}
1153*00b67f09SDavid van Moolenbroek 
1154*00b67f09SDavid van Moolenbroek 	return (idn_success);
1155*00b67f09SDavid van Moolenbroek }
1156*00b67f09SDavid van Moolenbroek 
1157*00b67f09SDavid van Moolenbroek static idn_result_t
parse_idn_encoding(idn_resconf_t ctx,char * args,int lineno)1158*00b67f09SDavid van Moolenbroek parse_idn_encoding(idn_resconf_t ctx, char *args, int lineno) {
1159*00b67f09SDavid van Moolenbroek 	idn_result_t r;
1160*00b67f09SDavid van Moolenbroek 	char *argv[MAX_CONF_LINE_ARGS + 1];
1161*00b67f09SDavid van Moolenbroek 	int argc;
1162*00b67f09SDavid van Moolenbroek 
1163*00b67f09SDavid van Moolenbroek 	argc = split_args(args, argv, MAX_CONF_LINE_ARGS + 1);
1164*00b67f09SDavid van Moolenbroek 
1165*00b67f09SDavid van Moolenbroek 	if (argc != 1) {
1166*00b67f09SDavid van Moolenbroek 		ERROR(("libidnkit: wrong # of args for idn-encoding, "
1167*00b67f09SDavid van Moolenbroek 		       "line %d\n", lineno));
1168*00b67f09SDavid van Moolenbroek 		return (idn_invalid_syntax);
1169*00b67f09SDavid van Moolenbroek 	}
1170*00b67f09SDavid van Moolenbroek 
1171*00b67f09SDavid van Moolenbroek 	r = idn_converter_create(argv[0], &ctx->idn_converter,
1172*00b67f09SDavid van Moolenbroek 				 IDN_CONVERTER_DELAYEDOPEN |
1173*00b67f09SDavid van Moolenbroek 				 IDN_CONVERTER_RTCHECK);
1174*00b67f09SDavid van Moolenbroek 	if (r != idn_success) {
1175*00b67f09SDavid van Moolenbroek 		ERROR(("libidnkit: cannot create idn converter, %s, "
1176*00b67f09SDavid van Moolenbroek 		       "line %d\n", idn_result_tostring(r), lineno));
1177*00b67f09SDavid van Moolenbroek 	}
1178*00b67f09SDavid van Moolenbroek 
1179*00b67f09SDavid van Moolenbroek 	return (r);
1180*00b67f09SDavid van Moolenbroek }
1181*00b67f09SDavid van Moolenbroek 
1182*00b67f09SDavid van Moolenbroek static idn_result_t
parse_local_map(idn_resconf_t ctx,char * args,int lineno)1183*00b67f09SDavid van Moolenbroek parse_local_map(idn_resconf_t ctx, char *args, int lineno) {
1184*00b67f09SDavid van Moolenbroek 	idn_result_t r;
1185*00b67f09SDavid van Moolenbroek 	char *argv[MAX_CONF_LINE_ARGS + 1];
1186*00b67f09SDavid van Moolenbroek 	int argc;
1187*00b67f09SDavid van Moolenbroek 	int i;
1188*00b67f09SDavid van Moolenbroek 
1189*00b67f09SDavid van Moolenbroek 	argc = split_args(args, argv, MAX_CONF_LINE_ARGS + 1);
1190*00b67f09SDavid van Moolenbroek 
1191*00b67f09SDavid van Moolenbroek 	if (argc < 2 || argc > MAX_CONF_LINE_ARGS) {
1192*00b67f09SDavid van Moolenbroek 		ERROR(("libidnkit: wrong # of args for local-map, line %d\n",
1193*00b67f09SDavid van Moolenbroek 		       lineno));
1194*00b67f09SDavid van Moolenbroek 		return (idn_invalid_syntax);
1195*00b67f09SDavid van Moolenbroek 	}
1196*00b67f09SDavid van Moolenbroek 
1197*00b67f09SDavid van Moolenbroek 	if (ctx->local_mapper == NULL) {
1198*00b67f09SDavid van Moolenbroek 		r = idn_mapselector_create(&ctx->local_mapper);
1199*00b67f09SDavid van Moolenbroek 		if (r != idn_success) {
1200*00b67f09SDavid van Moolenbroek 			ERROR(("libidnkit: cannot create local mapper, %s, "
1201*00b67f09SDavid van Moolenbroek 			       "line %d\n", idn_result_tostring(r), lineno));
1202*00b67f09SDavid van Moolenbroek 			return (r);
1203*00b67f09SDavid van Moolenbroek 		}
1204*00b67f09SDavid van Moolenbroek 	}
1205*00b67f09SDavid van Moolenbroek 
1206*00b67f09SDavid van Moolenbroek 	for (i = 1; i < argc; i++) {
1207*00b67f09SDavid van Moolenbroek 		r = idn_mapselector_add(ctx->local_mapper, argv[0], argv[i]);
1208*00b67f09SDavid van Moolenbroek 		if (r == idn_invalid_name) {
1209*00b67f09SDavid van Moolenbroek 			ERROR(("libidnkit: map scheme unavailable \"%-.30s\""
1210*00b67f09SDavid van Moolenbroek 			       " or invalid TLD \"%-.30s\", line %d\n",
1211*00b67f09SDavid van Moolenbroek 			       argv[i], argv[0], lineno));
1212*00b67f09SDavid van Moolenbroek 			return (r);
1213*00b67f09SDavid van Moolenbroek 		} else if (r != idn_success) {
1214*00b67f09SDavid van Moolenbroek 			return (r);
1215*00b67f09SDavid van Moolenbroek 		}
1216*00b67f09SDavid van Moolenbroek 	}
1217*00b67f09SDavid van Moolenbroek 
1218*00b67f09SDavid van Moolenbroek 	return (idn_success);
1219*00b67f09SDavid van Moolenbroek }
1220*00b67f09SDavid van Moolenbroek 
1221*00b67f09SDavid van Moolenbroek static idn_result_t
parse_nameprep(idn_resconf_t ctx,char * args,int lineno)1222*00b67f09SDavid van Moolenbroek parse_nameprep(idn_resconf_t ctx, char *args, int lineno) {
1223*00b67f09SDavid van Moolenbroek 	idn_result_t r;
1224*00b67f09SDavid van Moolenbroek 	char *argv[MAX_CONF_LINE_ARGS + 1];
1225*00b67f09SDavid van Moolenbroek 	char scheme_name[MAX_CONF_LINE_LENGTH + 1];
1226*00b67f09SDavid van Moolenbroek 	int argc;
1227*00b67f09SDavid van Moolenbroek 
1228*00b67f09SDavid van Moolenbroek 	argc = split_args(args, argv, MAX_CONF_LINE_ARGS + 1);
1229*00b67f09SDavid van Moolenbroek 
1230*00b67f09SDavid van Moolenbroek 	if (argc != 1) {
1231*00b67f09SDavid van Moolenbroek 		ERROR(("libidnkit: wrong # of args for nameprep, line %d\n",
1232*00b67f09SDavid van Moolenbroek 		       lineno));
1233*00b67f09SDavid van Moolenbroek 		return (idn_invalid_syntax);
1234*00b67f09SDavid van Moolenbroek 	}
1235*00b67f09SDavid van Moolenbroek 
1236*00b67f09SDavid van Moolenbroek 	/*
1237*00b67f09SDavid van Moolenbroek 	 * Set mapper.
1238*00b67f09SDavid van Moolenbroek 	 */
1239*00b67f09SDavid van Moolenbroek 	r = idn_mapper_create(&ctx->mapper);
1240*00b67f09SDavid van Moolenbroek 	if (r != idn_success) {
1241*00b67f09SDavid van Moolenbroek 		ERROR(("libidnkit: cannot create mapper, %s, line %d\n",
1242*00b67f09SDavid van Moolenbroek 		       idn_result_tostring(r), lineno));
1243*00b67f09SDavid van Moolenbroek 		return (r);
1244*00b67f09SDavid van Moolenbroek 	}
1245*00b67f09SDavid van Moolenbroek 
1246*00b67f09SDavid van Moolenbroek 	r = idn_mapper_add(ctx->mapper, argv[0]);
1247*00b67f09SDavid van Moolenbroek 	if (r == idn_invalid_name) {
1248*00b67f09SDavid van Moolenbroek 		ERROR(("libidnkit: map scheme unavailable \"%-.30s\", "
1249*00b67f09SDavid van Moolenbroek 		       "line %d\n", argv[0], lineno));
1250*00b67f09SDavid van Moolenbroek 		return (r);
1251*00b67f09SDavid van Moolenbroek 	} else if (r != idn_success) {
1252*00b67f09SDavid van Moolenbroek 		return (r);
1253*00b67f09SDavid van Moolenbroek 	}
1254*00b67f09SDavid van Moolenbroek 
1255*00b67f09SDavid van Moolenbroek 	/*
1256*00b67f09SDavid van Moolenbroek 	 * Set normalizer.
1257*00b67f09SDavid van Moolenbroek 	 */
1258*00b67f09SDavid van Moolenbroek 	r = idn_normalizer_create(&ctx->normalizer);
1259*00b67f09SDavid van Moolenbroek 	if (r != idn_success) {
1260*00b67f09SDavid van Moolenbroek 		ERROR(("libidnkit: cannot create normalizer, %s, line %d\n",
1261*00b67f09SDavid van Moolenbroek 		       idn_result_tostring(r), lineno));
1262*00b67f09SDavid van Moolenbroek 		return (r);
1263*00b67f09SDavid van Moolenbroek 	}
1264*00b67f09SDavid van Moolenbroek 
1265*00b67f09SDavid van Moolenbroek 	r = idn_normalizer_add(ctx->normalizer, argv[0]);
1266*00b67f09SDavid van Moolenbroek 	if (r == idn_invalid_name) {
1267*00b67f09SDavid van Moolenbroek 		ERROR(("libidnkit: unknown normalization scheme \"%-.30s\", "
1268*00b67f09SDavid van Moolenbroek 		       "line %d\n", argv[0], lineno));
1269*00b67f09SDavid van Moolenbroek 		return (r);
1270*00b67f09SDavid van Moolenbroek 	} else if (r != idn_success) {
1271*00b67f09SDavid van Moolenbroek 		return (r);
1272*00b67f09SDavid van Moolenbroek 	}
1273*00b67f09SDavid van Moolenbroek 
1274*00b67f09SDavid van Moolenbroek 	/*
1275*00b67f09SDavid van Moolenbroek 	 * Set prohibit checker.
1276*00b67f09SDavid van Moolenbroek 	 */
1277*00b67f09SDavid van Moolenbroek 	r = idn_checker_create(&ctx->prohibit_checker);
1278*00b67f09SDavid van Moolenbroek 	if (r != idn_success) {
1279*00b67f09SDavid van Moolenbroek 		ERROR(("libidnkit: cannot create prohibit checker, %s, "
1280*00b67f09SDavid van Moolenbroek 		       "line %d\n", idn_result_tostring(r), lineno));
1281*00b67f09SDavid van Moolenbroek 		return (r);
1282*00b67f09SDavid van Moolenbroek 	}
1283*00b67f09SDavid van Moolenbroek 
1284*00b67f09SDavid van Moolenbroek 	sprintf(scheme_name, "%s%s", IDN_CHECKER_PROHIBIT_PREFIX, argv[0]);
1285*00b67f09SDavid van Moolenbroek 	r = idn_checker_add(ctx->prohibit_checker, scheme_name);
1286*00b67f09SDavid van Moolenbroek 	if (r == idn_invalid_name) {
1287*00b67f09SDavid van Moolenbroek 		ERROR(("libidnkit: unknown prohibit scheme \"%-.30s\", "
1288*00b67f09SDavid van Moolenbroek 		       "line %d\n", argv[0], lineno));
1289*00b67f09SDavid van Moolenbroek 		return (r);
1290*00b67f09SDavid van Moolenbroek 	} else if (r != idn_success) {
1291*00b67f09SDavid van Moolenbroek 		return (r);
1292*00b67f09SDavid van Moolenbroek 	}
1293*00b67f09SDavid van Moolenbroek 
1294*00b67f09SDavid van Moolenbroek 	/*
1295*00b67f09SDavid van Moolenbroek 	 * Set unassigned checker.
1296*00b67f09SDavid van Moolenbroek 	 */
1297*00b67f09SDavid van Moolenbroek 	r = idn_checker_create(&ctx->unassigned_checker);
1298*00b67f09SDavid van Moolenbroek 	if (r != idn_success) {
1299*00b67f09SDavid van Moolenbroek 		ERROR(("libidnkit: cannot create unassigned checker, %s, "
1300*00b67f09SDavid van Moolenbroek 		       "line %d\n", idn_result_tostring(r), lineno));
1301*00b67f09SDavid van Moolenbroek 		return (r);
1302*00b67f09SDavid van Moolenbroek 	}
1303*00b67f09SDavid van Moolenbroek 
1304*00b67f09SDavid van Moolenbroek 	sprintf(scheme_name, "%s%s", IDN_CHECKER_UNASSIGNED_PREFIX, argv[0]);
1305*00b67f09SDavid van Moolenbroek 	r = idn_checker_add(ctx->unassigned_checker, scheme_name);
1306*00b67f09SDavid van Moolenbroek 	if (r == idn_invalid_name) {
1307*00b67f09SDavid van Moolenbroek 		ERROR(("libidnkit: unknown unassigned scheme \"%-.30s\", "
1308*00b67f09SDavid van Moolenbroek 		       "line %d\n", argv[0], lineno));
1309*00b67f09SDavid van Moolenbroek 		return (r);
1310*00b67f09SDavid van Moolenbroek 	} else if (r != idn_success) {
1311*00b67f09SDavid van Moolenbroek 		return (r);
1312*00b67f09SDavid van Moolenbroek 	}
1313*00b67f09SDavid van Moolenbroek 
1314*00b67f09SDavid van Moolenbroek 	/*
1315*00b67f09SDavid van Moolenbroek 	 * Set bidi checker.
1316*00b67f09SDavid van Moolenbroek 	 */
1317*00b67f09SDavid van Moolenbroek 	r = idn_checker_create(&ctx->bidi_checker);
1318*00b67f09SDavid van Moolenbroek 	if (r != idn_success) {
1319*00b67f09SDavid van Moolenbroek 		ERROR(("libidnkit: cannot create bidi checker, %s, line %d\n",
1320*00b67f09SDavid van Moolenbroek 		       idn_result_tostring(r), lineno));
1321*00b67f09SDavid van Moolenbroek 		return (r);
1322*00b67f09SDavid van Moolenbroek 	}
1323*00b67f09SDavid van Moolenbroek 
1324*00b67f09SDavid van Moolenbroek 	sprintf(scheme_name, "%s%s", IDN_CHECKER_BIDI_PREFIX, argv[0]);
1325*00b67f09SDavid van Moolenbroek 	r = idn_checker_add(ctx->bidi_checker, scheme_name);
1326*00b67f09SDavid van Moolenbroek 	if (r == idn_invalid_name) {
1327*00b67f09SDavid van Moolenbroek 		ERROR(("libidnkit: unknown bidi scheme \"%-.30s\", "
1328*00b67f09SDavid van Moolenbroek 		       "line %d\n", argv[0], lineno));
1329*00b67f09SDavid van Moolenbroek 		return (r);
1330*00b67f09SDavid van Moolenbroek 	} else if (r != idn_success) {
1331*00b67f09SDavid van Moolenbroek 		return (r);
1332*00b67f09SDavid van Moolenbroek 	}
1333*00b67f09SDavid van Moolenbroek 
1334*00b67f09SDavid van Moolenbroek 	return (idn_success);
1335*00b67f09SDavid van Moolenbroek }
1336*00b67f09SDavid van Moolenbroek 
1337*00b67f09SDavid van Moolenbroek static int
split_args(char * s,char ** av,int max_ac)1338*00b67f09SDavid van Moolenbroek split_args(char *s, char **av, int max_ac) {
1339*00b67f09SDavid van Moolenbroek 	int ac;
1340*00b67f09SDavid van Moolenbroek 	int i;
1341*00b67f09SDavid van Moolenbroek 
1342*00b67f09SDavid van Moolenbroek 	for (ac = 0; *s != '\0' && ac < max_ac; ac++) {
1343*00b67f09SDavid van Moolenbroek 		if (ac > 0)
1344*00b67f09SDavid van Moolenbroek 			*s++ = '\0';
1345*00b67f09SDavid van Moolenbroek 		while (isspace((unsigned char)*s))
1346*00b67f09SDavid van Moolenbroek 			s++;
1347*00b67f09SDavid van Moolenbroek 		if (*s == '\0')
1348*00b67f09SDavid van Moolenbroek 			break;
1349*00b67f09SDavid van Moolenbroek 		if (*s == '"' || *s == '\'') {
1350*00b67f09SDavid van Moolenbroek 			int qc = *s++;
1351*00b67f09SDavid van Moolenbroek 			av[ac] = s;
1352*00b67f09SDavid van Moolenbroek 			while (*s != qc) {
1353*00b67f09SDavid van Moolenbroek 				if (*s == '\0')
1354*00b67f09SDavid van Moolenbroek 					return (-1);
1355*00b67f09SDavid van Moolenbroek 				s++;
1356*00b67f09SDavid van Moolenbroek 			}
1357*00b67f09SDavid van Moolenbroek 		} else {
1358*00b67f09SDavid van Moolenbroek 			av[ac] = s;
1359*00b67f09SDavid van Moolenbroek 			while (*s != '\0' && !isspace((unsigned char)*s))
1360*00b67f09SDavid van Moolenbroek 				s++;
1361*00b67f09SDavid van Moolenbroek 		}
1362*00b67f09SDavid van Moolenbroek 	}
1363*00b67f09SDavid van Moolenbroek 
1364*00b67f09SDavid van Moolenbroek 	for (i = ac; i < max_ac; i++)
1365*00b67f09SDavid van Moolenbroek 		av[i] = NULL;
1366*00b67f09SDavid van Moolenbroek 
1367*00b67f09SDavid van Moolenbroek 	return (ac);
1368*00b67f09SDavid van Moolenbroek }
1369*00b67f09SDavid van Moolenbroek 
1370*00b67f09SDavid van Moolenbroek static void
resetconf(idn_resconf_t ctx)1371*00b67f09SDavid van Moolenbroek resetconf(idn_resconf_t ctx) {
1372*00b67f09SDavid van Moolenbroek #ifndef WITHOUT_ICONV
1373*00b67f09SDavid van Moolenbroek 	idn_resconf_setlocalconverter(ctx, NULL);
1374*00b67f09SDavid van Moolenbroek #endif
1375*00b67f09SDavid van Moolenbroek 	idn_resconf_setidnconverter(ctx, NULL);
1376*00b67f09SDavid van Moolenbroek 	idn_resconf_setauxidnconverter(ctx, NULL);
1377*00b67f09SDavid van Moolenbroek 	idn_resconf_setdelimitermap(ctx, NULL);
1378*00b67f09SDavid van Moolenbroek 	idn_resconf_setlocalmapselector(ctx, NULL);
1379*00b67f09SDavid van Moolenbroek 	idn_resconf_setmapper(ctx, NULL);
1380*00b67f09SDavid van Moolenbroek 	idn_resconf_setnormalizer(ctx, NULL);
1381*00b67f09SDavid van Moolenbroek 	idn_resconf_setprohibitchecker(ctx, NULL);
1382*00b67f09SDavid van Moolenbroek 	idn_resconf_setunassignedchecker(ctx, NULL);
1383*00b67f09SDavid van Moolenbroek 	idn_resconf_setbidichecker(ctx, NULL);
1384*00b67f09SDavid van Moolenbroek }
1385*00b67f09SDavid van Moolenbroek 
1386*00b67f09SDavid van Moolenbroek #ifndef WITHOUT_ICONV
1387*00b67f09SDavid van Moolenbroek static idn_result_t
update_local_converter(idn_resconf_t ctx)1388*00b67f09SDavid van Moolenbroek update_local_converter(idn_resconf_t ctx) {
1389*00b67f09SDavid van Moolenbroek 	idn_result_t r;
1390*00b67f09SDavid van Moolenbroek 	const char *old_encoding;
1391*00b67f09SDavid van Moolenbroek 	const char *new_encoding;
1392*00b67f09SDavid van Moolenbroek 
1393*00b67f09SDavid van Moolenbroek 	/*
1394*00b67f09SDavid van Moolenbroek 	 * We don't update local converter, if the converter is set
1395*00b67f09SDavid van Moolenbroek 	 * by idn_resconf_setlocalconverter() or
1396*00b67f09SDavid van Moolenbroek 	 * idn_resconf_setlocalconvertername().
1397*00b67f09SDavid van Moolenbroek 	 */
1398*00b67f09SDavid van Moolenbroek 	if (ctx->local_converter_is_static)
1399*00b67f09SDavid van Moolenbroek 		return (idn_success);
1400*00b67f09SDavid van Moolenbroek 
1401*00b67f09SDavid van Moolenbroek 	/*
1402*00b67f09SDavid van Moolenbroek 	 * Update the local converter if the local encoding is changed.
1403*00b67f09SDavid van Moolenbroek 	 */
1404*00b67f09SDavid van Moolenbroek 	old_encoding = (ctx->local_converter != NULL) ?
1405*00b67f09SDavid van Moolenbroek 		       idn_converter_localencoding(ctx->local_converter) :
1406*00b67f09SDavid van Moolenbroek 		       NULL;
1407*00b67f09SDavid van Moolenbroek 	new_encoding = idn_localencoding_name();
1408*00b67f09SDavid van Moolenbroek 	if (new_encoding == NULL) {
1409*00b67f09SDavid van Moolenbroek 		ERROR(("cannot determine local codeset name\n"));
1410*00b67f09SDavid van Moolenbroek 		return (idn_notfound);
1411*00b67f09SDavid van Moolenbroek 	}
1412*00b67f09SDavid van Moolenbroek 
1413*00b67f09SDavid van Moolenbroek 	if (old_encoding != NULL &&
1414*00b67f09SDavid van Moolenbroek 	    new_encoding != NULL &&
1415*00b67f09SDavid van Moolenbroek 	    strcmp(old_encoding, new_encoding) == 0) {
1416*00b67f09SDavid van Moolenbroek 		return (idn_success);
1417*00b67f09SDavid van Moolenbroek 	}
1418*00b67f09SDavid van Moolenbroek 
1419*00b67f09SDavid van Moolenbroek 	if (ctx->local_converter != NULL) {
1420*00b67f09SDavid van Moolenbroek 		idn_converter_destroy(ctx->local_converter);
1421*00b67f09SDavid van Moolenbroek 		ctx->local_converter = NULL;
1422*00b67f09SDavid van Moolenbroek 	}
1423*00b67f09SDavid van Moolenbroek 
1424*00b67f09SDavid van Moolenbroek 	r = idn_converter_create(new_encoding,
1425*00b67f09SDavid van Moolenbroek 				 &ctx->local_converter,
1426*00b67f09SDavid van Moolenbroek 				 IDN_CONVERTER_RTCHECK);
1427*00b67f09SDavid van Moolenbroek 	return (r);
1428*00b67f09SDavid van Moolenbroek }
1429*00b67f09SDavid van Moolenbroek #endif
1430*00b67f09SDavid van Moolenbroek 
1431*00b67f09SDavid van Moolenbroek idn_result_t
idn_resconf_setdefaults(idn_resconf_t ctx)1432*00b67f09SDavid van Moolenbroek idn_resconf_setdefaults(idn_resconf_t ctx)
1433*00b67f09SDavid van Moolenbroek {
1434*00b67f09SDavid van Moolenbroek 	idn_result_t r;
1435*00b67f09SDavid van Moolenbroek 
1436*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
1437*00b67f09SDavid van Moolenbroek 
1438*00b67f09SDavid van Moolenbroek 	TRACE(("idn_resconf_setdefaults()\n"));
1439*00b67f09SDavid van Moolenbroek 
1440*00b67f09SDavid van Moolenbroek 	resetconf(ctx);
1441*00b67f09SDavid van Moolenbroek 	r = idn_delimitermap_create(&ctx->delimiter_mapper);
1442*00b67f09SDavid van Moolenbroek 	if (r != idn_success) {
1443*00b67f09SDavid van Moolenbroek 		ERROR(("libidnkit: cannot create delimiter mapper, %s\n",
1444*00b67f09SDavid van Moolenbroek 		       idn_result_tostring(r)));
1445*00b67f09SDavid van Moolenbroek 		return (r);
1446*00b67f09SDavid van Moolenbroek 	}
1447*00b67f09SDavid van Moolenbroek 
1448*00b67f09SDavid van Moolenbroek 	return setdefaults_body(ctx, 0);
1449*00b67f09SDavid van Moolenbroek }
1450*00b67f09SDavid van Moolenbroek 
1451*00b67f09SDavid van Moolenbroek static idn_result_t
setdefaults_body(idn_resconf_t ctx,int conf_mask)1452*00b67f09SDavid van Moolenbroek setdefaults_body(idn_resconf_t ctx, int conf_mask) {
1453*00b67f09SDavid van Moolenbroek 	idn_result_t r;
1454*00b67f09SDavid van Moolenbroek 
1455*00b67f09SDavid van Moolenbroek 	TRACE(("setdefaults_body()\n"));
1456*00b67f09SDavid van Moolenbroek 	assert(ctx != NULL);
1457*00b67f09SDavid van Moolenbroek 
1458*00b67f09SDavid van Moolenbroek 	if (!(conf_mask & DEFAULT_CONF_NAMEPREP)) {
1459*00b67f09SDavid van Moolenbroek 		TRACE(("set default nameprep\n"));
1460*00b67f09SDavid van Moolenbroek 		r = idn_resconf_setnameprepversion(ctx, IDN_NAMEPREP_CURRENT);
1461*00b67f09SDavid van Moolenbroek 		if (r != idn_success) {
1462*00b67f09SDavid van Moolenbroek 			return (r);
1463*00b67f09SDavid van Moolenbroek 		}
1464*00b67f09SDavid van Moolenbroek 	}
1465*00b67f09SDavid van Moolenbroek 	if (!(conf_mask & DEFAULT_CONF_IDN_ENCODING)) {
1466*00b67f09SDavid van Moolenbroek 		TRACE(("set default idn encoding\n"));
1467*00b67f09SDavid van Moolenbroek 		r = idn_converter_create(IDN_ENCODING_CURRENT,
1468*00b67f09SDavid van Moolenbroek 					 &ctx->idn_converter,
1469*00b67f09SDavid van Moolenbroek 					 IDN_CONVERTER_DELAYEDOPEN |
1470*00b67f09SDavid van Moolenbroek 					 IDN_CONVERTER_RTCHECK);
1471*00b67f09SDavid van Moolenbroek 		if (r != idn_success) {
1472*00b67f09SDavid van Moolenbroek 			ERROR(("libidnkit: cannot create idn converter, %s\n",
1473*00b67f09SDavid van Moolenbroek 			       idn_result_tostring(r)));
1474*00b67f09SDavid van Moolenbroek 			return (r);
1475*00b67f09SDavid van Moolenbroek 		}
1476*00b67f09SDavid van Moolenbroek 	}
1477*00b67f09SDavid van Moolenbroek 
1478*00b67f09SDavid van Moolenbroek 	return (idn_success);
1479*00b67f09SDavid van Moolenbroek }
1480