1 /* $NetBSD: resconf.c,v 1.4 2014/12/10 04:37:55 christos Exp $ */
4 static char *rcsid
= "Id: resconf.c,v 1.1 2003/06/04 00:26:12 marka Exp ";
8 * Copyright (c) 2000 Japan Network Information Center. All rights reserved.
10 * By using this file, you agree to the terms and conditions set forth bellow.
12 * LICENSE TERMS AND CONDITIONS
14 * The following License Terms and Conditions apply, unless a different
15 * license is obtained from Japan Network Information Center ("JPNIC"),
16 * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
17 * Chiyoda-ku, Tokyo 101-0047, Japan.
19 * 1. Use, Modification and Redistribution (including distribution of any
20 * modified or derived work) in source and/or binary forms is permitted
21 * under this License Terms and Conditions.
23 * 2. Redistribution of source code must retain the copyright notices as they
24 * appear in each source code file, this License Terms and Conditions.
26 * 3. Redistribution in binary form must reproduce the Copyright Notice,
27 * this License Terms and Conditions, in the documentation and/or other
28 * materials provided with the distribution. For the purposes of binary
29 * distribution the "Copyright Notice" refers to the following language:
30 * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
32 * 4. The name of JPNIC may not be used to endorse or promote products
33 * derived from this Software without specific prior written approval of
36 * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
37 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
38 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
39 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
40 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
41 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
42 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
46 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
65 #include <idn/result.h>
66 #include <idn/assert.h>
67 #include <idn/logmacro.h>
68 #include <idn/converter.h>
69 #include <idn/nameprep.h>
70 #include <idn/normalizer.h>
71 #include <idn/checker.h>
72 #include <idn/mapper.h>
73 #include <idn/mapselector.h>
74 #include <idn/delimitermap.h>
75 #include <idn/localencoding.h>
76 #include <idn/resconf.h>
77 #include <idn/debug.h>
81 #define MAX_PATH_SIZE 500 /* a good longer than MAX_PATH */
82 #define IDNVAL_CONFFILE "ConfFile"
85 #ifndef IDN_RESCONF_DIR
86 #define IDN_RESCONF_DIR "/etc"
88 #define IDN_RESCONF_FILE IDN_RESCONF_DIR "/idn.conf"
89 #define IDN_USER_RESCONF_FILE "/.idnrc"
93 #define MAX_CONF_LINE_LENGTH 255
94 #define MAX_CONF_LINE_ARGS 63
96 #define DEFAULT_CONF_NAMEPREP 0x0001
97 #define DEFAULT_CONF_IDN_ENCODING 0x0010
98 #define DEFAULT_CONF_ALL (DEFAULT_CONF_NAMEPREP | \
99 DEFAULT_CONF_IDN_ENCODING)
101 #define IDN_ENCODING_CURRENT "Punycode"
103 #ifdef ENABLE_MDNKIT_COMPAT
104 #define MDN_RESCONF_FILE IDN_RESCONF_DIR "/mdn.conf"
108 int local_converter_is_static
;
109 idn_converter_t local_converter
;
110 idn_converter_t idn_converter
;
111 idn_converter_t aux_idn_converter
;
112 idn_normalizer_t normalizer
;
113 idn_checker_t prohibit_checker
;
114 idn_checker_t unassigned_checker
;
115 idn_checker_t bidi_checker
;
117 idn_mapselector_t local_mapper
;
118 idn_delimitermap_t delimiter_mapper
;
122 static int initialized
;
125 static const char * userhomedir(void);
127 static idn_result_t
open_userdefaultfile(FILE **fpp
);
128 static idn_result_t
open_defaultfile(FILE **fpp
);
129 static idn_result_t
parse_conf(idn_resconf_t ctx
, FILE *fp
);
130 static idn_result_t
parse_idn_encoding(idn_resconf_t ctx
, char *args
,
132 static idn_result_t
parse_local_map(idn_resconf_t ctx
, char *args
,
134 static idn_result_t
parse_nameprep(idn_resconf_t ctx
, char *args
,
136 static int split_args(char *s
, char **av
, int max_ac
);
137 static void resetconf(idn_resconf_t ctx
);
138 #ifndef WITHOUT_ICONV
139 static idn_result_t
update_local_converter(idn_resconf_t ctx
);
141 static idn_result_t
setdefaults_body(idn_resconf_t ctx
, int conf_mask
);
144 idn_resconf_initialize(void) {
147 TRACE(("idn_resconf_initialize()\n"));
155 * Initialize sub modules.
157 if ((r
= idn_converter_initialize()) != idn_success
)
159 if ((r
= idn_normalizer_initialize()) != idn_success
)
161 if ((r
= idn_checker_initialize()) != idn_success
)
163 if ((r
= idn_mapselector_initialize()) != idn_success
)
165 if ((r
= idn_mapper_initialize()) != idn_success
)
171 TRACE(("idn_resconf_initialize(): %s\n", idn_result_tostring(r
)));
176 idn_resconf_create(idn_resconf_t
*ctxp
) {
177 idn_resconf_t ctx
= NULL
;
180 assert(ctxp
!= NULL
);
182 TRACE(("idn_resconf_create()\n"));
188 if ((ctx
= malloc(sizeof(*ctx
))) == NULL
) {
193 ctx
->local_converter_is_static
= 0;
194 ctx
->local_converter
= NULL
;
195 ctx
->idn_converter
= NULL
;
196 ctx
->aux_idn_converter
= NULL
;
197 ctx
->normalizer
= NULL
;
198 ctx
->prohibit_checker
= NULL
;
199 ctx
->unassigned_checker
= NULL
;
200 ctx
->bidi_checker
= NULL
;
202 ctx
->local_mapper
= NULL
;
203 ctx
->reference_count
= 1;
205 r
= idn_delimitermap_create(&ctx
->delimiter_mapper
);
206 if (r
!= idn_success
)
212 TRACE(("idn_resconf_create(): %s\n", idn_result_tostring(r
)));
217 idn_resconf_defaultfile() {
219 static char default_path
[MAX_PATH_SIZE
];
221 if (idn__util_getregistrystring(idn__util_hkey_localmachine
,
222 IDNVAL_CONFFILE
, default_path
,
223 sizeof(default_path
))) {
224 return (default_path
);
229 return (IDN_RESCONF_FILE
);
245 return (pwd
->pw_dir
);
250 open_userdefaultfile(FILE **fpp
) {
252 char user_path
[MAX_PATH_SIZE
];
254 TRACE(("open_userdefaultfile()\n"));
256 if (idn__util_getregistrystring(idn__util_hkey_currentuser
,
257 IDNVAL_CONFFILE
, user_path
,
258 sizeof(user_path
)) == 0) {
261 *fpp
= fopen(user_path
, "r");
265 return (idn_success
);
271 TRACE(("open_userdefaultfile()\n"));
273 homedir
= userhomedir();
274 len
= strlen(IDN_USER_RESCONF_FILE
) + 1;
275 if (homedir
!= NULL
) {
276 len
+= strlen(homedir
);
278 return (idn_notfound
);
281 file
= (char *)malloc(sizeof(char) * len
);
283 WARNING(("open_userdefaultfile(): malloc failed\n"));
284 return (idn_nomemory
);
287 (void)strcpy(file
, homedir
);
288 strcat(file
, IDN_USER_RESCONF_FILE
);
290 *fpp
= fopen(file
, "r");
296 return (idn_success
);
301 open_defaultfile(FILE **fpp
) {
305 r
= open_userdefaultfile(fpp
);
306 if (r
== idn_nofile
|| r
== idn_notfound
) {
307 TRACE(("open_defaultfile: "
308 "cannot open user configuration file\n"));
309 file
= idn_resconf_defaultfile();
310 *fpp
= fopen(file
, "r");
311 #ifdef ENABLE_MDNKIT_COMPAT
313 *fpp
= fopen(MDN_RESCONF_FILE
, "r");
316 TRACE(("open_defaultfile: "
317 "cannot open system configuration file\n"));
320 } else if (r
!= idn_success
) {
324 return (idn_success
);
328 idn_resconf_loadfile(idn_resconf_t ctx
, const char *file
) {
334 TRACE(("idn_resconf_loadfile(file=%s)\n",
335 file
== NULL
? "<null>" : file
));
338 r
= idn_delimitermap_create(&ctx
->delimiter_mapper
);
339 if (r
!= idn_success
) {
344 r
= open_defaultfile(&fp
);
345 if (r
== idn_nofile
|| r
== idn_notfound
) {
346 r
= setdefaults_body(ctx
, 0);
348 } else if (r
!= idn_success
) {
352 fp
= fopen(file
, "r");
354 TRACE(("idn_resconf_loadfile: cannot open %-.40s\n",
361 r
= parse_conf(ctx
, fp
);
365 TRACE(("idn_resconf_loadfile(): %s\n", idn_result_tostring(r
)));
370 idn_resconf_destroy(idn_resconf_t ctx
) {
373 TRACE(("idn_resconf_destroy()\n"));
375 ctx
->reference_count
--;
376 if (ctx
->reference_count
<= 0) {
379 TRACE(("idn_resconf_destroy: the object is destroyed\n"));
381 TRACE(("idn_resconf_destroy(): "
382 "update reference count (%d->%d)\n",
383 ctx
->reference_count
+ 1, ctx
->reference_count
));
388 idn_resconf_incrref(idn_resconf_t ctx
) {
391 TRACE(("idn_resconf_incrref()\n"));
392 TRACE(("idn_resconf_incrref: update reference count (%d->%d)\n",
393 ctx
->reference_count
, ctx
->reference_count
+ 1));
395 ctx
->reference_count
++;
399 idn_resconf_getalternateconverter(idn_resconf_t ctx
) {
402 TRACE(("idn_resconf_getalternateconverter()\n"));
404 return (idn_resconf_getidnconverter(ctx
));
408 idn_resconf_getdelimitermap(idn_resconf_t ctx
) {
411 TRACE(("idn_resconf_getdelimitermap()\n"));
413 if (ctx
->delimiter_mapper
!= NULL
)
414 idn_delimitermap_incrref(ctx
->delimiter_mapper
);
415 return (ctx
->delimiter_mapper
);
419 idn_resconf_getidnconverter(idn_resconf_t ctx
) {
422 TRACE(("idn_resconf_getidnconverter()\n"));
424 if (ctx
->idn_converter
!= NULL
)
425 idn_converter_incrref(ctx
->idn_converter
);
426 return (ctx
->idn_converter
);
430 idn_resconf_getauxidnconverter(idn_resconf_t ctx
) {
433 TRACE(("idn_resconf_getauxidnconverter()\n"));
435 if (ctx
->aux_idn_converter
!= NULL
)
436 idn_converter_incrref(ctx
->aux_idn_converter
);
437 return (ctx
->aux_idn_converter
);
441 idn_resconf_getlocalconverter(idn_resconf_t ctx
) {
444 TRACE(("idn_resconf_getlocalconverter()\n"));
449 #else /* WITHOUT_ICONV */
450 if (update_local_converter(ctx
) != idn_success
)
453 idn_converter_incrref(ctx
->local_converter
);
454 return (ctx
->local_converter
);
456 #endif /* WITHOUT_ICONV */
460 idn_resconf_getlocalmapselector(idn_resconf_t ctx
) {
463 TRACE(("idn_resconf_getlocalmapselector()\n"));
465 if (ctx
->local_mapper
!= NULL
)
466 idn_mapselector_incrref(ctx
->local_mapper
);
467 return (ctx
->local_mapper
);
471 idn_resconf_getmapper(idn_resconf_t ctx
) {
474 TRACE(("idn_resconf_getmapper()\n"));
476 if (ctx
->mapper
!= NULL
)
477 idn_mapper_incrref(ctx
->mapper
);
478 return (ctx
->mapper
);
482 idn_resconf_getnormalizer(idn_resconf_t ctx
) {
485 TRACE(("idn_resconf_getnormalizer()\n"));
487 if (ctx
->normalizer
!= NULL
)
488 idn_normalizer_incrref(ctx
->normalizer
);
489 return (ctx
->normalizer
);
493 idn_resconf_getprohibitchecker(idn_resconf_t ctx
) {
496 TRACE(("idn_resconf_getprohibitchecker()\n"));
498 if (ctx
->prohibit_checker
!= NULL
)
499 idn_checker_incrref(ctx
->prohibit_checker
);
500 return (ctx
->prohibit_checker
);
504 idn_resconf_getunassignedchecker(idn_resconf_t ctx
) {
507 TRACE(("idn_resconf_getunassignedchecker()\n"));
509 if (ctx
->unassigned_checker
!= NULL
)
510 idn_checker_incrref(ctx
->unassigned_checker
);
511 return (ctx
->unassigned_checker
);
515 idn_resconf_getbidichecker(idn_resconf_t ctx
) {
518 TRACE(("idn_resconf_getbidichecker()\n"));
520 if (ctx
->bidi_checker
!= NULL
)
521 idn_checker_incrref(ctx
->bidi_checker
);
522 return (ctx
->bidi_checker
);
526 idn_resconf_setalternateconverter(idn_resconf_t ctx
,
527 idn_converter_t alternate_converter
) {
530 TRACE(("idn_resconf_setalternateconverter()\n"));
534 idn_resconf_setdelimitermap(idn_resconf_t ctx
,
535 idn_delimitermap_t delimiter_mapper
) {
538 TRACE(("idn_resconf_setdelimitermap()\n"));
540 if (ctx
->delimiter_mapper
!= NULL
)
541 idn_delimitermap_destroy(ctx
->delimiter_mapper
);
542 ctx
->delimiter_mapper
= delimiter_mapper
;
543 if (delimiter_mapper
!= NULL
)
544 idn_delimitermap_incrref(ctx
->delimiter_mapper
);
548 idn_resconf_setidnconverter(idn_resconf_t ctx
,
549 idn_converter_t idn_converter
) {
552 TRACE(("idn_resconf_setidnconverter()\n"));
554 if (ctx
->idn_converter
!= NULL
)
555 idn_converter_destroy(ctx
->idn_converter
);
556 ctx
->idn_converter
= idn_converter
;
557 if (idn_converter
!= NULL
)
558 idn_converter_incrref(ctx
->idn_converter
);
562 idn_resconf_setauxidnconverter(idn_resconf_t ctx
,
563 idn_converter_t aux_idn_converter
) {
566 TRACE(("idn_resconf_setauxidnconverter()\n"));
568 if (ctx
->aux_idn_converter
!= NULL
)
569 idn_converter_destroy(ctx
->aux_idn_converter
);
570 ctx
->aux_idn_converter
= aux_idn_converter
;
571 if (aux_idn_converter
!= NULL
)
572 idn_converter_incrref(ctx
->aux_idn_converter
);
576 idn_resconf_setlocalconverter(idn_resconf_t ctx
,
577 idn_converter_t local_converter
) {
578 #ifndef WITHOUT_ICONV
581 TRACE(("idn_resconf_setlocalconverter()\n"));
583 if (ctx
->local_converter
!= NULL
) {
584 idn_converter_destroy(ctx
->local_converter
);
585 ctx
->local_converter
= NULL
;
588 if (local_converter
== NULL
)
589 ctx
->local_converter_is_static
= 0;
591 ctx
->local_converter
= local_converter
;
592 idn_converter_incrref(local_converter
);
593 ctx
->local_converter_is_static
= 1;
595 #endif /* WITHOUT_ICONV */
599 idn_resconf_setlocalmapselector(idn_resconf_t ctx
,
600 idn_mapselector_t local_mapper
) {
603 TRACE(("idn_resconf_setlocalmapselector()\n"));
605 if (ctx
->local_mapper
!= NULL
)
606 idn_mapselector_destroy(ctx
->local_mapper
);
607 ctx
->local_mapper
= local_mapper
;
608 if (local_mapper
!= NULL
)
609 idn_mapselector_incrref(ctx
->local_mapper
);
613 idn_resconf_setmapper(idn_resconf_t ctx
, idn_mapper_t mapper
) {
616 TRACE(("idn_resconf_setmapper()\n"));
618 if (ctx
->mapper
!= NULL
)
619 idn_mapper_destroy(ctx
->mapper
);
620 ctx
->mapper
= mapper
;
622 idn_mapper_incrref(ctx
->mapper
);
626 idn_resconf_setnormalizer(idn_resconf_t ctx
, idn_normalizer_t normalizer
) {
629 TRACE(("idn_resconf_setnormalizer()\n"));
631 if (ctx
->normalizer
!= NULL
)
632 idn_normalizer_destroy(ctx
->normalizer
);
633 ctx
->normalizer
= normalizer
;
634 if (normalizer
!= NULL
)
635 idn_normalizer_incrref(ctx
->normalizer
);
639 idn_resconf_setprohibitchecker(idn_resconf_t ctx
,
640 idn_checker_t prohibit_checker
) {
643 TRACE(("idn_resconf_setprohibitchecker()\n"));
645 if (ctx
->prohibit_checker
!= NULL
)
646 idn_checker_destroy(ctx
->prohibit_checker
);
647 ctx
->prohibit_checker
= prohibit_checker
;
648 if (prohibit_checker
!= NULL
)
649 idn_checker_incrref(ctx
->prohibit_checker
);
653 idn_resconf_setunassignedchecker(idn_resconf_t ctx
,
654 idn_checker_t unassigned_checker
) {
657 TRACE(("idn_resconf_setunassignedchecker()\n"));
659 if (ctx
->unassigned_checker
!= NULL
)
660 idn_checker_destroy(ctx
->unassigned_checker
);
661 ctx
->unassigned_checker
= unassigned_checker
;
662 if (unassigned_checker
!= NULL
)
663 idn_checker_incrref(ctx
->unassigned_checker
);
667 idn_resconf_setbidichecker(idn_resconf_t ctx
,
668 idn_checker_t bidi_checker
) {
671 TRACE(("idn_resconf_setbidichecker()\n"));
673 if (ctx
->bidi_checker
!= NULL
)
674 idn_checker_destroy(ctx
->bidi_checker
);
675 ctx
->bidi_checker
= bidi_checker
;
676 if (bidi_checker
!= NULL
)
677 idn_checker_incrref(ctx
->bidi_checker
);
681 idn_resconf_setnameprepversion(idn_resconf_t ctx
, const char *version
)
683 char prohibit_scheme_name
[MAX_CONF_LINE_LENGTH
+ 1];
684 char unassigned_scheme_name
[MAX_CONF_LINE_LENGTH
+ 1];
685 char bidi_scheme_name
[MAX_CONF_LINE_LENGTH
+ 1];
686 idn_mapper_t mapper
= NULL
;
687 idn_normalizer_t normalizer
= NULL
;
688 idn_checker_t prohibit_checker
= NULL
;
689 idn_checker_t unassigned_checker
= NULL
;
690 idn_checker_t bidi_checker
= NULL
;
693 assert(ctx
!= NULL
&& version
!= NULL
);
695 TRACE(("idn_resconf_setnameprepversion()\n"));
698 * Set canonical scheme names.
700 if (strlen(version
) + strlen(IDN_CHECKER_PROHIBIT_PREFIX
)
701 > MAX_CONF_LINE_LENGTH
) {
702 r
= idn_invalid_name
;
705 sprintf(prohibit_scheme_name
, "%s%s",
706 IDN_CHECKER_PROHIBIT_PREFIX
, version
);
708 if (strlen(version
) + strlen(IDN_CHECKER_UNASSIGNED_PREFIX
)
709 > MAX_CONF_LINE_LENGTH
) {
710 r
= idn_invalid_name
;
713 sprintf(unassigned_scheme_name
, "%s%s",
714 IDN_CHECKER_UNASSIGNED_PREFIX
, version
);
716 if (strlen(version
) + strlen(IDN_CHECKER_BIDI_PREFIX
)
717 > MAX_CONF_LINE_LENGTH
) {
718 r
= idn_invalid_name
;
721 sprintf(bidi_scheme_name
, "%s%s",
722 IDN_CHECKER_BIDI_PREFIX
, version
);
727 r
= idn_mapper_create(&mapper
);
728 if (r
!= idn_success
)
730 r
= idn_normalizer_create(&normalizer
);
731 if (r
!= idn_success
)
733 r
= idn_checker_create(&prohibit_checker
);
734 if (r
!= idn_success
)
736 r
= idn_checker_create(&unassigned_checker
);
737 if (r
!= idn_success
)
739 r
= idn_checker_create(&bidi_checker
);
740 if (r
!= idn_success
)
743 r
= idn_mapper_add(mapper
, version
);
744 if (r
!= idn_success
)
746 r
= idn_normalizer_add(normalizer
, version
);
747 if (r
!= idn_success
)
749 r
= idn_checker_add(prohibit_checker
, prohibit_scheme_name
);
750 if (r
!= idn_success
)
752 r
= idn_checker_add(unassigned_checker
, unassigned_scheme_name
);
753 if (r
!= idn_success
)
755 r
= idn_checker_add(bidi_checker
, bidi_scheme_name
);
756 if (r
!= idn_success
)
762 idn_resconf_setmapper(ctx
, mapper
);
763 idn_resconf_setnormalizer(ctx
, normalizer
);
764 idn_resconf_setprohibitchecker(ctx
, prohibit_checker
);
765 idn_resconf_setunassignedchecker(ctx
, unassigned_checker
);
766 idn_resconf_setbidichecker(ctx
, bidi_checker
);
769 * Destroy the objects.
771 idn_mapper_destroy(mapper
);
772 idn_normalizer_destroy(normalizer
);
773 idn_checker_destroy(prohibit_checker
);
774 idn_checker_destroy(unassigned_checker
);
775 idn_checker_destroy(bidi_checker
);
777 return (idn_success
);
781 idn_mapper_destroy(mapper
);
782 if (normalizer
!= NULL
)
783 idn_normalizer_destroy(normalizer
);
784 if (prohibit_checker
!= NULL
)
785 idn_checker_destroy(prohibit_checker
);
786 if (unassigned_checker
!= NULL
)
787 idn_checker_destroy(unassigned_checker
);
788 if (bidi_checker
!= NULL
)
789 idn_checker_destroy(bidi_checker
);
795 idn_resconf_setalternateconvertername(idn_resconf_t ctx
, const char *name
,
797 assert(ctx
!= NULL
&& name
!= NULL
);
799 TRACE(("idn_resconf_setalternateconvertername(name=%s, flags=%d)\n",
802 return (idn_success
);
806 idn_resconf_setidnconvertername(idn_resconf_t ctx
, const char *name
,
808 idn_converter_t idn_converter
;
811 assert(ctx
!= NULL
&& name
!= NULL
);
813 TRACE(("idn_resconf_setidnconvertername(name=%s, flags=%d)\n",
816 r
= idn_converter_create(name
, &idn_converter
, flags
);
817 if (r
!= idn_success
)
820 if (ctx
->idn_converter
!= NULL
)
821 idn_converter_destroy(ctx
->idn_converter
);
822 ctx
->idn_converter
= idn_converter
;
824 return (idn_success
);
828 idn_resconf_setauxidnconvertername(idn_resconf_t ctx
, const char *name
,
830 idn_converter_t aux_idn_converter
;
831 const char *old_name
;
834 assert(ctx
!= NULL
&& name
!= NULL
);
836 TRACE(("idn_resconf_setauxidnconvertername(name=%s, flags=%d)\n",
839 if (ctx
->aux_idn_converter
!= NULL
) {
840 old_name
= idn_converter_localencoding(ctx
->aux_idn_converter
);
841 if (old_name
!= NULL
&& strcmp(old_name
, name
) == 0)
842 return (idn_success
);
845 r
= idn_converter_create(name
, &aux_idn_converter
, flags
);
846 if (r
!= idn_success
)
849 if (ctx
->aux_idn_converter
!= NULL
)
850 idn_converter_destroy(ctx
->aux_idn_converter
);
851 ctx
->aux_idn_converter
= aux_idn_converter
;
853 return (idn_success
);
857 idn_resconf_setlocalconvertername(idn_resconf_t ctx
, const char *name
,
862 #else /* WITHOUT_ICONV */
863 idn_converter_t local_converter
;
868 TRACE(("idn_resconf_setlocalconvertername(name=%s, flags=%d)\n",
869 name
== NULL
? "<null>" : name
, flags
));
871 if (ctx
->local_converter
!= NULL
) {
872 idn_converter_destroy(ctx
->local_converter
);
873 ctx
->local_converter
= NULL
;
875 ctx
->local_converter_is_static
= 0;
878 r
= idn_converter_create(name
, &local_converter
, flags
);
879 if (r
!= idn_success
)
881 ctx
->local_converter
= local_converter
;
882 ctx
->local_converter_is_static
= 1;
885 return (idn_success
);
887 #endif /* WITHOUT_ICONV */
891 idn_resconf_addalldelimitermapucs(idn_resconf_t ctx
, unsigned long *v
,
895 TRACE(("idn_resconf_addalldelimitermapucs(nv=%d)\n", nv
));
897 if (ctx
->delimiter_mapper
== NULL
) {
898 r
= idn_delimitermap_create(&(ctx
->delimiter_mapper
));
899 if (r
!= idn_success
)
903 r
= idn_delimitermap_addall(ctx
->delimiter_mapper
, v
, nv
);
908 idn_resconf_addalllocalmapselectornames(idn_resconf_t ctx
, const char *tld
,
909 const char **names
, int nnames
) {
912 assert(ctx
!= NULL
&& names
!= NULL
&& tld
!= NULL
);
914 TRACE(("idn_resconf_addalllocalmapselectorname(tld=%s, nnames=%d)\n",
917 if (ctx
->local_mapper
== NULL
) {
918 r
= idn_mapselector_create(&(ctx
->local_mapper
));
919 if (r
!= idn_success
)
923 r
= idn_mapselector_addall(ctx
->local_mapper
, tld
, names
, nnames
);
928 idn_resconf_addallmappernames(idn_resconf_t ctx
, const char **names
,
932 assert(ctx
!= NULL
&& names
!= NULL
);
934 TRACE(("idn_resconf_addallmappername()\n"));
936 if (ctx
->mapper
== NULL
) {
937 r
= idn_mapper_create(&(ctx
->mapper
));
938 if (r
!= idn_success
)
942 r
= idn_mapper_addall(ctx
->mapper
, names
, nnames
);
947 idn_resconf_addallnormalizernames(idn_resconf_t ctx
, const char **names
,
951 assert(ctx
!= NULL
&& names
!= NULL
);
953 TRACE(("idn_resconf_addallnormalizername(nnames=%d)\n", nnames
));
955 if (ctx
->normalizer
== NULL
) {
956 r
= idn_normalizer_create(&(ctx
->normalizer
));
957 if (r
!= idn_success
)
961 r
= idn_normalizer_addall(ctx
->normalizer
, names
, nnames
);
966 idn_resconf_addallprohibitcheckernames(idn_resconf_t ctx
, const char **names
,
968 char long_name
[MAX_CONF_LINE_LENGTH
+ 1];
972 assert(ctx
!= NULL
&& names
!= NULL
);
974 TRACE(("idn_resconf_addallprohibitcheckername(nnames=%d)\n", nnames
));
976 if (ctx
->prohibit_checker
== NULL
) {
977 r
= idn_checker_create(&(ctx
->prohibit_checker
));
978 if (r
!= idn_success
)
982 for (i
= 0; i
< nnames
; i
++, names
++) {
983 if (strlen(*names
) + strlen(IDN_CHECKER_PROHIBIT_PREFIX
)
984 > MAX_CONF_LINE_LENGTH
) {
985 return (idn_invalid_name
);
987 strcpy(long_name
, IDN_CHECKER_PROHIBIT_PREFIX
);
988 strcat(long_name
, *names
);
990 r
= idn_checker_add(ctx
->prohibit_checker
, long_name
);
991 if (r
!= idn_success
)
995 return (idn_success
);
999 idn_resconf_addallunassignedcheckernames(idn_resconf_t ctx
, const char **names
,
1001 char long_name
[MAX_CONF_LINE_LENGTH
+ 1];
1005 assert(ctx
!= NULL
&& names
!= NULL
);
1007 TRACE(("idn_resconf_addallunassignedcheckername(nnames=%d)\n",
1010 if (ctx
->unassigned_checker
== NULL
) {
1011 r
= idn_checker_create(&(ctx
->unassigned_checker
));
1012 if (r
!= idn_success
)
1016 for (i
= 0; i
< nnames
; i
++, names
++) {
1017 if (strlen(*names
) + strlen(IDN_CHECKER_UNASSIGNED_PREFIX
)
1018 > MAX_CONF_LINE_LENGTH
) {
1019 return (idn_invalid_name
);
1021 strcpy(long_name
, IDN_CHECKER_UNASSIGNED_PREFIX
);
1022 strcat(long_name
, *names
);
1024 r
= idn_checker_add(ctx
->unassigned_checker
, long_name
);
1025 if (r
!= idn_success
)
1029 return (idn_success
);
1033 idn_resconf_addallbidicheckernames(idn_resconf_t ctx
, const char **names
,
1035 char long_name
[MAX_CONF_LINE_LENGTH
+ 1];
1039 assert(ctx
!= NULL
&& names
!= NULL
);
1041 TRACE(("idn_resconf_addallbidicheckername(nnames=%d)\n", nnames
));
1043 if (ctx
->bidi_checker
== NULL
) {
1044 r
= idn_checker_create(&(ctx
->bidi_checker
));
1045 if (r
!= idn_success
)
1049 for (i
= 0; i
< nnames
; i
++, names
++) {
1050 if (strlen(*names
) + strlen(IDN_CHECKER_BIDI_PREFIX
)
1051 > MAX_CONF_LINE_LENGTH
) {
1052 return (idn_invalid_name
);
1054 strcpy(long_name
, IDN_CHECKER_BIDI_PREFIX
);
1055 strcat(long_name
, *names
);
1057 r
= idn_checker_add(ctx
->bidi_checker
, long_name
);
1058 if (r
!= idn_success
)
1062 return (idn_success
);
1066 parse_conf(idn_resconf_t ctx
, FILE *fp
) {
1067 char line
[MAX_CONF_LINE_LENGTH
+ 1];
1074 TRACE(("parse_conf()\n"));
1077 * Parse config file. parsing of 'idn-encoding' line is
1078 * postponed because 'alias-file' line must be processed
1081 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
1085 newline
= strpbrk(line
, "\r\n");
1086 if (newline
!= NULL
)
1088 else if (fgetc(fp
) != EOF
) {
1089 ERROR(("libidnkit: too long line \"%-.30s\", "
1090 "line %d\n", line
, lineno
));
1091 return (idn_invalid_syntax
);
1094 argc
= split_args(line
, argv
, 2);
1096 ERROR(("libidnkit: syntax error, line %d\n", lineno
));
1097 return (idn_invalid_syntax
);
1098 } else if (argc
== 0 || argv
[0][0] == '#') {
1100 } else if (argc
== 1) {
1101 ERROR(("libidnkit: syntax error, line %d\n", lineno
));
1102 return (idn_invalid_syntax
);
1105 if (strcmp(argv
[0], "idn-encoding") == 0) {
1106 if (conf_mask
& DEFAULT_CONF_IDN_ENCODING
) {
1107 ERROR(("libidnkit: \"%s\" redefined, "
1108 "line %d\n", argv
[0], lineno
));
1109 r
= idn_invalid_syntax
;
1111 conf_mask
|= DEFAULT_CONF_IDN_ENCODING
;
1112 r
= parse_idn_encoding(ctx
, argv
[1], lineno
);
1114 } else if (strcmp(argv
[0], "local-map") == 0) {
1115 r
= parse_local_map(ctx
, argv
[1], lineno
);
1117 } else if (strcmp(argv
[0], "nameprep") == 0) {
1118 if (conf_mask
& DEFAULT_CONF_NAMEPREP
) {
1119 ERROR(("libidnkit: \"%s\" redefined, "
1120 "line %d\n", argv
[0], lineno
));
1121 r
= idn_invalid_syntax
;
1123 conf_mask
|= DEFAULT_CONF_NAMEPREP
;
1124 r
= parse_nameprep(ctx
, argv
[1], lineno
);
1126 } else if (strcmp(argv
[0], "nameprep-map") == 0 ||
1127 strcmp(argv
[0], "nameprep-normalize") == 0 ||
1128 strcmp(argv
[0], "nameprep-prohibit") == 0 ||
1129 strcmp(argv
[0], "nameprep-unassigned") == 0 ||
1130 strcmp(argv
[0], "alias-file") == 0 ||
1131 strcmp(argv
[0], "encoding-alias-file") == 0 ||
1132 strcmp(argv
[0], "normalize") == 0 ||
1133 strcmp(argv
[0], "server-encoding") == 0 ||
1134 strcmp(argv
[0], "alternate-encoding") == 0 ||
1135 strcmp(argv
[0], "delimiter-map") == 0) {
1136 WARNING(("libidnkit: obsolete command \"%s\", line %d "
1137 "(ignored)\n", argv
[0], lineno
));
1140 ERROR(("libidnkit: unknown command \"%-.30s\", "
1141 "line %d\n", argv
[0], lineno
));
1142 r
= idn_invalid_syntax
;
1144 if (r
!= idn_success
)
1150 if (conf_mask
!= DEFAULT_CONF_ALL
) {
1151 return setdefaults_body(ctx
, conf_mask
);
1154 return (idn_success
);
1158 parse_idn_encoding(idn_resconf_t ctx
, char *args
, int lineno
) {
1160 char *argv
[MAX_CONF_LINE_ARGS
+ 1];
1163 argc
= split_args(args
, argv
, MAX_CONF_LINE_ARGS
+ 1);
1166 ERROR(("libidnkit: wrong # of args for idn-encoding, "
1167 "line %d\n", lineno
));
1168 return (idn_invalid_syntax
);
1171 r
= idn_converter_create(argv
[0], &ctx
->idn_converter
,
1172 IDN_CONVERTER_DELAYEDOPEN
|
1173 IDN_CONVERTER_RTCHECK
);
1174 if (r
!= idn_success
) {
1175 ERROR(("libidnkit: cannot create idn converter, %s, "
1176 "line %d\n", idn_result_tostring(r
), lineno
));
1183 parse_local_map(idn_resconf_t ctx
, char *args
, int lineno
) {
1185 char *argv
[MAX_CONF_LINE_ARGS
+ 1];
1189 argc
= split_args(args
, argv
, MAX_CONF_LINE_ARGS
+ 1);
1191 if (argc
< 2 || argc
> MAX_CONF_LINE_ARGS
) {
1192 ERROR(("libidnkit: wrong # of args for local-map, line %d\n",
1194 return (idn_invalid_syntax
);
1197 if (ctx
->local_mapper
== NULL
) {
1198 r
= idn_mapselector_create(&ctx
->local_mapper
);
1199 if (r
!= idn_success
) {
1200 ERROR(("libidnkit: cannot create local mapper, %s, "
1201 "line %d\n", idn_result_tostring(r
), lineno
));
1206 for (i
= 1; i
< argc
; i
++) {
1207 r
= idn_mapselector_add(ctx
->local_mapper
, argv
[0], argv
[i
]);
1208 if (r
== idn_invalid_name
) {
1209 ERROR(("libidnkit: map scheme unavailable \"%-.30s\""
1210 " or invalid TLD \"%-.30s\", line %d\n",
1211 argv
[i
], argv
[0], lineno
));
1213 } else if (r
!= idn_success
) {
1218 return (idn_success
);
1222 parse_nameprep(idn_resconf_t ctx
, char *args
, int lineno
) {
1224 char *argv
[MAX_CONF_LINE_ARGS
+ 1];
1225 char scheme_name
[MAX_CONF_LINE_LENGTH
+ 1];
1228 argc
= split_args(args
, argv
, MAX_CONF_LINE_ARGS
+ 1);
1231 ERROR(("libidnkit: wrong # of args for nameprep, line %d\n",
1233 return (idn_invalid_syntax
);
1239 r
= idn_mapper_create(&ctx
->mapper
);
1240 if (r
!= idn_success
) {
1241 ERROR(("libidnkit: cannot create mapper, %s, line %d\n",
1242 idn_result_tostring(r
), lineno
));
1246 r
= idn_mapper_add(ctx
->mapper
, argv
[0]);
1247 if (r
== idn_invalid_name
) {
1248 ERROR(("libidnkit: map scheme unavailable \"%-.30s\", "
1249 "line %d\n", argv
[0], lineno
));
1251 } else if (r
!= idn_success
) {
1258 r
= idn_normalizer_create(&ctx
->normalizer
);
1259 if (r
!= idn_success
) {
1260 ERROR(("libidnkit: cannot create normalizer, %s, line %d\n",
1261 idn_result_tostring(r
), lineno
));
1265 r
= idn_normalizer_add(ctx
->normalizer
, argv
[0]);
1266 if (r
== idn_invalid_name
) {
1267 ERROR(("libidnkit: unknown normalization scheme \"%-.30s\", "
1268 "line %d\n", argv
[0], lineno
));
1270 } else if (r
!= idn_success
) {
1275 * Set prohibit checker.
1277 r
= idn_checker_create(&ctx
->prohibit_checker
);
1278 if (r
!= idn_success
) {
1279 ERROR(("libidnkit: cannot create prohibit checker, %s, "
1280 "line %d\n", idn_result_tostring(r
), lineno
));
1284 sprintf(scheme_name
, "%s%s", IDN_CHECKER_PROHIBIT_PREFIX
, argv
[0]);
1285 r
= idn_checker_add(ctx
->prohibit_checker
, scheme_name
);
1286 if (r
== idn_invalid_name
) {
1287 ERROR(("libidnkit: unknown prohibit scheme \"%-.30s\", "
1288 "line %d\n", argv
[0], lineno
));
1290 } else if (r
!= idn_success
) {
1295 * Set unassigned checker.
1297 r
= idn_checker_create(&ctx
->unassigned_checker
);
1298 if (r
!= idn_success
) {
1299 ERROR(("libidnkit: cannot create unassigned checker, %s, "
1300 "line %d\n", idn_result_tostring(r
), lineno
));
1304 sprintf(scheme_name
, "%s%s", IDN_CHECKER_UNASSIGNED_PREFIX
, argv
[0]);
1305 r
= idn_checker_add(ctx
->unassigned_checker
, scheme_name
);
1306 if (r
== idn_invalid_name
) {
1307 ERROR(("libidnkit: unknown unassigned scheme \"%-.30s\", "
1308 "line %d\n", argv
[0], lineno
));
1310 } else if (r
!= idn_success
) {
1317 r
= idn_checker_create(&ctx
->bidi_checker
);
1318 if (r
!= idn_success
) {
1319 ERROR(("libidnkit: cannot create bidi checker, %s, line %d\n",
1320 idn_result_tostring(r
), lineno
));
1324 sprintf(scheme_name
, "%s%s", IDN_CHECKER_BIDI_PREFIX
, argv
[0]);
1325 r
= idn_checker_add(ctx
->bidi_checker
, scheme_name
);
1326 if (r
== idn_invalid_name
) {
1327 ERROR(("libidnkit: unknown bidi scheme \"%-.30s\", "
1328 "line %d\n", argv
[0], lineno
));
1330 } else if (r
!= idn_success
) {
1334 return (idn_success
);
1338 split_args(char *s
, char **av
, int max_ac
) {
1342 for (ac
= 0; *s
!= '\0' && ac
< max_ac
; ac
++) {
1345 while (isspace((unsigned char)*s
))
1349 if (*s
== '"' || *s
== '\'') {
1359 while (*s
!= '\0' && !isspace((unsigned char)*s
))
1364 for (i
= ac
; i
< max_ac
; i
++)
1371 resetconf(idn_resconf_t ctx
) {
1372 #ifndef WITHOUT_ICONV
1373 idn_resconf_setlocalconverter(ctx
, NULL
);
1375 idn_resconf_setidnconverter(ctx
, NULL
);
1376 idn_resconf_setauxidnconverter(ctx
, NULL
);
1377 idn_resconf_setdelimitermap(ctx
, NULL
);
1378 idn_resconf_setlocalmapselector(ctx
, NULL
);
1379 idn_resconf_setmapper(ctx
, NULL
);
1380 idn_resconf_setnormalizer(ctx
, NULL
);
1381 idn_resconf_setprohibitchecker(ctx
, NULL
);
1382 idn_resconf_setunassignedchecker(ctx
, NULL
);
1383 idn_resconf_setbidichecker(ctx
, NULL
);
1386 #ifndef WITHOUT_ICONV
1388 update_local_converter(idn_resconf_t ctx
) {
1390 const char *old_encoding
;
1391 const char *new_encoding
;
1394 * We don't update local converter, if the converter is set
1395 * by idn_resconf_setlocalconverter() or
1396 * idn_resconf_setlocalconvertername().
1398 if (ctx
->local_converter_is_static
)
1399 return (idn_success
);
1402 * Update the local converter if the local encoding is changed.
1404 old_encoding
= (ctx
->local_converter
!= NULL
) ?
1405 idn_converter_localencoding(ctx
->local_converter
) :
1407 new_encoding
= idn_localencoding_name();
1408 if (new_encoding
== NULL
) {
1409 ERROR(("cannot determine local codeset name\n"));
1410 return (idn_notfound
);
1413 if (old_encoding
!= NULL
&&
1414 new_encoding
!= NULL
&&
1415 strcmp(old_encoding
, new_encoding
) == 0) {
1416 return (idn_success
);
1419 if (ctx
->local_converter
!= NULL
) {
1420 idn_converter_destroy(ctx
->local_converter
);
1421 ctx
->local_converter
= NULL
;
1424 r
= idn_converter_create(new_encoding
,
1425 &ctx
->local_converter
,
1426 IDN_CONVERTER_RTCHECK
);
1432 idn_resconf_setdefaults(idn_resconf_t ctx
)
1436 assert(ctx
!= NULL
);
1438 TRACE(("idn_resconf_setdefaults()\n"));
1441 r
= idn_delimitermap_create(&ctx
->delimiter_mapper
);
1442 if (r
!= idn_success
) {
1443 ERROR(("libidnkit: cannot create delimiter mapper, %s\n",
1444 idn_result_tostring(r
)));
1448 return setdefaults_body(ctx
, 0);
1452 setdefaults_body(idn_resconf_t ctx
, int conf_mask
) {
1455 TRACE(("setdefaults_body()\n"));
1456 assert(ctx
!= NULL
);
1458 if (!(conf_mask
& DEFAULT_CONF_NAMEPREP
)) {
1459 TRACE(("set default nameprep\n"));
1460 r
= idn_resconf_setnameprepversion(ctx
, IDN_NAMEPREP_CURRENT
);
1461 if (r
!= idn_success
) {
1465 if (!(conf_mask
& DEFAULT_CONF_IDN_ENCODING
)) {
1466 TRACE(("set default idn encoding\n"));
1467 r
= idn_converter_create(IDN_ENCODING_CURRENT
,
1468 &ctx
->idn_converter
,
1469 IDN_CONVERTER_DELAYEDOPEN
|
1470 IDN_CONVERTER_RTCHECK
);
1471 if (r
!= idn_success
) {
1472 ERROR(("libidnkit: cannot create idn converter, %s\n",
1473 idn_result_tostring(r
)));
1478 return (idn_success
);