Remove building with NOCRYPTO option
[minix.git] / external / bsd / bind / dist / contrib / idn / idnkit-1.0-src / tools / idnconv / util.c
blobfdb7ff91a434de1b0719ad129984c1eff6b44028
1 /* $NetBSD: util.c,v 1.4 2014/12/10 04:37:56 christos Exp $ */
3 #ifndef lint
4 static char *rcsid = "Id: util.c,v 1.1 2003/06/04 00:27:08 marka Exp ";
5 #endif
7 /*
8 * Copyright (c) 2000,2002 Japan Network Information Center.
9 * All rights reserved.
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
35 * JPNIC.
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.
50 #include <config.h>
52 #include <stdio.h>
53 #include <stddef.h>
54 #include <stdlib.h>
55 #include <stdarg.h>
56 #include <string.h>
57 #include <ctype.h>
58 #include <errno.h>
60 #include <idn/resconf.h>
61 #include <idn/converter.h>
62 #include <idn/res.h>
63 #include <idn/utf8.h>
65 #include "util.h"
66 #include "selectiveencode.h"
68 extern int line_number;
70 idn_result_t
71 selective_encode(idn_resconf_t conf, idn_action_t actions,
72 char *from, char *to, int tolen)
74 for (;;) {
75 int len;
76 char *region_start, *region_end;
77 idn_result_t r;
78 char save;
81 * Find the region that needs conversion.
83 r = idn_selectiveencode_findregion(from, &region_start,
84 &region_end);
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);
92 return (idn_success);
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));
97 return (r);
101 * We have found a region to convert.
102 * First, copy the prefix part verbatim.
104 len = region_start - from;
105 if (tolen < len) {
106 errormsg("internal buffer overflow at line %d\n",
107 line_number);
108 return (idn_buffer_overflow);
110 (void)memcpy(to, from, len);
111 to += len;
112 tolen -= len;
115 * Terminate the region with NUL.
117 save = *region_end;
118 *region_end = '\0';
121 * Encode the region.
123 r = idn_res_encodename(conf, actions, region_start, to, tolen);
126 * Restore character.
128 *region_end = save;
130 if (r != idn_success)
131 return (r);
133 len = strlen(to);
134 to += len;
135 tolen -= len;
137 from = region_end;
141 idn_result_t
142 selective_decode(idn_resconf_t conf, idn_action_t actions,
143 char *from, char *to, int tolen)
145 char *domain_name;
146 char *ignored_chunk;
147 char save;
148 int len;
149 idn_result_t r;
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
154 * domain name.
156 domain_name = NULL;
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;
167 for (;;) {
168 if (*from == '-') {
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;
175 domain_name = NULL;
177 } else if (ignored_chunk == NULL) {
178 ignored_chunk = from;
181 } else if (*from == '.') {
183 * We don't recognize `-.' nor `..' as a part of
184 * domain name.
186 if (domain_name != NULL) {
187 if (*(from - 1) == '-' || *(from - 1) == '.') {
188 ignored_chunk = domain_name;
189 domain_name = NULL;
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)
199 domain_name = from;
201 } else {
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;
208 if (tolen < len)
209 return (idn_buffer_overflow);
210 (void)memcpy(to, ignored_chunk, len);
211 to += len;
212 tolen -= 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
218 * to `to'.
220 save = *from;
221 *from = '\0';
222 r = idn_res_decodename(conf, actions,
223 domain_name, to, tolen);
224 *from = save;
226 if (r == idn_success) {
227 len = strlen(to);
228 } else if (r == idn_invalid_encoding) {
229 len = from - domain_name;
230 if (tolen < len)
231 return (idn_buffer_overflow);
232 (void)memcpy(to, domain_name, len);
233 } else {
234 return (r);
236 to += len;
237 tolen -= len;
241 * Copy a character `*from' to `to'.
243 if (tolen < 1)
244 return (idn_buffer_overflow);
245 *to = *from;
246 to++;
247 tolen--;
249 domain_name = NULL;
250 ignored_chunk = NULL;
252 if (*from == '\0')
253 break;
256 from++;
259 return (idn_success);
262 void
263 set_defaults(idn_resconf_t conf) {
264 idn_result_t r;
266 if ((r = idn_resconf_setdefaults(conf)) != idn_success) {
267 errormsg("error setting default configuration: %s\n",
268 idn_result_tostring(r));
269 exit(1);
273 void
274 load_conf_file(idn_resconf_t conf, const char *file) {
275 idn_result_t r;
277 if ((r = idn_resconf_loadfile(conf, file)) != idn_success) {
278 errormsg("error reading configuration file: %s\n",
279 idn_result_tostring(r));
280 exit(1);
284 void
285 set_encoding_alias(const char *encoding_alias) {
286 idn_result_t r;
288 if ((r = idn_converter_resetalias()) != idn_success) {
289 errormsg("cannot reset alias information: %s\n",
290 idn_result_tostring(r));
291 exit(1);
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));
297 exit(1);
301 void
302 set_localcode(idn_resconf_t conf, const char *code) {
303 idn_result_t r;
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));
310 exit(1);
314 void
315 set_idncode(idn_resconf_t conf, const char *code) {
316 idn_result_t r;
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));
323 exit(1);
327 void
328 set_delimitermapper(idn_resconf_t conf, unsigned long *delimiters,
329 int ndelimiters) {
330 idn_result_t r;
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));
336 exit(1);
340 void
341 set_localmapper(idn_resconf_t conf, char **mappers, int nmappers) {
342 idn_result_t r;
344 /* Add mapping. */
345 r = idn_resconf_addalllocalmapselectornames(conf,
346 IDN_MAPSELECTOR_DEFAULTTLD,
347 (const char **)mappers,
348 nmappers);
349 if (r != idn_success) {
350 errormsg("cannot add local map: %s\n",
351 idn_result_tostring(r));
352 exit(1);
356 void
357 set_nameprep(idn_resconf_t conf, char *version) {
358 idn_result_t r;
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));
364 exit(1);
368 void
369 set_mapper(idn_resconf_t conf, char **mappers, int nmappers) {
370 idn_result_t r;
372 /* Configure mapper. */
373 r = idn_resconf_addallmappernames(conf, (const char **)mappers,
374 nmappers);
375 if (r != idn_success) {
376 errormsg("cannot add nameprep map: %s\n",
377 idn_result_tostring(r));
378 exit(1);
382 void
383 set_normalizer(idn_resconf_t conf, char **normalizers, int nnormalizer) {
384 idn_result_t r;
386 r = idn_resconf_addallnormalizernames(conf,
387 (const char **)normalizers,
388 nnormalizer);
389 if (r != idn_success) {
390 errormsg("cannot add normalizer: %s\n",
391 idn_result_tostring(r));
392 exit(1);
396 void
397 set_prohibit_checkers(idn_resconf_t conf, char **prohibits, int nprohibits) {
398 idn_result_t r;
400 r = idn_resconf_addallprohibitcheckernames(conf,
401 (const char **)prohibits,
402 nprohibits);
403 if (r != idn_success) {
404 errormsg("cannot add prohibit checker: %s\n",
405 idn_result_tostring(r));
406 exit(1);
410 void
411 set_unassigned_checkers(idn_resconf_t conf, char **unassigns, int nunassigns) {
412 idn_result_t r;
414 r = idn_resconf_addallunassignedcheckernames(conf,
415 (const char **)unassigns,
416 nunassigns);
417 if (r != idn_success) {
418 errormsg("cannot add unassigned checker: %s\n",
419 idn_result_tostring(r));
420 exit(1);
424 void
425 errormsg(const char *fmt, ...) {
426 va_list args;
428 va_start(args, fmt);
429 vfprintf(stderr, fmt, args);
430 va_end(args);
435 * Dynamic Stirng Buffer Utility
438 void
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;
446 buf->str[0] = '\0';
447 buf->size = sizeof(buf->local_buf);
450 void
451 strbuf_reset(idnconv_strbuf_t *buf) {
453 * Reset the given string buffer.
454 * Free memory allocated by this utility, and
455 * re-initialize.
457 if (buf->str != NULL && buf->str != buf->local_buf) {
458 free(buf->str);
460 strbuf_init(buf);
463 char *
464 strbuf_get(idnconv_strbuf_t *buf) {
466 * Get the pointer of the buffer.
468 return (buf->str);
471 size_t
472 strbuf_size(idnconv_strbuf_t *buf) {
474 * Get the allocated size of the buffer.
476 return (buf->size);
479 char *
480 strbuf_copy(idnconv_strbuf_t *buf, const char *str) {
482 * Copy STR to BUF.
484 size_t len = strlen(str);
486 if (strbuf_alloc(buf, len + 1) == NULL)
487 return (NULL);
488 strcpy(buf->str, str);
489 return (buf->str);
492 char *
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);
499 char *p;
500 #define MARGIN 50
502 p = strbuf_alloc(buf, len1 + len2 + 1 + MARGIN);
503 if (p != NULL)
504 strcpy(buf->str + len1, str);
505 return (p);
508 char *
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.
514 char *p;
516 if (buf->size >= size)
517 return (buf->str);
518 if (buf->str == buf->local_buf) {
519 if ((p = malloc(size)) == NULL)
520 return (NULL);
521 memcpy(p, buf->local_buf, sizeof(buf->local_buf));
522 } else {
523 if ((p = realloc(buf->str, size)) == NULL)
524 return (NULL);
526 buf->str = p;
527 buf->size = size;
528 return (buf->str);
531 char *
532 strbuf_double(idnconv_strbuf_t *buf) {
534 * Double the size of the buffer of BUF.
536 return (strbuf_alloc(buf, buf->size * 2));
539 char *
540 strbuf_getline(idnconv_strbuf_t *buf, FILE *fp) {
542 * Read a line from FP.
544 char s[256];
546 buf->str[0] = '\0';
547 while (fgets(s, sizeof(s), fp) != NULL) {
548 if (strbuf_append(buf, s) == NULL)
549 return (NULL);
550 if (strlen(s) < sizeof(s) - 1 || s[sizeof(s) - 2] == '\n')
551 return (buf->str);
553 if (buf->str[0] != '\0')
554 return (buf->str);
555 return (NULL);