1*00b67f09SDavid van Moolenbroek /* $NetBSD: res.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: res.c,v 1.1 2003/06/04 00:26:10 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 <stddef.h>
53*00b67f09SDavid van Moolenbroek #include <stdlib.h>
54*00b67f09SDavid van Moolenbroek #include <string.h>
55*00b67f09SDavid van Moolenbroek
56*00b67f09SDavid van Moolenbroek #include <idn/result.h>
57*00b67f09SDavid van Moolenbroek #include <idn/assert.h>
58*00b67f09SDavid van Moolenbroek #include <idn/logmacro.h>
59*00b67f09SDavid van Moolenbroek #include <idn/converter.h>
60*00b67f09SDavid van Moolenbroek #include <idn/normalizer.h>
61*00b67f09SDavid van Moolenbroek #include <idn/checker.h>
62*00b67f09SDavid van Moolenbroek #include <idn/mapper.h>
63*00b67f09SDavid van Moolenbroek #include <idn/mapselector.h>
64*00b67f09SDavid van Moolenbroek #include <idn/delimitermap.h>
65*00b67f09SDavid van Moolenbroek #include <idn/resconf.h>
66*00b67f09SDavid van Moolenbroek #include <idn/res.h>
67*00b67f09SDavid van Moolenbroek #include <idn/util.h>
68*00b67f09SDavid van Moolenbroek #include <idn/debug.h>
69*00b67f09SDavid van Moolenbroek #include <idn/ucs4.h>
70*00b67f09SDavid van Moolenbroek
71*00b67f09SDavid van Moolenbroek #ifndef IDN_UTF8_ENCODING_NAME
72*00b67f09SDavid van Moolenbroek #define IDN_UTF8_ENCODING_NAME "UTF-8" /* by IANA */
73*00b67f09SDavid van Moolenbroek #endif
74*00b67f09SDavid van Moolenbroek
75*00b67f09SDavid van Moolenbroek #ifndef WITHOUT_ICONV
76*00b67f09SDavid van Moolenbroek #define ENCODE_MASK \
77*00b67f09SDavid van Moolenbroek (IDN_LOCALCONV | IDN_DELIMMAP | IDN_LOCALMAP | IDN_MAP | \
78*00b67f09SDavid van Moolenbroek IDN_NORMALIZE | IDN_PROHCHECK | IDN_UNASCHECK | IDN_BIDICHECK | \
79*00b67f09SDavid van Moolenbroek IDN_ASCCHECK | IDN_IDNCONV | IDN_LENCHECK | IDN_ENCODE_QUERY | \
80*00b67f09SDavid van Moolenbroek IDN_UNDOIFERR)
81*00b67f09SDavid van Moolenbroek #define DECODE_MASK \
82*00b67f09SDavid van Moolenbroek (IDN_DELIMMAP | IDN_MAP | IDN_NORMALIZE | IDN_PROHCHECK | \
83*00b67f09SDavid van Moolenbroek IDN_UNASCHECK | IDN_BIDICHECK | IDN_IDNCONV | IDN_ASCCHECK | \
84*00b67f09SDavid van Moolenbroek IDN_RTCHECK | IDN_LOCALCONV | IDN_DECODE_QUERY)
85*00b67f09SDavid van Moolenbroek #else
86*00b67f09SDavid van Moolenbroek #define ENCODE_MASK \
87*00b67f09SDavid van Moolenbroek (IDN_DELIMMAP | IDN_LOCALMAP | IDN_MAP | IDN_NORMALIZE | \
88*00b67f09SDavid van Moolenbroek IDN_PROHCHECK | IDN_UNASCHECK | IDN_BIDICHECK | IDN_ASCCHECK | \
89*00b67f09SDavid van Moolenbroek IDN_IDNCONV | IDN_LENCHECK | IDN_ENCODE_QUERY | IDN_UNDOIFERR)
90*00b67f09SDavid van Moolenbroek #define DECODE_MASK \
91*00b67f09SDavid van Moolenbroek (IDN_DELIMMAP | IDN_MAP | IDN_NORMALIZE | IDN_PROHCHECK | \
92*00b67f09SDavid van Moolenbroek IDN_UNASCHECK | IDN_BIDICHECK | IDN_IDNCONV | IDN_ASCCHECK | \
93*00b67f09SDavid van Moolenbroek IDN_RTCHECK | IDN_DECODE_QUERY)
94*00b67f09SDavid van Moolenbroek #endif
95*00b67f09SDavid van Moolenbroek
96*00b67f09SDavid van Moolenbroek #define MAX_LABEL_LENGTH 63
97*00b67f09SDavid van Moolenbroek
98*00b67f09SDavid van Moolenbroek /*
99*00b67f09SDavid van Moolenbroek * label to convert.
100*00b67f09SDavid van Moolenbroek */
101*00b67f09SDavid van Moolenbroek typedef struct labellist * labellist_t;
102*00b67f09SDavid van Moolenbroek struct labellist {
103*00b67f09SDavid van Moolenbroek unsigned long *name;
104*00b67f09SDavid van Moolenbroek size_t name_length;
105*00b67f09SDavid van Moolenbroek unsigned long *undo_name;
106*00b67f09SDavid van Moolenbroek labellist_t next;
107*00b67f09SDavid van Moolenbroek labellist_t previous;
108*00b67f09SDavid van Moolenbroek int dot_followed;
109*00b67f09SDavid van Moolenbroek };
110*00b67f09SDavid van Moolenbroek
111*00b67f09SDavid van Moolenbroek typedef idn_result_t (*res_insnproc_t)(idn_resconf_t ctx,
112*00b67f09SDavid van Moolenbroek labellist_t label);
113*00b67f09SDavid van Moolenbroek
114*00b67f09SDavid van Moolenbroek static void idn_res_initialize(void);
115*00b67f09SDavid van Moolenbroek static idn_result_t copy_verbatim(const char *from, char *to,
116*00b67f09SDavid van Moolenbroek size_t tolen);
117*00b67f09SDavid van Moolenbroek static idn_result_t labellist_create(const unsigned long *name,
118*00b67f09SDavid van Moolenbroek labellist_t *labelp);
119*00b67f09SDavid van Moolenbroek static void labellist_destroy(labellist_t label);
120*00b67f09SDavid van Moolenbroek static idn_result_t labellist_setname(labellist_t label,
121*00b67f09SDavid van Moolenbroek const unsigned long *name);
122*00b67f09SDavid van Moolenbroek static const unsigned long *
123*00b67f09SDavid van Moolenbroek labellist_getname(labellist_t label);
124*00b67f09SDavid van Moolenbroek static const unsigned long *
125*00b67f09SDavid van Moolenbroek labellist_gettldname(labellist_t label);
126*00b67f09SDavid van Moolenbroek static idn_result_t labellist_getnamelist(labellist_t label,
127*00b67f09SDavid van Moolenbroek unsigned long *name,
128*00b67f09SDavid van Moolenbroek size_t label_length);
129*00b67f09SDavid van Moolenbroek static void labellist_undo(labellist_t label);
130*00b67f09SDavid van Moolenbroek static labellist_t labellist_tail(labellist_t label);
131*00b67f09SDavid van Moolenbroek static labellist_t labellist_previous(labellist_t label);
132*00b67f09SDavid van Moolenbroek
133*00b67f09SDavid van Moolenbroek #ifndef WITHOUT_ICONV
134*00b67f09SDavid van Moolenbroek static idn_result_t label_localdecodecheck(idn_resconf_t ctx,
135*00b67f09SDavid van Moolenbroek labellist_t label);
136*00b67f09SDavid van Moolenbroek #endif
137*00b67f09SDavid van Moolenbroek static idn_result_t label_idnencode_ace(idn_resconf_t ctx,
138*00b67f09SDavid van Moolenbroek labellist_t label);
139*00b67f09SDavid van Moolenbroek static idn_result_t label_idndecode(idn_resconf_t ctx, labellist_t label);
140*00b67f09SDavid van Moolenbroek static idn_result_t label_localmap(idn_resconf_t ctx, labellist_t label);
141*00b67f09SDavid van Moolenbroek static idn_result_t label_map(idn_resconf_t ctx, labellist_t label);
142*00b67f09SDavid van Moolenbroek static idn_result_t label_normalize(idn_resconf_t ctx, labellist_t label);
143*00b67f09SDavid van Moolenbroek static idn_result_t label_prohcheck(idn_resconf_t ctx, labellist_t label);
144*00b67f09SDavid van Moolenbroek static idn_result_t label_unascheck(idn_resconf_t ctx, labellist_t label);
145*00b67f09SDavid van Moolenbroek static idn_result_t label_bidicheck(idn_resconf_t ctx, labellist_t label);
146*00b67f09SDavid van Moolenbroek static idn_result_t label_asccheck(idn_resconf_t ctx, labellist_t label);
147*00b67f09SDavid van Moolenbroek static idn_result_t label_lencheck_ace(idn_resconf_t ctx,
148*00b67f09SDavid van Moolenbroek labellist_t label);
149*00b67f09SDavid van Moolenbroek static idn_result_t label_lencheck_nonace(idn_resconf_t ctx,
150*00b67f09SDavid van Moolenbroek labellist_t label);
151*00b67f09SDavid van Moolenbroek static idn_result_t label_rtcheck(idn_resconf_t ctx, idn_action_t actions,
152*00b67f09SDavid van Moolenbroek labellist_t label,
153*00b67f09SDavid van Moolenbroek const unsigned long *original_name);
154*00b67f09SDavid van Moolenbroek
155*00b67f09SDavid van Moolenbroek static int initialized;
156*00b67f09SDavid van Moolenbroek static int enabled;
157*00b67f09SDavid van Moolenbroek
158*00b67f09SDavid van Moolenbroek void
idn_res_enable(int on_off)159*00b67f09SDavid van Moolenbroek idn_res_enable(int on_off) {
160*00b67f09SDavid van Moolenbroek if (!initialized) {
161*00b67f09SDavid van Moolenbroek idn_res_initialize();
162*00b67f09SDavid van Moolenbroek }
163*00b67f09SDavid van Moolenbroek
164*00b67f09SDavid van Moolenbroek if (on_off == 0) {
165*00b67f09SDavid van Moolenbroek enabled = 0;
166*00b67f09SDavid van Moolenbroek } else {
167*00b67f09SDavid van Moolenbroek enabled = 1;
168*00b67f09SDavid van Moolenbroek }
169*00b67f09SDavid van Moolenbroek }
170*00b67f09SDavid van Moolenbroek
171*00b67f09SDavid van Moolenbroek static void
idn_res_initialize(void)172*00b67f09SDavid van Moolenbroek idn_res_initialize(void) {
173*00b67f09SDavid van Moolenbroek if (!initialized) {
174*00b67f09SDavid van Moolenbroek char *value = getenv("IDN_DISABLE");
175*00b67f09SDavid van Moolenbroek
176*00b67f09SDavid van Moolenbroek if (value == NULL) {
177*00b67f09SDavid van Moolenbroek enabled = 1;
178*00b67f09SDavid van Moolenbroek } else {
179*00b67f09SDavid van Moolenbroek enabled = 0;
180*00b67f09SDavid van Moolenbroek }
181*00b67f09SDavid van Moolenbroek initialized = 1;
182*00b67f09SDavid van Moolenbroek }
183*00b67f09SDavid van Moolenbroek }
184*00b67f09SDavid van Moolenbroek
185*00b67f09SDavid van Moolenbroek idn_result_t
idn_res_encodename(idn_resconf_t ctx,idn_action_t actions,const char * from,char * to,size_t tolen)186*00b67f09SDavid van Moolenbroek idn_res_encodename(idn_resconf_t ctx, idn_action_t actions, const char *from,
187*00b67f09SDavid van Moolenbroek char *to, size_t tolen) {
188*00b67f09SDavid van Moolenbroek idn_converter_t local_converter = NULL;
189*00b67f09SDavid van Moolenbroek idn_converter_t idn_converter = NULL;
190*00b67f09SDavid van Moolenbroek idn_delimitermap_t delimiter_mapper;
191*00b67f09SDavid van Moolenbroek idn_result_t r;
192*00b67f09SDavid van Moolenbroek labellist_t labels = NULL, l;
193*00b67f09SDavid van Moolenbroek unsigned long *buffer = NULL;
194*00b67f09SDavid van Moolenbroek size_t buffer_length;
195*00b67f09SDavid van Moolenbroek int from_is_root;
196*00b67f09SDavid van Moolenbroek int idn_is_ace;
197*00b67f09SDavid van Moolenbroek
198*00b67f09SDavid van Moolenbroek assert(ctx != NULL && from != NULL && to != NULL);
199*00b67f09SDavid van Moolenbroek
200*00b67f09SDavid van Moolenbroek TRACE(("idn_res_encodename(actions=%s, from=\"%s\", tolen=%d)\n",
201*00b67f09SDavid van Moolenbroek idn__res_actionstostring(actions),
202*00b67f09SDavid van Moolenbroek idn__debug_xstring(from, 50), (int)tolen));
203*00b67f09SDavid van Moolenbroek
204*00b67f09SDavid van Moolenbroek if (actions & ~ENCODE_MASK) {
205*00b67f09SDavid van Moolenbroek WARNING(("idn_res_encodename: invalid actions 0x%x\n",
206*00b67f09SDavid van Moolenbroek actions));
207*00b67f09SDavid van Moolenbroek r = idn_invalid_action;
208*00b67f09SDavid van Moolenbroek goto ret;
209*00b67f09SDavid van Moolenbroek }
210*00b67f09SDavid van Moolenbroek
211*00b67f09SDavid van Moolenbroek if (!initialized)
212*00b67f09SDavid van Moolenbroek idn_res_initialize();
213*00b67f09SDavid van Moolenbroek if (!enabled || actions == 0) {
214*00b67f09SDavid van Moolenbroek r = copy_verbatim(from, to, tolen);
215*00b67f09SDavid van Moolenbroek goto ret;
216*00b67f09SDavid van Moolenbroek } else if (tolen <= 0) {
217*00b67f09SDavid van Moolenbroek r = idn_buffer_overflow;
218*00b67f09SDavid van Moolenbroek goto ret;
219*00b67f09SDavid van Moolenbroek }
220*00b67f09SDavid van Moolenbroek
221*00b67f09SDavid van Moolenbroek if (actions & IDN_ENCODE_QUERY) {
222*00b67f09SDavid van Moolenbroek #ifndef WITHOUT_ICONV
223*00b67f09SDavid van Moolenbroek actions |= (IDN_LOCALCONV | IDN_DELIMMAP | IDN_LOCALMAP | \
224*00b67f09SDavid van Moolenbroek IDN_MAP | IDN_NORMALIZE | IDN_PROHCHECK | \
225*00b67f09SDavid van Moolenbroek IDN_BIDICHECK | IDN_IDNCONV | IDN_LENCHECK);
226*00b67f09SDavid van Moolenbroek #else
227*00b67f09SDavid van Moolenbroek actions |= (IDN_DELIMMAP | IDN_LOCALMAP | IDN_MAP | \
228*00b67f09SDavid van Moolenbroek IDN_NORMALIZE | IDN_PROHCHECK | IDN_BIDICHECK | \
229*00b67f09SDavid van Moolenbroek IDN_IDNCONV | IDN_LENCHECK);
230*00b67f09SDavid van Moolenbroek #endif
231*00b67f09SDavid van Moolenbroek }
232*00b67f09SDavid van Moolenbroek
233*00b67f09SDavid van Moolenbroek /*
234*00b67f09SDavid van Moolenbroek * Convert `from' to UCS4.
235*00b67f09SDavid van Moolenbroek */
236*00b67f09SDavid van Moolenbroek local_converter = idn_resconf_getlocalconverter(ctx);
237*00b67f09SDavid van Moolenbroek #ifndef WITHOUT_ICONV
238*00b67f09SDavid van Moolenbroek if (local_converter == NULL) {
239*00b67f09SDavid van Moolenbroek r = idn_invalid_name;
240*00b67f09SDavid van Moolenbroek goto ret;
241*00b67f09SDavid van Moolenbroek }
242*00b67f09SDavid van Moolenbroek #endif
243*00b67f09SDavid van Moolenbroek
244*00b67f09SDavid van Moolenbroek idn_converter = idn_resconf_getidnconverter(ctx);
245*00b67f09SDavid van Moolenbroek if (idn_converter != NULL &&
246*00b67f09SDavid van Moolenbroek idn_converter_isasciicompatible(idn_converter))
247*00b67f09SDavid van Moolenbroek idn_is_ace = 1;
248*00b67f09SDavid van Moolenbroek else
249*00b67f09SDavid van Moolenbroek idn_is_ace = 0;
250*00b67f09SDavid van Moolenbroek
251*00b67f09SDavid van Moolenbroek buffer_length = tolen * 2;
252*00b67f09SDavid van Moolenbroek
253*00b67f09SDavid van Moolenbroek for (;;) {
254*00b67f09SDavid van Moolenbroek void *new_buffer;
255*00b67f09SDavid van Moolenbroek
256*00b67f09SDavid van Moolenbroek new_buffer = realloc(buffer, sizeof(*buffer) * buffer_length);
257*00b67f09SDavid van Moolenbroek if (new_buffer == NULL) {
258*00b67f09SDavid van Moolenbroek r = idn_nomemory;
259*00b67f09SDavid van Moolenbroek goto ret;
260*00b67f09SDavid van Moolenbroek }
261*00b67f09SDavid van Moolenbroek buffer = (unsigned long *)new_buffer;
262*00b67f09SDavid van Moolenbroek
263*00b67f09SDavid van Moolenbroek if (actions & IDN_LOCALCONV) {
264*00b67f09SDavid van Moolenbroek r = idn_converter_convtoucs4(local_converter, from,
265*00b67f09SDavid van Moolenbroek buffer, buffer_length);
266*00b67f09SDavid van Moolenbroek } else {
267*00b67f09SDavid van Moolenbroek r = idn_ucs4_utf8toucs4(from, buffer, buffer_length);
268*00b67f09SDavid van Moolenbroek }
269*00b67f09SDavid van Moolenbroek if (r == idn_success)
270*00b67f09SDavid van Moolenbroek break;
271*00b67f09SDavid van Moolenbroek else if (r != idn_buffer_overflow)
272*00b67f09SDavid van Moolenbroek goto ret;
273*00b67f09SDavid van Moolenbroek
274*00b67f09SDavid van Moolenbroek buffer_length *= 2;
275*00b67f09SDavid van Moolenbroek }
276*00b67f09SDavid van Moolenbroek
277*00b67f09SDavid van Moolenbroek if (*buffer == '\0') {
278*00b67f09SDavid van Moolenbroek if (tolen <= 0) {
279*00b67f09SDavid van Moolenbroek r = idn_buffer_overflow;
280*00b67f09SDavid van Moolenbroek goto ret;
281*00b67f09SDavid van Moolenbroek }
282*00b67f09SDavid van Moolenbroek *to = '\0';
283*00b67f09SDavid van Moolenbroek r = idn_success;
284*00b67f09SDavid van Moolenbroek goto ret;
285*00b67f09SDavid van Moolenbroek }
286*00b67f09SDavid van Moolenbroek
287*00b67f09SDavid van Moolenbroek /*
288*00b67f09SDavid van Moolenbroek * Delimiter map.
289*00b67f09SDavid van Moolenbroek */
290*00b67f09SDavid van Moolenbroek if (actions & IDN_DELIMMAP) {
291*00b67f09SDavid van Moolenbroek TRACE(("res delimitermap(name=\"%s\")\n",
292*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(buffer, 50)));
293*00b67f09SDavid van Moolenbroek
294*00b67f09SDavid van Moolenbroek delimiter_mapper = idn_resconf_getdelimitermap(ctx);
295*00b67f09SDavid van Moolenbroek if (delimiter_mapper != NULL) {
296*00b67f09SDavid van Moolenbroek r = idn_delimitermap_map(delimiter_mapper, buffer,
297*00b67f09SDavid van Moolenbroek buffer, buffer_length);
298*00b67f09SDavid van Moolenbroek idn_delimitermap_destroy(delimiter_mapper);
299*00b67f09SDavid van Moolenbroek if (r != idn_success)
300*00b67f09SDavid van Moolenbroek goto ret;
301*00b67f09SDavid van Moolenbroek }
302*00b67f09SDavid van Moolenbroek TRACE(("res delimitermap(): success (name=\"%s\")\n",
303*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(buffer, 50)));
304*00b67f09SDavid van Moolenbroek }
305*00b67f09SDavid van Moolenbroek
306*00b67f09SDavid van Moolenbroek from_is_root = (buffer[0] == '.' && buffer[1] == '\0');
307*00b67f09SDavid van Moolenbroek
308*00b67f09SDavid van Moolenbroek /*
309*00b67f09SDavid van Moolenbroek * Split the name into a list of labels.
310*00b67f09SDavid van Moolenbroek */
311*00b67f09SDavid van Moolenbroek r = labellist_create(buffer, &labels);
312*00b67f09SDavid van Moolenbroek if (r != idn_success)
313*00b67f09SDavid van Moolenbroek goto ret;
314*00b67f09SDavid van Moolenbroek
315*00b67f09SDavid van Moolenbroek /*
316*00b67f09SDavid van Moolenbroek * Perform conversions and tests.
317*00b67f09SDavid van Moolenbroek */
318*00b67f09SDavid van Moolenbroek for (l = labellist_tail(labels); l != NULL;
319*00b67f09SDavid van Moolenbroek l = labellist_previous(l)) {
320*00b67f09SDavid van Moolenbroek
321*00b67f09SDavid van Moolenbroek if (!idn__util_ucs4isasciirange(labellist_getname(l))) {
322*00b67f09SDavid van Moolenbroek if (actions & IDN_LOCALMAP) {
323*00b67f09SDavid van Moolenbroek r = label_localmap(ctx, l);
324*00b67f09SDavid van Moolenbroek if (r != idn_success)
325*00b67f09SDavid van Moolenbroek goto ret;
326*00b67f09SDavid van Moolenbroek }
327*00b67f09SDavid van Moolenbroek }
328*00b67f09SDavid van Moolenbroek
329*00b67f09SDavid van Moolenbroek if (!idn__util_ucs4isasciirange(labellist_getname(l))) {
330*00b67f09SDavid van Moolenbroek if (actions & IDN_MAP) {
331*00b67f09SDavid van Moolenbroek r = label_map(ctx, l);
332*00b67f09SDavid van Moolenbroek if (r != idn_success)
333*00b67f09SDavid van Moolenbroek goto ret;
334*00b67f09SDavid van Moolenbroek }
335*00b67f09SDavid van Moolenbroek if (actions & IDN_NORMALIZE) {
336*00b67f09SDavid van Moolenbroek r = label_normalize(ctx, l);
337*00b67f09SDavid van Moolenbroek if (r != idn_success)
338*00b67f09SDavid van Moolenbroek goto ret;
339*00b67f09SDavid van Moolenbroek }
340*00b67f09SDavid van Moolenbroek if (actions & IDN_PROHCHECK) {
341*00b67f09SDavid van Moolenbroek r = label_prohcheck(ctx, l);
342*00b67f09SDavid van Moolenbroek if (r == idn_prohibited &&
343*00b67f09SDavid van Moolenbroek (actions & IDN_UNDOIFERR)) {
344*00b67f09SDavid van Moolenbroek labellist_undo(l);
345*00b67f09SDavid van Moolenbroek continue;
346*00b67f09SDavid van Moolenbroek } else if (r != idn_success) {
347*00b67f09SDavid van Moolenbroek goto ret;
348*00b67f09SDavid van Moolenbroek }
349*00b67f09SDavid van Moolenbroek }
350*00b67f09SDavid van Moolenbroek if (actions & IDN_UNASCHECK) {
351*00b67f09SDavid van Moolenbroek r = label_unascheck(ctx, l);
352*00b67f09SDavid van Moolenbroek if (r == idn_prohibited &&
353*00b67f09SDavid van Moolenbroek (actions & IDN_UNDOIFERR)) {
354*00b67f09SDavid van Moolenbroek labellist_undo(l);
355*00b67f09SDavid van Moolenbroek continue;
356*00b67f09SDavid van Moolenbroek } else if (r != idn_success) {
357*00b67f09SDavid van Moolenbroek goto ret;
358*00b67f09SDavid van Moolenbroek }
359*00b67f09SDavid van Moolenbroek }
360*00b67f09SDavid van Moolenbroek if (actions & IDN_BIDICHECK) {
361*00b67f09SDavid van Moolenbroek r = label_bidicheck(ctx, l);
362*00b67f09SDavid van Moolenbroek if (r == idn_prohibited &&
363*00b67f09SDavid van Moolenbroek (actions & IDN_UNDOIFERR)) {
364*00b67f09SDavid van Moolenbroek labellist_undo(l);
365*00b67f09SDavid van Moolenbroek continue;
366*00b67f09SDavid van Moolenbroek } else if (r != idn_success) {
367*00b67f09SDavid van Moolenbroek goto ret;
368*00b67f09SDavid van Moolenbroek }
369*00b67f09SDavid van Moolenbroek }
370*00b67f09SDavid van Moolenbroek }
371*00b67f09SDavid van Moolenbroek
372*00b67f09SDavid van Moolenbroek if (actions & IDN_ASCCHECK) {
373*00b67f09SDavid van Moolenbroek r = label_asccheck(ctx, l);
374*00b67f09SDavid van Moolenbroek if (r == idn_prohibited && (actions & IDN_UNDOIFERR)) {
375*00b67f09SDavid van Moolenbroek labellist_undo(l);
376*00b67f09SDavid van Moolenbroek continue;
377*00b67f09SDavid van Moolenbroek } else if (r != idn_success) {
378*00b67f09SDavid van Moolenbroek goto ret;
379*00b67f09SDavid van Moolenbroek }
380*00b67f09SDavid van Moolenbroek }
381*00b67f09SDavid van Moolenbroek
382*00b67f09SDavid van Moolenbroek if (!idn__util_ucs4isasciirange(labellist_getname(l))) {
383*00b67f09SDavid van Moolenbroek if ((actions & IDN_IDNCONV) && idn_is_ace) {
384*00b67f09SDavid van Moolenbroek r = label_idnencode_ace(ctx, l);
385*00b67f09SDavid van Moolenbroek if (r != idn_success)
386*00b67f09SDavid van Moolenbroek goto ret;
387*00b67f09SDavid van Moolenbroek }
388*00b67f09SDavid van Moolenbroek }
389*00b67f09SDavid van Moolenbroek
390*00b67f09SDavid van Moolenbroek if (!from_is_root && (actions & IDN_LENCHECK)) {
391*00b67f09SDavid van Moolenbroek if (idn_is_ace)
392*00b67f09SDavid van Moolenbroek r = label_lencheck_ace(ctx, l);
393*00b67f09SDavid van Moolenbroek else
394*00b67f09SDavid van Moolenbroek r = label_lencheck_nonace(ctx, l);
395*00b67f09SDavid van Moolenbroek if (r == idn_invalid_length &&
396*00b67f09SDavid van Moolenbroek (actions & IDN_UNDOIFERR)) {
397*00b67f09SDavid van Moolenbroek labellist_undo(l);
398*00b67f09SDavid van Moolenbroek continue;
399*00b67f09SDavid van Moolenbroek } else if (r != idn_success) {
400*00b67f09SDavid van Moolenbroek goto ret;
401*00b67f09SDavid van Moolenbroek }
402*00b67f09SDavid van Moolenbroek }
403*00b67f09SDavid van Moolenbroek }
404*00b67f09SDavid van Moolenbroek
405*00b67f09SDavid van Moolenbroek /*
406*00b67f09SDavid van Moolenbroek * Concat a list of labels to a name.
407*00b67f09SDavid van Moolenbroek */
408*00b67f09SDavid van Moolenbroek for (;;) {
409*00b67f09SDavid van Moolenbroek void *new_buffer;
410*00b67f09SDavid van Moolenbroek
411*00b67f09SDavid van Moolenbroek new_buffer = realloc(buffer, sizeof(*buffer) * buffer_length);
412*00b67f09SDavid van Moolenbroek if (new_buffer == NULL) {
413*00b67f09SDavid van Moolenbroek r = idn_nomemory;
414*00b67f09SDavid van Moolenbroek goto ret;
415*00b67f09SDavid van Moolenbroek }
416*00b67f09SDavid van Moolenbroek buffer = (unsigned long *)new_buffer;
417*00b67f09SDavid van Moolenbroek
418*00b67f09SDavid van Moolenbroek r = labellist_getnamelist(labels, buffer, buffer_length);
419*00b67f09SDavid van Moolenbroek if (r == idn_success)
420*00b67f09SDavid van Moolenbroek break;
421*00b67f09SDavid van Moolenbroek else if (r != idn_buffer_overflow)
422*00b67f09SDavid van Moolenbroek goto ret;
423*00b67f09SDavid van Moolenbroek
424*00b67f09SDavid van Moolenbroek buffer_length *= 2;
425*00b67f09SDavid van Moolenbroek }
426*00b67f09SDavid van Moolenbroek
427*00b67f09SDavid van Moolenbroek if ((actions & IDN_IDNCONV) && idn_converter != NULL && !idn_is_ace) {
428*00b67f09SDavid van Moolenbroek r = idn_converter_convfromucs4(idn_converter, buffer, to,
429*00b67f09SDavid van Moolenbroek tolen);
430*00b67f09SDavid van Moolenbroek } else {
431*00b67f09SDavid van Moolenbroek r = idn_ucs4_ucs4toutf8(buffer, to, tolen);
432*00b67f09SDavid van Moolenbroek }
433*00b67f09SDavid van Moolenbroek
434*00b67f09SDavid van Moolenbroek ret:
435*00b67f09SDavid van Moolenbroek if (r == idn_success) {
436*00b67f09SDavid van Moolenbroek TRACE(("idn_res_encodename(): success (to=\"%s\")\n",
437*00b67f09SDavid van Moolenbroek idn__debug_xstring(to, 50)));
438*00b67f09SDavid van Moolenbroek } else {
439*00b67f09SDavid van Moolenbroek TRACE(("idn_res_encodename(): %s\n", idn_result_tostring(r)));
440*00b67f09SDavid van Moolenbroek }
441*00b67f09SDavid van Moolenbroek free(buffer);
442*00b67f09SDavid van Moolenbroek if (local_converter != NULL)
443*00b67f09SDavid van Moolenbroek idn_converter_destroy(local_converter);
444*00b67f09SDavid van Moolenbroek if (idn_converter != NULL)
445*00b67f09SDavid van Moolenbroek idn_converter_destroy(idn_converter);
446*00b67f09SDavid van Moolenbroek if (labels != NULL)
447*00b67f09SDavid van Moolenbroek labellist_destroy(labels);
448*00b67f09SDavid van Moolenbroek return (r);
449*00b67f09SDavid van Moolenbroek }
450*00b67f09SDavid van Moolenbroek
451*00b67f09SDavid van Moolenbroek idn_result_t
idn_res_decodename(idn_resconf_t ctx,idn_action_t actions,const char * from,char * to,size_t tolen)452*00b67f09SDavid van Moolenbroek idn_res_decodename(idn_resconf_t ctx, idn_action_t actions, const char *from,
453*00b67f09SDavid van Moolenbroek char *to, size_t tolen) {
454*00b67f09SDavid van Moolenbroek idn_converter_t local_converter = NULL;
455*00b67f09SDavid van Moolenbroek idn_converter_t idn_converter = NULL;
456*00b67f09SDavid van Moolenbroek idn_delimitermap_t delimiter_mapper;
457*00b67f09SDavid van Moolenbroek idn_result_t r;
458*00b67f09SDavid van Moolenbroek labellist_t labels = NULL, l;
459*00b67f09SDavid van Moolenbroek unsigned long *buffer = NULL;
460*00b67f09SDavid van Moolenbroek unsigned long *saved_name = NULL;
461*00b67f09SDavid van Moolenbroek size_t buffer_length;
462*00b67f09SDavid van Moolenbroek int idn_is_ace;
463*00b67f09SDavid van Moolenbroek
464*00b67f09SDavid van Moolenbroek assert(ctx != NULL && from != NULL && to != NULL);
465*00b67f09SDavid van Moolenbroek
466*00b67f09SDavid van Moolenbroek TRACE(("idn_res_decodename(actions=%s, from=\"%s\", tolen=%d)\n",
467*00b67f09SDavid van Moolenbroek idn__res_actionstostring(actions),
468*00b67f09SDavid van Moolenbroek idn__debug_xstring(from, 50), (int)tolen));
469*00b67f09SDavid van Moolenbroek
470*00b67f09SDavid van Moolenbroek if (actions & ~DECODE_MASK) {
471*00b67f09SDavid van Moolenbroek WARNING(("idn_res_decodename: invalid actions 0x%x\n",
472*00b67f09SDavid van Moolenbroek actions));
473*00b67f09SDavid van Moolenbroek r = idn_invalid_action;
474*00b67f09SDavid van Moolenbroek goto ret;
475*00b67f09SDavid van Moolenbroek }
476*00b67f09SDavid van Moolenbroek
477*00b67f09SDavid van Moolenbroek if (!initialized)
478*00b67f09SDavid van Moolenbroek idn_res_initialize();
479*00b67f09SDavid van Moolenbroek if (!enabled || actions == 0) {
480*00b67f09SDavid van Moolenbroek r = copy_verbatim(from, to, tolen);
481*00b67f09SDavid van Moolenbroek goto ret;
482*00b67f09SDavid van Moolenbroek } else if (tolen <= 0) {
483*00b67f09SDavid van Moolenbroek r = idn_buffer_overflow;
484*00b67f09SDavid van Moolenbroek goto ret;
485*00b67f09SDavid van Moolenbroek }
486*00b67f09SDavid van Moolenbroek
487*00b67f09SDavid van Moolenbroek if (actions & IDN_DECODE_QUERY) {
488*00b67f09SDavid van Moolenbroek #ifndef WITHOUT_ICONV
489*00b67f09SDavid van Moolenbroek actions |= (IDN_DELIMMAP | IDN_MAP | IDN_NORMALIZE | \
490*00b67f09SDavid van Moolenbroek IDN_PROHCHECK | IDN_BIDICHECK | IDN_IDNCONV | \
491*00b67f09SDavid van Moolenbroek IDN_RTCHECK | IDN_LOCALCONV);
492*00b67f09SDavid van Moolenbroek #else
493*00b67f09SDavid van Moolenbroek actions |= (IDN_DELIMMAP | IDN_MAP | IDN_NORMALIZE | \
494*00b67f09SDavid van Moolenbroek IDN_PROHCHECK | IDN_BIDICHECK | IDN_IDNCONV | \
495*00b67f09SDavid van Moolenbroek IDN_RTCHECK);
496*00b67f09SDavid van Moolenbroek #endif
497*00b67f09SDavid van Moolenbroek }
498*00b67f09SDavid van Moolenbroek
499*00b67f09SDavid van Moolenbroek /*
500*00b67f09SDavid van Moolenbroek * Convert `from' to UCS4.
501*00b67f09SDavid van Moolenbroek */
502*00b67f09SDavid van Moolenbroek local_converter = idn_resconf_getlocalconverter(ctx);
503*00b67f09SDavid van Moolenbroek #ifndef WITHOUT_ICONV
504*00b67f09SDavid van Moolenbroek if (local_converter == NULL) {
505*00b67f09SDavid van Moolenbroek r = idn_invalid_name;
506*00b67f09SDavid van Moolenbroek goto ret;
507*00b67f09SDavid van Moolenbroek }
508*00b67f09SDavid van Moolenbroek #endif
509*00b67f09SDavid van Moolenbroek
510*00b67f09SDavid van Moolenbroek idn_converter = idn_resconf_getidnconverter(ctx);
511*00b67f09SDavid van Moolenbroek if (idn_converter != NULL &&
512*00b67f09SDavid van Moolenbroek idn_converter_isasciicompatible(idn_converter))
513*00b67f09SDavid van Moolenbroek idn_is_ace = 1;
514*00b67f09SDavid van Moolenbroek else
515*00b67f09SDavid van Moolenbroek idn_is_ace = 0;
516*00b67f09SDavid van Moolenbroek
517*00b67f09SDavid van Moolenbroek buffer_length = tolen * 2;
518*00b67f09SDavid van Moolenbroek
519*00b67f09SDavid van Moolenbroek TRACE(("res idndecode(name=\"%s\")\n", idn__debug_xstring(from, 50)));
520*00b67f09SDavid van Moolenbroek
521*00b67f09SDavid van Moolenbroek for (;;) {
522*00b67f09SDavid van Moolenbroek void *new_buffer;
523*00b67f09SDavid van Moolenbroek
524*00b67f09SDavid van Moolenbroek new_buffer = realloc(buffer, sizeof(*buffer) * buffer_length);
525*00b67f09SDavid van Moolenbroek if (new_buffer == NULL) {
526*00b67f09SDavid van Moolenbroek r = idn_nomemory;
527*00b67f09SDavid van Moolenbroek goto ret;
528*00b67f09SDavid van Moolenbroek }
529*00b67f09SDavid van Moolenbroek buffer = (unsigned long *)new_buffer;
530*00b67f09SDavid van Moolenbroek
531*00b67f09SDavid van Moolenbroek if ((actions & IDN_IDNCONV) &&
532*00b67f09SDavid van Moolenbroek idn_converter != NULL && !idn_is_ace) {
533*00b67f09SDavid van Moolenbroek r = idn_converter_convtoucs4(idn_converter, from,
534*00b67f09SDavid van Moolenbroek buffer, buffer_length);
535*00b67f09SDavid van Moolenbroek } else {
536*00b67f09SDavid van Moolenbroek r = idn_ucs4_utf8toucs4(from, buffer, buffer_length);
537*00b67f09SDavid van Moolenbroek }
538*00b67f09SDavid van Moolenbroek if (r == idn_success)
539*00b67f09SDavid van Moolenbroek break;
540*00b67f09SDavid van Moolenbroek else if (r != idn_buffer_overflow)
541*00b67f09SDavid van Moolenbroek goto ret;
542*00b67f09SDavid van Moolenbroek
543*00b67f09SDavid van Moolenbroek buffer_length *= 2;
544*00b67f09SDavid van Moolenbroek }
545*00b67f09SDavid van Moolenbroek
546*00b67f09SDavid van Moolenbroek if (*buffer == '\0') {
547*00b67f09SDavid van Moolenbroek if (tolen <= 0) {
548*00b67f09SDavid van Moolenbroek r = idn_buffer_overflow;
549*00b67f09SDavid van Moolenbroek goto ret;
550*00b67f09SDavid van Moolenbroek }
551*00b67f09SDavid van Moolenbroek *to = '\0';
552*00b67f09SDavid van Moolenbroek r = idn_success;
553*00b67f09SDavid van Moolenbroek goto ret;
554*00b67f09SDavid van Moolenbroek }
555*00b67f09SDavid van Moolenbroek
556*00b67f09SDavid van Moolenbroek /*
557*00b67f09SDavid van Moolenbroek * Delimiter map.
558*00b67f09SDavid van Moolenbroek */
559*00b67f09SDavid van Moolenbroek if (actions & IDN_DELIMMAP) {
560*00b67f09SDavid van Moolenbroek TRACE(("res delimitermap(name=\"%s\")\n",
561*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(buffer, 50)));
562*00b67f09SDavid van Moolenbroek
563*00b67f09SDavid van Moolenbroek delimiter_mapper = idn_resconf_getdelimitermap(ctx);
564*00b67f09SDavid van Moolenbroek if (delimiter_mapper != NULL) {
565*00b67f09SDavid van Moolenbroek r = idn_delimitermap_map(delimiter_mapper, buffer,
566*00b67f09SDavid van Moolenbroek buffer, buffer_length);
567*00b67f09SDavid van Moolenbroek idn_delimitermap_destroy(delimiter_mapper);
568*00b67f09SDavid van Moolenbroek if (r != idn_success)
569*00b67f09SDavid van Moolenbroek goto ret;
570*00b67f09SDavid van Moolenbroek }
571*00b67f09SDavid van Moolenbroek TRACE(("res delimitermap(): success (name=\"%s\")\n",
572*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(buffer, 50)));
573*00b67f09SDavid van Moolenbroek }
574*00b67f09SDavid van Moolenbroek
575*00b67f09SDavid van Moolenbroek /*
576*00b67f09SDavid van Moolenbroek * Split the name into a list of labels.
577*00b67f09SDavid van Moolenbroek */
578*00b67f09SDavid van Moolenbroek r = labellist_create(buffer, &labels);
579*00b67f09SDavid van Moolenbroek if (r != idn_success)
580*00b67f09SDavid van Moolenbroek goto ret;
581*00b67f09SDavid van Moolenbroek
582*00b67f09SDavid van Moolenbroek /*
583*00b67f09SDavid van Moolenbroek * Perform conversions and tests.
584*00b67f09SDavid van Moolenbroek */
585*00b67f09SDavid van Moolenbroek for (l = labellist_tail(labels); l != NULL;
586*00b67f09SDavid van Moolenbroek l = labellist_previous(l)) {
587*00b67f09SDavid van Moolenbroek
588*00b67f09SDavid van Moolenbroek free(saved_name);
589*00b67f09SDavid van Moolenbroek saved_name = NULL;
590*00b67f09SDavid van Moolenbroek
591*00b67f09SDavid van Moolenbroek if (!idn__util_ucs4isasciirange(labellist_getname(l))) {
592*00b67f09SDavid van Moolenbroek if (actions & IDN_MAP) {
593*00b67f09SDavid van Moolenbroek r = label_map(ctx, l);
594*00b67f09SDavid van Moolenbroek if (r != idn_success)
595*00b67f09SDavid van Moolenbroek goto ret;
596*00b67f09SDavid van Moolenbroek }
597*00b67f09SDavid van Moolenbroek if (actions & IDN_NORMALIZE) {
598*00b67f09SDavid van Moolenbroek r = label_normalize(ctx, l);
599*00b67f09SDavid van Moolenbroek if (r != idn_success)
600*00b67f09SDavid van Moolenbroek goto ret;
601*00b67f09SDavid van Moolenbroek }
602*00b67f09SDavid van Moolenbroek if (actions & IDN_PROHCHECK) {
603*00b67f09SDavid van Moolenbroek r = label_prohcheck(ctx, l);
604*00b67f09SDavid van Moolenbroek if (r == idn_prohibited) {
605*00b67f09SDavid van Moolenbroek labellist_undo(l);
606*00b67f09SDavid van Moolenbroek continue;
607*00b67f09SDavid van Moolenbroek } else if (r != idn_success) {
608*00b67f09SDavid van Moolenbroek goto ret;
609*00b67f09SDavid van Moolenbroek }
610*00b67f09SDavid van Moolenbroek }
611*00b67f09SDavid van Moolenbroek if (actions & IDN_UNASCHECK) {
612*00b67f09SDavid van Moolenbroek r = label_unascheck(ctx, l);
613*00b67f09SDavid van Moolenbroek if (r == idn_prohibited) {
614*00b67f09SDavid van Moolenbroek labellist_undo(l);
615*00b67f09SDavid van Moolenbroek continue;
616*00b67f09SDavid van Moolenbroek } else if (r != idn_success) {
617*00b67f09SDavid van Moolenbroek goto ret;
618*00b67f09SDavid van Moolenbroek }
619*00b67f09SDavid van Moolenbroek }
620*00b67f09SDavid van Moolenbroek if (actions & IDN_BIDICHECK) {
621*00b67f09SDavid van Moolenbroek r = label_bidicheck(ctx, l);
622*00b67f09SDavid van Moolenbroek if (r == idn_prohibited) {
623*00b67f09SDavid van Moolenbroek labellist_undo(l);
624*00b67f09SDavid van Moolenbroek continue;
625*00b67f09SDavid van Moolenbroek } else if (r != idn_success) {
626*00b67f09SDavid van Moolenbroek goto ret;
627*00b67f09SDavid van Moolenbroek }
628*00b67f09SDavid van Moolenbroek }
629*00b67f09SDavid van Moolenbroek }
630*00b67f09SDavid van Moolenbroek
631*00b67f09SDavid van Moolenbroek if ((actions & IDN_IDNCONV) && idn_is_ace) {
632*00b67f09SDavid van Moolenbroek saved_name = idn_ucs4_strdup(labellist_getname(l));
633*00b67f09SDavid van Moolenbroek if (saved_name == NULL) {
634*00b67f09SDavid van Moolenbroek r = idn_nomemory;
635*00b67f09SDavid van Moolenbroek goto ret;
636*00b67f09SDavid van Moolenbroek }
637*00b67f09SDavid van Moolenbroek r = label_idndecode(ctx, l);
638*00b67f09SDavid van Moolenbroek if (r == idn_invalid_encoding) {
639*00b67f09SDavid van Moolenbroek labellist_undo(l);
640*00b67f09SDavid van Moolenbroek continue;
641*00b67f09SDavid van Moolenbroek } else if (r != idn_success) {
642*00b67f09SDavid van Moolenbroek goto ret;
643*00b67f09SDavid van Moolenbroek }
644*00b67f09SDavid van Moolenbroek }
645*00b67f09SDavid van Moolenbroek if ((actions & IDN_RTCHECK) && saved_name != NULL) {
646*00b67f09SDavid van Moolenbroek r = label_rtcheck(ctx, actions, l, saved_name);
647*00b67f09SDavid van Moolenbroek if (r == idn_invalid_encoding) {
648*00b67f09SDavid van Moolenbroek labellist_undo(l);
649*00b67f09SDavid van Moolenbroek continue;
650*00b67f09SDavid van Moolenbroek } else if (r != idn_success) {
651*00b67f09SDavid van Moolenbroek goto ret;
652*00b67f09SDavid van Moolenbroek }
653*00b67f09SDavid van Moolenbroek }
654*00b67f09SDavid van Moolenbroek
655*00b67f09SDavid van Moolenbroek #ifndef WITHOUT_ICONV
656*00b67f09SDavid van Moolenbroek if (actions & IDN_LOCALCONV) {
657*00b67f09SDavid van Moolenbroek r = label_localdecodecheck(ctx, l);
658*00b67f09SDavid van Moolenbroek if (r != idn_success)
659*00b67f09SDavid van Moolenbroek goto ret;
660*00b67f09SDavid van Moolenbroek }
661*00b67f09SDavid van Moolenbroek #endif
662*00b67f09SDavid van Moolenbroek }
663*00b67f09SDavid van Moolenbroek
664*00b67f09SDavid van Moolenbroek /*
665*00b67f09SDavid van Moolenbroek * Concat a list of labels to a name.
666*00b67f09SDavid van Moolenbroek */
667*00b67f09SDavid van Moolenbroek for (;;) {
668*00b67f09SDavid van Moolenbroek void *new_buffer;
669*00b67f09SDavid van Moolenbroek
670*00b67f09SDavid van Moolenbroek new_buffer = realloc(buffer, sizeof(*buffer) * buffer_length);
671*00b67f09SDavid van Moolenbroek if (new_buffer == NULL) {
672*00b67f09SDavid van Moolenbroek r = idn_nomemory;
673*00b67f09SDavid van Moolenbroek goto ret;
674*00b67f09SDavid van Moolenbroek }
675*00b67f09SDavid van Moolenbroek buffer = (unsigned long *)new_buffer;
676*00b67f09SDavid van Moolenbroek
677*00b67f09SDavid van Moolenbroek r = labellist_getnamelist(labels, buffer, buffer_length);
678*00b67f09SDavid van Moolenbroek if (r == idn_success)
679*00b67f09SDavid van Moolenbroek break;
680*00b67f09SDavid van Moolenbroek else if (r != idn_buffer_overflow)
681*00b67f09SDavid van Moolenbroek goto ret;
682*00b67f09SDavid van Moolenbroek
683*00b67f09SDavid van Moolenbroek buffer_length *= 2;
684*00b67f09SDavid van Moolenbroek }
685*00b67f09SDavid van Moolenbroek
686*00b67f09SDavid van Moolenbroek if (actions & IDN_LOCALCONV) {
687*00b67f09SDavid van Moolenbroek r = idn_converter_convfromucs4(local_converter, buffer, to,
688*00b67f09SDavid van Moolenbroek tolen);
689*00b67f09SDavid van Moolenbroek } else {
690*00b67f09SDavid van Moolenbroek r = idn_ucs4_ucs4toutf8(buffer, to, tolen);
691*00b67f09SDavid van Moolenbroek }
692*00b67f09SDavid van Moolenbroek
693*00b67f09SDavid van Moolenbroek ret:
694*00b67f09SDavid van Moolenbroek if (r == idn_success) {
695*00b67f09SDavid van Moolenbroek TRACE(("idn_res_decodename(): success (to=\"%s\")\n",
696*00b67f09SDavid van Moolenbroek idn__debug_xstring(to, 50)));
697*00b67f09SDavid van Moolenbroek } else {
698*00b67f09SDavid van Moolenbroek TRACE(("idn_res_decodename(): %s\n", idn_result_tostring(r)));
699*00b67f09SDavid van Moolenbroek }
700*00b67f09SDavid van Moolenbroek free(saved_name);
701*00b67f09SDavid van Moolenbroek free(buffer);
702*00b67f09SDavid van Moolenbroek if (local_converter != NULL)
703*00b67f09SDavid van Moolenbroek idn_converter_destroy(local_converter);
704*00b67f09SDavid van Moolenbroek if (idn_converter != NULL)
705*00b67f09SDavid van Moolenbroek idn_converter_destroy(idn_converter);
706*00b67f09SDavid van Moolenbroek if (labels != NULL)
707*00b67f09SDavid van Moolenbroek labellist_destroy(labels);
708*00b67f09SDavid van Moolenbroek return (r);
709*00b67f09SDavid van Moolenbroek }
710*00b67f09SDavid van Moolenbroek
711*00b67f09SDavid van Moolenbroek idn_result_t
idn_res_decodename2(idn_resconf_t ctx,idn_action_t actions,const char * from,char * to,size_t tolen,const char * auxencoding)712*00b67f09SDavid van Moolenbroek idn_res_decodename2(idn_resconf_t ctx, idn_action_t actions, const char *from,
713*00b67f09SDavid van Moolenbroek char *to, size_t tolen, const char *auxencoding) {
714*00b67f09SDavid van Moolenbroek #ifdef WITHOUT_ICONV
715*00b67f09SDavid van Moolenbroek return idn_failure;
716*00b67f09SDavid van Moolenbroek
717*00b67f09SDavid van Moolenbroek #else /* WITHOUT_ICONV */
718*00b67f09SDavid van Moolenbroek idn_result_t r;
719*00b67f09SDavid van Moolenbroek idn_converter_t aux_converter = NULL;
720*00b67f09SDavid van Moolenbroek unsigned long *buffer_ucs4 = NULL;
721*00b67f09SDavid van Moolenbroek char *buffer_utf8 = NULL;
722*00b67f09SDavid van Moolenbroek size_t buffer_length;
723*00b67f09SDavid van Moolenbroek
724*00b67f09SDavid van Moolenbroek assert(ctx != NULL && from != NULL && to != NULL);
725*00b67f09SDavid van Moolenbroek
726*00b67f09SDavid van Moolenbroek TRACE(("idn_res_decodename2(actions=%s, from=\"%s\", tolen=%d, "
727*00b67f09SDavid van Moolenbroek "auxencoding=\"%s\")\n",
728*00b67f09SDavid van Moolenbroek idn__res_actionstostring(actions),
729*00b67f09SDavid van Moolenbroek idn__debug_xstring(from, 50), (int)tolen,
730*00b67f09SDavid van Moolenbroek (auxencoding != NULL) ? auxencoding : "<null>"));
731*00b67f09SDavid van Moolenbroek
732*00b67f09SDavid van Moolenbroek if (!initialized)
733*00b67f09SDavid van Moolenbroek idn_res_initialize();
734*00b67f09SDavid van Moolenbroek if (!enabled || actions == 0) {
735*00b67f09SDavid van Moolenbroek r = copy_verbatim(from, to, tolen);
736*00b67f09SDavid van Moolenbroek goto ret;
737*00b67f09SDavid van Moolenbroek } else if (tolen <= 0) {
738*00b67f09SDavid van Moolenbroek r = idn_buffer_overflow;
739*00b67f09SDavid van Moolenbroek goto ret;
740*00b67f09SDavid van Moolenbroek }
741*00b67f09SDavid van Moolenbroek
742*00b67f09SDavid van Moolenbroek if (auxencoding == NULL ||
743*00b67f09SDavid van Moolenbroek strcmp(auxencoding, IDN_UTF8_ENCODING_NAME) == 0 ||
744*00b67f09SDavid van Moolenbroek strcmp(auxencoding, "UTF-8") == 0) {
745*00b67f09SDavid van Moolenbroek return idn_res_decodename(ctx, actions, from, to, tolen);
746*00b67f09SDavid van Moolenbroek }
747*00b67f09SDavid van Moolenbroek
748*00b67f09SDavid van Moolenbroek /*
749*00b67f09SDavid van Moolenbroek * Convert `from' to UCS4.
750*00b67f09SDavid van Moolenbroek */
751*00b67f09SDavid van Moolenbroek r = idn_resconf_setauxidnconvertername(ctx, auxencoding,
752*00b67f09SDavid van Moolenbroek IDN_CONVERTER_DELAYEDOPEN);
753*00b67f09SDavid van Moolenbroek if (r != idn_success) {
754*00b67f09SDavid van Moolenbroek goto ret;
755*00b67f09SDavid van Moolenbroek }
756*00b67f09SDavid van Moolenbroek
757*00b67f09SDavid van Moolenbroek aux_converter = idn_resconf_getauxidnconverter(ctx);
758*00b67f09SDavid van Moolenbroek if (aux_converter == NULL) {
759*00b67f09SDavid van Moolenbroek r = idn_failure;
760*00b67f09SDavid van Moolenbroek goto ret;
761*00b67f09SDavid van Moolenbroek }
762*00b67f09SDavid van Moolenbroek
763*00b67f09SDavid van Moolenbroek buffer_length = tolen * 2;
764*00b67f09SDavid van Moolenbroek for (;;) {
765*00b67f09SDavid van Moolenbroek void *new_buffer;
766*00b67f09SDavid van Moolenbroek
767*00b67f09SDavid van Moolenbroek new_buffer = realloc(buffer_ucs4,
768*00b67f09SDavid van Moolenbroek sizeof(*buffer_ucs4) * buffer_length);
769*00b67f09SDavid van Moolenbroek if (new_buffer == NULL) {
770*00b67f09SDavid van Moolenbroek r = idn_nomemory;
771*00b67f09SDavid van Moolenbroek goto ret;
772*00b67f09SDavid van Moolenbroek }
773*00b67f09SDavid van Moolenbroek buffer_ucs4 = (unsigned long *)new_buffer;
774*00b67f09SDavid van Moolenbroek
775*00b67f09SDavid van Moolenbroek r = idn_converter_convtoucs4(aux_converter, from,
776*00b67f09SDavid van Moolenbroek buffer_ucs4,
777*00b67f09SDavid van Moolenbroek buffer_length);
778*00b67f09SDavid van Moolenbroek if (r == idn_success)
779*00b67f09SDavid van Moolenbroek break;
780*00b67f09SDavid van Moolenbroek else if (r != idn_buffer_overflow)
781*00b67f09SDavid van Moolenbroek goto ret;
782*00b67f09SDavid van Moolenbroek
783*00b67f09SDavid van Moolenbroek buffer_length *= 2;
784*00b67f09SDavid van Moolenbroek }
785*00b67f09SDavid van Moolenbroek
786*00b67f09SDavid van Moolenbroek if (*buffer_ucs4 == '\0') {
787*00b67f09SDavid van Moolenbroek if (tolen <= 0) {
788*00b67f09SDavid van Moolenbroek r = idn_buffer_overflow;
789*00b67f09SDavid van Moolenbroek goto ret;
790*00b67f09SDavid van Moolenbroek }
791*00b67f09SDavid van Moolenbroek *to = '\0';
792*00b67f09SDavid van Moolenbroek r = idn_success;
793*00b67f09SDavid van Moolenbroek goto ret;
794*00b67f09SDavid van Moolenbroek }
795*00b67f09SDavid van Moolenbroek
796*00b67f09SDavid van Moolenbroek /*
797*00b67f09SDavid van Moolenbroek * Convert `buffer_ucs4' to UTF-8.
798*00b67f09SDavid van Moolenbroek */
799*00b67f09SDavid van Moolenbroek buffer_length = tolen * 2;
800*00b67f09SDavid van Moolenbroek for (;;) {
801*00b67f09SDavid van Moolenbroek void *new_buffer;
802*00b67f09SDavid van Moolenbroek
803*00b67f09SDavid van Moolenbroek new_buffer = realloc(buffer_utf8,
804*00b67f09SDavid van Moolenbroek sizeof(*buffer_utf8) * buffer_length);
805*00b67f09SDavid van Moolenbroek if (new_buffer == NULL) {
806*00b67f09SDavid van Moolenbroek r = idn_nomemory;
807*00b67f09SDavid van Moolenbroek goto ret;
808*00b67f09SDavid van Moolenbroek }
809*00b67f09SDavid van Moolenbroek buffer_utf8 = (char *)new_buffer;
810*00b67f09SDavid van Moolenbroek r = idn_ucs4_ucs4toutf8(buffer_ucs4, buffer_utf8,
811*00b67f09SDavid van Moolenbroek buffer_length);
812*00b67f09SDavid van Moolenbroek
813*00b67f09SDavid van Moolenbroek if (r == idn_success)
814*00b67f09SDavid van Moolenbroek break;
815*00b67f09SDavid van Moolenbroek else if (r != idn_buffer_overflow)
816*00b67f09SDavid van Moolenbroek goto ret;
817*00b67f09SDavid van Moolenbroek
818*00b67f09SDavid van Moolenbroek buffer_length *= 2;
819*00b67f09SDavid van Moolenbroek }
820*00b67f09SDavid van Moolenbroek
821*00b67f09SDavid van Moolenbroek if (*buffer_utf8 == '\0') {
822*00b67f09SDavid van Moolenbroek if (tolen <= 0) {
823*00b67f09SDavid van Moolenbroek r = idn_buffer_overflow;
824*00b67f09SDavid van Moolenbroek goto ret;
825*00b67f09SDavid van Moolenbroek }
826*00b67f09SDavid van Moolenbroek *to = '\0';
827*00b67f09SDavid van Moolenbroek r = idn_success;
828*00b67f09SDavid van Moolenbroek goto ret;
829*00b67f09SDavid van Moolenbroek }
830*00b67f09SDavid van Moolenbroek
831*00b67f09SDavid van Moolenbroek r = idn_res_decodename(ctx, actions, buffer_utf8, to, tolen);
832*00b67f09SDavid van Moolenbroek
833*00b67f09SDavid van Moolenbroek ret:
834*00b67f09SDavid van Moolenbroek if (r == idn_success) {
835*00b67f09SDavid van Moolenbroek TRACE(("idn_res_decodename2(): success (to=\"%s\")\n",
836*00b67f09SDavid van Moolenbroek idn__debug_xstring(to, 50)));
837*00b67f09SDavid van Moolenbroek } else {
838*00b67f09SDavid van Moolenbroek TRACE(("idn_res_decodename2(): %s\n", idn_result_tostring(r)));
839*00b67f09SDavid van Moolenbroek }
840*00b67f09SDavid van Moolenbroek free(buffer_ucs4);
841*00b67f09SDavid van Moolenbroek free(buffer_utf8);
842*00b67f09SDavid van Moolenbroek if (aux_converter != NULL)
843*00b67f09SDavid van Moolenbroek idn_converter_destroy(aux_converter);
844*00b67f09SDavid van Moolenbroek
845*00b67f09SDavid van Moolenbroek return (r);
846*00b67f09SDavid van Moolenbroek
847*00b67f09SDavid van Moolenbroek #endif /* WITHOUT_ICONV */
848*00b67f09SDavid van Moolenbroek }
849*00b67f09SDavid van Moolenbroek
850*00b67f09SDavid van Moolenbroek static idn_result_t
copy_verbatim(const char * from,char * to,size_t tolen)851*00b67f09SDavid van Moolenbroek copy_verbatim(const char *from, char *to, size_t tolen) {
852*00b67f09SDavid van Moolenbroek size_t fromlen = strlen(from);
853*00b67f09SDavid van Moolenbroek
854*00b67f09SDavid van Moolenbroek if (fromlen + 1 > tolen)
855*00b67f09SDavid van Moolenbroek return (idn_buffer_overflow);
856*00b67f09SDavid van Moolenbroek (void)memcpy(to, from, fromlen + 1);
857*00b67f09SDavid van Moolenbroek return (idn_success);
858*00b67f09SDavid van Moolenbroek }
859*00b67f09SDavid van Moolenbroek
860*00b67f09SDavid van Moolenbroek static idn_result_t
labellist_create(const unsigned long * name,labellist_t * labelp)861*00b67f09SDavid van Moolenbroek labellist_create(const unsigned long *name, labellist_t *labelp) {
862*00b67f09SDavid van Moolenbroek size_t length, malloc_length;
863*00b67f09SDavid van Moolenbroek labellist_t head_label = NULL;
864*00b67f09SDavid van Moolenbroek labellist_t tail_label = NULL;
865*00b67f09SDavid van Moolenbroek labellist_t new_label = NULL;
866*00b67f09SDavid van Moolenbroek const unsigned long *endp = NULL;
867*00b67f09SDavid van Moolenbroek idn_result_t r;
868*00b67f09SDavid van Moolenbroek
869*00b67f09SDavid van Moolenbroek while (*name != '\0') {
870*00b67f09SDavid van Moolenbroek for (endp = name; *endp != '.' && *endp != '\0'; endp++)
871*00b67f09SDavid van Moolenbroek ; /* nothing to be done */
872*00b67f09SDavid van Moolenbroek length = (endp - name) + 1;
873*00b67f09SDavid van Moolenbroek malloc_length = length + 15; /* add 15 for margin */
874*00b67f09SDavid van Moolenbroek
875*00b67f09SDavid van Moolenbroek new_label = (labellist_t)
876*00b67f09SDavid van Moolenbroek malloc(sizeof(struct labellist));
877*00b67f09SDavid van Moolenbroek if (new_label == NULL) {
878*00b67f09SDavid van Moolenbroek r = idn_nomemory;
879*00b67f09SDavid van Moolenbroek goto ret;
880*00b67f09SDavid van Moolenbroek }
881*00b67f09SDavid van Moolenbroek if (head_label == NULL)
882*00b67f09SDavid van Moolenbroek head_label = new_label;
883*00b67f09SDavid van Moolenbroek
884*00b67f09SDavid van Moolenbroek new_label->name = NULL;
885*00b67f09SDavid van Moolenbroek new_label->undo_name = NULL;
886*00b67f09SDavid van Moolenbroek new_label->name_length = malloc_length;
887*00b67f09SDavid van Moolenbroek new_label->next = NULL;
888*00b67f09SDavid van Moolenbroek new_label->previous = NULL;
889*00b67f09SDavid van Moolenbroek new_label->dot_followed = (*endp == '.');
890*00b67f09SDavid van Moolenbroek
891*00b67f09SDavid van Moolenbroek new_label->name = (unsigned long *)
892*00b67f09SDavid van Moolenbroek malloc(sizeof(long) * malloc_length);
893*00b67f09SDavid van Moolenbroek if (new_label->name == NULL) {
894*00b67f09SDavid van Moolenbroek r = idn_nomemory;
895*00b67f09SDavid van Moolenbroek goto ret;
896*00b67f09SDavid van Moolenbroek }
897*00b67f09SDavid van Moolenbroek memcpy(new_label->name, name, sizeof(long) * length);
898*00b67f09SDavid van Moolenbroek *(new_label->name + length - 1) = '\0';
899*00b67f09SDavid van Moolenbroek
900*00b67f09SDavid van Moolenbroek new_label->undo_name = (unsigned long *)
901*00b67f09SDavid van Moolenbroek malloc(sizeof(long) * malloc_length);
902*00b67f09SDavid van Moolenbroek if (new_label->undo_name == NULL) {
903*00b67f09SDavid van Moolenbroek r = idn_nomemory;
904*00b67f09SDavid van Moolenbroek goto ret;
905*00b67f09SDavid van Moolenbroek }
906*00b67f09SDavid van Moolenbroek memcpy(new_label->undo_name, name, sizeof(long) * length);
907*00b67f09SDavid van Moolenbroek *(new_label->undo_name + length - 1) = '\0';
908*00b67f09SDavid van Moolenbroek
909*00b67f09SDavid van Moolenbroek if (tail_label != NULL) {
910*00b67f09SDavid van Moolenbroek tail_label->next = new_label;
911*00b67f09SDavid van Moolenbroek new_label->previous = tail_label;
912*00b67f09SDavid van Moolenbroek }
913*00b67f09SDavid van Moolenbroek tail_label = new_label;
914*00b67f09SDavid van Moolenbroek
915*00b67f09SDavid van Moolenbroek if (*endp == '.')
916*00b67f09SDavid van Moolenbroek name = endp + 1;
917*00b67f09SDavid van Moolenbroek else
918*00b67f09SDavid van Moolenbroek name = endp;
919*00b67f09SDavid van Moolenbroek }
920*00b67f09SDavid van Moolenbroek
921*00b67f09SDavid van Moolenbroek *labelp = head_label;
922*00b67f09SDavid van Moolenbroek r = idn_success;
923*00b67f09SDavid van Moolenbroek
924*00b67f09SDavid van Moolenbroek ret:
925*00b67f09SDavid van Moolenbroek if (r != idn_success) {
926*00b67f09SDavid van Moolenbroek if (new_label != NULL) {
927*00b67f09SDavid van Moolenbroek free(new_label->name);
928*00b67f09SDavid van Moolenbroek free(new_label->undo_name);
929*00b67f09SDavid van Moolenbroek free(new_label);
930*00b67f09SDavid van Moolenbroek }
931*00b67f09SDavid van Moolenbroek if (head_label != NULL)
932*00b67f09SDavid van Moolenbroek labellist_destroy(head_label);
933*00b67f09SDavid van Moolenbroek }
934*00b67f09SDavid van Moolenbroek return (r);
935*00b67f09SDavid van Moolenbroek }
936*00b67f09SDavid van Moolenbroek
937*00b67f09SDavid van Moolenbroek
938*00b67f09SDavid van Moolenbroek static void
labellist_destroy(labellist_t label)939*00b67f09SDavid van Moolenbroek labellist_destroy(labellist_t label) {
940*00b67f09SDavid van Moolenbroek labellist_t l, l_next;
941*00b67f09SDavid van Moolenbroek
942*00b67f09SDavid van Moolenbroek for (l = label; l != NULL; l = l_next) {
943*00b67f09SDavid van Moolenbroek l_next = l->next;
944*00b67f09SDavid van Moolenbroek free(l->name);
945*00b67f09SDavid van Moolenbroek free(l->undo_name);
946*00b67f09SDavid van Moolenbroek free(l);
947*00b67f09SDavid van Moolenbroek }
948*00b67f09SDavid van Moolenbroek }
949*00b67f09SDavid van Moolenbroek
950*00b67f09SDavid van Moolenbroek static idn_result_t
labellist_setname(labellist_t label,const unsigned long * name)951*00b67f09SDavid van Moolenbroek labellist_setname(labellist_t label, const unsigned long *name) {
952*00b67f09SDavid van Moolenbroek unsigned long *new_name;
953*00b67f09SDavid van Moolenbroek size_t length, new_length;
954*00b67f09SDavid van Moolenbroek
955*00b67f09SDavid van Moolenbroek length = idn_ucs4_strlen(name) + 1;
956*00b67f09SDavid van Moolenbroek new_length = length + 15; /* add 15 for margin */
957*00b67f09SDavid van Moolenbroek
958*00b67f09SDavid van Moolenbroek if (label->name_length < new_length) {
959*00b67f09SDavid van Moolenbroek new_name = (unsigned long *)
960*00b67f09SDavid van Moolenbroek realloc(label->name, sizeof(long) * new_length);
961*00b67f09SDavid van Moolenbroek if (new_name == NULL)
962*00b67f09SDavid van Moolenbroek return (idn_nomemory);
963*00b67f09SDavid van Moolenbroek label->name = new_name;
964*00b67f09SDavid van Moolenbroek label->name_length = new_length;
965*00b67f09SDavid van Moolenbroek }
966*00b67f09SDavid van Moolenbroek memcpy(label->name, name, sizeof(long) * length);
967*00b67f09SDavid van Moolenbroek
968*00b67f09SDavid van Moolenbroek return (idn_success);
969*00b67f09SDavid van Moolenbroek }
970*00b67f09SDavid van Moolenbroek
971*00b67f09SDavid van Moolenbroek static const unsigned long *
labellist_getname(labellist_t label)972*00b67f09SDavid van Moolenbroek labellist_getname(labellist_t label) {
973*00b67f09SDavid van Moolenbroek return (label->name);
974*00b67f09SDavid van Moolenbroek }
975*00b67f09SDavid van Moolenbroek
976*00b67f09SDavid van Moolenbroek static const unsigned long *
labellist_gettldname(labellist_t label)977*00b67f09SDavid van Moolenbroek labellist_gettldname(labellist_t label) {
978*00b67f09SDavid van Moolenbroek labellist_t l;
979*00b67f09SDavid van Moolenbroek
980*00b67f09SDavid van Moolenbroek if (label->previous == NULL && label->next == NULL &&
981*00b67f09SDavid van Moolenbroek !label->dot_followed)
982*00b67f09SDavid van Moolenbroek return (idn_mapselector_getnotld());
983*00b67f09SDavid van Moolenbroek
984*00b67f09SDavid van Moolenbroek for (l = label; l->next != NULL; l = l->next)
985*00b67f09SDavid van Moolenbroek ; /* nothing to be done */
986*00b67f09SDavid van Moolenbroek
987*00b67f09SDavid van Moolenbroek return (l->name);
988*00b67f09SDavid van Moolenbroek }
989*00b67f09SDavid van Moolenbroek
990*00b67f09SDavid van Moolenbroek static idn_result_t
labellist_getnamelist(labellist_t label,unsigned long * name,size_t name_length)991*00b67f09SDavid van Moolenbroek labellist_getnamelist(labellist_t label, unsigned long *name,
992*00b67f09SDavid van Moolenbroek size_t name_length) {
993*00b67f09SDavid van Moolenbroek static const unsigned long dot_string[] = {0x002e, 0x0000}; /* "." */
994*00b67f09SDavid van Moolenbroek size_t length;
995*00b67f09SDavid van Moolenbroek labellist_t l;
996*00b67f09SDavid van Moolenbroek
997*00b67f09SDavid van Moolenbroek for (l = label, length = 0; l != NULL; l = l->next)
998*00b67f09SDavid van Moolenbroek length += idn_ucs4_strlen(l->name) + 1; /* name + `.' */
999*00b67f09SDavid van Moolenbroek length++; /* for NUL */
1000*00b67f09SDavid van Moolenbroek
1001*00b67f09SDavid van Moolenbroek if (name_length < length)
1002*00b67f09SDavid van Moolenbroek return (idn_buffer_overflow);
1003*00b67f09SDavid van Moolenbroek
1004*00b67f09SDavid van Moolenbroek *name = '\0';
1005*00b67f09SDavid van Moolenbroek for (l = label; l != NULL; l = l->next) {
1006*00b67f09SDavid van Moolenbroek idn_ucs4_strcat(name, l->name);
1007*00b67f09SDavid van Moolenbroek name += idn_ucs4_strlen(name);
1008*00b67f09SDavid van Moolenbroek if (l->dot_followed)
1009*00b67f09SDavid van Moolenbroek idn_ucs4_strcat(name, dot_string);
1010*00b67f09SDavid van Moolenbroek }
1011*00b67f09SDavid van Moolenbroek return (idn_success);
1012*00b67f09SDavid van Moolenbroek }
1013*00b67f09SDavid van Moolenbroek
1014*00b67f09SDavid van Moolenbroek static void
labellist_undo(labellist_t label)1015*00b67f09SDavid van Moolenbroek labellist_undo(labellist_t label) {
1016*00b67f09SDavid van Moolenbroek size_t length;
1017*00b67f09SDavid van Moolenbroek
1018*00b67f09SDavid van Moolenbroek length = idn_ucs4_strlen(label->undo_name) + 1;
1019*00b67f09SDavid van Moolenbroek memcpy(label->name, label->undo_name, sizeof(long) * length);
1020*00b67f09SDavid van Moolenbroek }
1021*00b67f09SDavid van Moolenbroek
1022*00b67f09SDavid van Moolenbroek static labellist_t
labellist_tail(labellist_t label)1023*00b67f09SDavid van Moolenbroek labellist_tail(labellist_t label) {
1024*00b67f09SDavid van Moolenbroek labellist_t l;
1025*00b67f09SDavid van Moolenbroek
1026*00b67f09SDavid van Moolenbroek if (label == NULL)
1027*00b67f09SDavid van Moolenbroek return (NULL);
1028*00b67f09SDavid van Moolenbroek for (l = label; l->next != NULL; l = l->next)
1029*00b67f09SDavid van Moolenbroek ; /* nothing to be done */
1030*00b67f09SDavid van Moolenbroek return (l);
1031*00b67f09SDavid van Moolenbroek }
1032*00b67f09SDavid van Moolenbroek
1033*00b67f09SDavid van Moolenbroek static labellist_t
labellist_previous(labellist_t label)1034*00b67f09SDavid van Moolenbroek labellist_previous(labellist_t label) {
1035*00b67f09SDavid van Moolenbroek return (label->previous);
1036*00b67f09SDavid van Moolenbroek }
1037*00b67f09SDavid van Moolenbroek
1038*00b67f09SDavid van Moolenbroek #ifndef WITHOUT_ICONV
1039*00b67f09SDavid van Moolenbroek
1040*00b67f09SDavid van Moolenbroek static idn_result_t
label_localdecodecheck(idn_resconf_t ctx,labellist_t label)1041*00b67f09SDavid van Moolenbroek label_localdecodecheck(idn_resconf_t ctx, labellist_t label) {
1042*00b67f09SDavid van Moolenbroek idn_converter_t local_converter = NULL;
1043*00b67f09SDavid van Moolenbroek const unsigned long *from;
1044*00b67f09SDavid van Moolenbroek char *to = NULL;
1045*00b67f09SDavid van Moolenbroek size_t to_length;
1046*00b67f09SDavid van Moolenbroek idn_result_t r;
1047*00b67f09SDavid van Moolenbroek
1048*00b67f09SDavid van Moolenbroek from = labellist_getname(label);
1049*00b67f09SDavid van Moolenbroek to_length = idn_ucs4_strlen(from) + 1 + 15; /* 15 for margin */
1050*00b67f09SDavid van Moolenbroek TRACE(("res ucs4tolocal_check(label=\"%s\")\n",
1051*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(from, 50)));
1052*00b67f09SDavid van Moolenbroek
1053*00b67f09SDavid van Moolenbroek local_converter = idn_resconf_getlocalconverter(ctx);
1054*00b67f09SDavid van Moolenbroek if (local_converter == NULL) {
1055*00b67f09SDavid van Moolenbroek r = idn_success;
1056*00b67f09SDavid van Moolenbroek goto ret;
1057*00b67f09SDavid van Moolenbroek }
1058*00b67f09SDavid van Moolenbroek
1059*00b67f09SDavid van Moolenbroek for (;;) {
1060*00b67f09SDavid van Moolenbroek char *new_buffer;
1061*00b67f09SDavid van Moolenbroek
1062*00b67f09SDavid van Moolenbroek new_buffer = (char *)realloc(to, to_length);
1063*00b67f09SDavid van Moolenbroek if (new_buffer == NULL) {
1064*00b67f09SDavid van Moolenbroek r = idn_nomemory;
1065*00b67f09SDavid van Moolenbroek goto ret;
1066*00b67f09SDavid van Moolenbroek }
1067*00b67f09SDavid van Moolenbroek to = new_buffer;
1068*00b67f09SDavid van Moolenbroek r = idn_converter_convfromucs4(local_converter, from, to,
1069*00b67f09SDavid van Moolenbroek to_length);
1070*00b67f09SDavid van Moolenbroek if (r == idn_success)
1071*00b67f09SDavid van Moolenbroek break;
1072*00b67f09SDavid van Moolenbroek else if (r == idn_nomapping) {
1073*00b67f09SDavid van Moolenbroek r = label_idnencode_ace(ctx, label);
1074*00b67f09SDavid van Moolenbroek if (r != idn_success)
1075*00b67f09SDavid van Moolenbroek goto ret;
1076*00b67f09SDavid van Moolenbroek break;
1077*00b67f09SDavid van Moolenbroek } else if (r != idn_buffer_overflow) {
1078*00b67f09SDavid van Moolenbroek goto ret;
1079*00b67f09SDavid van Moolenbroek }
1080*00b67f09SDavid van Moolenbroek to_length *= 2;
1081*00b67f09SDavid van Moolenbroek }
1082*00b67f09SDavid van Moolenbroek
1083*00b67f09SDavid van Moolenbroek r = idn_success;
1084*00b67f09SDavid van Moolenbroek ret:
1085*00b67f09SDavid van Moolenbroek TRACE(("res ucs4tolocal_check(): %s\n", idn_result_tostring(r)));
1086*00b67f09SDavid van Moolenbroek if (local_converter != NULL)
1087*00b67f09SDavid van Moolenbroek idn_converter_destroy(local_converter);
1088*00b67f09SDavid van Moolenbroek free(to);
1089*00b67f09SDavid van Moolenbroek return (r);
1090*00b67f09SDavid van Moolenbroek }
1091*00b67f09SDavid van Moolenbroek
1092*00b67f09SDavid van Moolenbroek #endif /* !WITHOUT_ICONV */
1093*00b67f09SDavid van Moolenbroek
1094*00b67f09SDavid van Moolenbroek static idn_result_t
label_idndecode(idn_resconf_t ctx,labellist_t label)1095*00b67f09SDavid van Moolenbroek label_idndecode(idn_resconf_t ctx, labellist_t label) {
1096*00b67f09SDavid van Moolenbroek idn_converter_t idn_converter = NULL;
1097*00b67f09SDavid van Moolenbroek const unsigned long *from;
1098*00b67f09SDavid van Moolenbroek char *ascii_from = NULL;
1099*00b67f09SDavid van Moolenbroek unsigned long *to = NULL;
1100*00b67f09SDavid van Moolenbroek size_t from_length, to_length;
1101*00b67f09SDavid van Moolenbroek idn_result_t r;
1102*00b67f09SDavid van Moolenbroek
1103*00b67f09SDavid van Moolenbroek from = labellist_getname(label);
1104*00b67f09SDavid van Moolenbroek from_length = idn_ucs4_strlen(from) + 1;
1105*00b67f09SDavid van Moolenbroek TRACE(("res idntoucs4(label=\"%s\")\n",
1106*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(from, 50)));
1107*00b67f09SDavid van Moolenbroek
1108*00b67f09SDavid van Moolenbroek idn_converter = idn_resconf_getidnconverter(ctx);
1109*00b67f09SDavid van Moolenbroek if (idn_converter == NULL) {
1110*00b67f09SDavid van Moolenbroek r = idn_success;
1111*00b67f09SDavid van Moolenbroek goto ret;
1112*00b67f09SDavid van Moolenbroek }
1113*00b67f09SDavid van Moolenbroek
1114*00b67f09SDavid van Moolenbroek for (;;) {
1115*00b67f09SDavid van Moolenbroek char *new_buffer;
1116*00b67f09SDavid van Moolenbroek
1117*00b67f09SDavid van Moolenbroek new_buffer = (char *) realloc(ascii_from, from_length);
1118*00b67f09SDavid van Moolenbroek if (new_buffer == NULL) {
1119*00b67f09SDavid van Moolenbroek r = idn_nomemory;
1120*00b67f09SDavid van Moolenbroek goto ret;
1121*00b67f09SDavid van Moolenbroek }
1122*00b67f09SDavid van Moolenbroek ascii_from = new_buffer;
1123*00b67f09SDavid van Moolenbroek r = idn_ucs4_ucs4toutf8(from, ascii_from, from_length);
1124*00b67f09SDavid van Moolenbroek if (r == idn_success)
1125*00b67f09SDavid van Moolenbroek break;
1126*00b67f09SDavid van Moolenbroek else if (r != idn_buffer_overflow)
1127*00b67f09SDavid van Moolenbroek goto ret;
1128*00b67f09SDavid van Moolenbroek from_length *= 2;
1129*00b67f09SDavid van Moolenbroek }
1130*00b67f09SDavid van Moolenbroek
1131*00b67f09SDavid van Moolenbroek to = NULL;
1132*00b67f09SDavid van Moolenbroek to_length = from_length;
1133*00b67f09SDavid van Moolenbroek
1134*00b67f09SDavid van Moolenbroek for (;;) {
1135*00b67f09SDavid van Moolenbroek unsigned long *new_buffer;
1136*00b67f09SDavid van Moolenbroek
1137*00b67f09SDavid van Moolenbroek new_buffer = (unsigned long *)
1138*00b67f09SDavid van Moolenbroek realloc(to, sizeof(long) * to_length);
1139*00b67f09SDavid van Moolenbroek if (new_buffer == NULL) {
1140*00b67f09SDavid van Moolenbroek r = idn_nomemory;
1141*00b67f09SDavid van Moolenbroek goto ret;
1142*00b67f09SDavid van Moolenbroek }
1143*00b67f09SDavid van Moolenbroek to = new_buffer;
1144*00b67f09SDavid van Moolenbroek r = idn_converter_convtoucs4(idn_converter, ascii_from, to,
1145*00b67f09SDavid van Moolenbroek to_length);
1146*00b67f09SDavid van Moolenbroek if (r == idn_success)
1147*00b67f09SDavid van Moolenbroek break;
1148*00b67f09SDavid van Moolenbroek else if (r != idn_buffer_overflow)
1149*00b67f09SDavid van Moolenbroek goto ret;
1150*00b67f09SDavid van Moolenbroek to_length *= 2;
1151*00b67f09SDavid van Moolenbroek }
1152*00b67f09SDavid van Moolenbroek
1153*00b67f09SDavid van Moolenbroek r = labellist_setname(label, to);
1154*00b67f09SDavid van Moolenbroek ret:
1155*00b67f09SDavid van Moolenbroek if (r == idn_success) {
1156*00b67f09SDavid van Moolenbroek TRACE(("res idntoucs4(): success (label=\"%s\")\n",
1157*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(labellist_getname(label),
1158*00b67f09SDavid van Moolenbroek 50)));
1159*00b67f09SDavid van Moolenbroek } else {
1160*00b67f09SDavid van Moolenbroek TRACE(("res idntoucs4(): %s\n", idn_result_tostring(r)));
1161*00b67f09SDavid van Moolenbroek }
1162*00b67f09SDavid van Moolenbroek if (idn_converter != NULL)
1163*00b67f09SDavid van Moolenbroek idn_converter_destroy(idn_converter);
1164*00b67f09SDavid van Moolenbroek free(to);
1165*00b67f09SDavid van Moolenbroek free(ascii_from);
1166*00b67f09SDavid van Moolenbroek return (r);
1167*00b67f09SDavid van Moolenbroek }
1168*00b67f09SDavid van Moolenbroek
1169*00b67f09SDavid van Moolenbroek static idn_result_t
label_idnencode_ace(idn_resconf_t ctx,labellist_t label)1170*00b67f09SDavid van Moolenbroek label_idnencode_ace(idn_resconf_t ctx, labellist_t label) {
1171*00b67f09SDavid van Moolenbroek idn_converter_t idn_converter = NULL;
1172*00b67f09SDavid van Moolenbroek const unsigned long *from;
1173*00b67f09SDavid van Moolenbroek char *ascii_to = NULL;
1174*00b67f09SDavid van Moolenbroek unsigned long *to = NULL;
1175*00b67f09SDavid van Moolenbroek size_t to_length;
1176*00b67f09SDavid van Moolenbroek idn_result_t r;
1177*00b67f09SDavid van Moolenbroek
1178*00b67f09SDavid van Moolenbroek from = labellist_getname(label);
1179*00b67f09SDavid van Moolenbroek TRACE(("res ucs4toidn(label=\"%s\")\n",
1180*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(from, 50)));
1181*00b67f09SDavid van Moolenbroek
1182*00b67f09SDavid van Moolenbroek idn_converter = idn_resconf_getidnconverter(ctx);
1183*00b67f09SDavid van Moolenbroek if (idn_converter == NULL) {
1184*00b67f09SDavid van Moolenbroek r = idn_success;
1185*00b67f09SDavid van Moolenbroek goto ret;
1186*00b67f09SDavid van Moolenbroek }
1187*00b67f09SDavid van Moolenbroek
1188*00b67f09SDavid van Moolenbroek ascii_to = NULL;
1189*00b67f09SDavid van Moolenbroek to_length = idn_ucs4_strlen(from) * 4 + 16; /* add mergin */
1190*00b67f09SDavid van Moolenbroek
1191*00b67f09SDavid van Moolenbroek for (;;) {
1192*00b67f09SDavid van Moolenbroek char *new_buffer;
1193*00b67f09SDavid van Moolenbroek
1194*00b67f09SDavid van Moolenbroek new_buffer = (char *) realloc(ascii_to, to_length);
1195*00b67f09SDavid van Moolenbroek if (new_buffer == NULL) {
1196*00b67f09SDavid van Moolenbroek r = idn_nomemory;
1197*00b67f09SDavid van Moolenbroek goto ret;
1198*00b67f09SDavid van Moolenbroek }
1199*00b67f09SDavid van Moolenbroek ascii_to = new_buffer;
1200*00b67f09SDavid van Moolenbroek r = idn_converter_convfromucs4(idn_converter, from, ascii_to,
1201*00b67f09SDavid van Moolenbroek to_length);
1202*00b67f09SDavid van Moolenbroek if (r == idn_success)
1203*00b67f09SDavid van Moolenbroek break;
1204*00b67f09SDavid van Moolenbroek else if (r != idn_buffer_overflow)
1205*00b67f09SDavid van Moolenbroek goto ret;
1206*00b67f09SDavid van Moolenbroek to_length *= 2;
1207*00b67f09SDavid van Moolenbroek }
1208*00b67f09SDavid van Moolenbroek
1209*00b67f09SDavid van Moolenbroek for (;;) {
1210*00b67f09SDavid van Moolenbroek unsigned long *new_buffer;
1211*00b67f09SDavid van Moolenbroek
1212*00b67f09SDavid van Moolenbroek new_buffer = (unsigned long *)
1213*00b67f09SDavid van Moolenbroek realloc(to, sizeof(long) * to_length);
1214*00b67f09SDavid van Moolenbroek if (new_buffer == NULL) {
1215*00b67f09SDavid van Moolenbroek r = idn_nomemory;
1216*00b67f09SDavid van Moolenbroek goto ret;
1217*00b67f09SDavid van Moolenbroek }
1218*00b67f09SDavid van Moolenbroek to = new_buffer;
1219*00b67f09SDavid van Moolenbroek r = idn_ucs4_utf8toucs4(ascii_to, to, to_length);
1220*00b67f09SDavid van Moolenbroek if (r == idn_success)
1221*00b67f09SDavid van Moolenbroek break;
1222*00b67f09SDavid van Moolenbroek else if (r != idn_buffer_overflow)
1223*00b67f09SDavid van Moolenbroek goto ret;
1224*00b67f09SDavid van Moolenbroek to_length *= 2;
1225*00b67f09SDavid van Moolenbroek }
1226*00b67f09SDavid van Moolenbroek
1227*00b67f09SDavid van Moolenbroek if (r != idn_success)
1228*00b67f09SDavid van Moolenbroek goto ret;
1229*00b67f09SDavid van Moolenbroek
1230*00b67f09SDavid van Moolenbroek r = labellist_setname(label, to);
1231*00b67f09SDavid van Moolenbroek ret:
1232*00b67f09SDavid van Moolenbroek if (r == idn_success) {
1233*00b67f09SDavid van Moolenbroek TRACE(("res ucs4toidn(): success (label=\"%s\")\n",
1234*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(labellist_getname(label),
1235*00b67f09SDavid van Moolenbroek 50)));
1236*00b67f09SDavid van Moolenbroek } else {
1237*00b67f09SDavid van Moolenbroek TRACE(("res ucs4toidn(): %s\n", idn_result_tostring(r)));
1238*00b67f09SDavid van Moolenbroek }
1239*00b67f09SDavid van Moolenbroek if (idn_converter != NULL)
1240*00b67f09SDavid van Moolenbroek idn_converter_destroy(idn_converter);
1241*00b67f09SDavid van Moolenbroek free(to);
1242*00b67f09SDavid van Moolenbroek free(ascii_to);
1243*00b67f09SDavid van Moolenbroek return (r);
1244*00b67f09SDavid van Moolenbroek }
1245*00b67f09SDavid van Moolenbroek
1246*00b67f09SDavid van Moolenbroek static idn_result_t
label_localmap(idn_resconf_t ctx,labellist_t label)1247*00b67f09SDavid van Moolenbroek label_localmap(idn_resconf_t ctx, labellist_t label) {
1248*00b67f09SDavid van Moolenbroek const unsigned long *from;
1249*00b67f09SDavid van Moolenbroek const unsigned long *tld;
1250*00b67f09SDavid van Moolenbroek unsigned long *to = NULL;
1251*00b67f09SDavid van Moolenbroek size_t to_length;
1252*00b67f09SDavid van Moolenbroek idn_mapselector_t local_mapper;
1253*00b67f09SDavid van Moolenbroek idn_result_t r;
1254*00b67f09SDavid van Moolenbroek
1255*00b67f09SDavid van Moolenbroek from = labellist_getname(label);
1256*00b67f09SDavid van Moolenbroek tld = labellist_gettldname(label);
1257*00b67f09SDavid van Moolenbroek TRACE(("res localmap(label=\"%s\", tld=\"%s\")\n",
1258*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(from, 50),
1259*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(tld, 50)));
1260*00b67f09SDavid van Moolenbroek
1261*00b67f09SDavid van Moolenbroek local_mapper = idn_resconf_getlocalmapselector(ctx);
1262*00b67f09SDavid van Moolenbroek if (local_mapper == NULL) {
1263*00b67f09SDavid van Moolenbroek r = idn_success;
1264*00b67f09SDavid van Moolenbroek goto ret;
1265*00b67f09SDavid van Moolenbroek }
1266*00b67f09SDavid van Moolenbroek
1267*00b67f09SDavid van Moolenbroek if (tld == from)
1268*00b67f09SDavid van Moolenbroek tld = idn_mapselector_getdefaulttld();
1269*00b67f09SDavid van Moolenbroek to_length = idn_ucs4_strlen(from) + 1 + 15; /* 15 for margin */
1270*00b67f09SDavid van Moolenbroek
1271*00b67f09SDavid van Moolenbroek for (;;) {
1272*00b67f09SDavid van Moolenbroek unsigned long *new_buffer;
1273*00b67f09SDavid van Moolenbroek
1274*00b67f09SDavid van Moolenbroek new_buffer = (unsigned long *)
1275*00b67f09SDavid van Moolenbroek realloc(to, sizeof(long) * to_length);
1276*00b67f09SDavid van Moolenbroek if (new_buffer == NULL) {
1277*00b67f09SDavid van Moolenbroek r = idn_nomemory;
1278*00b67f09SDavid van Moolenbroek goto ret;
1279*00b67f09SDavid van Moolenbroek }
1280*00b67f09SDavid van Moolenbroek to = new_buffer;
1281*00b67f09SDavid van Moolenbroek r = idn_mapselector_map2(local_mapper, from, tld, to,
1282*00b67f09SDavid van Moolenbroek to_length);
1283*00b67f09SDavid van Moolenbroek if (r == idn_success)
1284*00b67f09SDavid van Moolenbroek break;
1285*00b67f09SDavid van Moolenbroek else if (r != idn_buffer_overflow)
1286*00b67f09SDavid van Moolenbroek goto ret;
1287*00b67f09SDavid van Moolenbroek to_length *= 2;
1288*00b67f09SDavid van Moolenbroek }
1289*00b67f09SDavid van Moolenbroek
1290*00b67f09SDavid van Moolenbroek r = labellist_setname(label, to);
1291*00b67f09SDavid van Moolenbroek ret:
1292*00b67f09SDavid van Moolenbroek if (r == idn_success) {
1293*00b67f09SDavid van Moolenbroek TRACE(("res localmap(): success (label=\"%s\")\n",
1294*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(labellist_getname(label),
1295*00b67f09SDavid van Moolenbroek 50)));
1296*00b67f09SDavid van Moolenbroek } else {
1297*00b67f09SDavid van Moolenbroek TRACE(("res localmap(): %s\n", idn_result_tostring(r)));
1298*00b67f09SDavid van Moolenbroek }
1299*00b67f09SDavid van Moolenbroek if (local_mapper != NULL)
1300*00b67f09SDavid van Moolenbroek idn_mapselector_destroy(local_mapper);
1301*00b67f09SDavid van Moolenbroek free(to);
1302*00b67f09SDavid van Moolenbroek return (r);
1303*00b67f09SDavid van Moolenbroek }
1304*00b67f09SDavid van Moolenbroek
1305*00b67f09SDavid van Moolenbroek static idn_result_t
label_map(idn_resconf_t ctx,labellist_t label)1306*00b67f09SDavid van Moolenbroek label_map(idn_resconf_t ctx, labellist_t label) {
1307*00b67f09SDavid van Moolenbroek const unsigned long *from;
1308*00b67f09SDavid van Moolenbroek unsigned long *to = NULL;
1309*00b67f09SDavid van Moolenbroek size_t to_length;
1310*00b67f09SDavid van Moolenbroek idn_mapper_t mapper;
1311*00b67f09SDavid van Moolenbroek idn_result_t r;
1312*00b67f09SDavid van Moolenbroek
1313*00b67f09SDavid van Moolenbroek from = labellist_getname(label);
1314*00b67f09SDavid van Moolenbroek TRACE(("res map(label=\"%s\")\n", idn__debug_ucs4xstring(from, 50)));
1315*00b67f09SDavid van Moolenbroek
1316*00b67f09SDavid van Moolenbroek mapper = idn_resconf_getmapper(ctx);
1317*00b67f09SDavid van Moolenbroek if (mapper == NULL) {
1318*00b67f09SDavid van Moolenbroek r = idn_success;
1319*00b67f09SDavid van Moolenbroek goto ret;
1320*00b67f09SDavid van Moolenbroek }
1321*00b67f09SDavid van Moolenbroek to_length = idn_ucs4_strlen(from) + 1 + 15; /* 15 for margin */
1322*00b67f09SDavid van Moolenbroek
1323*00b67f09SDavid van Moolenbroek for (;;) {
1324*00b67f09SDavid van Moolenbroek unsigned long *new_buffer;
1325*00b67f09SDavid van Moolenbroek
1326*00b67f09SDavid van Moolenbroek new_buffer = (unsigned long *)
1327*00b67f09SDavid van Moolenbroek realloc(to, sizeof(long) * to_length);
1328*00b67f09SDavid van Moolenbroek if (new_buffer == NULL) {
1329*00b67f09SDavid van Moolenbroek r = idn_nomemory;
1330*00b67f09SDavid van Moolenbroek goto ret;
1331*00b67f09SDavid van Moolenbroek }
1332*00b67f09SDavid van Moolenbroek to = new_buffer;
1333*00b67f09SDavid van Moolenbroek r = idn_mapper_map(mapper, from, to, to_length);
1334*00b67f09SDavid van Moolenbroek if (r == idn_success)
1335*00b67f09SDavid van Moolenbroek break;
1336*00b67f09SDavid van Moolenbroek else if (r != idn_buffer_overflow)
1337*00b67f09SDavid van Moolenbroek goto ret;
1338*00b67f09SDavid van Moolenbroek to_length *= 2;
1339*00b67f09SDavid van Moolenbroek }
1340*00b67f09SDavid van Moolenbroek
1341*00b67f09SDavid van Moolenbroek r = labellist_setname(label, to);
1342*00b67f09SDavid van Moolenbroek ret:
1343*00b67f09SDavid van Moolenbroek if (r == idn_success) {
1344*00b67f09SDavid van Moolenbroek TRACE(("res map(): success (label=\"%s\")\n",
1345*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(labellist_getname(label),
1346*00b67f09SDavid van Moolenbroek 50)));
1347*00b67f09SDavid van Moolenbroek } else {
1348*00b67f09SDavid van Moolenbroek TRACE(("res map(): %s\n", idn_result_tostring(r)));
1349*00b67f09SDavid van Moolenbroek }
1350*00b67f09SDavid van Moolenbroek if (mapper != NULL)
1351*00b67f09SDavid van Moolenbroek idn_mapper_destroy(mapper);
1352*00b67f09SDavid van Moolenbroek free(to);
1353*00b67f09SDavid van Moolenbroek return (r);
1354*00b67f09SDavid van Moolenbroek }
1355*00b67f09SDavid van Moolenbroek
1356*00b67f09SDavid van Moolenbroek static idn_result_t
label_normalize(idn_resconf_t ctx,labellist_t label)1357*00b67f09SDavid van Moolenbroek label_normalize(idn_resconf_t ctx, labellist_t label) {
1358*00b67f09SDavid van Moolenbroek const unsigned long *from;
1359*00b67f09SDavid van Moolenbroek unsigned long *to = NULL;
1360*00b67f09SDavid van Moolenbroek size_t to_length;
1361*00b67f09SDavid van Moolenbroek idn_normalizer_t normalizer;
1362*00b67f09SDavid van Moolenbroek idn_result_t r;
1363*00b67f09SDavid van Moolenbroek
1364*00b67f09SDavid van Moolenbroek from = labellist_getname(label);
1365*00b67f09SDavid van Moolenbroek TRACE(("res normalzie(label=\"%s\")\n",
1366*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(from, 50)));
1367*00b67f09SDavid van Moolenbroek
1368*00b67f09SDavid van Moolenbroek normalizer = idn_resconf_getnormalizer(ctx);
1369*00b67f09SDavid van Moolenbroek if (normalizer == NULL) {
1370*00b67f09SDavid van Moolenbroek r = idn_success;
1371*00b67f09SDavid van Moolenbroek goto ret;
1372*00b67f09SDavid van Moolenbroek }
1373*00b67f09SDavid van Moolenbroek to_length = idn_ucs4_strlen(from) + 1 + 15; /* 15 for margin */
1374*00b67f09SDavid van Moolenbroek
1375*00b67f09SDavid van Moolenbroek for (;;) {
1376*00b67f09SDavid van Moolenbroek unsigned long *new_buffer;
1377*00b67f09SDavid van Moolenbroek
1378*00b67f09SDavid van Moolenbroek new_buffer = (unsigned long *)
1379*00b67f09SDavid van Moolenbroek realloc(to, sizeof(long) * to_length);
1380*00b67f09SDavid van Moolenbroek if (new_buffer == NULL) {
1381*00b67f09SDavid van Moolenbroek r = idn_nomemory;
1382*00b67f09SDavid van Moolenbroek goto ret;
1383*00b67f09SDavid van Moolenbroek }
1384*00b67f09SDavid van Moolenbroek to = new_buffer;
1385*00b67f09SDavid van Moolenbroek r = idn_normalizer_normalize(normalizer, from, to, to_length);
1386*00b67f09SDavid van Moolenbroek if (r == idn_success)
1387*00b67f09SDavid van Moolenbroek break;
1388*00b67f09SDavid van Moolenbroek else if (r != idn_buffer_overflow)
1389*00b67f09SDavid van Moolenbroek goto ret;
1390*00b67f09SDavid van Moolenbroek to_length *= 2;
1391*00b67f09SDavid van Moolenbroek }
1392*00b67f09SDavid van Moolenbroek
1393*00b67f09SDavid van Moolenbroek r = labellist_setname(label, to);
1394*00b67f09SDavid van Moolenbroek ret:
1395*00b67f09SDavid van Moolenbroek if (r == idn_success) {
1396*00b67f09SDavid van Moolenbroek TRACE(("res normalize(): success (label=\"%s\")\n",
1397*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(labellist_getname(label),
1398*00b67f09SDavid van Moolenbroek 50)));
1399*00b67f09SDavid van Moolenbroek } else {
1400*00b67f09SDavid van Moolenbroek TRACE(("res normalize(): %s\n", idn_result_tostring(r)));
1401*00b67f09SDavid van Moolenbroek }
1402*00b67f09SDavid van Moolenbroek if (normalizer != NULL)
1403*00b67f09SDavid van Moolenbroek idn_normalizer_destroy(normalizer);
1404*00b67f09SDavid van Moolenbroek free(to);
1405*00b67f09SDavid van Moolenbroek return (r);
1406*00b67f09SDavid van Moolenbroek }
1407*00b67f09SDavid van Moolenbroek
1408*00b67f09SDavid van Moolenbroek static idn_result_t
label_prohcheck(idn_resconf_t ctx,labellist_t label)1409*00b67f09SDavid van Moolenbroek label_prohcheck(idn_resconf_t ctx, labellist_t label) {
1410*00b67f09SDavid van Moolenbroek const unsigned long *name, *found;
1411*00b67f09SDavid van Moolenbroek idn_checker_t prohibit_checker;
1412*00b67f09SDavid van Moolenbroek idn_result_t r;
1413*00b67f09SDavid van Moolenbroek
1414*00b67f09SDavid van Moolenbroek name = labellist_getname(label);
1415*00b67f09SDavid van Moolenbroek TRACE(("res prohcheck(label=\"%s\")\n",
1416*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(name, 50)));
1417*00b67f09SDavid van Moolenbroek
1418*00b67f09SDavid van Moolenbroek prohibit_checker = idn_resconf_getprohibitchecker(ctx);
1419*00b67f09SDavid van Moolenbroek if (prohibit_checker == NULL) {
1420*00b67f09SDavid van Moolenbroek r = idn_success;
1421*00b67f09SDavid van Moolenbroek goto ret;
1422*00b67f09SDavid van Moolenbroek }
1423*00b67f09SDavid van Moolenbroek
1424*00b67f09SDavid van Moolenbroek r = idn_checker_lookup(prohibit_checker, name, &found);
1425*00b67f09SDavid van Moolenbroek idn_checker_destroy(prohibit_checker);
1426*00b67f09SDavid van Moolenbroek if (r == idn_success && found != NULL)
1427*00b67f09SDavid van Moolenbroek r = idn_prohibited;
1428*00b67f09SDavid van Moolenbroek
1429*00b67f09SDavid van Moolenbroek ret:
1430*00b67f09SDavid van Moolenbroek TRACE(("res prohcheck(): %s\n", idn_result_tostring(r)));
1431*00b67f09SDavid van Moolenbroek return (r);
1432*00b67f09SDavid van Moolenbroek }
1433*00b67f09SDavid van Moolenbroek
1434*00b67f09SDavid van Moolenbroek static idn_result_t
label_unascheck(idn_resconf_t ctx,labellist_t label)1435*00b67f09SDavid van Moolenbroek label_unascheck(idn_resconf_t ctx, labellist_t label) {
1436*00b67f09SDavid van Moolenbroek const unsigned long *name, *found;
1437*00b67f09SDavid van Moolenbroek idn_checker_t unassigned_checker;
1438*00b67f09SDavid van Moolenbroek idn_result_t r;
1439*00b67f09SDavid van Moolenbroek
1440*00b67f09SDavid van Moolenbroek name = labellist_getname(label);
1441*00b67f09SDavid van Moolenbroek TRACE(("res unascheck(label=\"%s\")\n",
1442*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(name, 50)));
1443*00b67f09SDavid van Moolenbroek
1444*00b67f09SDavid van Moolenbroek unassigned_checker = idn_resconf_getunassignedchecker(ctx);
1445*00b67f09SDavid van Moolenbroek if (unassigned_checker == NULL) {
1446*00b67f09SDavid van Moolenbroek r = idn_success;
1447*00b67f09SDavid van Moolenbroek goto ret;
1448*00b67f09SDavid van Moolenbroek }
1449*00b67f09SDavid van Moolenbroek
1450*00b67f09SDavid van Moolenbroek r = idn_checker_lookup(unassigned_checker, name, &found);
1451*00b67f09SDavid van Moolenbroek idn_checker_destroy(unassigned_checker);
1452*00b67f09SDavid van Moolenbroek if (r == idn_success && found != NULL)
1453*00b67f09SDavid van Moolenbroek r = idn_prohibited;
1454*00b67f09SDavid van Moolenbroek
1455*00b67f09SDavid van Moolenbroek ret:
1456*00b67f09SDavid van Moolenbroek TRACE(("res unascheck(): %s\n", idn_result_tostring(r)));
1457*00b67f09SDavid van Moolenbroek return (r);
1458*00b67f09SDavid van Moolenbroek }
1459*00b67f09SDavid van Moolenbroek
1460*00b67f09SDavid van Moolenbroek static idn_result_t
label_bidicheck(idn_resconf_t ctx,labellist_t label)1461*00b67f09SDavid van Moolenbroek label_bidicheck(idn_resconf_t ctx, labellist_t label) {
1462*00b67f09SDavid van Moolenbroek const unsigned long *name, *found;
1463*00b67f09SDavid van Moolenbroek idn_checker_t bidi_checker;
1464*00b67f09SDavid van Moolenbroek idn_result_t r;
1465*00b67f09SDavid van Moolenbroek
1466*00b67f09SDavid van Moolenbroek name = labellist_getname(label);
1467*00b67f09SDavid van Moolenbroek TRACE(("res bidicheck(label=\"%s\")\n",
1468*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(name, 50)));
1469*00b67f09SDavid van Moolenbroek
1470*00b67f09SDavid van Moolenbroek bidi_checker = idn_resconf_getbidichecker(ctx);
1471*00b67f09SDavid van Moolenbroek if (bidi_checker == NULL) {
1472*00b67f09SDavid van Moolenbroek r = idn_success;
1473*00b67f09SDavid van Moolenbroek goto ret;
1474*00b67f09SDavid van Moolenbroek }
1475*00b67f09SDavid van Moolenbroek
1476*00b67f09SDavid van Moolenbroek r = idn_checker_lookup(bidi_checker, name, &found);
1477*00b67f09SDavid van Moolenbroek idn_checker_destroy(bidi_checker);
1478*00b67f09SDavid van Moolenbroek if (r == idn_success && found != NULL)
1479*00b67f09SDavid van Moolenbroek r = idn_prohibited;
1480*00b67f09SDavid van Moolenbroek
1481*00b67f09SDavid van Moolenbroek ret:
1482*00b67f09SDavid van Moolenbroek TRACE(("res bidicheck(): %s\n", idn_result_tostring(r)));
1483*00b67f09SDavid van Moolenbroek return (r);
1484*00b67f09SDavid van Moolenbroek }
1485*00b67f09SDavid van Moolenbroek
1486*00b67f09SDavid van Moolenbroek static idn_result_t
label_asccheck(idn_resconf_t ctx,labellist_t label)1487*00b67f09SDavid van Moolenbroek label_asccheck(idn_resconf_t ctx, labellist_t label) {
1488*00b67f09SDavid van Moolenbroek const unsigned long *name, *n;
1489*00b67f09SDavid van Moolenbroek idn_result_t r;
1490*00b67f09SDavid van Moolenbroek
1491*00b67f09SDavid van Moolenbroek name = labellist_getname(label);
1492*00b67f09SDavid van Moolenbroek TRACE(("res asccheck(label=\"%s\")\n",
1493*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(name, 50)));
1494*00b67f09SDavid van Moolenbroek
1495*00b67f09SDavid van Moolenbroek if (*name == '-') {
1496*00b67f09SDavid van Moolenbroek r = idn_prohibited;
1497*00b67f09SDavid van Moolenbroek goto ret;
1498*00b67f09SDavid van Moolenbroek }
1499*00b67f09SDavid van Moolenbroek
1500*00b67f09SDavid van Moolenbroek for (n = name; *n != '\0'; n++) {
1501*00b67f09SDavid van Moolenbroek if (*n <= '\177') {
1502*00b67f09SDavid van Moolenbroek if ((*n < '0' || *n > '9') &&
1503*00b67f09SDavid van Moolenbroek (*n < 'A' || *n > 'Z') &&
1504*00b67f09SDavid van Moolenbroek (*n < 'a' || *n > 'z') &&
1505*00b67f09SDavid van Moolenbroek *n != '-') {
1506*00b67f09SDavid van Moolenbroek r = idn_prohibited;
1507*00b67f09SDavid van Moolenbroek goto ret;
1508*00b67f09SDavid van Moolenbroek }
1509*00b67f09SDavid van Moolenbroek }
1510*00b67f09SDavid van Moolenbroek }
1511*00b67f09SDavid van Moolenbroek
1512*00b67f09SDavid van Moolenbroek if (n > name && *(n - 1) == '-') {
1513*00b67f09SDavid van Moolenbroek r = idn_prohibited;
1514*00b67f09SDavid van Moolenbroek goto ret;
1515*00b67f09SDavid van Moolenbroek }
1516*00b67f09SDavid van Moolenbroek
1517*00b67f09SDavid van Moolenbroek r = idn_success;
1518*00b67f09SDavid van Moolenbroek ret:
1519*00b67f09SDavid van Moolenbroek TRACE(("res asccheck(): %s\n", idn_result_tostring(r)));
1520*00b67f09SDavid van Moolenbroek return (r);
1521*00b67f09SDavid van Moolenbroek }
1522*00b67f09SDavid van Moolenbroek
1523*00b67f09SDavid van Moolenbroek static idn_result_t
label_lencheck_ace(idn_resconf_t ctx,labellist_t label)1524*00b67f09SDavid van Moolenbroek label_lencheck_ace(idn_resconf_t ctx, labellist_t label) {
1525*00b67f09SDavid van Moolenbroek const unsigned long *name;
1526*00b67f09SDavid van Moolenbroek size_t name_length;
1527*00b67f09SDavid van Moolenbroek idn_result_t r;
1528*00b67f09SDavid van Moolenbroek
1529*00b67f09SDavid van Moolenbroek name = labellist_getname(label);
1530*00b67f09SDavid van Moolenbroek name_length = idn_ucs4_strlen(name);
1531*00b67f09SDavid van Moolenbroek TRACE(("res lencheck(label=\"%s\")\n",
1532*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(name, 50)));
1533*00b67f09SDavid van Moolenbroek
1534*00b67f09SDavid van Moolenbroek if (name_length == 0 || name_length > MAX_LABEL_LENGTH) {
1535*00b67f09SDavid van Moolenbroek r = idn_invalid_length;
1536*00b67f09SDavid van Moolenbroek goto ret;
1537*00b67f09SDavid van Moolenbroek }
1538*00b67f09SDavid van Moolenbroek
1539*00b67f09SDavid van Moolenbroek r = idn_success;
1540*00b67f09SDavid van Moolenbroek ret:
1541*00b67f09SDavid van Moolenbroek TRACE(("res lencheck(): %s\n", idn_result_tostring(r)));
1542*00b67f09SDavid van Moolenbroek return (r);
1543*00b67f09SDavid van Moolenbroek }
1544*00b67f09SDavid van Moolenbroek
1545*00b67f09SDavid van Moolenbroek static idn_result_t
label_lencheck_nonace(idn_resconf_t ctx,labellist_t label)1546*00b67f09SDavid van Moolenbroek label_lencheck_nonace(idn_resconf_t ctx, labellist_t label) {
1547*00b67f09SDavid van Moolenbroek idn_converter_t idn_converter;
1548*00b67f09SDavid van Moolenbroek const unsigned long *from;
1549*00b67f09SDavid van Moolenbroek size_t to_length;
1550*00b67f09SDavid van Moolenbroek idn_result_t r;
1551*00b67f09SDavid van Moolenbroek char *buffer = NULL;
1552*00b67f09SDavid van Moolenbroek size_t buffer_length;
1553*00b67f09SDavid van Moolenbroek
1554*00b67f09SDavid van Moolenbroek from = labellist_getname(label);
1555*00b67f09SDavid van Moolenbroek TRACE(("res lencheck(label=\"%s\")\n",
1556*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(from, 50)));
1557*00b67f09SDavid van Moolenbroek
1558*00b67f09SDavid van Moolenbroek buffer_length = idn_ucs4_strlen(from) * 4 + 16; /* 16 for margin */
1559*00b67f09SDavid van Moolenbroek idn_converter = idn_resconf_getidnconverter(ctx);
1560*00b67f09SDavid van Moolenbroek
1561*00b67f09SDavid van Moolenbroek for (;;) {
1562*00b67f09SDavid van Moolenbroek void *new_buffer;
1563*00b67f09SDavid van Moolenbroek
1564*00b67f09SDavid van Moolenbroek new_buffer = realloc(buffer, sizeof(*buffer) * buffer_length);
1565*00b67f09SDavid van Moolenbroek if (new_buffer == NULL) {
1566*00b67f09SDavid van Moolenbroek r = idn_nomemory;
1567*00b67f09SDavid van Moolenbroek goto ret;
1568*00b67f09SDavid van Moolenbroek }
1569*00b67f09SDavid van Moolenbroek buffer = (char *)new_buffer;
1570*00b67f09SDavid van Moolenbroek
1571*00b67f09SDavid van Moolenbroek if (idn_converter != NULL) {
1572*00b67f09SDavid van Moolenbroek r = idn_converter_convfromucs4(idn_converter, from,
1573*00b67f09SDavid van Moolenbroek buffer, buffer_length);
1574*00b67f09SDavid van Moolenbroek } else {
1575*00b67f09SDavid van Moolenbroek r = idn_ucs4_ucs4toutf8(from, buffer, buffer_length);
1576*00b67f09SDavid van Moolenbroek }
1577*00b67f09SDavid van Moolenbroek if (r == idn_success)
1578*00b67f09SDavid van Moolenbroek break;
1579*00b67f09SDavid van Moolenbroek else if (r != idn_buffer_overflow)
1580*00b67f09SDavid van Moolenbroek goto ret;
1581*00b67f09SDavid van Moolenbroek
1582*00b67f09SDavid van Moolenbroek buffer_length *= 2;
1583*00b67f09SDavid van Moolenbroek }
1584*00b67f09SDavid van Moolenbroek
1585*00b67f09SDavid van Moolenbroek to_length = strlen(buffer);
1586*00b67f09SDavid van Moolenbroek if (to_length == 0 || to_length > MAX_LABEL_LENGTH) {
1587*00b67f09SDavid van Moolenbroek r = idn_invalid_length;
1588*00b67f09SDavid van Moolenbroek goto ret;
1589*00b67f09SDavid van Moolenbroek }
1590*00b67f09SDavid van Moolenbroek
1591*00b67f09SDavid van Moolenbroek r = idn_success;
1592*00b67f09SDavid van Moolenbroek ret:
1593*00b67f09SDavid van Moolenbroek TRACE(("res lencheck(): %s\n", idn_result_tostring(r)));
1594*00b67f09SDavid van Moolenbroek if (idn_converter != NULL)
1595*00b67f09SDavid van Moolenbroek idn_converter_destroy(idn_converter);
1596*00b67f09SDavid van Moolenbroek free(buffer);
1597*00b67f09SDavid van Moolenbroek return (r);
1598*00b67f09SDavid van Moolenbroek }
1599*00b67f09SDavid van Moolenbroek
1600*00b67f09SDavid van Moolenbroek static idn_result_t
label_rtcheck(idn_resconf_t ctx,idn_action_t actions,labellist_t label,const unsigned long * original_name)1601*00b67f09SDavid van Moolenbroek label_rtcheck(idn_resconf_t ctx, idn_action_t actions, labellist_t label,
1602*00b67f09SDavid van Moolenbroek const unsigned long *original_name) {
1603*00b67f09SDavid van Moolenbroek labellist_t rt_label = NULL;
1604*00b67f09SDavid van Moolenbroek const unsigned long *rt_name;
1605*00b67f09SDavid van Moolenbroek const unsigned long *cur_name;
1606*00b67f09SDavid van Moolenbroek idn_result_t r;
1607*00b67f09SDavid van Moolenbroek
1608*00b67f09SDavid van Moolenbroek cur_name = labellist_getname(label);
1609*00b67f09SDavid van Moolenbroek TRACE(("res rtcheck(label=\"%s\", org_label=\"%s\")\n",
1610*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(cur_name, 50),
1611*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(original_name, 50)));
1612*00b67f09SDavid van Moolenbroek
1613*00b67f09SDavid van Moolenbroek r = labellist_create(cur_name, &rt_label);
1614*00b67f09SDavid van Moolenbroek if (r != idn_success)
1615*00b67f09SDavid van Moolenbroek goto ret;
1616*00b67f09SDavid van Moolenbroek if (rt_label == NULL) {
1617*00b67f09SDavid van Moolenbroek if (*original_name == '\0')
1618*00b67f09SDavid van Moolenbroek r = idn_success;
1619*00b67f09SDavid van Moolenbroek else
1620*00b67f09SDavid van Moolenbroek r = idn_invalid_encoding;
1621*00b67f09SDavid van Moolenbroek goto ret;
1622*00b67f09SDavid van Moolenbroek }
1623*00b67f09SDavid van Moolenbroek
1624*00b67f09SDavid van Moolenbroek if (!idn__util_ucs4isasciirange(labellist_getname(rt_label))) {
1625*00b67f09SDavid van Moolenbroek r = label_map(ctx, rt_label);
1626*00b67f09SDavid van Moolenbroek if (r != idn_success)
1627*00b67f09SDavid van Moolenbroek goto ret;
1628*00b67f09SDavid van Moolenbroek r = label_normalize(ctx, rt_label);
1629*00b67f09SDavid van Moolenbroek if (r != idn_success)
1630*00b67f09SDavid van Moolenbroek goto ret;
1631*00b67f09SDavid van Moolenbroek r = label_prohcheck(ctx, rt_label);
1632*00b67f09SDavid van Moolenbroek if (r != idn_success)
1633*00b67f09SDavid van Moolenbroek goto ret;
1634*00b67f09SDavid van Moolenbroek if (actions & IDN_UNASCHECK) {
1635*00b67f09SDavid van Moolenbroek r = label_unascheck(ctx, rt_label);
1636*00b67f09SDavid van Moolenbroek if (r != idn_success)
1637*00b67f09SDavid van Moolenbroek goto ret;
1638*00b67f09SDavid van Moolenbroek }
1639*00b67f09SDavid van Moolenbroek r = label_bidicheck(ctx, rt_label);
1640*00b67f09SDavid van Moolenbroek if (r != idn_success)
1641*00b67f09SDavid van Moolenbroek goto ret;
1642*00b67f09SDavid van Moolenbroek }
1643*00b67f09SDavid van Moolenbroek
1644*00b67f09SDavid van Moolenbroek if (actions & IDN_ASCCHECK) {
1645*00b67f09SDavid van Moolenbroek r = label_asccheck(ctx, rt_label);
1646*00b67f09SDavid van Moolenbroek if (r != idn_success)
1647*00b67f09SDavid van Moolenbroek goto ret;
1648*00b67f09SDavid van Moolenbroek }
1649*00b67f09SDavid van Moolenbroek if (!idn__util_ucs4isasciirange(labellist_getname(rt_label))) {
1650*00b67f09SDavid van Moolenbroek r = label_idnencode_ace(ctx, rt_label);
1651*00b67f09SDavid van Moolenbroek if (r != idn_success)
1652*00b67f09SDavid van Moolenbroek goto ret;
1653*00b67f09SDavid van Moolenbroek }
1654*00b67f09SDavid van Moolenbroek r = label_lencheck_ace(ctx, rt_label);
1655*00b67f09SDavid van Moolenbroek if (r != idn_success)
1656*00b67f09SDavid van Moolenbroek goto ret;
1657*00b67f09SDavid van Moolenbroek rt_name = labellist_getname(rt_label);
1658*00b67f09SDavid van Moolenbroek
1659*00b67f09SDavid van Moolenbroek if (idn_ucs4_strcasecmp(rt_name, original_name) != 0) {
1660*00b67f09SDavid van Moolenbroek TRACE(("res rtcheck(): round trip failed, org =\"%s\", rt=\"%s\"\n",
1661*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(original_name, 50),
1662*00b67f09SDavid van Moolenbroek idn__debug_ucs4xstring(rt_name, 50)));
1663*00b67f09SDavid van Moolenbroek r = idn_invalid_encoding;
1664*00b67f09SDavid van Moolenbroek goto ret;
1665*00b67f09SDavid van Moolenbroek }
1666*00b67f09SDavid van Moolenbroek
1667*00b67f09SDavid van Moolenbroek r = idn_success;
1668*00b67f09SDavid van Moolenbroek ret:
1669*00b67f09SDavid van Moolenbroek if (r != idn_nomemory && r != idn_success)
1670*00b67f09SDavid van Moolenbroek r = idn_invalid_encoding;
1671*00b67f09SDavid van Moolenbroek TRACE(("res rtcheck(): %s\n", idn_result_tostring(r)));
1672*00b67f09SDavid van Moolenbroek if (rt_label != NULL)
1673*00b67f09SDavid van Moolenbroek labellist_destroy(rt_label);
1674*00b67f09SDavid van Moolenbroek return (r);
1675*00b67f09SDavid van Moolenbroek }
1676*00b67f09SDavid van Moolenbroek
1677*00b67f09SDavid van Moolenbroek const char *
idn__res_actionstostring(idn_action_t actions)1678*00b67f09SDavid van Moolenbroek idn__res_actionstostring(idn_action_t actions) {
1679*00b67f09SDavid van Moolenbroek static char buf[100];
1680*00b67f09SDavid van Moolenbroek
1681*00b67f09SDavid van Moolenbroek buf[0] = '\0';
1682*00b67f09SDavid van Moolenbroek
1683*00b67f09SDavid van Moolenbroek if (actions == IDN_ENCODE_QUERY)
1684*00b67f09SDavid van Moolenbroek strcpy(buf, "encode-query");
1685*00b67f09SDavid van Moolenbroek else if (actions == IDN_DECODE_QUERY)
1686*00b67f09SDavid van Moolenbroek strcpy(buf, "decode-query");
1687*00b67f09SDavid van Moolenbroek else if (actions == IDN_ENCODE_APP)
1688*00b67f09SDavid van Moolenbroek strcpy(buf, "encode-app");
1689*00b67f09SDavid van Moolenbroek else if (actions == IDN_DECODE_APP)
1690*00b67f09SDavid van Moolenbroek strcpy(buf, "decode-app");
1691*00b67f09SDavid van Moolenbroek else if (actions == IDN_ENCODE_STORED)
1692*00b67f09SDavid van Moolenbroek strcpy(buf, "encode-stored");
1693*00b67f09SDavid van Moolenbroek else if (actions == IDN_DECODE_STORED)
1694*00b67f09SDavid van Moolenbroek strcpy(buf, "decode-stored");
1695*00b67f09SDavid van Moolenbroek else {
1696*00b67f09SDavid van Moolenbroek if (actions & IDN_LOCALCONV)
1697*00b67f09SDavid van Moolenbroek strcat(buf, "|localconv");
1698*00b67f09SDavid van Moolenbroek if (actions & IDN_DELIMMAP)
1699*00b67f09SDavid van Moolenbroek strcat(buf, "|delimmap");
1700*00b67f09SDavid van Moolenbroek if (actions & IDN_LOCALMAP)
1701*00b67f09SDavid van Moolenbroek strcat(buf, "|localmap");
1702*00b67f09SDavid van Moolenbroek
1703*00b67f09SDavid van Moolenbroek if (actions & IDN_MAP)
1704*00b67f09SDavid van Moolenbroek strcat(buf, "|map");
1705*00b67f09SDavid van Moolenbroek if (actions & IDN_NORMALIZE)
1706*00b67f09SDavid van Moolenbroek strcat(buf, "|normalize");
1707*00b67f09SDavid van Moolenbroek if (actions & IDN_PROHCHECK)
1708*00b67f09SDavid van Moolenbroek strcat(buf, "|prohcheck");
1709*00b67f09SDavid van Moolenbroek if (actions & IDN_UNASCHECK)
1710*00b67f09SDavid van Moolenbroek strcat(buf, "|unascheck");
1711*00b67f09SDavid van Moolenbroek if (actions & IDN_BIDICHECK)
1712*00b67f09SDavid van Moolenbroek strcat(buf, "|bidicheck");
1713*00b67f09SDavid van Moolenbroek
1714*00b67f09SDavid van Moolenbroek if (actions & IDN_IDNCONV)
1715*00b67f09SDavid van Moolenbroek strcat(buf, "|idnconv");
1716*00b67f09SDavid van Moolenbroek if (actions & IDN_ASCCHECK)
1717*00b67f09SDavid van Moolenbroek strcat(buf, "|asccheck");
1718*00b67f09SDavid van Moolenbroek if (actions & IDN_LENCHECK)
1719*00b67f09SDavid van Moolenbroek strcat(buf, "|lencheck");
1720*00b67f09SDavid van Moolenbroek if (actions & IDN_RTCHECK)
1721*00b67f09SDavid van Moolenbroek strcat(buf, "|rtcheck");
1722*00b67f09SDavid van Moolenbroek }
1723*00b67f09SDavid van Moolenbroek
1724*00b67f09SDavid van Moolenbroek if (buf[0] == '|')
1725*00b67f09SDavid van Moolenbroek return (buf + 1);
1726*00b67f09SDavid van Moolenbroek else
1727*00b67f09SDavid van Moolenbroek return (buf);
1728*00b67f09SDavid van Moolenbroek }
1729