xref: /minix3/external/bsd/bind/dist/contrib/idn/idnkit-1.0-src/tools/idnconv/util.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: util.c,v 1.4 2014/12/10 04:37:56 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek #ifndef lint
4*00b67f09SDavid van Moolenbroek static char *rcsid = "Id: util.c,v 1.1 2003/06/04 00:27:08 marka Exp ";
5*00b67f09SDavid van Moolenbroek #endif
6*00b67f09SDavid van Moolenbroek 
7*00b67f09SDavid van Moolenbroek /*
8*00b67f09SDavid van Moolenbroek  * Copyright (c) 2000,2002 Japan Network Information Center.
9*00b67f09SDavid van Moolenbroek  * All rights reserved.
10*00b67f09SDavid van Moolenbroek  *
11*00b67f09SDavid van Moolenbroek  * By using this file, you agree to the terms and conditions set forth bellow.
12*00b67f09SDavid van Moolenbroek  *
13*00b67f09SDavid van Moolenbroek  * 			LICENSE TERMS AND CONDITIONS
14*00b67f09SDavid van Moolenbroek  *
15*00b67f09SDavid van Moolenbroek  * The following License Terms and Conditions apply, unless a different
16*00b67f09SDavid van Moolenbroek  * license is obtained from Japan Network Information Center ("JPNIC"),
17*00b67f09SDavid van Moolenbroek  * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
18*00b67f09SDavid van Moolenbroek  * Chiyoda-ku, Tokyo 101-0047, Japan.
19*00b67f09SDavid van Moolenbroek  *
20*00b67f09SDavid van Moolenbroek  * 1. Use, Modification and Redistribution (including distribution of any
21*00b67f09SDavid van Moolenbroek  *    modified or derived work) in source and/or binary forms is permitted
22*00b67f09SDavid van Moolenbroek  *    under this License Terms and Conditions.
23*00b67f09SDavid van Moolenbroek  *
24*00b67f09SDavid van Moolenbroek  * 2. Redistribution of source code must retain the copyright notices as they
25*00b67f09SDavid van Moolenbroek  *    appear in each source code file, this License Terms and Conditions.
26*00b67f09SDavid van Moolenbroek  *
27*00b67f09SDavid van Moolenbroek  * 3. Redistribution in binary form must reproduce the Copyright Notice,
28*00b67f09SDavid van Moolenbroek  *    this License Terms and Conditions, in the documentation and/or other
29*00b67f09SDavid van Moolenbroek  *    materials provided with the distribution.  For the purposes of binary
30*00b67f09SDavid van Moolenbroek  *    distribution the "Copyright Notice" refers to the following language:
31*00b67f09SDavid van Moolenbroek  *    "Copyright (c) 2000-2002 Japan Network Information Center.  All rights reserved."
32*00b67f09SDavid van Moolenbroek  *
33*00b67f09SDavid van Moolenbroek  * 4. The name of JPNIC may not be used to endorse or promote products
34*00b67f09SDavid van Moolenbroek  *    derived from this Software without specific prior written approval of
35*00b67f09SDavid van Moolenbroek  *    JPNIC.
36*00b67f09SDavid van Moolenbroek  *
37*00b67f09SDavid van Moolenbroek  * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
38*00b67f09SDavid van Moolenbroek  *    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
39*00b67f09SDavid van Moolenbroek  *    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
40*00b67f09SDavid van Moolenbroek  *    PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL JPNIC BE LIABLE
41*00b67f09SDavid van Moolenbroek  *    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42*00b67f09SDavid van Moolenbroek  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
43*00b67f09SDavid van Moolenbroek  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
44*00b67f09SDavid van Moolenbroek  *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
45*00b67f09SDavid van Moolenbroek  *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
46*00b67f09SDavid van Moolenbroek  *    OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
47*00b67f09SDavid van Moolenbroek  *    ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
48*00b67f09SDavid van Moolenbroek  */
49*00b67f09SDavid van Moolenbroek 
50*00b67f09SDavid van Moolenbroek #include <config.h>
51*00b67f09SDavid van Moolenbroek 
52*00b67f09SDavid van Moolenbroek #include <stdio.h>
53*00b67f09SDavid van Moolenbroek #include <stddef.h>
54*00b67f09SDavid van Moolenbroek #include <stdlib.h>
55*00b67f09SDavid van Moolenbroek #include <stdarg.h>
56*00b67f09SDavid van Moolenbroek #include <string.h>
57*00b67f09SDavid van Moolenbroek #include <ctype.h>
58*00b67f09SDavid van Moolenbroek #include <errno.h>
59*00b67f09SDavid van Moolenbroek 
60*00b67f09SDavid van Moolenbroek #include <idn/resconf.h>
61*00b67f09SDavid van Moolenbroek #include <idn/converter.h>
62*00b67f09SDavid van Moolenbroek #include <idn/res.h>
63*00b67f09SDavid van Moolenbroek #include <idn/utf8.h>
64*00b67f09SDavid van Moolenbroek 
65*00b67f09SDavid van Moolenbroek #include "util.h"
66*00b67f09SDavid van Moolenbroek #include "selectiveencode.h"
67*00b67f09SDavid van Moolenbroek 
68*00b67f09SDavid van Moolenbroek extern int		line_number;
69*00b67f09SDavid van Moolenbroek 
70*00b67f09SDavid van Moolenbroek idn_result_t
selective_encode(idn_resconf_t conf,idn_action_t actions,char * from,char * to,int tolen)71*00b67f09SDavid van Moolenbroek selective_encode(idn_resconf_t conf, idn_action_t actions,
72*00b67f09SDavid van Moolenbroek 		 char *from, char *to, int tolen)
73*00b67f09SDavid van Moolenbroek {
74*00b67f09SDavid van Moolenbroek 	for (;;) {
75*00b67f09SDavid van Moolenbroek 		int len;
76*00b67f09SDavid van Moolenbroek 		char *region_start, *region_end;
77*00b67f09SDavid van Moolenbroek 		idn_result_t r;
78*00b67f09SDavid van Moolenbroek 		char save;
79*00b67f09SDavid van Moolenbroek 
80*00b67f09SDavid van Moolenbroek 		/*
81*00b67f09SDavid van Moolenbroek 		 * Find the region that needs conversion.
82*00b67f09SDavid van Moolenbroek 		 */
83*00b67f09SDavid van Moolenbroek 		r = idn_selectiveencode_findregion(from, &region_start,
84*00b67f09SDavid van Moolenbroek 						   &region_end);
85*00b67f09SDavid van Moolenbroek 		if (r == idn_notfound) {
86*00b67f09SDavid van Moolenbroek 			/*
87*00b67f09SDavid van Moolenbroek 			 * Not found.  Just copy the whole thing.
88*00b67f09SDavid van Moolenbroek 			 */
89*00b67f09SDavid van Moolenbroek 			if (tolen <= strlen(from))
90*00b67f09SDavid van Moolenbroek 				return (idn_buffer_overflow);
91*00b67f09SDavid van Moolenbroek 			(void)strcpy(to, from);
92*00b67f09SDavid van Moolenbroek 			return (idn_success);
93*00b67f09SDavid van Moolenbroek 		} else if (r != idn_success) {
94*00b67f09SDavid van Moolenbroek 			/* This should not happen.. */
95*00b67f09SDavid van Moolenbroek 			errormsg("internal error at line %d: %s\n",
96*00b67f09SDavid van Moolenbroek 				 line_number, idn_result_tostring(r));
97*00b67f09SDavid van Moolenbroek 			return (r);
98*00b67f09SDavid van Moolenbroek 		}
99*00b67f09SDavid van Moolenbroek 
100*00b67f09SDavid van Moolenbroek 		/*
101*00b67f09SDavid van Moolenbroek 		 * We have found a region to convert.
102*00b67f09SDavid van Moolenbroek 		 * First, copy the prefix part verbatim.
103*00b67f09SDavid van Moolenbroek 		 */
104*00b67f09SDavid van Moolenbroek 		len = region_start - from;
105*00b67f09SDavid van Moolenbroek 		if (tolen < len) {
106*00b67f09SDavid van Moolenbroek 			errormsg("internal buffer overflow at line %d\n",
107*00b67f09SDavid van Moolenbroek 				 line_number);
108*00b67f09SDavid van Moolenbroek 			return (idn_buffer_overflow);
109*00b67f09SDavid van Moolenbroek 		}
110*00b67f09SDavid van Moolenbroek 		(void)memcpy(to, from, len);
111*00b67f09SDavid van Moolenbroek 		to += len;
112*00b67f09SDavid van Moolenbroek 		tolen -= len;
113*00b67f09SDavid van Moolenbroek 
114*00b67f09SDavid van Moolenbroek 		/*
115*00b67f09SDavid van Moolenbroek 		 * Terminate the region with NUL.
116*00b67f09SDavid van Moolenbroek 		 */
117*00b67f09SDavid van Moolenbroek 		save = *region_end;
118*00b67f09SDavid van Moolenbroek 		*region_end = '\0';
119*00b67f09SDavid van Moolenbroek 
120*00b67f09SDavid van Moolenbroek 		/*
121*00b67f09SDavid van Moolenbroek 		 * Encode the region.
122*00b67f09SDavid van Moolenbroek 		 */
123*00b67f09SDavid van Moolenbroek 		r = idn_res_encodename(conf, actions, region_start, to, tolen);
124*00b67f09SDavid van Moolenbroek 
125*00b67f09SDavid van Moolenbroek 		/*
126*00b67f09SDavid van Moolenbroek 		 * Restore character.
127*00b67f09SDavid van Moolenbroek 		 */
128*00b67f09SDavid van Moolenbroek 		*region_end = save;
129*00b67f09SDavid van Moolenbroek 
130*00b67f09SDavid van Moolenbroek 		if (r != idn_success)
131*00b67f09SDavid van Moolenbroek 			return (r);
132*00b67f09SDavid van Moolenbroek 
133*00b67f09SDavid van Moolenbroek 		len = strlen(to);
134*00b67f09SDavid van Moolenbroek 		to += len;
135*00b67f09SDavid van Moolenbroek 		tolen -= len;
136*00b67f09SDavid van Moolenbroek 
137*00b67f09SDavid van Moolenbroek 		from = region_end;
138*00b67f09SDavid van Moolenbroek 	}
139*00b67f09SDavid van Moolenbroek }
140*00b67f09SDavid van Moolenbroek 
141*00b67f09SDavid van Moolenbroek idn_result_t
selective_decode(idn_resconf_t conf,idn_action_t actions,char * from,char * to,int tolen)142*00b67f09SDavid van Moolenbroek selective_decode(idn_resconf_t conf, idn_action_t actions,
143*00b67f09SDavid van Moolenbroek 		 char *from, char *to, int tolen)
144*00b67f09SDavid van Moolenbroek {
145*00b67f09SDavid van Moolenbroek 	char *domain_name;
146*00b67f09SDavid van Moolenbroek 	char *ignored_chunk;
147*00b67f09SDavid van Moolenbroek 	char save;
148*00b67f09SDavid van Moolenbroek 	int len;
149*00b67f09SDavid van Moolenbroek 	idn_result_t r;
150*00b67f09SDavid van Moolenbroek 
151*00b67f09SDavid van Moolenbroek 	/*
152*00b67f09SDavid van Moolenbroek 	 * While `*from' points to a character in a string which may be
153*00b67f09SDavid van Moolenbroek 	 * a domain name, `domain_name' refers to the beginning of the
154*00b67f09SDavid van Moolenbroek 	 * domain name.
155*00b67f09SDavid van Moolenbroek 	 */
156*00b67f09SDavid van Moolenbroek 	domain_name = NULL;
157*00b67f09SDavid van Moolenbroek 
158*00b67f09SDavid van Moolenbroek 	/*
159*00b67f09SDavid van Moolenbroek 	 * We ignore chunks matching to the regular expression:
160*00b67f09SDavid van Moolenbroek 	 *    [\-\.][0-9A-Za-z\-\.]*
161*00b67f09SDavid van Moolenbroek 	 *
162*00b67f09SDavid van Moolenbroek 	 * While `*from' points to a character in such a chunk,
163*00b67f09SDavid van Moolenbroek 	 * `ignored_chunk' refers to the beginning of the chunk.
164*00b67f09SDavid van Moolenbroek 	 */
165*00b67f09SDavid van Moolenbroek 	ignored_chunk = NULL;
166*00b67f09SDavid van Moolenbroek 
167*00b67f09SDavid van Moolenbroek 	for (;;) {
168*00b67f09SDavid van Moolenbroek 		if (*from == '-') {
169*00b67f09SDavid van Moolenbroek 			/*
170*00b67f09SDavid van Moolenbroek 			 * We don't recognize `.-' as a part of domain name.
171*00b67f09SDavid van Moolenbroek 			 */
172*00b67f09SDavid van Moolenbroek 			if (domain_name != NULL) {
173*00b67f09SDavid van Moolenbroek 				if (*(from - 1) == '.') {
174*00b67f09SDavid van Moolenbroek 					ignored_chunk = domain_name;
175*00b67f09SDavid van Moolenbroek 					domain_name = NULL;
176*00b67f09SDavid van Moolenbroek 				}
177*00b67f09SDavid van Moolenbroek 			} else if (ignored_chunk == NULL) {
178*00b67f09SDavid van Moolenbroek 				ignored_chunk = from;
179*00b67f09SDavid van Moolenbroek 			}
180*00b67f09SDavid van Moolenbroek 
181*00b67f09SDavid van Moolenbroek 		} else if (*from == '.') {
182*00b67f09SDavid van Moolenbroek 			/*
183*00b67f09SDavid van Moolenbroek 			 * We don't recognize `-.' nor `..' as a part of
184*00b67f09SDavid van Moolenbroek 			 * domain name.
185*00b67f09SDavid van Moolenbroek 			 */
186*00b67f09SDavid van Moolenbroek 			if (domain_name != NULL) {
187*00b67f09SDavid van Moolenbroek 				if (*(from - 1) == '-' || *(from - 1) == '.') {
188*00b67f09SDavid van Moolenbroek 					ignored_chunk = domain_name;
189*00b67f09SDavid van Moolenbroek 					domain_name = NULL;
190*00b67f09SDavid van Moolenbroek 				}
191*00b67f09SDavid van Moolenbroek 			} else if (ignored_chunk == NULL) {
192*00b67f09SDavid van Moolenbroek 				ignored_chunk = from;
193*00b67f09SDavid van Moolenbroek 			}
194*00b67f09SDavid van Moolenbroek 
195*00b67f09SDavid van Moolenbroek 		} else if (('a' <= *from && *from <= 'z') ||
196*00b67f09SDavid van Moolenbroek 			   ('A' <= *from && *from <= 'Z') ||
197*00b67f09SDavid van Moolenbroek 			   ('0' <= *from && *from <= '9')) {
198*00b67f09SDavid van Moolenbroek 			if (ignored_chunk == NULL && domain_name == NULL)
199*00b67f09SDavid van Moolenbroek 				domain_name = from;
200*00b67f09SDavid van Moolenbroek 
201*00b67f09SDavid van Moolenbroek 		} else {
202*00b67f09SDavid van Moolenbroek 			if (ignored_chunk != NULL) {
203*00b67f09SDavid van Moolenbroek 				/*
204*00b67f09SDavid van Moolenbroek 				 * `from' reaches the end of the ignored chunk.
205*00b67f09SDavid van Moolenbroek 				 * Copy the chunk to `to'.
206*00b67f09SDavid van Moolenbroek 				 */
207*00b67f09SDavid van Moolenbroek 				len = from - ignored_chunk;
208*00b67f09SDavid van Moolenbroek 				if (tolen < len)
209*00b67f09SDavid van Moolenbroek 					return (idn_buffer_overflow);
210*00b67f09SDavid van Moolenbroek 				(void)memcpy(to, ignored_chunk, len);
211*00b67f09SDavid van Moolenbroek 				to += len;
212*00b67f09SDavid van Moolenbroek 				tolen -= len;
213*00b67f09SDavid van Moolenbroek 
214*00b67f09SDavid van Moolenbroek 			} else if (domain_name != NULL) {
215*00b67f09SDavid van Moolenbroek 				/*
216*00b67f09SDavid van Moolenbroek 				 * `from' reaches the end of the domain name.
217*00b67f09SDavid van Moolenbroek 				 * Decode the domain name, and copy the result
218*00b67f09SDavid van Moolenbroek 				 * to `to'.
219*00b67f09SDavid van Moolenbroek 				 */
220*00b67f09SDavid van Moolenbroek 				save = *from;
221*00b67f09SDavid van Moolenbroek 				*from = '\0';
222*00b67f09SDavid van Moolenbroek 				r = idn_res_decodename(conf, actions,
223*00b67f09SDavid van Moolenbroek 						       domain_name, to, tolen);
224*00b67f09SDavid van Moolenbroek 				*from = save;
225*00b67f09SDavid van Moolenbroek 
226*00b67f09SDavid van Moolenbroek 				if (r == idn_success) {
227*00b67f09SDavid van Moolenbroek 					len = strlen(to);
228*00b67f09SDavid van Moolenbroek 				} else if (r == idn_invalid_encoding) {
229*00b67f09SDavid van Moolenbroek 					len = from - domain_name;
230*00b67f09SDavid van Moolenbroek 					if (tolen < len)
231*00b67f09SDavid van Moolenbroek 						return (idn_buffer_overflow);
232*00b67f09SDavid van Moolenbroek 					(void)memcpy(to, domain_name, len);
233*00b67f09SDavid van Moolenbroek 				} else {
234*00b67f09SDavid van Moolenbroek 					return (r);
235*00b67f09SDavid van Moolenbroek 				}
236*00b67f09SDavid van Moolenbroek 				to += len;
237*00b67f09SDavid van Moolenbroek 				tolen -= len;
238*00b67f09SDavid van Moolenbroek 			}
239*00b67f09SDavid van Moolenbroek 
240*00b67f09SDavid van Moolenbroek 			/*
241*00b67f09SDavid van Moolenbroek 			 * Copy a character `*from' to `to'.
242*00b67f09SDavid van Moolenbroek 			 */
243*00b67f09SDavid van Moolenbroek 			if (tolen < 1)
244*00b67f09SDavid van Moolenbroek 				return (idn_buffer_overflow);
245*00b67f09SDavid van Moolenbroek 			*to = *from;
246*00b67f09SDavid van Moolenbroek 			to++;
247*00b67f09SDavid van Moolenbroek 			tolen--;
248*00b67f09SDavid van Moolenbroek 
249*00b67f09SDavid van Moolenbroek 			domain_name = NULL;
250*00b67f09SDavid van Moolenbroek 			ignored_chunk = NULL;
251*00b67f09SDavid van Moolenbroek 
252*00b67f09SDavid van Moolenbroek 			if (*from == '\0')
253*00b67f09SDavid van Moolenbroek 				break;
254*00b67f09SDavid van Moolenbroek 		}
255*00b67f09SDavid van Moolenbroek 
256*00b67f09SDavid van Moolenbroek 		from++;
257*00b67f09SDavid van Moolenbroek 	}
258*00b67f09SDavid van Moolenbroek 
259*00b67f09SDavid van Moolenbroek 	return (idn_success);
260*00b67f09SDavid van Moolenbroek }
261*00b67f09SDavid van Moolenbroek 
262*00b67f09SDavid van Moolenbroek void
set_defaults(idn_resconf_t conf)263*00b67f09SDavid van Moolenbroek set_defaults(idn_resconf_t conf) {
264*00b67f09SDavid van Moolenbroek 	idn_result_t r;
265*00b67f09SDavid van Moolenbroek 
266*00b67f09SDavid van Moolenbroek 	if ((r = idn_resconf_setdefaults(conf)) != idn_success) {
267*00b67f09SDavid van Moolenbroek 		errormsg("error setting default configuration: %s\n",
268*00b67f09SDavid van Moolenbroek 			 idn_result_tostring(r));
269*00b67f09SDavid van Moolenbroek 		exit(1);
270*00b67f09SDavid van Moolenbroek 	}
271*00b67f09SDavid van Moolenbroek }
272*00b67f09SDavid van Moolenbroek 
273*00b67f09SDavid van Moolenbroek void
load_conf_file(idn_resconf_t conf,const char * file)274*00b67f09SDavid van Moolenbroek load_conf_file(idn_resconf_t conf, const char *file) {
275*00b67f09SDavid van Moolenbroek 	idn_result_t r;
276*00b67f09SDavid van Moolenbroek 
277*00b67f09SDavid van Moolenbroek 	if ((r = idn_resconf_loadfile(conf, file)) != idn_success) {
278*00b67f09SDavid van Moolenbroek 		errormsg("error reading configuration file: %s\n",
279*00b67f09SDavid van Moolenbroek 			 idn_result_tostring(r));
280*00b67f09SDavid van Moolenbroek 		exit(1);
281*00b67f09SDavid van Moolenbroek 	}
282*00b67f09SDavid van Moolenbroek }
283*00b67f09SDavid van Moolenbroek 
284*00b67f09SDavid van Moolenbroek void
set_encoding_alias(const char * encoding_alias)285*00b67f09SDavid van Moolenbroek set_encoding_alias(const char *encoding_alias) {
286*00b67f09SDavid van Moolenbroek 	idn_result_t r;
287*00b67f09SDavid van Moolenbroek 
288*00b67f09SDavid van Moolenbroek 	if ((r = idn_converter_resetalias()) != idn_success) {
289*00b67f09SDavid van Moolenbroek 		errormsg("cannot reset alias information: %s\n",
290*00b67f09SDavid van Moolenbroek 			 idn_result_tostring(r));
291*00b67f09SDavid van Moolenbroek 		exit(1);
292*00b67f09SDavid van Moolenbroek 	}
293*00b67f09SDavid van Moolenbroek 
294*00b67f09SDavid van Moolenbroek 	if ((r = idn_converter_aliasfile(encoding_alias)) != idn_success) {
295*00b67f09SDavid van Moolenbroek 		errormsg("cannot read alias file %s: %s\n",
296*00b67f09SDavid van Moolenbroek 			 encoding_alias, idn_result_tostring(r));
297*00b67f09SDavid van Moolenbroek 		exit(1);
298*00b67f09SDavid van Moolenbroek 	}
299*00b67f09SDavid van Moolenbroek }
300*00b67f09SDavid van Moolenbroek 
301*00b67f09SDavid van Moolenbroek void
set_localcode(idn_resconf_t conf,const char * code)302*00b67f09SDavid van Moolenbroek set_localcode(idn_resconf_t conf, const char *code) {
303*00b67f09SDavid van Moolenbroek 	idn_result_t r;
304*00b67f09SDavid van Moolenbroek 
305*00b67f09SDavid van Moolenbroek 	r = idn_resconf_setlocalconvertername(conf, code,
306*00b67f09SDavid van Moolenbroek 					      IDN_CONVERTER_RTCHECK);
307*00b67f09SDavid van Moolenbroek 	if (r != idn_success) {
308*00b67f09SDavid van Moolenbroek 		errormsg("cannot create converter for codeset %s: %s\n",
309*00b67f09SDavid van Moolenbroek 			 code, idn_result_tostring(r));
310*00b67f09SDavid van Moolenbroek 		exit(1);
311*00b67f09SDavid van Moolenbroek 	}
312*00b67f09SDavid van Moolenbroek }
313*00b67f09SDavid van Moolenbroek 
314*00b67f09SDavid van Moolenbroek void
set_idncode(idn_resconf_t conf,const char * code)315*00b67f09SDavid van Moolenbroek set_idncode(idn_resconf_t conf, const char *code) {
316*00b67f09SDavid van Moolenbroek 	idn_result_t r;
317*00b67f09SDavid van Moolenbroek 
318*00b67f09SDavid van Moolenbroek 	r = idn_resconf_setidnconvertername(conf, code,
319*00b67f09SDavid van Moolenbroek 					    IDN_CONVERTER_RTCHECK);
320*00b67f09SDavid van Moolenbroek 	if (r != idn_success) {
321*00b67f09SDavid van Moolenbroek 		errormsg("cannot create converter for codeset %s: %s\n",
322*00b67f09SDavid van Moolenbroek 			 code, idn_result_tostring(r));
323*00b67f09SDavid van Moolenbroek 		exit(1);
324*00b67f09SDavid van Moolenbroek 	}
325*00b67f09SDavid van Moolenbroek }
326*00b67f09SDavid van Moolenbroek 
327*00b67f09SDavid van Moolenbroek void
set_delimitermapper(idn_resconf_t conf,unsigned long * delimiters,int ndelimiters)328*00b67f09SDavid van Moolenbroek set_delimitermapper(idn_resconf_t conf, unsigned long *delimiters,
329*00b67f09SDavid van Moolenbroek 		    int ndelimiters) {
330*00b67f09SDavid van Moolenbroek 	idn_result_t r;
331*00b67f09SDavid van Moolenbroek 
332*00b67f09SDavid van Moolenbroek 	r = idn_resconf_addalldelimitermapucs(conf, delimiters, ndelimiters);
333*00b67f09SDavid van Moolenbroek 	if (r != idn_success) {
334*00b67f09SDavid van Moolenbroek 		errormsg("cannot add delimiter: %s\n",
335*00b67f09SDavid van Moolenbroek 			 idn_result_tostring(r));
336*00b67f09SDavid van Moolenbroek 		exit(1);
337*00b67f09SDavid van Moolenbroek 	}
338*00b67f09SDavid van Moolenbroek }
339*00b67f09SDavid van Moolenbroek 
340*00b67f09SDavid van Moolenbroek void
set_localmapper(idn_resconf_t conf,char ** mappers,int nmappers)341*00b67f09SDavid van Moolenbroek set_localmapper(idn_resconf_t conf, char **mappers, int nmappers) {
342*00b67f09SDavid van Moolenbroek 	idn_result_t r;
343*00b67f09SDavid van Moolenbroek 
344*00b67f09SDavid van Moolenbroek 	/* Add mapping. */
345*00b67f09SDavid van Moolenbroek 	r = idn_resconf_addalllocalmapselectornames(conf,
346*00b67f09SDavid van Moolenbroek 						    IDN_MAPSELECTOR_DEFAULTTLD,
347*00b67f09SDavid van Moolenbroek 						    (const char **)mappers,
348*00b67f09SDavid van Moolenbroek 						    nmappers);
349*00b67f09SDavid van Moolenbroek 	if (r != idn_success) {
350*00b67f09SDavid van Moolenbroek 		errormsg("cannot add local map: %s\n",
351*00b67f09SDavid van Moolenbroek 			 idn_result_tostring(r));
352*00b67f09SDavid van Moolenbroek 		exit(1);
353*00b67f09SDavid van Moolenbroek 	}
354*00b67f09SDavid van Moolenbroek }
355*00b67f09SDavid van Moolenbroek 
356*00b67f09SDavid van Moolenbroek void
set_nameprep(idn_resconf_t conf,char * version)357*00b67f09SDavid van Moolenbroek set_nameprep(idn_resconf_t conf, char *version) {
358*00b67f09SDavid van Moolenbroek 	idn_result_t r;
359*00b67f09SDavid van Moolenbroek 
360*00b67f09SDavid van Moolenbroek 	r = idn_resconf_setnameprepversion(conf, version);
361*00b67f09SDavid van Moolenbroek 	if (r != idn_success) {
362*00b67f09SDavid van Moolenbroek 		errormsg("error setting nameprep %s: %s\n",
363*00b67f09SDavid van Moolenbroek 			 version, idn_result_tostring(r));
364*00b67f09SDavid van Moolenbroek 		exit(1);
365*00b67f09SDavid van Moolenbroek 	}
366*00b67f09SDavid van Moolenbroek }
367*00b67f09SDavid van Moolenbroek 
368*00b67f09SDavid van Moolenbroek void
set_mapper(idn_resconf_t conf,char ** mappers,int nmappers)369*00b67f09SDavid van Moolenbroek set_mapper(idn_resconf_t conf, char **mappers, int nmappers) {
370*00b67f09SDavid van Moolenbroek 	idn_result_t r;
371*00b67f09SDavid van Moolenbroek 
372*00b67f09SDavid van Moolenbroek 	/* Configure mapper. */
373*00b67f09SDavid van Moolenbroek 	r = idn_resconf_addallmappernames(conf, (const char **)mappers,
374*00b67f09SDavid van Moolenbroek 					  nmappers);
375*00b67f09SDavid van Moolenbroek 	if (r != idn_success) {
376*00b67f09SDavid van Moolenbroek 		errormsg("cannot add nameprep map: %s\n",
377*00b67f09SDavid van Moolenbroek 			 idn_result_tostring(r));
378*00b67f09SDavid van Moolenbroek 		exit(1);
379*00b67f09SDavid van Moolenbroek 	}
380*00b67f09SDavid van Moolenbroek }
381*00b67f09SDavid van Moolenbroek 
382*00b67f09SDavid van Moolenbroek void
set_normalizer(idn_resconf_t conf,char ** normalizers,int nnormalizer)383*00b67f09SDavid van Moolenbroek set_normalizer(idn_resconf_t conf, char **normalizers, int nnormalizer) {
384*00b67f09SDavid van Moolenbroek 	idn_result_t r;
385*00b67f09SDavid van Moolenbroek 
386*00b67f09SDavid van Moolenbroek 	r = idn_resconf_addallnormalizernames(conf,
387*00b67f09SDavid van Moolenbroek 					      (const char **)normalizers,
388*00b67f09SDavid van Moolenbroek 					      nnormalizer);
389*00b67f09SDavid van Moolenbroek 	if (r != idn_success) {
390*00b67f09SDavid van Moolenbroek 		errormsg("cannot add normalizer: %s\n",
391*00b67f09SDavid van Moolenbroek 			 idn_result_tostring(r));
392*00b67f09SDavid van Moolenbroek 		exit(1);
393*00b67f09SDavid van Moolenbroek 	}
394*00b67f09SDavid van Moolenbroek }
395*00b67f09SDavid van Moolenbroek 
396*00b67f09SDavid van Moolenbroek void
set_prohibit_checkers(idn_resconf_t conf,char ** prohibits,int nprohibits)397*00b67f09SDavid van Moolenbroek set_prohibit_checkers(idn_resconf_t conf, char **prohibits, int nprohibits) {
398*00b67f09SDavid van Moolenbroek 	idn_result_t r;
399*00b67f09SDavid van Moolenbroek 
400*00b67f09SDavid van Moolenbroek 	r = idn_resconf_addallprohibitcheckernames(conf,
401*00b67f09SDavid van Moolenbroek 						   (const char **)prohibits,
402*00b67f09SDavid van Moolenbroek 						   nprohibits);
403*00b67f09SDavid van Moolenbroek 	if (r != idn_success) {
404*00b67f09SDavid van Moolenbroek 		errormsg("cannot add prohibit checker: %s\n",
405*00b67f09SDavid van Moolenbroek 			 idn_result_tostring(r));
406*00b67f09SDavid van Moolenbroek 		exit(1);
407*00b67f09SDavid van Moolenbroek 	}
408*00b67f09SDavid van Moolenbroek }
409*00b67f09SDavid van Moolenbroek 
410*00b67f09SDavid van Moolenbroek void
set_unassigned_checkers(idn_resconf_t conf,char ** unassigns,int nunassigns)411*00b67f09SDavid van Moolenbroek set_unassigned_checkers(idn_resconf_t conf, char **unassigns, int nunassigns) {
412*00b67f09SDavid van Moolenbroek 	idn_result_t r;
413*00b67f09SDavid van Moolenbroek 
414*00b67f09SDavid van Moolenbroek 	r = idn_resconf_addallunassignedcheckernames(conf,
415*00b67f09SDavid van Moolenbroek 						     (const char **)unassigns,
416*00b67f09SDavid van Moolenbroek 						     nunassigns);
417*00b67f09SDavid van Moolenbroek 	if (r != idn_success) {
418*00b67f09SDavid van Moolenbroek 		errormsg("cannot add unassigned checker: %s\n",
419*00b67f09SDavid van Moolenbroek 			 idn_result_tostring(r));
420*00b67f09SDavid van Moolenbroek 		exit(1);
421*00b67f09SDavid van Moolenbroek 	}
422*00b67f09SDavid van Moolenbroek }
423*00b67f09SDavid van Moolenbroek 
424*00b67f09SDavid van Moolenbroek void
errormsg(const char * fmt,...)425*00b67f09SDavid van Moolenbroek errormsg(const char *fmt, ...) {
426*00b67f09SDavid van Moolenbroek 	va_list args;
427*00b67f09SDavid van Moolenbroek 
428*00b67f09SDavid van Moolenbroek 	va_start(args, fmt);
429*00b67f09SDavid van Moolenbroek 	vfprintf(stderr, fmt, args);
430*00b67f09SDavid van Moolenbroek 	va_end(args);
431*00b67f09SDavid van Moolenbroek }
432*00b67f09SDavid van Moolenbroek 
433*00b67f09SDavid van Moolenbroek 
434*00b67f09SDavid van Moolenbroek /*
435*00b67f09SDavid van Moolenbroek  * Dynamic Stirng Buffer Utility
436*00b67f09SDavid van Moolenbroek  */
437*00b67f09SDavid van Moolenbroek 
438*00b67f09SDavid van Moolenbroek void
strbuf_init(idnconv_strbuf_t * buf)439*00b67f09SDavid van Moolenbroek strbuf_init(idnconv_strbuf_t *buf) {
440*00b67f09SDavid van Moolenbroek 	/*
441*00b67f09SDavid van Moolenbroek 	 * Initialize the given string buffer.
442*00b67f09SDavid van Moolenbroek 	 * Caller must allocate the structure (idnconv_strbuf_t)
443*00b67f09SDavid van Moolenbroek 	 * as an automatic variable or by malloc().
444*00b67f09SDavid van Moolenbroek 	 */
445*00b67f09SDavid van Moolenbroek 	buf->str = buf->local_buf;
446*00b67f09SDavid van Moolenbroek 	buf->str[0] = '\0';
447*00b67f09SDavid van Moolenbroek 	buf->size = sizeof(buf->local_buf);
448*00b67f09SDavid van Moolenbroek }
449*00b67f09SDavid van Moolenbroek 
450*00b67f09SDavid van Moolenbroek void
strbuf_reset(idnconv_strbuf_t * buf)451*00b67f09SDavid van Moolenbroek strbuf_reset(idnconv_strbuf_t *buf) {
452*00b67f09SDavid van Moolenbroek 	/*
453*00b67f09SDavid van Moolenbroek 	 * Reset the given string buffer.
454*00b67f09SDavid van Moolenbroek 	 * Free memory allocated by this utility, and
455*00b67f09SDavid van Moolenbroek 	 * re-initialize.
456*00b67f09SDavid van Moolenbroek 	 */
457*00b67f09SDavid van Moolenbroek 	if (buf->str != NULL && buf->str != buf->local_buf) {
458*00b67f09SDavid van Moolenbroek 		free(buf->str);
459*00b67f09SDavid van Moolenbroek 	}
460*00b67f09SDavid van Moolenbroek 	strbuf_init(buf);
461*00b67f09SDavid van Moolenbroek }
462*00b67f09SDavid van Moolenbroek 
463*00b67f09SDavid van Moolenbroek char *
strbuf_get(idnconv_strbuf_t * buf)464*00b67f09SDavid van Moolenbroek strbuf_get(idnconv_strbuf_t *buf) {
465*00b67f09SDavid van Moolenbroek 	/*
466*00b67f09SDavid van Moolenbroek 	 * Get the pointer of the buffer.
467*00b67f09SDavid van Moolenbroek 	 */
468*00b67f09SDavid van Moolenbroek 	return (buf->str);
469*00b67f09SDavid van Moolenbroek }
470*00b67f09SDavid van Moolenbroek 
471*00b67f09SDavid van Moolenbroek size_t
strbuf_size(idnconv_strbuf_t * buf)472*00b67f09SDavid van Moolenbroek strbuf_size(idnconv_strbuf_t *buf) {
473*00b67f09SDavid van Moolenbroek 	/*
474*00b67f09SDavid van Moolenbroek 	 * Get the allocated size of the buffer.
475*00b67f09SDavid van Moolenbroek 	 */
476*00b67f09SDavid van Moolenbroek 	return (buf->size);
477*00b67f09SDavid van Moolenbroek }
478*00b67f09SDavid van Moolenbroek 
479*00b67f09SDavid van Moolenbroek char *
strbuf_copy(idnconv_strbuf_t * buf,const char * str)480*00b67f09SDavid van Moolenbroek strbuf_copy(idnconv_strbuf_t *buf, const char *str) {
481*00b67f09SDavid van Moolenbroek 	/*
482*00b67f09SDavid van Moolenbroek 	 * Copy STR to BUF.
483*00b67f09SDavid van Moolenbroek 	 */
484*00b67f09SDavid van Moolenbroek 	size_t	len = strlen(str);
485*00b67f09SDavid van Moolenbroek 
486*00b67f09SDavid van Moolenbroek 	if (strbuf_alloc(buf, len + 1) == NULL)
487*00b67f09SDavid van Moolenbroek 		return (NULL);
488*00b67f09SDavid van Moolenbroek 	strcpy(buf->str, str);
489*00b67f09SDavid van Moolenbroek 	return (buf->str);
490*00b67f09SDavid van Moolenbroek }
491*00b67f09SDavid van Moolenbroek 
492*00b67f09SDavid van Moolenbroek char *
strbuf_append(idnconv_strbuf_t * buf,const char * str)493*00b67f09SDavid van Moolenbroek strbuf_append(idnconv_strbuf_t *buf, const char *str) {
494*00b67f09SDavid van Moolenbroek 	/*
495*00b67f09SDavid van Moolenbroek 	 * Append STR to the end of BUF.
496*00b67f09SDavid van Moolenbroek 	 */
497*00b67f09SDavid van Moolenbroek 	size_t	len1 = strlen(buf->str);
498*00b67f09SDavid van Moolenbroek 	size_t	len2 = strlen(str);
499*00b67f09SDavid van Moolenbroek 	char *p;
500*00b67f09SDavid van Moolenbroek #define MARGIN	50
501*00b67f09SDavid van Moolenbroek 
502*00b67f09SDavid van Moolenbroek 	p = strbuf_alloc(buf, len1 + len2 + 1 + MARGIN);
503*00b67f09SDavid van Moolenbroek 	if (p != NULL)
504*00b67f09SDavid van Moolenbroek 		strcpy(buf->str + len1, str);
505*00b67f09SDavid van Moolenbroek 	return (p);
506*00b67f09SDavid van Moolenbroek }
507*00b67f09SDavid van Moolenbroek 
508*00b67f09SDavid van Moolenbroek char *
strbuf_alloc(idnconv_strbuf_t * buf,size_t size)509*00b67f09SDavid van Moolenbroek strbuf_alloc(idnconv_strbuf_t *buf, size_t size) {
510*00b67f09SDavid van Moolenbroek 	/*
511*00b67f09SDavid van Moolenbroek 	 * Reallocate the buffer of BUF if needed
512*00b67f09SDavid van Moolenbroek 	 * so that BUF can hold SIZE bytes of data at least.
513*00b67f09SDavid van Moolenbroek 	 */
514*00b67f09SDavid van Moolenbroek 	char *p;
515*00b67f09SDavid van Moolenbroek 
516*00b67f09SDavid van Moolenbroek 	if (buf->size >= size)
517*00b67f09SDavid van Moolenbroek 		return (buf->str);
518*00b67f09SDavid van Moolenbroek 	if (buf->str == buf->local_buf) {
519*00b67f09SDavid van Moolenbroek 		if ((p = malloc(size)) == NULL)
520*00b67f09SDavid van Moolenbroek 			return (NULL);
521*00b67f09SDavid van Moolenbroek 		memcpy(p, buf->local_buf, sizeof(buf->local_buf));
522*00b67f09SDavid van Moolenbroek 	} else {
523*00b67f09SDavid van Moolenbroek 		if ((p = realloc(buf->str, size)) == NULL)
524*00b67f09SDavid van Moolenbroek 			return (NULL);
525*00b67f09SDavid van Moolenbroek 	}
526*00b67f09SDavid van Moolenbroek 	buf->str = p;
527*00b67f09SDavid van Moolenbroek 	buf->size = size;
528*00b67f09SDavid van Moolenbroek 	return (buf->str);
529*00b67f09SDavid van Moolenbroek }
530*00b67f09SDavid van Moolenbroek 
531*00b67f09SDavid van Moolenbroek char *
strbuf_double(idnconv_strbuf_t * buf)532*00b67f09SDavid van Moolenbroek strbuf_double(idnconv_strbuf_t *buf) {
533*00b67f09SDavid van Moolenbroek 	/*
534*00b67f09SDavid van Moolenbroek 	 * Double the size of the buffer of BUF.
535*00b67f09SDavid van Moolenbroek 	 */
536*00b67f09SDavid van Moolenbroek 	return (strbuf_alloc(buf, buf->size * 2));
537*00b67f09SDavid van Moolenbroek }
538*00b67f09SDavid van Moolenbroek 
539*00b67f09SDavid van Moolenbroek char *
strbuf_getline(idnconv_strbuf_t * buf,FILE * fp)540*00b67f09SDavid van Moolenbroek strbuf_getline(idnconv_strbuf_t *buf, FILE *fp) {
541*00b67f09SDavid van Moolenbroek 	/*
542*00b67f09SDavid van Moolenbroek 	 * Read a line from FP.
543*00b67f09SDavid van Moolenbroek 	 */
544*00b67f09SDavid van Moolenbroek 	char s[256];
545*00b67f09SDavid van Moolenbroek 
546*00b67f09SDavid van Moolenbroek 	buf->str[0] = '\0';
547*00b67f09SDavid van Moolenbroek 	while (fgets(s, sizeof(s), fp) != NULL) {
548*00b67f09SDavid van Moolenbroek 		if (strbuf_append(buf, s) == NULL)
549*00b67f09SDavid van Moolenbroek 			return (NULL);
550*00b67f09SDavid van Moolenbroek 		if (strlen(s) < sizeof(s) - 1 || s[sizeof(s) - 2] == '\n')
551*00b67f09SDavid van Moolenbroek 			return (buf->str);
552*00b67f09SDavid van Moolenbroek 	}
553*00b67f09SDavid van Moolenbroek 	if (buf->str[0] != '\0')
554*00b67f09SDavid van Moolenbroek 		return (buf->str);
555*00b67f09SDavid van Moolenbroek 	return (NULL);
556*00b67f09SDavid van Moolenbroek }
557