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, ®ion_start,
84*00b67f09SDavid van Moolenbroek ®ion_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