1 /*
2 * TERMS AND CONDITIONS
3 * FOR
4 * OPEN SOURCE CODE LICENSE
5 * Version 1.1
6 *
7 * Japan Registry Services Co., Ltd. ("JPRS"), a Japanese corporation
8 * having its head office at Chiyoda First Bldg. East 13F 3-8-1 Nishi-Kanda,
9 * Chiyoda-ku, Tokyo 101-0065, Japan, grants you the license for open source
10 * code specified in EXHIBIT A the "Code" subject to the following Terms and
11 * Conditions ("OSCL").
12 *
13 * 1. License Grant.
14 * JPRS hereby grants you a worldwide, royalty-free, non-exclusive
15 * license, subject to third party intellectual property claims:
16 * (a) under intellectual property rights (other than patent or
17 * trademark) licensable by JPRS to use, reproduce, modify, display,
18 * perform, sublicense and distribute the Code (or portions thereof)
19 * with or without modifications, and/or as part of a derivative work;
20 * or
21 * (b) under claims of the infringement through the making, using,
22 * offering to sell and/or otherwise disposing the JPRS Revised Code
23 * (or portions thereof);
24 * (c) the licenses granted in this Section 1(a) and (b) are effective on
25 * the date JPRS first distributes the Code to you under the terms of
26 * this OSCL;
27 * (d) Notwithstanding the above stated terms, no patent license is
28 * granted:
29 * 1) for a code that you delete from the Code;
30 * 2) separate from the Code; or
31 * 3) for infringements caused by:
32 * i) modification of the Code; or
33 * ii) combination of the Code with other software or devices.
34 *
35 * 2. Consents.
36 * You agree that:
37 * (a) you must include a copy of this OSCL and the notice set forth in
38 * EXHIBIT A with every copy of the Code you distribute;
39 * (b) you must include a copy of this OSCL and the notice set forth in
40 * EXHIBIT A with every copy of binary form of the Code in the
41 * documentation and/or other materials provided with the distribution;
42 * (c) you may not offer or impose any terms on any source code version
43 * that alters or restricts the applicable version of this OSCL or
44 * the recipients' rights hereunder.
45 * (d) If the terms and conditions are set forth in EXHIBIT A, you must
46 * comply with those terms and conditions.
47 *
48 * 3. Proprietary Information.
49 * All trademarks, service marks, patents, copyrights, trade secrets, and
50 * other proprietary rights in or related to the Code are and will remain
51 * the exclusive property of JPRS or its licensors, whether or not
52 * specifically recognized or perfected under local law except specified
53 * in this OSCL; provided however you agree and understand that the JPRS
54 * name may not be used to endorse or promote this Code without prior
55 * written approval of JPRS.
56 *
57 * 4. WARRANTY DISCLAIMER.
58 * JPRS MAKES NO REPRESENTATIONS AND WARRANTIES REGARDING THE USE OF THE
59 * CODE, NOR DOES JPRS MAKE ANY REPRESENTATIONS THAT THE CODE WILL BECOME
60 * COMMERCIALLY AVAILABLE. JPRS, ITS AFFILIATES, AND ITS SUPPLIERS DO NOT
61 * WARRANT OR REPRESENT THAT THE CODE IS FREE OF ERRORS OR THAT THE CODE
62 * IS SUITABLE FOR TRANSLATION AND/OR LOCALIZATION. THE CODE IS PROVIDED
63 * ON AN "AS IS" BASIS AND JPRS AND ITS SUPPLIERS HAVE NO OBLIGATION TO
64 * CORRECT ERRORS OR TO SUPPORT THE CODE UNDER THIS OSCL FOR ANY REASON.
65 * TO THE FULL EXTENT PERMITTED BY LAW, ALL OBLIGATIONS ARE HEREBY
66 * EXCLUDED WHETHER EXPRESS, STATUTORY OR IMPLIED UNDER LAW, COURSE OF
67 * DEALING, CUSTOM, TRADE USAGE, ORAL OR WRITTEN STATEMENT OR OTHERWISE,
68 * INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY
69 * OR FITNESS FOR A PARTICULAR PURPOSE CONCERNING THE CODE.
70 *
71 * 5. NO LIABILITY.
72 * UNDER NO CIRCUMSTANCES SHALL JPRS AND/OR ITS AFFILIATES, LICENSORS, OR
73 * REPRESENTATIVES BE LIABLE FOR ANY DAMAGES INCLUDING BUT NOT LIMITED TO
74 * CONSEQUENTIAL, INDIRECT, SPECIAL, PUNITIVE OR INCIDENTAL DAMAGES,
75 * WHETHER FORESEEABLE OR UNFORESEEABLE, BASED ON YOUR CLAIMS, INCLUDING,
76 * BUT NOT LIMITED TO, CLAIMS FOR LOSS OF DATA, GOODWILL, PROFITS, USE OF
77 * MONEY, INTERRUPTION IN USE OR AVAILABILITY OF DATA, STOPPAGE, IMPLIED
78 * WARRANTY, BREACH OF CONTRACT, MISREPRESENTATION, NEGLIGENCE, STRICT
79 * LIABILITY IN TORT, OR OTHERWISE.
80 *
81 * 6. Indemnification.
82 * You hereby agree to indemnify, defend, and hold harmless JPRS for any
83 * liability incurred by JRPS due to your terms of warranty, support,
84 * indemnity, or liability offered by you to any third party.
85 *
86 * 7. Termination.
87 * 7.1 This OSCL shall be automatically terminated in the events that:
88 * (a) You fail to comply with the terms herein and fail to cure such
89 * breach within 30 days of becoming aware of the breach;
90 * (b) You initiate patent or copyright infringement litigation against
91 * any party (including a cross-claim or counterclaim in a lawsuit)
92 * alleging that the Code constitutes a direct or indirect patent or
93 * copyright infringement, in such case, this OSCL to you shall
94 * terminate as of the date such litigation is filed;
95 * 7.2 In the event of termination under Sections 7.1(a) or 7.1(b) above,
96 * all end user license agreements (excluding distributors and
97 * resellers) which have been validly granted by You or any distributor
98 * hereunder prior to termination shall survive termination.
99 *
100 *
101 * 8. General.
102 * This OSCL shall be governed by, and construed and enforced in
103 * accordance with, the laws of Japan. Any litigation or arbitration
104 * between the parties shall be conducted exclusively in Tokyo, Japan
105 * except written consent of JPRS provides other venue.
106 *
107 *
108 * EXHIBIT A
109 *
110 * The original open source code of idnkit-2 is idnkit-1.0 developed and
111 * conceived by Japan Network Information Center ("JPNIC"), a Japanese
112 * association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
113 * Chiyoda-ku, Tokyo 101-0047, Japan, and JPRS modifies above original code
114 * under following Terms and Conditions set forth by JPNIC.
115 *
116 * JPNIC
117 *
118 * Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved.
119 *
120 * By using this file, you agree to the terms and conditions set forth bellow.
121 *
122 * LICENSE TERMS AND CONDITIONS
123 *
124 * The following License Terms and Conditions apply, unless a different
125 * license is obtained from Japan Network Information Center ("JPNIC"),
126 * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
127 * Chiyoda-ku, Tokyo 101-0047, Japan.
128 *
129 * 1. Use, Modification and Redistribution (including distribution of any
130 * modified or derived work) in source and/or binary forms is permitted
131 * under this License Terms and Conditions.
132 *
133 * 2. Redistribution of source code must retain the copyright notices as they
134 * appear in each source code file, this License Terms and Conditions.
135 *
136 * 3. Redistribution in binary form must reproduce the Copyright Notice,
137 * this License Terms and Conditions, in the documentation and/or other
138 * materials provided with the distribution. For the purposes of binary
139 * distribution the "Copyright Notice" refers to the following language:
140 * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
141 *
142 * 4. The name of JPNIC may not be used to endorse or promote products
143 * derived from this Software without specific prior written approval of
144 * JPNIC.
145 *
146 * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
147 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
148 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
149 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
150 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
151 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
152 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
153 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
154 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
155 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
156 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
157 *
158 *
159 * JPRS Public License Notice
160 * For
161 * idnkit-2.
162 *
163 * The contents of this file are subject to the Terms and Conditions for
164 * the Open Source Code License (the "OSCL"). You may not use this file
165 * except in compliance with above terms and conditions. A copy of the OSCL
166 * is available at <http://jprs.co.jp/idn/>.
167 * The JPRS Revised Code is idnkit-2.
168 * The Initial Developer of the JPRS Revised Code is Japan Network
169 * Information Center ("JPNIC"), a Japanese association,
170 * Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda, Chiyoda-ku, Tokyo
171 * 101-0047, Japan.
172 * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
173 * "Copyright (c) 2010-2012 Japan Registry Services Co., Ltd. All rights reserved."
174 * Contributor(s): ______________________________________.
175 *
176 * If you wish to allow use of your version of this file only under the
177 * above License(s) and not to allow others to use your version of this
178 * file, please indicate your decision by deleting the relevant provisions
179 * above and replacing them with the notice and other provisions required
180 * by the above License(s). If you do not delete the relevant provisions,
181 * a recipient may use your version of this file under either the above
182 * License(s).
183 */
184
185 /*
186 * idncheck -- Check an internatinalized domain name and print the result.
187 */
188
189 #include <config.h>
190
191 #include <stddef.h>
192 #include <stdarg.h>
193 #include <stdio.h>
194 #include <stdlib.h>
195 #include <string.h>
196 #include <errno.h>
197 #ifdef HAVE_LOCALE_H
198 #include <locale.h>
199 #endif
200
201 #include <idn/result.h>
202 #include <idn/punycode.h>
203 #include <idn/res.h>
204 #include <idn/resconf.h>
205 #include <idn/util.h>
206 #include <idn/utf8.h>
207 #include <idn/version.h>
208
209 /*
210 * Exit codes.
211 */
212 #define IDNCHECK_EXITCODE_SUCCESS 0
213 #define IDNCHECK_EXITCODE_CHECKERROR 2
214 #define IDNCHECK_EXITCODE_FAILURE 3
215
216 /*
217 * Domain name registration / lookup procotols.
218 */
219 typedef enum idncheck_protocol {
220 idncheck_lookup = 0,
221 idncheck_registration = 1
222 } idncheck_protocol_t;
223
224 /*
225 * Parsing result of command line arguments.
226 */
227 typedef struct {
228 char *in_code;
229 char *conf_file;
230 int no_conf;
231 idncheck_protocol_t protocol;
232 char *localcheck_file;
233 idn_action_t skip_actions;
234 char *name;
235 int quiet;
236 int test;
237 } idncheck_option_t;
238
239 /*
240 * Quiet mode flag.
241 */
242 int quiet_mode = 0;
243
244 static void idncheck_option_init(idncheck_option_t *option);
245 static int parse_command_line(int ac, char **av,
246 idncheck_option_t *option);
247 static int parse_skip(const char *s, idn_action_t *action);
248 static int create_resconf(idn_resconf_t *resconf, int no_conf,
249 const char *conf_file,
250 const char *localencoding,
251 const char *localcheck_file);
252 static void print_test_status(idn_resconf_t conf);
253 static void print_version(void);
254 static void print_usage(void);
255 static void errormsg(const char *fmt, ...);
256
257 int
main(int ac,char ** av)258 main(int ac, char **av) {
259 idn_result_t r;
260 int exit_code = IDNCHECK_EXITCODE_SUCCESS;
261 idncheck_option_t option;
262 idn_action_t actions;
263 idn_resconf_t resconf = NULL;
264
265 #ifdef HAVE_SETLOCALE
266 setlocale(LC_ALL, "");
267 #endif
268
269 /*
270 * Parse command line options.
271 */
272 idncheck_option_init(&option);
273 if (!parse_command_line(ac, av, &option)) {
274 errormsg("try 'idncheck -help' for more information.\n");
275 exit_code = IDNCHECK_EXITCODE_FAILURE;
276 goto ret;
277 }
278
279 quiet_mode = option.quiet;
280
281 /*
282 * Initialize idnkit library.
283 */
284 r = idn_resconf_initialize();
285 if (r != idn_success) {
286 errormsg("error initializing library\n");
287 exit_code = IDNCHECK_EXITCODE_FAILURE;
288 goto ret;
289 }
290
291 /*
292 * Create a resource context.
293 */
294 if (!create_resconf(&resconf, option.no_conf, option.conf_file,
295 option.in_code, option.localcheck_file)) {
296 exit_code = IDNCHECK_EXITCODE_FAILURE;
297 goto ret;
298 }
299
300 /*
301 * Determine main actions.
302 */
303 if (option.protocol == idncheck_registration)
304 actions = IDN_CHECK_REGIST & ~option.skip_actions;
305 else
306 actions = IDN_CHECK_LOOKUP & ~option.skip_actions;
307 if (option.localcheck_file != NULL &&
308 !(option.skip_actions & ~IDN_LOCALCHECK)) {
309 actions |= IDN_LOCALCHECK;
310 }
311
312 /*
313 * Test mode.
314 */
315 if (option.test) {
316 print_test_status(resconf);
317 goto ret;
318 }
319
320 /*
321 * Encode two names and compare them.
322 */
323 r = idn_res_checkname(resconf, actions, option.name);
324
325 if (r == idn_success) {
326 errormsg("passed.\n");
327 } else if (r == idn_prohcheck_error ||
328 r == idn_unascheck_error ||
329 r == idn_nfccheck_error ||
330 r == idn_prefcheck_error ||
331 r == idn_hyphcheck_error ||
332 r == idn_combcheck_error ||
333 r == idn_ctxjcheck_error ||
334 r == idn_ctxocheck_error ||
335 r == idn_bidicheck_error ||
336 r == idn_localcheck_error ||
337 r == idn_lencheck_error ||
338 r == idn_rtcheck_error ||
339 r == idn_tr46check_error) {
340 errormsg("%s\n", idn_result_tostring(r));
341 exit_code = IDNCHECK_EXITCODE_CHECKERROR;
342 } else if (r != idn_success) {
343 errormsg("%s\n", idn_result_tostring(r));
344 exit_code = IDNCHECK_EXITCODE_FAILURE;
345 }
346
347 ret:
348 if (resconf != NULL)
349 idn_resconf_destroy(resconf);
350
351 return (exit_code);
352 }
353
354 static void
idncheck_option_init(idncheck_option_t * option)355 idncheck_option_init(idncheck_option_t *option) {
356 option->in_code = NULL;
357 option->conf_file = NULL;
358 option->no_conf = 0;
359 option->protocol = idncheck_registration;
360 option->localcheck_file = NULL;
361 option->skip_actions = 0;
362 option->name = NULL;
363 option->quiet = 0;
364 option->test = 0;
365 }
366
367 /*
368 * Parse command line arguments.
369 */
370 static int
parse_command_line(int ac,char ** av,idncheck_option_t * option)371 parse_command_line(int ac, char **av, idncheck_option_t *option) {
372 ac--;
373 av++;
374 while (ac > 0 && **av == '-') {
375 if (strcmp(*av, "--") == 0) {
376 ac--;
377 av++;
378 break;
379 } else if (strcmp(*av, "-in") == 0 ||
380 strcmp(*av, "-i") == 0) {
381 if (ac < 2) {
382 errormsg("option '%s' requires an argument.\n", *av);
383 return (0);
384 }
385 option->in_code = av[1];
386 ac--;
387 av++;
388 } else if (strcmp(*av, "-conf") == 0 ||
389 strcmp(*av, "-c") == 0) {
390 if (ac < 2) {
391 errormsg("option '%s' requires an argument.\n", *av);
392 return (0);
393 }
394 option->conf_file = av[1];
395 ac--;
396 av++;
397 } else if (strcmp(*av, "-noconf") == 0 ||
398 strcmp(*av, "-C") == 0) {
399 option->no_conf = 1;
400 } else if (strcmp(*av, "-registration") == 0 ||
401 strcmp(*av, "-g") == 0) {
402 option->protocol = idncheck_registration;
403 } else if (strcmp(*av, "-lookup") == 0 ||
404 strcmp(*av, "-l") == 0) {
405 option->protocol = idncheck_lookup;
406 } else if (strcmp(*av, "-nomap") == 0 ||
407 strcmp(*av, "-M") == 0) {
408 if (!parse_skip("map", &option->skip_actions))
409 return (0);
410 } else if (strcmp(*av, "-skip") == 0) {
411 if (ac < 2) {
412 errormsg("option '%s' requires an argument.\n", *av);
413 return (0);
414 }
415 if (!parse_skip(av[1], &option->skip_actions)) {
416 errormsg("invalid argument to option '-skip'.\n", *av);
417 return (0);
418 }
419 ac--;
420 av++;
421 } else if (strcmp(*av, "-localcheck") == 0 ||
422 strcmp(*av, "-e") == 0) {
423 if (ac < 2) {
424 errormsg("option '%s' requires an argument.\n", *av);
425 return (0);
426 }
427 option->localcheck_file = av[1];
428 ac--;
429 av++;
430 } else if (strcmp(*av, "-quiet") == 0 ||
431 strcmp(*av, "-q") == 0) {
432 option->quiet = 1;
433 } else if (strcmp(*av, "-test") == 0 ||
434 strcmp(*av, "-t") == 0) {
435 option->test = 1;
436 } else if (strcmp(*av, "-version") == 0 ||
437 strcmp(*av, "-v") == 0) {
438 print_version();
439 exit(IDNCHECK_EXITCODE_SUCCESS);
440 } else if (strcmp(*av, "-help") == 0 ||
441 strcmp(*av, "-h") == 0) {
442 print_usage();
443 exit(IDNCHECK_EXITCODE_SUCCESS);
444 } else {
445 errormsg("unrecognized option '%s'.\n", *av);
446 return (0);
447 }
448 ac--;
449 av++;
450 }
451
452 if (option->test) {
453 option->name = "";
454 } else if (ac > 1) {
455 errormsg("too many arguments.\n");
456 return (0);
457 } else if (ac < 1) {
458 errormsg("too few argument.\n");
459 return (0);
460 } else {
461 option->name = av[0];
462 }
463
464 /*
465 * Resolve conflicts between options.
466 */
467 if (option->no_conf && option->conf_file != NULL)
468 option->conf_file = NULL;
469
470 return (1);
471 }
472
473 struct idncheck_actionmap {
474 char *name;
475 idn_action_t value;
476 };
477
478 static const struct idncheck_actionmap action_maps[] = {
479 {"map", IDN_MAP},
480 {"asclower", IDN_ASCLOWER},
481 {"rtconv", IDN_RTCONV},
482 {"prohcheck", IDN_PROHCHECK},
483 {"unascheck", IDN_UNASCHECK},
484 {"nfccheck", IDN_NFCCHECK},
485 {"prefcheck", IDN_PREFCHECK},
486 {"hyphcheck", IDN_HYPHCHECK},
487 {"combcheck", IDN_COMBCHECK},
488 {"ctxjcheck", IDN_CTXJCHECK},
489 {"ctxocheck", IDN_CTXOCHECK},
490 {"ctxolitecheck", IDN_CTXOLITECHECK},
491 {"bidicheck", IDN_BIDICHECK},
492 {"idnconv", IDN_IDNCONV},
493 {"lencheck", IDN_LENCHECK},
494 {"rtcheck", IDN_RTCHECK},
495 {NULL, 0}
496 };
497
498 static int
parse_skip(const char * arg,idn_action_t * action)499 parse_skip(const char *arg, idn_action_t *action) {
500 const struct idncheck_actionmap *mapp;
501 int found;
502
503 while (*arg != '\0') {
504 found = 0;
505 for (mapp = action_maps; mapp->name != NULL; mapp++) {
506 const char *s1 = arg;
507 const char *s2 = mapp->name;
508
509 while (*s1 != ',' && *s1 != '\0') {
510 if (*s1 != *s2 || *s2 == '\0')
511 break;
512 s1++;
513 s2++;
514 }
515 if (*s1 == ',' && *s2 == '\0') {
516 if (*(s1 + 1) == '\0')
517 return (0);
518 *action |= mapp->value;
519 arg = s1 + 1;
520 found = 1;
521 break;
522 } else if (*s1 == '\0' && *s2 == '\0') {
523 *action |= mapp->value;
524 arg = s1;
525 found = 1;
526 break;
527 }
528 }
529 if (!found)
530 return (0);
531 }
532 return (1);
533 }
534
535 static int
create_resconf(idn_resconf_t * resconf,int no_conf,const char * conf_file,const char * localencoding,const char * localcheck_file)536 create_resconf(idn_resconf_t *resconf, int no_conf,
537 const char *conf_file, const char *localencoding,
538 const char *localcheck_file) {
539 idn_result_t r;
540
541 r = idn_resconf_create(resconf);
542 if (r != idn_success) {
543 errormsg("failed to initialize configuration "
544 "contexts, %s\n", idn_result_tostring(r));
545 return (0);
546 }
547
548 if (!no_conf) {
549 r = idn_resconf_loadfile(*resconf, conf_file);
550 if (r != idn_success &&
551 (r != idn_nofile || conf_file != NULL)) {
552 errormsg("failed to read a configuration file, "
553 "%s\n", idn_result_tostring(r));
554 return (0);
555 }
556 }
557
558 /*
559 * For backward compatibility to idnkit-1.0, 'Punycode' specified
560 * as local encoding, we assumes it as UTF-8.
561 */
562 if (localencoding != NULL &&
563 strcmp(localencoding, IDN__PUNYCODE_ACENAME) == 0)
564 localencoding = IDN__UTF8_ENCODINGNAME;
565
566 r = idn_resconf_setlocalencoding(*resconf, localencoding);
567 if (r != idn_success) {
568 errormsg("failed to set the local encoding, %s\n",
569 idn_result_tostring(r));
570 return (0);
571 }
572
573 r = idn_resconf_setlocalcheckfile(*resconf, localcheck_file);
574 if (r != idn_success) {
575 errormsg("failed to set the localcheck file, %s\n",
576 idn_result_tostring(r));
577 return (0);
578 }
579
580 return (1);
581 }
582
583 static char *options[] = {
584 "Usage: idncheck [options..] name",
585 " -in INPUT-CODESET : specifies input codeset name.",
586 " -i INPUT-CODESET : synonym for -in",
587 " -conf CONF-FILE : specifies idnkit configuration file.",
588 " -c CONF-FILE : synonym for -conf",
589 " -noconf : do not load idnkit configuration file.",
590 " -C : synonym for -noconf",
591 " -registration : convert regions with the Domain Name Registration",
592 " protocol. (default)",
593 " -g : synonym for -registration",
594 " -lookup : convert regions with the Domain Name Lookup",
595 " protocol.",
596 " -l : synonym for -lookup",
597 " -nomap : do not perform mappings.",
598 " -M : synonym for -nomap",
599 " -skip ACTION,... : do not perform ACTION.",
600 " the following action names are recognized:",
601 " map : mappings",
602 " asclower : ASCII uppercase letters to lowercase",
603 " rtconv : conversion from Punycode to Unicode",
604 " for round trip check",
605 " prohcheck : prohibited code point check",
606 " unascheck : unassigned code point check",
607 " nfccheck : NFC conformance check",
608 " prefcheck : ACE prefix check",
609 " hyphcheck : hyphen check",
610 " combcheck : combining character check",
611 " ctxjcheck : CONTEXTJ code point check",
612 " ctxocheck : CONTEXTO code point check for the",
613 " Domain Name Registration protocol",
614 " ctxolitecheck",
615 " : CONTEXTO code point check for the",
616 " Domain Name Lookup protocol",
617 " bidicheck : Bidi check",
618 " localcheck : local check",
619 " idnconv : conversion from/to Punycode",
620 " lencheck : label length check",
621 " rtcheck : round trip check",
622 " -quiet : suppress a result message; yield exit status only.",
623 " -q : synonym for -quiet",
624 " -localcheck FILE : perform local check with a code point table FILE.",
625 " -e FILE : synonym for -localcheck",
626 " -test : output language and local encoding status,",
627 " then exit.",
628 " -t synonym for -test",
629 " -version : print version number, then exit.",
630 " -v : synonym for -version",
631 " -help : print this help, then exit.",
632 " -h : synonym for -help",
633 NULL
634 };
635
636 static void
print_test_status(idn_resconf_t conf)637 print_test_status(idn_resconf_t conf) {
638 printf("language = %s\n", idn_resconf_getlanguage(conf));
639 printf("input encoding = %s\n", idn_resconf_getlocalencoding(conf));
640 }
641
642 static void
print_version(void)643 print_version(void) {
644 printf("idncheck (idnkit) version: %s\n", IDNKIT_VERSION);
645 printf("%s\n", idn_version_getstring());
646 }
647
648 static void
print_usage(void)649 print_usage(void) {
650 int i;
651
652 for (i = 0; options[i] != NULL; i++)
653 printf("%s\n", options[i]);
654 }
655
656 static void
errormsg(const char * fmt,...)657 errormsg(const char *fmt, ...) {
658 va_list args;
659
660 if (quiet_mode)
661 return;
662
663 va_start(args, fmt);
664 vfprintf(stderr, fmt, args);
665 va_end(args);
666 }
667