1 /* $NetBSD: util.c,v 1.4 2014/12/10 04:37:56 christos Exp $ */
4 static char *rcsid
= "Id: util.c,v 1.1 2003/06/04 00:27:08 marka Exp ";
8 * Copyright (c) 2000,2002 Japan Network Information Center.
11 * By using this file, you agree to the terms and conditions set forth bellow.
13 * LICENSE TERMS AND CONDITIONS
15 * The following License Terms and Conditions apply, unless a different
16 * license is obtained from Japan Network Information Center ("JPNIC"),
17 * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
18 * Chiyoda-ku, Tokyo 101-0047, Japan.
20 * 1. Use, Modification and Redistribution (including distribution of any
21 * modified or derived work) in source and/or binary forms is permitted
22 * under this License Terms and Conditions.
24 * 2. Redistribution of source code must retain the copyright notices as they
25 * appear in each source code file, this License Terms and Conditions.
27 * 3. Redistribution in binary form must reproduce the Copyright Notice,
28 * this License Terms and Conditions, in the documentation and/or other
29 * materials provided with the distribution. For the purposes of binary
30 * distribution the "Copyright Notice" refers to the following language:
31 * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
33 * 4. The name of JPNIC may not be used to endorse or promote products
34 * derived from this Software without specific prior written approval of
37 * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
38 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
39 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
40 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
43 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
44 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
45 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
46 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
47 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
60 #include <idn/resconf.h>
61 #include <idn/converter.h>
66 #include "selectiveencode.h"
68 extern int line_number
;
71 selective_encode(idn_resconf_t conf
, idn_action_t actions
,
72 char *from
, char *to
, int tolen
)
76 char *region_start
, *region_end
;
81 * Find the region that needs conversion.
83 r
= idn_selectiveencode_findregion(from
, ®ion_start
,
85 if (r
== idn_notfound
) {
87 * Not found. Just copy the whole thing.
89 if (tolen
<= strlen(from
))
90 return (idn_buffer_overflow
);
91 (void)strcpy(to
, from
);
93 } else if (r
!= idn_success
) {
94 /* This should not happen.. */
95 errormsg("internal error at line %d: %s\n",
96 line_number
, idn_result_tostring(r
));
101 * We have found a region to convert.
102 * First, copy the prefix part verbatim.
104 len
= region_start
- from
;
106 errormsg("internal buffer overflow at line %d\n",
108 return (idn_buffer_overflow
);
110 (void)memcpy(to
, from
, len
);
115 * Terminate the region with NUL.
123 r
= idn_res_encodename(conf
, actions
, region_start
, to
, tolen
);
130 if (r
!= idn_success
)
142 selective_decode(idn_resconf_t conf
, idn_action_t actions
,
143 char *from
, char *to
, int tolen
)
152 * While `*from' points to a character in a string which may be
153 * a domain name, `domain_name' refers to the beginning of the
159 * We ignore chunks matching to the regular expression:
160 * [\-\.][0-9A-Za-z\-\.]*
162 * While `*from' points to a character in such a chunk,
163 * `ignored_chunk' refers to the beginning of the chunk.
165 ignored_chunk
= NULL
;
170 * We don't recognize `.-' as a part of domain name.
172 if (domain_name
!= NULL
) {
173 if (*(from
- 1) == '.') {
174 ignored_chunk
= domain_name
;
177 } else if (ignored_chunk
== NULL
) {
178 ignored_chunk
= from
;
181 } else if (*from
== '.') {
183 * We don't recognize `-.' nor `..' as a part of
186 if (domain_name
!= NULL
) {
187 if (*(from
- 1) == '-' || *(from
- 1) == '.') {
188 ignored_chunk
= domain_name
;
191 } else if (ignored_chunk
== NULL
) {
192 ignored_chunk
= from
;
195 } else if (('a' <= *from
&& *from
<= 'z') ||
196 ('A' <= *from
&& *from
<= 'Z') ||
197 ('0' <= *from
&& *from
<= '9')) {
198 if (ignored_chunk
== NULL
&& domain_name
== NULL
)
202 if (ignored_chunk
!= NULL
) {
204 * `from' reaches the end of the ignored chunk.
205 * Copy the chunk to `to'.
207 len
= from
- ignored_chunk
;
209 return (idn_buffer_overflow
);
210 (void)memcpy(to
, ignored_chunk
, len
);
214 } else if (domain_name
!= NULL
) {
216 * `from' reaches the end of the domain name.
217 * Decode the domain name, and copy the result
222 r
= idn_res_decodename(conf
, actions
,
223 domain_name
, to
, tolen
);
226 if (r
== idn_success
) {
228 } else if (r
== idn_invalid_encoding
) {
229 len
= from
- domain_name
;
231 return (idn_buffer_overflow
);
232 (void)memcpy(to
, domain_name
, len
);
241 * Copy a character `*from' to `to'.
244 return (idn_buffer_overflow
);
250 ignored_chunk
= NULL
;
259 return (idn_success
);
263 set_defaults(idn_resconf_t conf
) {
266 if ((r
= idn_resconf_setdefaults(conf
)) != idn_success
) {
267 errormsg("error setting default configuration: %s\n",
268 idn_result_tostring(r
));
274 load_conf_file(idn_resconf_t conf
, const char *file
) {
277 if ((r
= idn_resconf_loadfile(conf
, file
)) != idn_success
) {
278 errormsg("error reading configuration file: %s\n",
279 idn_result_tostring(r
));
285 set_encoding_alias(const char *encoding_alias
) {
288 if ((r
= idn_converter_resetalias()) != idn_success
) {
289 errormsg("cannot reset alias information: %s\n",
290 idn_result_tostring(r
));
294 if ((r
= idn_converter_aliasfile(encoding_alias
)) != idn_success
) {
295 errormsg("cannot read alias file %s: %s\n",
296 encoding_alias
, idn_result_tostring(r
));
302 set_localcode(idn_resconf_t conf
, const char *code
) {
305 r
= idn_resconf_setlocalconvertername(conf
, code
,
306 IDN_CONVERTER_RTCHECK
);
307 if (r
!= idn_success
) {
308 errormsg("cannot create converter for codeset %s: %s\n",
309 code
, idn_result_tostring(r
));
315 set_idncode(idn_resconf_t conf
, const char *code
) {
318 r
= idn_resconf_setidnconvertername(conf
, code
,
319 IDN_CONVERTER_RTCHECK
);
320 if (r
!= idn_success
) {
321 errormsg("cannot create converter for codeset %s: %s\n",
322 code
, idn_result_tostring(r
));
328 set_delimitermapper(idn_resconf_t conf
, unsigned long *delimiters
,
332 r
= idn_resconf_addalldelimitermapucs(conf
, delimiters
, ndelimiters
);
333 if (r
!= idn_success
) {
334 errormsg("cannot add delimiter: %s\n",
335 idn_result_tostring(r
));
341 set_localmapper(idn_resconf_t conf
, char **mappers
, int nmappers
) {
345 r
= idn_resconf_addalllocalmapselectornames(conf
,
346 IDN_MAPSELECTOR_DEFAULTTLD
,
347 (const char **)mappers
,
349 if (r
!= idn_success
) {
350 errormsg("cannot add local map: %s\n",
351 idn_result_tostring(r
));
357 set_nameprep(idn_resconf_t conf
, char *version
) {
360 r
= idn_resconf_setnameprepversion(conf
, version
);
361 if (r
!= idn_success
) {
362 errormsg("error setting nameprep %s: %s\n",
363 version
, idn_result_tostring(r
));
369 set_mapper(idn_resconf_t conf
, char **mappers
, int nmappers
) {
372 /* Configure mapper. */
373 r
= idn_resconf_addallmappernames(conf
, (const char **)mappers
,
375 if (r
!= idn_success
) {
376 errormsg("cannot add nameprep map: %s\n",
377 idn_result_tostring(r
));
383 set_normalizer(idn_resconf_t conf
, char **normalizers
, int nnormalizer
) {
386 r
= idn_resconf_addallnormalizernames(conf
,
387 (const char **)normalizers
,
389 if (r
!= idn_success
) {
390 errormsg("cannot add normalizer: %s\n",
391 idn_result_tostring(r
));
397 set_prohibit_checkers(idn_resconf_t conf
, char **prohibits
, int nprohibits
) {
400 r
= idn_resconf_addallprohibitcheckernames(conf
,
401 (const char **)prohibits
,
403 if (r
!= idn_success
) {
404 errormsg("cannot add prohibit checker: %s\n",
405 idn_result_tostring(r
));
411 set_unassigned_checkers(idn_resconf_t conf
, char **unassigns
, int nunassigns
) {
414 r
= idn_resconf_addallunassignedcheckernames(conf
,
415 (const char **)unassigns
,
417 if (r
!= idn_success
) {
418 errormsg("cannot add unassigned checker: %s\n",
419 idn_result_tostring(r
));
425 errormsg(const char *fmt
, ...) {
429 vfprintf(stderr
, fmt
, args
);
435 * Dynamic Stirng Buffer Utility
439 strbuf_init(idnconv_strbuf_t
*buf
) {
441 * Initialize the given string buffer.
442 * Caller must allocate the structure (idnconv_strbuf_t)
443 * as an automatic variable or by malloc().
445 buf
->str
= buf
->local_buf
;
447 buf
->size
= sizeof(buf
->local_buf
);
451 strbuf_reset(idnconv_strbuf_t
*buf
) {
453 * Reset the given string buffer.
454 * Free memory allocated by this utility, and
457 if (buf
->str
!= NULL
&& buf
->str
!= buf
->local_buf
) {
464 strbuf_get(idnconv_strbuf_t
*buf
) {
466 * Get the pointer of the buffer.
472 strbuf_size(idnconv_strbuf_t
*buf
) {
474 * Get the allocated size of the buffer.
480 strbuf_copy(idnconv_strbuf_t
*buf
, const char *str
) {
484 size_t len
= strlen(str
);
486 if (strbuf_alloc(buf
, len
+ 1) == NULL
)
488 strcpy(buf
->str
, str
);
493 strbuf_append(idnconv_strbuf_t
*buf
, const char *str
) {
495 * Append STR to the end of BUF.
497 size_t len1
= strlen(buf
->str
);
498 size_t len2
= strlen(str
);
502 p
= strbuf_alloc(buf
, len1
+ len2
+ 1 + MARGIN
);
504 strcpy(buf
->str
+ len1
, str
);
509 strbuf_alloc(idnconv_strbuf_t
*buf
, size_t size
) {
511 * Reallocate the buffer of BUF if needed
512 * so that BUF can hold SIZE bytes of data at least.
516 if (buf
->size
>= size
)
518 if (buf
->str
== buf
->local_buf
) {
519 if ((p
= malloc(size
)) == NULL
)
521 memcpy(p
, buf
->local_buf
, sizeof(buf
->local_buf
));
523 if ((p
= realloc(buf
->str
, size
)) == NULL
)
532 strbuf_double(idnconv_strbuf_t
*buf
) {
534 * Double the size of the buffer of BUF.
536 return (strbuf_alloc(buf
, buf
->size
* 2));
540 strbuf_getline(idnconv_strbuf_t
*buf
, FILE *fp
) {
542 * Read a line from FP.
547 while (fgets(s
, sizeof(s
), fp
) != NULL
) {
548 if (strbuf_append(buf
, s
) == NULL
)
550 if (strlen(s
) < sizeof(s
) - 1 || s
[sizeof(s
) - 2] == '\n')
553 if (buf
->str
[0] != '\0')