Add.
[libidn.git] / src / idn.c
blob1a951fbb4e3d9b8d763009d3a531ee9a29eec807
1 /* idn.c --- Command line interface to libidn.
2 * Copyright (C) 2003, 2004, 2005, 2006 Simon Josefsson
4 * This file is part of GNU Libidn.
6 * GNU Libidn is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GNU Libidn is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Libidn; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 #ifdef HAVE_CONFIG_H
23 # include "config.h"
24 #endif
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <errno.h>
31 #if HAVE_LOCALE_H
32 # include <locale.h>
33 #endif
35 /* Gnulib headers. */
36 #include "error.h"
37 #include "gettext.h"
38 #define _(String) dgettext (PACKAGE, String)
40 /* Libidn headers. */
41 #include <stringprep.h>
42 #include <punycode.h>
43 #include <idna.h>
44 #ifdef WITH_TLD
45 # include <tld.h>
46 #endif
48 #include "idn_cmd.h"
50 #define GREETING "Copyright 2002, 2003, 2004, 2005 Simon Josefsson.\n" \
51 "GNU Libidn comes with NO WARRANTY, to the extent permitted by law.\n" \
52 "You may redistribute copies of GNU Libidn under the terms of\n" \
53 "the GNU Lesser General Public License. For more information\n" \
54 "about these matters, see the file named COPYING.LIB.\n"
56 /* For error.c */
57 char *program_name;
59 int
60 main (int argc, char *argv[])
62 struct gengetopt_args_info args_info;
63 char readbuf[BUFSIZ];
64 char *p, *r;
65 uint32_t *q;
66 unsigned cmdn = 0;
67 int rc;
69 #ifdef HAVE_SETLOCALE
70 setlocale (LC_ALL, "");
71 #endif
72 program_name = argv[0];
73 bindtextdomain (PACKAGE, LOCALEDIR);
74 textdomain (PACKAGE);
76 if (cmdline_parser (argc, argv, &args_info) != 0)
77 return EXIT_FAILURE;
79 if (!args_info.stringprep_given &&
80 !args_info.punycode_encode_given && !args_info.punycode_decode_given &&
81 !args_info.idna_to_ascii_given && !args_info.idna_to_unicode_given)
82 args_info.idna_to_ascii_given = 1;
84 if ((args_info.stringprep_given ? 1 : 0) +
85 (args_info.punycode_encode_given ? 1 : 0) +
86 (args_info.punycode_decode_given ? 1 : 0) +
87 (args_info.idna_to_ascii_given ? 1 : 0) +
88 (args_info.idna_to_unicode_given ? 1 : 0) != 1)
90 error (0, 0, _("Only one of -s, -e, -d, -a or -u can be specified."));
91 cmdline_parser_print_help ();
92 return EXIT_FAILURE;
95 if (!args_info.quiet_given)
96 fprintf (stderr, "%s %s\n" GREETING, PACKAGE, VERSION);
98 if (args_info.debug_given)
99 fprintf (stderr, _("Charset `%s'.\n"), stringprep_locale_charset ());
101 if (!args_info.quiet_given && args_info.inputs_num == 0)
102 fprintf (stderr, _("Type each input string on a line by itself, "
103 "terminated by a newline character.\n"));
107 if (cmdn < args_info.inputs_num)
109 strncpy (readbuf, args_info.inputs[cmdn++], BUFSIZ - 1);
110 readbuf[BUFSIZ - 1] = '\0';
112 else if (fgets (readbuf, BUFSIZ, stdin) == NULL)
114 if (feof (stdin))
115 break;
117 error (EXIT_FAILURE, errno, _("Input error"));
120 if (readbuf[strlen (readbuf) - 1] == '\n')
121 readbuf[strlen (readbuf) - 1] = '\0';
123 if (args_info.stringprep_given)
125 p = stringprep_locale_to_utf8 (readbuf);
126 if (!p)
127 error (EXIT_FAILURE, 0, _("Could not convert from %s to UTF-8."),
128 stringprep_locale_charset ());
130 q = stringprep_utf8_to_ucs4 (p, -1, NULL);
131 if (!q)
133 free (p);
134 error (EXIT_FAILURE, 0,
135 _("Could not convert from UTF-8 to UCS-4."));
138 if (args_info.debug_given)
140 size_t i;
141 for (i = 0; q[i]; i++)
142 fprintf (stderr, _("input[%lu] = U+%04x\n"),
143 (unsigned long) i, q[i]);
145 free (q);
147 rc = stringprep_profile (p, &r,
148 args_info.profile_given ?
149 args_info.profile_arg : "Nameprep", 0);
150 free (p);
151 if (rc != STRINGPREP_OK)
152 error (EXIT_FAILURE, 0, _("stringprep_profile: %s"),
153 stringprep_strerror (rc));
155 q = stringprep_utf8_to_ucs4 (r, -1, NULL);
156 if (!q)
158 free (r);
159 error (EXIT_FAILURE, 0,
160 _("Could not convert from UTF-8 to UCS-4."));
163 if (args_info.debug_given)
165 size_t i;
166 for (i = 0; q[i]; i++)
167 fprintf (stderr, _("output[%lu] = U+%04x\n"),
168 (unsigned long) i, q[i]);
170 free (q);
172 p = stringprep_utf8_to_locale (r);
173 free (r);
174 if (!p)
175 error (EXIT_FAILURE, 0, _("Could not convert from UTF-8 to %s."),
176 stringprep_locale_charset ());
178 fprintf (stdout, "%s\n", p);
180 free (p);
183 if (args_info.punycode_encode_given)
185 size_t len, len2;
187 p = stringprep_locale_to_utf8 (readbuf);
188 if (!p)
189 error (EXIT_FAILURE, 0, _("Could not convert from %s to UTF-8."),
190 stringprep_locale_charset ());
192 q = stringprep_utf8_to_ucs4 (p, -1, &len);
193 free (p);
194 if (!q)
195 error (EXIT_FAILURE, 0,
196 _("Could not convert from UTF-8 to UCS-4."));
198 if (args_info.debug_given)
200 size_t i;
201 for (i = 0; i < len; i++)
202 fprintf (stderr, _("input[%lu] = U+%04x\n"),
203 (unsigned long) i, q[i]);
206 len2 = BUFSIZ - 1;
207 rc = punycode_encode (len, q, NULL, &len2, readbuf);
208 free (q);
209 if (rc != PUNYCODE_SUCCESS)
210 error (EXIT_FAILURE, 0, _("punycode_encode: %s"),
211 punycode_strerror (rc));
213 readbuf[len2] = '\0';
215 p = stringprep_utf8_to_locale (readbuf);
216 if (!p)
217 error (EXIT_FAILURE, 0, _("Could not convert from UTF-8 to %s."),
218 stringprep_locale_charset ());
220 fprintf (stdout, "%s\n", p);
222 free (p);
225 if (args_info.punycode_decode_given)
227 size_t len;
229 len = BUFSIZ;
230 q = (uint32_t *) malloc (len * sizeof (q[0]));
231 if (!q)
232 error (EXIT_FAILURE, ENOMEM, _("malloc"));
234 rc = punycode_decode (strlen (readbuf), readbuf, &len, q, NULL);
235 if (rc != PUNYCODE_SUCCESS)
237 free (q);
238 error (EXIT_FAILURE, 0, _("punycode_decode: %s"),
239 punycode_strerror (rc));
242 if (args_info.debug_given)
244 size_t i;
245 for (i = 0; i < len; i++)
246 fprintf (stderr, _("output[%lu] = U+%04x\n"),
247 (unsigned long) i, q[i]);
250 q[len] = 0;
251 r = stringprep_ucs4_to_utf8 (q, -1, NULL, NULL);
252 free (q);
253 if (!r)
254 error (EXIT_FAILURE, 0,
255 _("Could not convert from UCS-4 to UTF-8."));
257 p = stringprep_utf8_to_locale (r);
258 free (r);
259 if (!r)
260 error (EXIT_FAILURE, 0, _("Could not convert from UTF-8 to %s."),
261 stringprep_locale_charset ());
263 fprintf (stdout, "%s\n", p);
265 free (p);
268 if (args_info.idna_to_ascii_given)
270 p = stringprep_locale_to_utf8 (readbuf);
271 if (!p)
272 error (EXIT_FAILURE, 0, _("Could not convert from %s to UTF-8."),
273 stringprep_locale_charset ());
275 q = stringprep_utf8_to_ucs4 (p, -1, NULL);
276 free (p);
277 if (!q)
278 error (EXIT_FAILURE, 0,
279 _("Could not convert from UCS-4 to UTF-8."));
281 if (args_info.debug_given)
283 size_t i;
284 for (i = 0; q[i]; i++)
285 fprintf (stderr, _("input[%lu] = U+%04x\n"),
286 (unsigned long) i, q[i]);
289 rc = idna_to_ascii_4z (q, &p,
290 (args_info.allow_unassigned_given ?
291 IDNA_ALLOW_UNASSIGNED : 0) |
292 (args_info.usestd3asciirules_given ?
293 IDNA_USE_STD3_ASCII_RULES : 0));
294 free (q);
295 if (rc != IDNA_SUCCESS)
296 error (EXIT_FAILURE, 0, _("idna_to_ascii_4z: %s"),
297 idna_strerror (rc));
299 #ifdef WITH_TLD
300 if (args_info.tld_flag)
302 size_t errpos;
304 rc = idna_to_unicode_8z4z (p, &q,
305 (args_info.allow_unassigned_given ?
306 IDNA_ALLOW_UNASSIGNED : 0) |
307 (args_info.usestd3asciirules_given ?
308 IDNA_USE_STD3_ASCII_RULES : 0));
309 if (rc != IDNA_SUCCESS)
310 error (EXIT_FAILURE, 0, _("idna_to_unicode_8z4z (TLD): %s"),
311 idna_strerror (rc));
313 if (args_info.debug_given)
315 size_t i;
316 for (i = 0; q[i]; i++)
317 fprintf (stderr, _("tld[%lu] = U+%04x\n"),
318 (unsigned long) i, q[i]);
321 rc = tld_check_4z (q, &errpos, NULL);
322 free (q);
323 if (rc == TLD_INVALID)
324 error (EXIT_FAILURE, 0, _("tld_check_4z (position %lu): %s"),
325 (unsigned long) errpos, tld_strerror (rc));
326 if (rc != TLD_SUCCESS)
327 error (EXIT_FAILURE, 0, _("tld_check_4z: %s"),
328 tld_strerror (rc));
330 #endif
332 if (args_info.debug_given)
334 size_t i;
335 for (i = 0; p[i]; i++)
336 fprintf (stderr, _("output[%lu] = U+%04x\n"),
337 (unsigned long) i, p[i]);
340 fprintf (stdout, "%s\n", p);
342 free (p);
345 if (args_info.idna_to_unicode_given)
347 p = stringprep_locale_to_utf8 (readbuf);
348 if (!p)
349 error (EXIT_FAILURE, 0, _("Could not convert from %s to UTF-8."),
350 stringprep_locale_charset ());
352 q = stringprep_utf8_to_ucs4 (p, -1, NULL);
353 if (!q)
355 free (p);
356 error (EXIT_FAILURE, 0,
357 _("Could not convert from UCS-4 to UTF-8."));
360 if (args_info.debug_given)
362 size_t i;
363 for (i = 0; q[i]; i++)
364 fprintf (stderr, _("input[%lu] = U+%04x\n"),
365 (unsigned long) i, q[i]);
367 free (q);
369 rc = idna_to_unicode_8z4z (p, &q,
370 (args_info.allow_unassigned_given ?
371 IDNA_ALLOW_UNASSIGNED : 0) |
372 (args_info.usestd3asciirules_given ?
373 IDNA_USE_STD3_ASCII_RULES : 0));
374 free (p);
375 if (rc != IDNA_SUCCESS)
376 error (EXIT_FAILURE, 0, _("idna_to_unicode_8z4z: %s"),
377 idna_strerror (rc));
379 if (args_info.debug_given)
381 size_t i;
382 for (i = 0; q[i]; i++)
383 fprintf (stderr, _("output[%lu] = U+%04x\n"),
384 (unsigned long) i, q[i]);
387 #ifdef WITH_TLD
388 if (args_info.tld_flag)
390 size_t errpos;
392 rc = tld_check_4z (q, &errpos, NULL);
393 if (rc == TLD_INVALID)
395 free (q);
396 error (EXIT_FAILURE, 0, _("tld_check_4z (position %lu): %s"),
397 (unsigned long) errpos, tld_strerror (rc));
399 if (rc != TLD_SUCCESS)
401 free (q);
402 error (EXIT_FAILURE, 0, _("tld_check_4z: %s"),
403 tld_strerror (rc));
406 #endif
408 r = stringprep_ucs4_to_utf8 (q, -1, NULL, NULL);
409 free (q);
410 if (!r)
411 error (EXIT_FAILURE, 0,
412 _("Could not convert from UTF-8 to UCS-4."));
414 p = stringprep_utf8_to_locale (r);
415 free (r);
416 if (!r)
417 error (EXIT_FAILURE, 0, _("Could not convert from UTF-8 to %s."),
418 stringprep_locale_charset ());
420 fprintf (stdout, "%s\n", p);
422 free (p);
425 while (!feof (stdin) && !ferror (stdin) && (args_info.inputs_num == 0 ||
426 cmdn < args_info.inputs_num));
428 return EXIT_SUCCESS;