summaryrefslogtreecommitdiffstats
path: root/contrib/idn/idnkit-1.0-src/tools/idnconv
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/idn/idnkit-1.0-src/tools/idnconv')
-rw-r--r--contrib/idn/idnkit-1.0-src/tools/idnconv/Makefile.in116
-rw-r--r--contrib/idn/idnkit-1.0-src/tools/idnconv/idnconv.1373
-rw-r--r--contrib/idn/idnkit-1.0-src/tools/idnconv/idnconv.c803
-rw-r--r--contrib/idn/idnkit-1.0-src/tools/idnconv/idnslookup.in116
-rw-r--r--contrib/idn/idnkit-1.0-src/tools/idnconv/make.wnt72
-rw-r--r--contrib/idn/idnkit-1.0-src/tools/idnconv/selectiveencode.c127
-rw-r--r--contrib/idn/idnkit-1.0-src/tools/idnconv/selectiveencode.h70
-rw-r--r--contrib/idn/idnkit-1.0-src/tools/idnconv/util.c554
-rw-r--r--contrib/idn/idnkit-1.0-src/tools/idnconv/util.h96
9 files changed, 2327 insertions, 0 deletions
diff --git a/contrib/idn/idnkit-1.0-src/tools/idnconv/Makefile.in b/contrib/idn/idnkit-1.0-src/tools/idnconv/Makefile.in
new file mode 100644
index 0000000..671c2c0
--- /dev/null
+++ b/contrib/idn/idnkit-1.0-src/tools/idnconv/Makefile.in
@@ -0,0 +1,116 @@
+# $Id: Makefile.in,v 1.1.1.1 2003/06/04 00:27:05 marka Exp $
+# Copyright (c) 2000, 2002 Japan Network Information Center.
+# All rights reserved.
+#
+# By using this file, you agree to the terms and conditions set forth bellow.
+#
+# LICENSE TERMS AND CONDITIONS
+#
+# The following License Terms and Conditions apply, unless a different
+# license is obtained from Japan Network Information Center ("JPNIC"),
+# a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
+# Chiyoda-ku, Tokyo 101-0047, Japan.
+#
+# 1. Use, Modification and Redistribution (including distribution of any
+# modified or derived work) in source and/or binary forms is permitted
+# under this License Terms and Conditions.
+#
+# 2. Redistribution of source code must retain the copyright notices as they
+# appear in each source code file, this License Terms and Conditions.
+#
+# 3. Redistribution in binary form must reproduce the Copyright Notice,
+# this License Terms and Conditions, in the documentation and/or other
+# materials provided with the distribution. For the purposes of binary
+# distribution the "Copyright Notice" refers to the following language:
+# "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
+#
+# 4. The name of JPNIC may not be used to endorse or promote products
+# derived from this Software without specific prior written approval of
+# JPNIC.
+#
+# 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+top_builddir = ../..
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+mandir = @mandir@
+man1dir = $(mandir)/man1
+
+CC = @CC@
+RANLIB = @RANLIB@
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
+SHELL = @SHELL@
+LIBTOOL = @LIBTOOL@
+
+ICONVINC = @ICONVINC@
+ICONVLIB = @ICONVLIB@
+IDNLIB = ../../lib/libidnkit.la
+
+INCS = -I$(srcdir) -I$(srcdir)/../../include -I../../include $(ICONVINC)
+DEFS =
+
+CFLAGS = $(INCS) $(DEFS) @CPPFLAGS@ @CFLAGS@
+LDFLAGS = @LDFLAGS@
+
+SRCS = idnconv.c util.c selectiveencode.c
+OBJS = idnconv.o util.o selectiveencode.o
+
+@LITEONLY_TRUE@all:
+@LITEONLY_FALSE@all: idnconv idnslookup idnconv.1
+
+idnconv: $(OBJS) $(IDNLIB)
+ $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ \
+ $(OBJS) $(IDNLIB) $(ICONVLIB)
+
+idnslookup: $(srcdir)/idnslookup.in
+ sed -e 's%[@]bindir[@]%$(bindir)%' $(srcdir)/idnslookup.in > idnslookup
+ chmod 0755 idnslookup
+
+@LITEONLY_TRUE@install:
+@LITEONLY_FALSE@@COMPAT_TRUE@install: all install-nolite install-compat
+@LITEONLY_FALSE@@COMPAT_FALSE@install: all install-nolite
+
+install-nolite:
+ $(MKINSTALLDIRS) $(DESTDIR)$(bindir)
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) idnconv \
+ $(DESTDIR)$(bindir)/idnconv
+ $(MKINSTALLDIRS) $(DESTDIR)$(man1dir)
+ $(INSTALL_DATA) $(srcdir)/idnconv.1 $(DESTDIR)$(man1dir)/idnconv.1
+
+install-compat:
+ src=$(DESTDIR)$(bindir)/idnconv; \
+ dst=$(DESTDIR)$(bindir)/mdnconv; \
+ rm -f $$dst; \
+ ln $$src $$dst || cp $$src $$dst
+ src=$(DESTDIR)$(man1dir)/idnconv.1; \
+ dst=$(DESTDIR)$(man1dir)/mdnconv.1; \
+ rm -f $$dst; \
+ ln $$src $$dst || cp $$src $$dst
+
+clean:
+ rm -f *.o idnconv idnslookup *.core core *~
+ rm -fr .libs/
+
+distclean: clean
+ rm -f Makefile
+
+test check:
diff --git a/contrib/idn/idnkit-1.0-src/tools/idnconv/idnconv.1 b/contrib/idn/idnkit-1.0-src/tools/idnconv/idnconv.1
new file mode 100644
index 0000000..5e7551e
--- /dev/null
+++ b/contrib/idn/idnkit-1.0-src/tools/idnconv/idnconv.1
@@ -0,0 +1,373 @@
+.\" $Id: idnconv.1,v 1.1.1.1 2003/06/04 00:27:10 marka Exp $
+.\"
+.\" Copyright (c) 2000,2001,2002 Japan Network Information Center.
+.\" All rights reserved.
+.\"
+.\" By using this file, you agree to the terms and conditions set forth bellow.
+.\"
+.\" LICENSE TERMS AND CONDITIONS
+.\"
+.\" The following License Terms and Conditions apply, unless a different
+.\" license is obtained from Japan Network Information Center ("JPNIC"),
+.\" a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
+.\" Chiyoda-ku, Tokyo 101-0047, Japan.
+.\"
+.\" 1. Use, Modification and Redistribution (including distribution of any
+.\" modified or derived work) in source and/or binary forms is permitted
+.\" under this License Terms and Conditions.
+.\"
+.\" 2. Redistribution of source code must retain the copyright notices as they
+.\" appear in each source code file, this License Terms and Conditions.
+.\"
+.\" 3. Redistribution in binary form must reproduce the Copyright Notice,
+.\" this License Terms and Conditions, in the documentation and/or other
+.\" materials provided with the distribution. For the purposes of binary
+.\" distribution the "Copyright Notice" refers to the following language:
+.\" "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
+.\"
+.\" 4. The name of JPNIC may not be used to endorse or promote products
+.\" derived from this Software without specific prior written approval of
+.\" JPNIC.
+.\"
+.\" 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
+.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+.\" PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+.\"
+.TH IDNCONV 1 "Mar 3, 2001"
+.\"
+.SH NAME
+idnconv \- codeset converter for named.conf and zone master files
+.\"
+.SH SYNOPSIS
+\fBidnconv\fP [\fIoptions..\fP] [\fIfile\fP...]
+.\"
+.SH DESCRIPTION
+\fBidnconv\fR is a codeset converter for named configuration files
+and zone master files.
+\fBidnconv\fR performs codeset conversion specified either
+by the command-line arguments or by the configuration file,
+and writes the converted text to stdout.
+.PP
+If file name is specified, \fBidnconv\fR converts the contents of
+the file.
+Otherwise, \fBidnconv\fR converts \fIstdin\fR.
+.PP
+Since \fBidnconv\fR is specifically designed for converting
+internatinalized domain names, it may not be suitable as a general
+codeset converter.
+.\"
+.SH "OPERATION MODES"
+\fBidnconv\fR has two operation modes.
+.PP
+One is a mode to convert local-encoded domain names to IDN-encoded
+one. Usually this mode is used for preparing domain names to be
+listed in named configuration files or zone master files.
+In this mode, the following processes are performed in addition to
+the codeset (encoding) conversion.
+.RS 2
+.IP \- 2
+local mapping
+.IP \- 2
+standard domain name preperation (NAMEPREP)
+.RE
+.PP
+The other mode is a reverse conversion, from IDN-encoded domain name to
+local-encoded domain names.
+In this mode, local mapping and NAMEPREP are not performed since
+IDN-encoded names should already be normalized.
+Instead, a check is done in order to make sure the IDN-encoded domain name
+is properly NAMEPREP'ed. If it is not, the name will be output in
+IDN encoding, not in the local encoding.
+.\"
+.SH OPTIONS
+Normally \fBidnconv\fR reads system's default configuration file
+(idn.conf) and performs conversion or name preparation according to
+the parameters specified in the file.
+You can override the setting in the configuration file by various
+command line options below.
+.TP 4
+\fB\-in\fP \fIin-code\fP, \fB\-i\fP \fIin-code\fP
+Specify the codeset name of the input text.
+Any of the following codeset names can be specified.
+.RS 4
+.IP "\(bu" 2
+Any codeset names which \fIiconv_open()\fP library function accepts
+.IP "\(bu" 2
+\f(CWPunycode\fR
+.IP "\(bu" 2
+\f(CWUTF-8\fR
+.IP "\(bu" 2
+Any alias names for the above, defined by the codeset alias file.
+.RE
+.IP "" 4
+If this option is not specified, the default codeset is determined
+from the locale in normal conversion mode.
+In reverse conversion mode, the default codeset is the IDN encoding
+specified by the configuration file (``idn-encoding'' entry).
+.TP 4
+\fB\-out\fP \fIout-code\fP, \fB\-o\fP \fIout-code\fP
+Specify the codeset name of the output text. \fIout-code\fP can be any
+codeset name that can be specified for \fB\-in\fR option.
+.IP "" 4
+If this option is not specified, the default is the IDN encoding
+specified by the configuration file (``idn-encoding'' entry) in
+normal conversion mode.
+In reverse conversion mode, the default codeset is determined from
+the locale.
+.TP 4
+\fB\-conf\fP \fIpath\fP, \fB\-c\fP \fIpath\fP
+Specify the pathname of idnkit configuration file (``idn.conf'').
+If not specified, system's default file is used, unless \-noconf
+option is specified.
+.TP 4
+\fB\-noconf\fP, \fB\-C\fP
+Specify that no configuration file is to be used.
+.TP 4
+\fB\-reverse\fP, \fB\-r\fP
+Specify reverse conversion mode.
+.br
+If this option is not specified, the normal conversion mode is used.
+.TP 4
+\fB\-nameprep\fR \fIversion\fR, \fB\-n\fR \fIversion\fR
+Specify the version of NAMEPREP.
+The following is a list of currently available versions.
+.RS 4
+.IP \f(CWRFC3491\fR 4
+Perform NAMEPREP according to the RFC3491
+``rfc-3491.txt''.
+.RE
+.TP 4
+\fB\-nonameprep\fR, \fB\-N\fR
+Specify to skip NAMEPREP process (or NAMEPREP verification process
+in the reverse conversion mode).
+This option implies -nounassigncheck and -nobidicheck.
+.TP 4
+\fB\-localmap\fR \fImap\fR
+Specify the name of local mapping rule.
+Currently, following maps are available.
+.RS 4
+.IP \f(CWRFC3491\fR 4
+Use the list of mappings specified by RFC3491.
+.IP \f(CWfilemap:\fR\fIpath\fR 4
+Use list of mappings specified by mapfile \fIpath\fR.
+See idn.conf(5) for the format of a mapfile.
+.RE
+.IP "" 4
+This option can be specified more than once.
+In that case, each mapping will be performed in the order of the
+specification.
+.TP 4
+\fB\-nounassigncheck\fR, \fB\-U\fR
+Skip unassigned codepoint check.
+.TP 4
+\fB\-nobidicheck\fR, \fB\-B\fR
+Skip bidi character check.
+.TP 4
+\fB\-nolengthcheck\fR
+Do not check label length of normal conversion result.
+This option is only meaningful in the normal conversion mode.
+.TP 4
+\fB\-noasciicheck\fR, \fB\-A\fR
+Do not check ASCII range characters.
+This option is only meaningful in the normal conversion mode.
+.TP 4
+\fB\-noroundtripcheck\fR
+Do not perform round trip check.
+This option is only meaningful in the reverse conversion mode.
+.TP 4
+\fB\-delimiter\fR \fIcodepoint\fP
+Specify the character to be mapped to domain name delimiter (period).
+This option can be specified more than once in order to specify multiple
+characters.
+.br
+This option is only meaningful in the normal conversion mode.
+.TP 4
+\fB\-whole\fP, \fB\-w\fP
+Perform local mapping, nameprep and conversion to output codeset for the entire
+input text. If this option is not specified, only non-ASCII characters
+and their surrounding texts will be processed.
+See ``NORAML CONVERSION MECHANISM'' and ``REVERSE CONVERSION MECHANISM''
+for details.
+.TP 4
+\fB\-alias\fP \fIpath\fP, \fB\-a\fP \fIpath\fP
+Specify a codeset alias file. It is a simple text file, where
+each line has a pair of alias name and real name separated by one
+or more white spaces like below:
+.nf
+.ft CW
+
+ \fIalias-codeset-name\fP \fIreal-codeset-name\fP
+
+.ft R
+.fi
+Lines starting with ``#'' are treated as comments.
+.TP 4
+\fB\-flush\fP
+Force line-buffering mode.
+.TP 4
+\fB\-version\fP, \fB\-v\fP
+Print version information and quit.
+.\"
+.SH LOCAL CODESET
+idnconv guesses local codeset from locale and environment variables.
+See the ``LOCAL CODESET'' section in idn.conf(5) for more details.
+.\"
+.SH NORMAL CONVERSION MECHANISM
+\fBidnconv\fR performs conversion line by line.
+Here describes how \fBidnconv\fR does its job for each line.
+.\"
+.IP "1. read a line from input text" 4
+.IP "2. convert the line to UTF-8" 4
+\fBidnconv\fR converts the line from local encoding to UTF-8.
+.IP "3. find internationalized domain names" 4
+If the \-whole\ (or \-w) option is specified, the entire line is
+assumed as an internationalized domain name.
+Otherwise, \fBidnconv\fR recognizes any character sequences having
+the following properties in the line as internationalized domain names.
+.RS 4
+.IP "\(bu" 2
+containing at least one non-ASCII character, and
+.IP "\(bu" 2
+consisting of legal domain name characters (alphabets, digits, hypens),
+non-ASCII characters and period.
+.RE
+.IP "4. convert internationalized domain names to ACE" 4
+For each internationalized domain name found in the line,
+\fBidnconv\fR converts the name to ACE.
+The details about the conversion procedure is:
+.RS 4
+.IP "4.1. delimiter mapping" 4
+Substibute certain characters specified as domain name delimiter
+with period.
+.IP "4.2. local mapping" 4
+Perform local mapping.
+If the local mapping is specified by command line option \-localmap,
+the specified mapping rule is applied. Otherwise, find the mapping rule
+from the configuration file which matches to the TLD of the name,
+and perform mapping according to the matched rule.
+.br
+This step is skipped if the \-nolocalmap (or \-L) option is specified.
+.IP "4.3. NAMEPREP" 4
+Perform name preparation (NAMEPREP).
+Mapping, normalization, prohibited character checking, unassigned
+codepoint checking, bidirectional character checking are done in
+that order.
+If the prohibited character check, unassigned codepoint check, or
+bidi character check fails, the normal conversion procedure aborts.
+.br
+This step is skipped if the \-nonameprep (or \-N) option is specified.
+.IP "4.4. ASCII character checking" 4
+Checks ASCII range character in the domain name.
+the normal conversion procedure aborts, if the domain name has a label
+beginning or end with hyphen (U+002D) or it contains ASCII range character
+except for alphanumeric and hyphen,
+.br
+This step is skipped if the \-noasciicheck (or \-A) option is specified.
+.IP "4.5. ACE conversion" 4
+Convert the string to ACE.
+.IP "4.6. label length checking" 4
+The normal conversion procedure aborts, if the domain name has an empty
+label or too long label (64 characters or more).
+.br
+This step is skipped if the \-nolengthcheck option is specified.
+.RE
+.IP "5. output the result" 4
+.PP
+.\"
+.SH REVERSE CONVERSION MECHANISM
+This is like the normal conversion mechanism, but they are not symmetric.
+\fBidnconv\fR does its job for each line.
+.\"
+.IP "1. read a line from input text" 4
+.IP "2. convert the line to UTF-8" 4
+\fBidnconv\fR converts the line from local encoding to UTF-8.
+.IP "3. find internationalized domain names" 4
+If the \-whole\ (or \-w) option is specified, the entire line is
+assumed as an internationalized domain name.
+Otherwise, \fBidnconv\fR decodes any valid ASCII domain names
+including ACE names in the line.
+.IP "4. convert domain names to local encoding"
+Then, \fBidnconv\fR decodes the domain names.
+The decode procedure consists of the following steps.
+.RS 4
+.IP "4.1. Delimiter mapping" 4
+Substibute certain characters specified as domain name delimiter
+with period.
+.br
+.IP "4.2. NAMEPREP" 4
+Perform name preparation (NAMEPREP) for each label in the domain name.
+Mapping, normalization, prohibited character checking, unassigned
+codepoint checking, bidirectional character checking are done in
+that order.
+If the prohibited character check, unassigned codepoint check, or
+bidi character check fails, disqualified labels are restored to
+original input strings and further conversion on those labels are
+not performed.
+.br
+This step is skipped if the \-nonameprep (or \-N) option is specified.
+.IP "4.3. ACE conversion" 4
+Convert the string from ACE to UTF-8.
+.IP "4.4. Round trip checkning" 4
+For each label, perform the normal conversion and compare it with
+the result of the step 4.2.
+This check succeeds, if they are equivalent strings.
+In case of failure, disqualified labels are restored to original
+input strings and further conversion on those labels are not
+performed.
+.br
+This step is skipped if the \-noroundtripcheck option is specified.
+.IP "4.5. local encoding conversion" 4
+Convert the result of the step 4.3. from UTF-8 to local encoding.
+If a label in the domain name contains a character which cannot be
+represented in the local encoding, the label is restored to the
+original input string.
+.RE
+.IP "5. output the result" 4
+.PP
+.\"
+.SH FILE MANAGEMENT
+Maybe the best way to manage named.conf or zone master files that contains
+internationalized domain name is to keep them in your local codeset so that
+they can be edited with your favorite editor, and generate a version in
+the IDN encoding using \fBidnconv\fP.
+.PP
+`make' is a convenient tool for this purpose.
+Suppose the local codeset version has suffix `.lc', and its ACE version
+has suffix `.ace'. The following Makefile enables you to generate
+ACE version from local codeset version by just typing `make'.
+.RS 4
+.nf
+.ft CW
+
+\&.SUFFIXES: .lc .ace
+\&.lc.ace:
+ idnconv -in $(LOCALCODE) -out $(IDNCODE) \\
+ $(IDNCONVOPT) $< > $@
+
+LOCALCODE = EUC-JP
+IDNCODE = Punycode
+IDNCONVOPT =
+
+DESTFILES = db.zone1.ace db.zone2.ace
+
+all: $(DESTFILES)
+.ft
+.fi
+.RE
+.\"
+.SH SEE ALSO
+idn.conf(5),
+iconv(3)
+.\"
+.SH BUGS
+The automatic input-code selection depends on your system, and sometimes
+it cannot guess or guess wrong. It is better to explicitly specify it
+using \-in option.
diff --git a/contrib/idn/idnkit-1.0-src/tools/idnconv/idnconv.c b/contrib/idn/idnkit-1.0-src/tools/idnconv/idnconv.c
new file mode 100644
index 0000000..a10a738
--- /dev/null
+++ b/contrib/idn/idnkit-1.0-src/tools/idnconv/idnconv.c
@@ -0,0 +1,803 @@
+#ifndef lint
+static char *rcsid = "$Id: idnconv.c,v 1.1.1.1 2003/06/04 00:27:07 marka Exp $";
+#endif
+
+/*
+ * Copyright (c) 2000,2001,2002 Japan Network Information Center.
+ * All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set forth bellow.
+ *
+ * LICENSE TERMS AND CONDITIONS
+ *
+ * The following License Terms and Conditions apply, unless a different
+ * license is obtained from Japan Network Information Center ("JPNIC"),
+ * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
+ * Chiyoda-ku, Tokyo 101-0047, Japan.
+ *
+ * 1. Use, Modification and Redistribution (including distribution of any
+ * modified or derived work) in source and/or binary forms is permitted
+ * under this License Terms and Conditions.
+ *
+ * 2. Redistribution of source code must retain the copyright notices as they
+ * appear in each source code file, this License Terms and Conditions.
+ *
+ * 3. Redistribution in binary form must reproduce the Copyright Notice,
+ * this License Terms and Conditions, in the documentation and/or other
+ * materials provided with the distribution. For the purposes of binary
+ * distribution the "Copyright Notice" refers to the following language:
+ * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
+ *
+ * 4. The name of JPNIC may not be used to endorse or promote products
+ * derived from this Software without specific prior written approval of
+ * JPNIC.
+ *
+ * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+/*
+ * idnconv -- Codeset converter for named.conf and zone files
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#include <idn/result.h>
+#include <idn/converter.h>
+#include <idn/normalizer.h>
+#include <idn/utf8.h>
+#include <idn/resconf.h>
+#include <idn/res.h>
+#include <idn/util.h>
+#include <idn/version.h>
+
+#include "util.h"
+
+#define MAX_DELIMITER 10
+#define MAX_LOCALMAPPER 10
+#define MAX_MAPPER 10
+#define MAX_NORMALIZER 10
+#define MAX_CHEKER 10
+
+#define FLAG_REVERSE 0x0001
+#define FLAG_DELIMMAP 0x0002
+#define FLAG_LOCALMAP 0x0004
+#define FLAG_MAP 0x0008
+#define FLAG_NORMALIZE 0x0010
+#define FLAG_PROHIBITCHECK 0x0020
+#define FLAG_UNASSIGNCHECK 0x0040
+#define FLAG_BIDICHECK 0x0080
+#define FLAG_ASCIICHECK 0x0100
+#define FLAG_LENGTHCHECK 0x0200
+#define FLAG_ROUNDTRIPCHECK 0x0400
+#define FLAG_SELECTIVE 0x0800
+
+#define FLAG_NAMEPREP \
+ (FLAG_MAP|FLAG_NORMALIZE|FLAG_PROHIBITCHECK|FLAG_UNASSIGNCHECK|\
+ FLAG_BIDICHECK)
+
+#define DEFAULT_FLAGS \
+ (FLAG_LOCALMAP|FLAG_NAMEPREP|FLAG_ASCIICHECK|FLAG_LENGTHCHECK|\
+ FLAG_ROUNDTRIPCHECK|FLAG_SELECTIVE|FLAG_DELIMMAP)
+
+int line_number; /* current input file line number */
+static int flush_every_line = 0; /* pretty obvious */
+
+static int encode_file(idn_resconf_t conf1, idn_resconf_t conf2,
+ FILE *fp, int flags);
+static int decode_file(idn_resconf_t conf1, idn_resconf_t conf2,
+ FILE *fp, int flags);
+static int trim_newline(idnconv_strbuf_t *buf);
+static idn_result_t convert_line(idnconv_strbuf_t *from,
+ idnconv_strbuf_t *to,
+ idn_resconf_t conf,
+ idn_action_t actions, int flags);
+static void print_usage(char *cmd);
+static void print_version(void);
+static unsigned long get_ucs(const char *p);
+
+int
+main(int ac, char **av) {
+ char *cmd = *av;
+ char *cname;
+ unsigned long delimiters[MAX_DELIMITER];
+ char *localmappers[MAX_LOCALMAPPER];
+ char *nameprep_version = NULL;
+ int ndelimiters = 0;
+ int nlocalmappers = 0;
+ char *in_code = NULL;
+ char *out_code = NULL;
+ char *resconf_file = NULL;
+ int no_resconf = 0;
+ char *encoding_alias = NULL;
+ int flags = DEFAULT_FLAGS;
+ FILE *fp;
+ idn_result_t r;
+ idn_resconf_t resconf1, resconf2;
+ idn_converter_t conv;
+ int exit_value;
+
+#ifdef HAVE_SETLOCALE
+ (void)setlocale(LC_ALL, "");
+#endif
+
+ /*
+ * If the command name begins with 'r', reverse mode is assumed.
+ */
+ if ((cname = strrchr(cmd, '/')) != NULL)
+ cname++;
+ else
+ cname = cmd;
+ if (cname[0] == 'r')
+ flags |= FLAG_REVERSE;
+
+ ac--;
+ av++;
+ while (ac > 0 && **av == '-') {
+
+#define OPT_MATCH(opt) (strcmp(*av, opt) == 0)
+#define MUST_HAVE_ARG if (ac < 2) print_usage(cmd)
+#define APPEND_LIST(array, size, item, what) \
+ if (size >= (sizeof(array) / sizeof(array[0]))) { \
+ errormsg("too many " what "\n"); \
+ exit(1); \
+ } \
+ array[size++] = item; \
+ ac--; av++
+
+ if (OPT_MATCH("-in") || OPT_MATCH("-i")) {
+ MUST_HAVE_ARG;
+ in_code = av[1];
+ ac--;
+ av++;
+ } else if (OPT_MATCH("-out") || OPT_MATCH("-o")) {
+ MUST_HAVE_ARG;
+ out_code = av[1];
+ ac--;
+ av++;
+ } else if (OPT_MATCH("-conf") || OPT_MATCH("-c")) {
+ MUST_HAVE_ARG;
+ resconf_file = av[1];
+ ac--;
+ av++;
+ } else if (OPT_MATCH("-nameprep") || OPT_MATCH("-n")) {
+ MUST_HAVE_ARG;
+ nameprep_version = av[1];
+ ac--;
+ av++;
+ } else if (OPT_MATCH("-noconf") || OPT_MATCH("-C")) {
+ no_resconf = 1;
+ } else if (OPT_MATCH("-reverse") || OPT_MATCH("-r")) {
+ flags |= FLAG_REVERSE;
+ } else if (OPT_MATCH("-nolocalmap") || OPT_MATCH("-L")) {
+ flags &= ~FLAG_LOCALMAP;
+ } else if (OPT_MATCH("-nonameprep") || OPT_MATCH("-N")) {
+ flags &= ~FLAG_NAMEPREP;
+ } else if (OPT_MATCH("-unassigncheck") || OPT_MATCH("-u")) {
+ flags |= FLAG_UNASSIGNCHECK;
+ } else if (OPT_MATCH("-nounassigncheck") || OPT_MATCH("-U")) {
+ flags &= ~FLAG_UNASSIGNCHECK;
+ } else if (OPT_MATCH("-nobidicheck") || OPT_MATCH("-B")) {
+ flags &= ~FLAG_BIDICHECK;
+ } else if (OPT_MATCH("-noasciicheck") || OPT_MATCH("-A")) {
+ flags &= ~FLAG_ASCIICHECK;
+ } else if (OPT_MATCH("-nolengthcheck")) {
+ flags &= ~FLAG_LENGTHCHECK;
+ } else if (OPT_MATCH("-noroundtripcheck")) {
+ flags &= ~FLAG_ROUNDTRIPCHECK;
+ } else if (OPT_MATCH("-whole") || OPT_MATCH("-w")) {
+ flags &= ~FLAG_SELECTIVE;
+ } else if (OPT_MATCH("-localmap")) {
+ MUST_HAVE_ARG;
+ APPEND_LIST(localmappers, nlocalmappers, av[1],
+ "local maps");
+ } else if (OPT_MATCH("-delimiter")) {
+ unsigned long v;
+ MUST_HAVE_ARG;
+ v = get_ucs(av[1]);
+ APPEND_LIST(delimiters, ndelimiters, v,
+ "delimiter maps");
+ } else if (OPT_MATCH("-alias") || OPT_MATCH("-a")) {
+ MUST_HAVE_ARG;
+ encoding_alias = av[1];
+ ac--;
+ av++;
+ } else if (OPT_MATCH("-flush")) {
+ flush_every_line = 1;
+ } else if (OPT_MATCH("-version") || OPT_MATCH("-v")) {
+ print_version();
+ } else {
+ print_usage(cmd);
+ }
+#undef OPT_MATCH
+#undef MUST_HAVE_ARG
+#undef APPEND_LIST
+
+ ac--;
+ av++;
+ }
+
+ if (ac > 1)
+ print_usage(cmd);
+
+ /* Initialize. */
+ if ((r = idn_resconf_initialize()) != idn_success) {
+ errormsg("error initializing library\n");
+ return (1);
+ }
+
+ /*
+ * Create resource contexts.
+ * `resconf1' and `resconf2' are almost the same but local and
+ * IDN encodings are reversed.
+ */
+ resconf1 = NULL;
+ resconf2 = NULL;
+ if (idn_resconf_create(&resconf1) != idn_success ||
+ idn_resconf_create(&resconf2) != idn_success) {
+ errormsg("error initializing configuration contexts\n");
+ return (1);
+ }
+
+ /* Load configuration file. */
+ if (no_resconf) {
+ set_defaults(resconf1);
+ set_defaults(resconf2);
+ } else {
+ load_conf_file(resconf1, resconf_file);
+ load_conf_file(resconf2, resconf_file);
+ }
+
+ /* Set encoding alias file. */
+ if (encoding_alias != NULL)
+ set_encoding_alias(encoding_alias);
+
+ /* Set input codeset. */
+ if (flags & FLAG_REVERSE) {
+ if (in_code == NULL) {
+ conv = idn_resconf_getidnconverter(resconf1);
+ if (conv == NULL) {
+ errormsg("cannot get the IDN encoding.\n"
+ "please specify an appropriate one "
+ "with `-in' option.\n");
+ exit(1);
+ }
+ idn_resconf_setlocalconverter(resconf2, conv);
+ idn_converter_destroy(conv);
+ } else {
+ set_idncode(resconf1, in_code);
+ set_localcode(resconf2, in_code);
+ }
+ } else {
+ if (in_code == NULL) {
+ conv = idn_resconf_getlocalconverter(resconf1);
+ if (conv == NULL) {
+ errormsg("cannot get the local encoding.\n"
+ "please specify an appropriate one "
+ "with `-in' option.\n");
+ exit(1);
+ }
+ idn_resconf_setidnconverter(resconf2, conv);
+ idn_converter_destroy(conv);
+ } else {
+ set_localcode(resconf1, in_code);
+ set_idncode(resconf2, in_code);
+ }
+ }
+
+ /* Set output codeset. */
+ if (flags & FLAG_REVERSE) {
+ if (out_code == NULL) {
+ conv = idn_resconf_getlocalconverter(resconf1);
+ if (conv == NULL) {
+ errormsg("cannot get the local encoding.\n"
+ "please specify an appropriate one "
+ "with `-out' option.\n");
+ exit(1);
+ }
+ idn_resconf_setidnconverter(resconf2, conv);
+ idn_converter_destroy(conv);
+ } else {
+ set_localcode(resconf1, out_code);
+ set_idncode(resconf2, out_code);
+ }
+ } else {
+ if (out_code == NULL) {
+ conv = idn_resconf_getidnconverter(resconf1);
+ if (conv == NULL) {
+ errormsg("cannot get the IDN encoding.\n"
+ "please specify an appropriate one "
+ "with `-out' option.\n");
+ exit(1);
+ }
+ idn_resconf_setlocalconverter(resconf2, conv);
+ idn_converter_destroy(conv);
+ } else {
+ set_idncode(resconf1, out_code);
+ set_localcode(resconf2, out_code);
+ }
+ }
+
+ /* Set delimiter map(s). */
+ if (ndelimiters > 0) {
+ set_delimitermapper(resconf1, delimiters, ndelimiters);
+ set_delimitermapper(resconf2, delimiters, ndelimiters);
+ }
+
+ /* Set local map(s). */
+ if (nlocalmappers > 0) {
+ set_localmapper(resconf1, localmappers, nlocalmappers);
+ set_localmapper(resconf2, localmappers, nlocalmappers);
+ }
+
+ /* Set NAMEPREP version. */
+ if (nameprep_version != NULL) {
+ set_nameprep(resconf1, nameprep_version);
+ set_nameprep(resconf2, nameprep_version);
+ }
+
+ idn_res_enable(1);
+
+ /* Open input file. */
+ if (ac > 0) {
+ if ((fp = fopen(av[0], "r")) == NULL) {
+ errormsg("cannot open file %s: %s\n",
+ av[0], strerror(errno));
+ return (1);
+ }
+ } else {
+ fp = stdin;
+ }
+
+ /* Do the conversion. */
+ if (flags & FLAG_REVERSE)
+ exit_value = decode_file(resconf1, resconf2, fp, flags);
+ else
+ exit_value = encode_file(resconf1, resconf2, fp, flags);
+
+ idn_resconf_destroy(resconf1);
+ idn_resconf_destroy(resconf2);
+
+ return exit_value;
+}
+
+static int
+encode_file(idn_resconf_t conf1, idn_resconf_t conf2, FILE *fp, int flags) {
+ idn_result_t r;
+ idnconv_strbuf_t buf1, buf2;
+ idn_action_t actions1, actions2;
+ int nl_trimmed;
+ int local_ace_hack;
+ idn_converter_t conv;
+
+ /*
+ * See if the input codeset is an ACE.
+ */
+ conv = idn_resconf_getlocalconverter(conf1);
+ if (conv != NULL && idn_converter_isasciicompatible(conv) &&
+ (flags & FLAG_SELECTIVE))
+ local_ace_hack = 1;
+ else
+ local_ace_hack = 0;
+ if (conv != NULL)
+ idn_converter_destroy(conv);
+
+ if (local_ace_hack) {
+ actions1 = IDN_IDNCONV;
+ if (flags & FLAG_ROUNDTRIPCHECK)
+ actions1 |= IDN_RTCHECK;
+ } else {
+ actions1 = IDN_LOCALCONV;
+ }
+
+ actions2 = IDN_IDNCONV;
+ if (flags & FLAG_DELIMMAP)
+ actions2 |= IDN_DELIMMAP;
+ if (flags & FLAG_LOCALMAP)
+ actions2 |= IDN_LOCALMAP;
+ if (flags & FLAG_MAP)
+ actions2 |= IDN_MAP;
+ if (flags & FLAG_NORMALIZE)
+ actions2 |= IDN_NORMALIZE;
+ if (flags & FLAG_PROHIBITCHECK)
+ actions2 |= IDN_PROHCHECK;
+ if (flags & FLAG_UNASSIGNCHECK)
+ actions2 |= IDN_UNASCHECK;
+ if (flags & FLAG_BIDICHECK)
+ actions2 |= IDN_BIDICHECK;
+ if (flags & FLAG_ASCIICHECK)
+ actions2 |= IDN_ASCCHECK;
+ if (flags & FLAG_LENGTHCHECK)
+ actions2 |= IDN_LENCHECK;
+
+ strbuf_init(&buf1);
+ strbuf_init(&buf2);
+ line_number = 1;
+ while (strbuf_getline(&buf1, fp) != NULL) {
+ /*
+ * Trim newline at the end. This is needed for
+ * those ascii-comatible encodings such as UTF-5 or RACE
+ * not to try converting newlines, which will result
+ * in `invalid encoding' error.
+ */
+ nl_trimmed = trim_newline(&buf1);
+
+ /*
+ * Convert input line to UTF-8.
+ */
+ if (local_ace_hack)
+ r = convert_line(&buf1, &buf2, conf2, actions1,
+ FLAG_REVERSE|FLAG_SELECTIVE);
+ else
+ r = convert_line(&buf1, &buf2, conf1, actions1,
+ 0);
+
+ if (r != idn_success) {
+ errormsg("conversion failed at line %d: %s\n",
+ line_number,
+ idn_result_tostring(r));
+ goto error;
+ }
+ if (!idn_utf8_isvalidstring(strbuf_get(&buf2))) {
+ errormsg("conversion to utf-8 failed at line %d\n",
+ line_number);
+ goto error;
+ }
+
+ /*
+ * Perform local mapping and NAMEPREP, and convert to
+ * the output codeset.
+ */
+ r = convert_line(&buf2, &buf1, conf1, actions2,
+ flags & FLAG_SELECTIVE);
+
+ if (r != idn_success) {
+ errormsg("error in nameprep or output conversion "
+ "at line %d: %s\n",
+ line_number, idn_result_tostring(r));
+ goto error;
+ }
+
+ fputs(strbuf_get(&buf1), stdout);
+ if (nl_trimmed)
+ putc('\n', stdout);
+
+ if (flush_every_line)
+ fflush(stdout);
+
+ line_number++;
+ }
+
+ strbuf_reset(&buf1);
+ strbuf_reset(&buf2);
+ return (0);
+
+ error:
+ strbuf_reset(&buf1);
+ strbuf_reset(&buf2);
+ return (1);
+}
+
+static int
+decode_file(idn_resconf_t conf1, idn_resconf_t conf2, FILE *fp, int flags) {
+ idn_result_t r;
+ idnconv_strbuf_t buf1, buf2;
+ idn_action_t actions1, actions2;
+ int nl_trimmed;
+ int local_ace_hack, idn_ace_hack;
+ idn_converter_t conv;
+
+ /*
+ * See if the input codeset is an ACE.
+ */
+ conv = idn_resconf_getidnconverter(conf1);
+ if (conv != NULL && idn_converter_isasciicompatible(conv) &&
+ (flags & FLAG_SELECTIVE))
+ idn_ace_hack = 1;
+ else
+ idn_ace_hack = 0;
+ if (conv != NULL)
+ idn_converter_destroy(conv);
+
+ conv = idn_resconf_getlocalconverter(conf1);
+ if (conv != NULL && idn_converter_isasciicompatible(conv) &&
+ (flags & FLAG_SELECTIVE))
+ local_ace_hack = 1;
+ else
+ local_ace_hack = 0;
+ if (conv != NULL)
+ idn_converter_destroy(conv);
+
+ actions1 = IDN_IDNCONV;
+
+ if (local_ace_hack) {
+ actions2 = IDN_IDNCONV;
+ if (flags & FLAG_MAP)
+ actions2 |= IDN_MAP;
+ if (flags & FLAG_NORMALIZE)
+ actions2 |= IDN_NORMALIZE;
+ if (flags & FLAG_PROHIBITCHECK)
+ actions2 |= IDN_PROHCHECK;
+ if (flags & FLAG_UNASSIGNCHECK)
+ actions2 |= IDN_UNASCHECK;
+ if (flags & FLAG_BIDICHECK)
+ actions2 |= IDN_BIDICHECK;
+ if (flags & FLAG_ASCIICHECK)
+ actions2 |= IDN_ASCCHECK;
+ if (flags & FLAG_LENGTHCHECK)
+ actions2 |= IDN_LENCHECK;
+ } else {
+ actions2 = IDN_LOCALCONV;
+ }
+
+ if (flags & FLAG_DELIMMAP)
+ actions1 |= IDN_DELIMMAP;
+ if (flags & FLAG_MAP)
+ actions1 |= IDN_MAP;
+ if (flags & FLAG_NORMALIZE)
+ actions1 |= IDN_NORMALIZE;
+ if (flags & FLAG_NORMALIZE)
+ actions1 |= IDN_NORMALIZE;
+ if (flags & FLAG_PROHIBITCHECK)
+ actions1 |= IDN_PROHCHECK;
+ if (flags & FLAG_UNASSIGNCHECK)
+ actions1 |= IDN_UNASCHECK;
+ if (flags & FLAG_BIDICHECK)
+ actions1 |= IDN_BIDICHECK;
+ if (flags & FLAG_ASCIICHECK)
+ actions1 |= IDN_ASCCHECK;
+ if (flags & FLAG_ROUNDTRIPCHECK)
+ actions1 |= IDN_RTCHECK;
+
+ strbuf_init(&buf1);
+ strbuf_init(&buf2);
+ line_number = 1;
+ while (strbuf_getline(&buf1, fp) != NULL) {
+ /*
+ * Trim newline at the end. This is needed for
+ * those ascii-comatible encodings such as UTF-5 or RACE
+ * not to try converting newlines, which will result
+ * in `invalid encoding' error.
+ */
+ nl_trimmed = trim_newline(&buf1);
+
+ /*
+ * Treat input line as the string encoded in local
+ * encoding and convert it to UTF-8 encoded string.
+ */
+ if (local_ace_hack) {
+ if (strbuf_copy(&buf2, strbuf_get(&buf1)) == NULL)
+ r = idn_nomemory;
+ else
+ r = idn_success;
+ } else {
+ r = convert_line(&buf1, &buf2, conf1, IDN_LOCALCONV,
+ 0);
+ }
+ if (r != idn_success) {
+ errormsg("conversion failed at line %d: %s\n",
+ line_number, idn_result_tostring(r));
+ goto error;
+ }
+
+ /*
+ * Convert internationalized domain names in the line.
+ */
+ if (idn_ace_hack) {
+ r = convert_line(&buf2, &buf1, conf1, actions1,
+ FLAG_REVERSE|FLAG_SELECTIVE);
+ } else {
+ r = convert_line(&buf2, &buf1, conf1, actions1,
+ FLAG_REVERSE);
+ }
+ if (r != idn_success) {
+ errormsg("conversion failed at line %d: %s\n",
+ line_number,
+ idn_result_tostring(r));
+ goto error;
+ }
+ if (!idn_utf8_isvalidstring(strbuf_get(&buf1))) {
+ errormsg("conversion to utf-8 failed at line %d\n",
+ line_number);
+ goto error;
+ }
+
+ /*
+ * Perform round trip check and convert to the output
+ * codeset.
+ */
+ if (local_ace_hack) {
+ r = convert_line(&buf1, &buf2, conf2, actions2,
+ FLAG_SELECTIVE);
+ } else {
+ r = convert_line(&buf1, &buf2, conf1, actions2,
+ FLAG_REVERSE);
+ }
+
+ if (r != idn_success) {
+ errormsg("error in nameprep or output conversion "
+ "at line %d: %s\n",
+ line_number, idn_result_tostring(r));
+ goto error;
+ }
+
+ fputs(strbuf_get(&buf2), stdout);
+ if (nl_trimmed)
+ putc('\n', stdout);
+
+ if (flush_every_line)
+ fflush(stdout);
+
+ line_number++;
+ }
+ strbuf_reset(&buf1);
+ strbuf_reset(&buf2);
+ return (0);
+
+ error:
+ strbuf_reset(&buf1);
+ strbuf_reset(&buf2);
+ return (1);
+}
+
+static int
+trim_newline(idnconv_strbuf_t *buf) {
+ /*
+ * If the string in BUF ends with a newline, trim it and
+ * return 1. Otherwise, just return 0 without modifying BUF.
+ */
+ char *s = strbuf_get(buf);
+ size_t len = strlen(s);
+
+ if (s[len - 1] == '\n') {
+ s[len - 1] = '\0';
+ return (1);
+ }
+
+ return (0);
+}
+
+static idn_result_t
+convert_line(idnconv_strbuf_t *from, idnconv_strbuf_t *to,
+ idn_resconf_t conf, idn_action_t actions, int flags)
+{
+ idn_result_t r = idn_success;
+ char *from_str = strbuf_get(from);
+
+ for (;;) {
+ char *to_str = strbuf_get(to);
+ size_t to_size = strbuf_size(to);
+
+ switch (flags & (FLAG_REVERSE|FLAG_SELECTIVE)) {
+ case 0:
+ r = idn_res_encodename(conf, actions, from_str,
+ to_str, to_size);
+ break;
+ case FLAG_REVERSE:
+ r = idn_res_decodename(conf, actions, from_str,
+ to_str, to_size);
+ break;
+ case FLAG_SELECTIVE:
+ r = selective_encode(conf, actions, from_str,
+ to_str, to_size);
+ break;
+ case FLAG_REVERSE|FLAG_SELECTIVE:
+ r = selective_decode(conf, actions, from_str,
+ to_str, to_size);
+ break;
+ }
+ if (r == idn_buffer_overflow) {
+ /*
+ * Conversion is not successful because
+ * the size of the target buffer is not enough.
+ * Double the size and retry.
+ */
+ if (strbuf_double(to) == NULL) {
+ /* oops. allocation failed. */
+ return (idn_nomemory);
+ }
+ } else {
+ break;
+ }
+ }
+ return (r);
+}
+
+static char *options[] = {
+ "-in INPUT-CODESET : specifies input codeset name.",
+ "-i INPUT-CODESET : synonym for -in",
+ "-out OUTPUT-CODESET : specifies output codeset name.",
+ "-o OUTPUT-CODESET : synonym for -out",
+ "-conf CONF-FILE : specifies idnkit configuration file.",
+ "-c CONF-FILE : synonym for -conf",
+ "-noconf : do not load idnkit configuration file.",
+ "-C : synonym for -noconf",
+ "-reverse : specifies reverse conversion.",
+ " (i.e. IDN encoding to local encoding)",
+ "-r : synonym for -reverse",
+ "-nameprep VERSION : specifies version name of NAMEPREP.",
+ "-n VERSION : synonym for -nameprep",
+ "-nonameprep : do not perform NAMEPREP.",
+ "-N : synonym for -nonameprep",
+ "-localmap MAPPING : specifies local mapping.",
+ "-nolocalmap : do not perform local mapping.",
+ "-L : synonym for -nolocalmap",
+ "-nounassigncheck : do not perform unassigned codepoint check.",
+ "-U : synonym for -nounassigncheck",
+ "-nobidicheck : do not perform bidirectional text check.",
+ "-B : synonym for -nobidicheck",
+ "-nolengthcheck : do not check label length.",
+ "-noasciicheck : do not check ASCII range characters.",
+ "-A : synonym for -noasciicheck",
+ "-noroundtripcheck : do not perform round trip check.",
+ "-delimiter U+XXXX : specifies local delimiter code point.",
+ "-alias alias-file : specifies codeset alias file.",
+ "-a : synonym for -alias",
+ "-flush : line-buffering mode.",
+ "-whole : convert the whole region instead of",
+ " regions containing non-ascii characters.",
+ "-w : synonym for -whole",
+ "-version : print version number, then exit.",
+ "-v : synonym for -version",
+ "",
+ " The following options can be specified multiple times",
+ " -localmap, -delimiter",
+ NULL,
+};
+
+static void
+print_version() {
+ fprintf(stderr, "idnconv (idnkit) version: %s\n"
+ "library version: %s\n",
+ IDNKIT_VERSION,
+ idn_version_getstring());
+ exit(0);
+}
+
+static void
+print_usage(char *cmd) {
+ int i;
+
+ fprintf(stderr, "Usage: %s [options..] [file]\n", cmd);
+
+ for (i = 0; options[i] != NULL; i++)
+ fprintf(stderr, "\t%s\n", options[i]);
+
+ exit(1);
+}
+
+static unsigned long
+get_ucs(const char *p) {
+ unsigned long v;
+ char *end;
+
+ /* Skip optional 'U+' */
+ if (strncmp(p, "U+", 2) == 0)
+ p += 2;
+
+ v = strtoul(p, &end, 16);
+ if (*end != '\0') {
+ fprintf(stderr, "invalid UCS code point \"%s\"\n", p);
+ exit(1);
+ }
+
+ return v;
+}
diff --git a/contrib/idn/idnkit-1.0-src/tools/idnconv/idnslookup.in b/contrib/idn/idnkit-1.0-src/tools/idnconv/idnslookup.in
new file mode 100644
index 0000000..d380f1e
--- /dev/null
+++ b/contrib/idn/idnkit-1.0-src/tools/idnconv/idnslookup.in
@@ -0,0 +1,116 @@
+#! /bin/sh
+# $Id: idnslookup.in,v 1.1.1.1 2003/06/04 00:27:10 marka Exp $
+#
+# Copyright (c) 2000 Japan Network Information Center. All rights reserved.
+#
+# By using this file, you agree to the terms and conditions set forth bellow.
+#
+# LICENSE TERMS AND CONDITIONS
+#
+# The following License Terms and Conditions apply, unless a different
+# license is obtained from Japan Network Information Center ("JPNIC"),
+# a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
+# Chiyoda-ku, Tokyo 101-0047, Japan.
+#
+# 1. Use, Modification and Redistribution (including distribution of any
+# modified or derived work) in source and/or binary forms is permitted
+# under this License Terms and Conditions.
+#
+# 2. Redistribution of source code must retain the copyright notices as they
+# appear in each source code file, this License Terms and Conditions.
+#
+# 3. Redistribution in binary form must reproduce the Copyright Notice,
+# this License Terms and Conditions, in the documentation and/or other
+# materials provided with the distribution. For the purposes of binary
+# distribution the "Copyright Notice" refers to the following language:
+# "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
+#
+# 4. The name of JPNIC may not be used to endorse or promote products
+# derived from this Software without specific prior written approval of
+# JPNIC.
+#
+# 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+USAGE="Usage: $0 domain-name DNS-server"
+
+#
+# Parse command line arguments.
+#
+if [ $# -lt 2 ] ; then
+ echo "$0: too few argument" 1>&2
+ echo $USAGE 1>&2
+ exit 1
+fi
+
+if [ $# -gt 2 ] ; then
+ echo "$0: too many argument" 1>&2
+ echo $USAGE 1>&2
+ exit 1
+fi
+
+case "$1" in
+-*) echo "$0: unknown option $1" 1>&2
+ echo $USAGE 1>&2
+ exit 1
+ ;;
+esac
+
+LOCAL_DOMAIN_NAME="$1"
+NAME_SERVER="$2"
+
+#
+# Append some directories to PATH.
+#
+[ -d /usr/sbin ] && PATH=$PATH:/usr/sbin
+[ -d /sbin ] && PATH=$PATH:/sbin
+
+#
+# Find `nslookup' command.
+#
+if [ x"$NSLOOKUP" = x ] ; then
+ for I in `echo $PATH | sed -e 's/:/ /g'` ; do
+ if [ -x $I/nslookup ] ; then
+ NSLOOKUP="$I/nslookup"
+ break
+ fi
+ done
+ if [ "$NSLOOKUP" = "" ] ; then
+ echo "$0: nslookup not found" 1>&2
+ exit 1
+ fi
+fi
+if [ ! -x "$NSLOOKUP" ] ; then
+ echo "$0: nslookup not found" 1>&2
+ exit 1
+fi
+
+#
+# Check if `idnconv' command exists.
+#
+IDNCONV=${IDNCONV-"@bindir@/idnconv"}
+if [ ! -x "$IDNCONV" ] ; then
+ echo "$0: idnconv not found" 1>&2
+ exit 1
+fi
+
+#
+# Convert domain name to IDN encoding.
+#
+IDN_DOMAIN_NAME="`echo $LOCAL_DOMAIN_NAME | $IDNCONV -w`" || exit 1
+
+#
+# Invoke nslookup.
+#
+$NSLOOKUP $IDN_DOMAIN_NAME $NAME_SERVER < /dev/null || exit 1
+
+exit 0
diff --git a/contrib/idn/idnkit-1.0-src/tools/idnconv/make.wnt b/contrib/idn/idnkit-1.0-src/tools/idnconv/make.wnt
new file mode 100644
index 0000000..97ce188
--- /dev/null
+++ b/contrib/idn/idnkit-1.0-src/tools/idnconv/make.wnt
@@ -0,0 +1,72 @@
+# $Id: make.wnt,v 1.1.1.1 2003/06/04 00:27:06 marka Exp $
+# Makefile for idnconv, manually configured for WIN-NT (VC5.0)
+#
+# Copyright (c) 2000,2002 Japan Network Information Center. All rights reserved.
+#
+# By using this file, you agree to the terms and conditions set forth bellow.
+#
+# LICENSE TERMS AND CONDITIONS
+#
+# The following License Terms and Conditions apply, unless a different
+# license is obtained from Japan Network Information Center ("JPNIC"),
+# a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
+# Chiyoda-ku, Tokyo 101-0047, Japan.
+#
+# 1. Use, Modification and Redistribution (including distribution of any
+# modified or derived work) in source and/or binary forms is permitted
+# under this License Terms and Conditions.
+#
+# 2. Redistribution of source code must retain the copyright notices as they
+# appear in each source code file, this License Terms and Conditions.
+#
+# 3. Redistribution in binary form must reproduce the Copyright Notice,
+# this License Terms and Conditions, in the documentation and/or other
+# materials provided with the distribution. For the purposes of binary
+# distribution the "Copyright Notice" refers to the following language:
+# "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
+#
+# 4. The name of JPNIC may not be used to endorse or promote products
+# derived from this Software without specific prior written approval of
+# JPNIC.
+#
+# 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+!include <ntwin32.mak>
+
+INCDIR = ..\..\include
+ICONVDIR = ..\..\win
+IDNLIBDIR = ..\..\lib
+LIBS = $(IDNLIBDIR)\idnkit.lib $(ICONVDIR)\iconv.lib
+SYSLIBS = $(conlibsdll)
+
+SRCS = idnconv.c util.c selectiveencode.c
+OBJS = idnconv.obj util.obj selectiveencode.obj
+
+TARGET = idnconv.exe
+
+all: $(TARGET)
+
+idnconv.exe: $(OBJS) $(LIBS)
+ $(link) $(conflags) /out:idnconv.exe $(OBJS) $(LIBS) $(SYSLIBS)
+
+install:
+
+clean:
+ -del *.exe *.obj *.lib core *.core *~
+
+idnconv.obj: idnconv.c
+ $(cc) $(cflags) $(cvarsdll) -I$(INCDIR) $*.c
+util.obj: util.c
+ $(cc) $(cflags) $(cvarsdll) -I$(INCDIR) $*.c
+selectiveencode.obj: selectiveencode.c
+ $(cc) $(cflags) $(cvarsdll) -I$(INCDIR) $*.c
diff --git a/contrib/idn/idnkit-1.0-src/tools/idnconv/selectiveencode.c b/contrib/idn/idnkit-1.0-src/tools/idnconv/selectiveencode.c
new file mode 100644
index 0000000..ae509df
--- /dev/null
+++ b/contrib/idn/idnkit-1.0-src/tools/idnconv/selectiveencode.c
@@ -0,0 +1,127 @@
+#ifndef lint
+static char *rcsid = "$Id: selectiveencode.c,v 1.1.1.1 2003/06/04 00:27:07 marka Exp $";
+#endif
+
+/*
+ * Copyright (c) 2000,2002 Japan Network Information Center.
+ * All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set forth bellow.
+ *
+ * LICENSE TERMS AND CONDITIONS
+ *
+ * The following License Terms and Conditions apply, unless a different
+ * license is obtained from Japan Network Information Center ("JPNIC"),
+ * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
+ * Chiyoda-ku, Tokyo 101-0047, Japan.
+ *
+ * 1. Use, Modification and Redistribution (including distribution of any
+ * modified or derived work) in source and/or binary forms is permitted
+ * under this License Terms and Conditions.
+ *
+ * 2. Redistribution of source code must retain the copyright notices as they
+ * appear in each source code file, this License Terms and Conditions.
+ *
+ * 3. Redistribution in binary form must reproduce the Copyright Notice,
+ * this License Terms and Conditions, in the documentation and/or other
+ * materials provided with the distribution. For the purposes of binary
+ * distribution the "Copyright Notice" refers to the following language:
+ * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
+ *
+ * 4. The name of JPNIC may not be used to endorse or promote products
+ * derived from this Software without specific prior written approval of
+ * JPNIC.
+ *
+ * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <config.h>
+
+#include <stddef.h>
+
+#include <idn/assert.h>
+#include <idn/logmacro.h>
+#include <idn/result.h>
+#include <idn/utf8.h>
+#include <idn/debug.h>
+
+#include "selectiveencode.h"
+
+static int is_domain_delimiter(char c);
+static char *find_nonascii(const char *s);
+
+idn_result_t
+idn_selectiveencode_findregion(const char *s,
+ char **startp, char **endp)
+{
+ char *non_ascii;
+ char *start, *end;
+
+ assert(s != NULL && startp != NULL && endp != NULL);
+
+ TRACE(("idn_selectiveencode_findregion(s=\"%s\")\n",
+ idn__debug_xstring(s, 20)));
+
+ /*
+ * Scan the specified string looking for non-ascii character.
+ */
+ if ((non_ascii = find_nonascii(s)) == NULL)
+ return (idn_notfound);
+
+ /*
+ * Non-ascii character found.
+ * Determine the region to encode.
+ */
+
+ /*
+ * First, we scan backwards to find the beginning of the region
+ * that should be converted.
+ */
+ start = non_ascii;
+ while (start > s) {
+ char *prev = idn_utf8_findfirstbyte(start - 1, s);
+ if (is_domain_delimiter(*prev))
+ break; /* Found */
+ start = prev;
+ }
+ *startp = start;
+
+ /*
+ * Next we scan forwards looking for the end of the region.
+ */
+ end = non_ascii + idn_utf8_mblen(non_ascii);
+ while (!is_domain_delimiter(*end))
+ end += idn_utf8_mblen(end);
+ *endp = end;
+
+ return (idn_success);
+}
+
+static int
+is_domain_delimiter(char c) {
+ return ((unsigned char)c < 0x80 &&
+ !('A' <= c && c <= 'Z') &&
+ !('a' <= c && c <= 'z') &&
+ !('0' <= c && c <= '9') &&
+ c != '-' && c != '.');
+}
+
+static char *
+find_nonascii(const char *s) {
+ while (*s != '\0' && (unsigned char)*s < 0x80)
+ s++;
+ if (*s == '\0')
+ return (NULL);
+ else
+ return ((char *)s);
+}
diff --git a/contrib/idn/idnkit-1.0-src/tools/idnconv/selectiveencode.h b/contrib/idn/idnkit-1.0-src/tools/idnconv/selectiveencode.h
new file mode 100644
index 0000000..ec4d8f6
--- /dev/null
+++ b/contrib/idn/idnkit-1.0-src/tools/idnconv/selectiveencode.h
@@ -0,0 +1,70 @@
+/* $Id: selectiveencode.h,v 1.1.1.1 2003/06/04 00:27:08 marka Exp $ */
+/*
+ * Copyright (c) 2000,2002 Japan Network Information Center.
+ * All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set forth bellow.
+ *
+ * LICENSE TERMS AND CONDITIONS
+ *
+ * The following License Terms and Conditions apply, unless a different
+ * license is obtained from Japan Network Information Center ("JPNIC"),
+ * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
+ * Chiyoda-ku, Tokyo 101-0047, Japan.
+ *
+ * 1. Use, Modification and Redistribution (including distribution of any
+ * modified or derived work) in source and/or binary forms is permitted
+ * under this License Terms and Conditions.
+ *
+ * 2. Redistribution of source code must retain the copyright notices as they
+ * appear in each source code file, this License Terms and Conditions.
+ *
+ * 3. Redistribution in binary form must reproduce the Copyright Notice,
+ * this License Terms and Conditions, in the documentation and/or other
+ * materials provided with the distribution. For the purposes of binary
+ * distribution the "Copyright Notice" refers to the following language:
+ * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
+ *
+ * 4. The name of JPNIC may not be used to endorse or promote products
+ * derived from this Software without specific prior written approval of
+ * JPNIC.
+ *
+ * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifndef IDN_SELECTIVENCODE_H
+#define IDN_SELECTIVENCODE_H 1
+
+/*
+ * Find where to convert.
+ *
+ * Find a substring for which IDN domain name codeset conversion is necessary.
+ */
+
+#include <idn/result.h>
+
+/*
+ * Scan the given string 's' (in UTF-8 encoding) looking for a substring
+ * made of
+ * + at least one non-ascii character and
+ * + zero or more legitimate domain-name characters (i.e. ascii alphabets,
+ * digits and hyphens) and periods.
+ *
+ * Returns:
+ * idn_success -- ok, found.
+ * idn_notfound -- not found.
+ */
+extern idn_result_t
+idn_selectiveencode_findregion(const char *s, char **startp, char **endp);
+
+#endif /* IDN_SELECTIVENCODE_H */
diff --git a/contrib/idn/idnkit-1.0-src/tools/idnconv/util.c b/contrib/idn/idnkit-1.0-src/tools/idnconv/util.c
new file mode 100644
index 0000000..35677e9
--- /dev/null
+++ b/contrib/idn/idnkit-1.0-src/tools/idnconv/util.c
@@ -0,0 +1,554 @@
+#ifndef lint
+static char *rcsid = "$Id: util.c,v 1.1.1.1 2003/06/04 00:27:08 marka Exp $";
+#endif
+
+/*
+ * Copyright (c) 2000,2002 Japan Network Information Center.
+ * All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set forth bellow.
+ *
+ * LICENSE TERMS AND CONDITIONS
+ *
+ * The following License Terms and Conditions apply, unless a different
+ * license is obtained from Japan Network Information Center ("JPNIC"),
+ * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
+ * Chiyoda-ku, Tokyo 101-0047, Japan.
+ *
+ * 1. Use, Modification and Redistribution (including distribution of any
+ * modified or derived work) in source and/or binary forms is permitted
+ * under this License Terms and Conditions.
+ *
+ * 2. Redistribution of source code must retain the copyright notices as they
+ * appear in each source code file, this License Terms and Conditions.
+ *
+ * 3. Redistribution in binary form must reproduce the Copyright Notice,
+ * this License Terms and Conditions, in the documentation and/or other
+ * materials provided with the distribution. For the purposes of binary
+ * distribution the "Copyright Notice" refers to the following language:
+ * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
+ *
+ * 4. The name of JPNIC may not be used to endorse or promote products
+ * derived from this Software without specific prior written approval of
+ * JPNIC.
+ *
+ * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <idn/resconf.h>
+#include <idn/converter.h>
+#include <idn/res.h>
+#include <idn/utf8.h>
+
+#include "util.h"
+#include "selectiveencode.h"
+
+extern int line_number;
+
+idn_result_t
+selective_encode(idn_resconf_t conf, idn_action_t actions,
+ char *from, char *to, int tolen)
+{
+ for (;;) {
+ int len;
+ char *region_start, *region_end;
+ idn_result_t r;
+ char save;
+
+ /*
+ * Find the region that needs conversion.
+ */
+ r = idn_selectiveencode_findregion(from, &region_start,
+ &region_end);
+ if (r == idn_notfound) {
+ /*
+ * Not found. Just copy the whole thing.
+ */
+ if (tolen <= strlen(from))
+ return (idn_buffer_overflow);
+ (void)strcpy(to, from);
+ return (idn_success);
+ } else if (r != idn_success) {
+ /* This should not happen.. */
+ errormsg("internal error at line %d: %s\n",
+ line_number, idn_result_tostring(r));
+ return (r);
+ }
+
+ /*
+ * We have found a region to convert.
+ * First, copy the prefix part verbatim.
+ */
+ len = region_start - from;
+ if (tolen < len) {
+ errormsg("internal buffer overflow at line %d\n",
+ line_number);
+ return (idn_buffer_overflow);
+ }
+ (void)memcpy(to, from, len);
+ to += len;
+ tolen -= len;
+
+ /*
+ * Terminate the region with NUL.
+ */
+ save = *region_end;
+ *region_end = '\0';
+
+ /*
+ * Encode the region.
+ */
+ r = idn_res_encodename(conf, actions, region_start, to, tolen);
+
+ /*
+ * Restore character.
+ */
+ *region_end = save;
+
+ if (r != idn_success)
+ return (r);
+
+ len = strlen(to);
+ to += len;
+ tolen -= len;
+
+ from = region_end;
+ }
+}
+
+idn_result_t
+selective_decode(idn_resconf_t conf, idn_action_t actions,
+ char *from, char *to, int tolen)
+{
+ char *domain_name;
+ char *ignored_chunk;
+ char save;
+ int len;
+ idn_result_t r;
+
+ /*
+ * While `*from' points to a character in a string which may be
+ * a domain name, `domain_name' refers to the beginning of the
+ * domain name.
+ */
+ domain_name = NULL;
+
+ /*
+ * We ignore chunks matching to the regular expression:
+ * [\-\.][0-9A-Za-z\-\.]*
+ *
+ * While `*from' points to a character in such a chunk,
+ * `ignored_chunk' refers to the beginning of the chunk.
+ */
+ ignored_chunk = NULL;
+
+ for (;;) {
+ if (*from == '-') {
+ /*
+ * We don't recognize `.-' as a part of domain name.
+ */
+ if (domain_name != NULL) {
+ if (*(from - 1) == '.') {
+ ignored_chunk = domain_name;
+ domain_name = NULL;
+ }
+ } else if (ignored_chunk == NULL) {
+ ignored_chunk = from;
+ }
+
+ } else if (*from == '.') {
+ /*
+ * We don't recognize `-.' nor `..' as a part of
+ * domain name.
+ */
+ if (domain_name != NULL) {
+ if (*(from - 1) == '-' || *(from - 1) == '.') {
+ ignored_chunk = domain_name;
+ domain_name = NULL;
+ }
+ } else if (ignored_chunk == NULL) {
+ ignored_chunk = from;
+ }
+
+ } else if (('a' <= *from && *from <= 'z') ||
+ ('A' <= *from && *from <= 'Z') ||
+ ('0' <= *from && *from <= '9')) {
+ if (ignored_chunk == NULL && domain_name == NULL)
+ domain_name = from;
+
+ } else {
+ if (ignored_chunk != NULL) {
+ /*
+ * `from' reaches the end of the ignored chunk.
+ * Copy the chunk to `to'.
+ */
+ len = from - ignored_chunk;
+ if (tolen < len)
+ return (idn_buffer_overflow);
+ (void)memcpy(to, ignored_chunk, len);
+ to += len;
+ tolen -= len;
+
+ } else if (domain_name != NULL) {
+ /*
+ * `from' reaches the end of the domain name.
+ * Decode the domain name, and copy the result
+ * to `to'.
+ */
+ save = *from;
+ *from = '\0';
+ r = idn_res_decodename(conf, actions,
+ domain_name, to, tolen);
+ *from = save;
+
+ if (r == idn_success) {
+ len = strlen(to);
+ } else if (r == idn_invalid_encoding) {
+ len = from - domain_name;
+ if (tolen < len)
+ return (idn_buffer_overflow);
+ (void)memcpy(to, domain_name, len);
+ } else {
+ return (r);
+ }
+ to += len;
+ tolen -= len;
+ }
+
+ /*
+ * Copy a character `*from' to `to'.
+ */
+ if (tolen < 1)
+ return (idn_buffer_overflow);
+ *to = *from;
+ to++;
+ tolen--;
+
+ domain_name = NULL;
+ ignored_chunk = NULL;
+
+ if (*from == '\0')
+ break;
+ }
+
+ from++;
+ }
+
+ return (idn_success);
+}
+
+void
+set_defaults(idn_resconf_t conf) {
+ idn_result_t r;
+
+ if ((r = idn_resconf_setdefaults(conf)) != idn_success) {
+ errormsg("error setting default configuration: %s\n",
+ idn_result_tostring(r));
+ exit(1);
+ }
+}
+
+void
+load_conf_file(idn_resconf_t conf, const char *file) {
+ idn_result_t r;
+
+ if ((r = idn_resconf_loadfile(conf, file)) != idn_success) {
+ errormsg("error reading configuration file: %s\n",
+ idn_result_tostring(r));
+ exit(1);
+ }
+}
+
+void
+set_encoding_alias(const char *encoding_alias) {
+ idn_result_t r;
+
+ if ((r = idn_converter_resetalias()) != idn_success) {
+ errormsg("cannot reset alias information: %s\n",
+ idn_result_tostring(r));
+ exit(1);
+ }
+
+ if ((r = idn_converter_aliasfile(encoding_alias)) != idn_success) {
+ errormsg("cannot read alias file %s: %s\n",
+ encoding_alias, idn_result_tostring(r));
+ exit(1);
+ }
+}
+
+void
+set_localcode(idn_resconf_t conf, const char *code) {
+ idn_result_t r;
+
+ r = idn_resconf_setlocalconvertername(conf, code,
+ IDN_CONVERTER_RTCHECK);
+ if (r != idn_success) {
+ errormsg("cannot create converter for codeset %s: %s\n",
+ code, idn_result_tostring(r));
+ exit(1);
+ }
+}
+
+void
+set_idncode(idn_resconf_t conf, const char *code) {
+ idn_result_t r;
+
+ r = idn_resconf_setidnconvertername(conf, code,
+ IDN_CONVERTER_RTCHECK);
+ if (r != idn_success) {
+ errormsg("cannot create converter for codeset %s: %s\n",
+ code, idn_result_tostring(r));
+ exit(1);
+ }
+}
+
+void
+set_delimitermapper(idn_resconf_t conf, unsigned long *delimiters,
+ int ndelimiters) {
+ idn_result_t r;
+
+ r = idn_resconf_addalldelimitermapucs(conf, delimiters, ndelimiters);
+ if (r != idn_success) {
+ errormsg("cannot add delimiter: %s\n",
+ idn_result_tostring(r));
+ exit(1);
+ }
+}
+
+void
+set_localmapper(idn_resconf_t conf, char **mappers, int nmappers) {
+ idn_result_t r;
+
+ /* Add mapping. */
+ r = idn_resconf_addalllocalmapselectornames(conf,
+ IDN_MAPSELECTOR_DEFAULTTLD,
+ (const char **)mappers,
+ nmappers);
+ if (r != idn_success) {
+ errormsg("cannot add local map: %s\n",
+ idn_result_tostring(r));
+ exit(1);
+ }
+}
+
+void
+set_nameprep(idn_resconf_t conf, char *version) {
+ idn_result_t r;
+
+ r = idn_resconf_setnameprepversion(conf, version);
+ if (r != idn_success) {
+ errormsg("error setting nameprep %s: %s\n",
+ version, idn_result_tostring(r));
+ exit(1);
+ }
+}
+
+void
+set_mapper(idn_resconf_t conf, char **mappers, int nmappers) {
+ idn_result_t r;
+
+ /* Configure mapper. */
+ r = idn_resconf_addallmappernames(conf, (const char **)mappers,
+ nmappers);
+ if (r != idn_success) {
+ errormsg("cannot add nameprep map: %s\n",
+ idn_result_tostring(r));
+ exit(1);
+ }
+}
+
+void
+set_normalizer(idn_resconf_t conf, char **normalizers, int nnormalizer) {
+ idn_result_t r;
+
+ r = idn_resconf_addallnormalizernames(conf,
+ (const char **)normalizers,
+ nnormalizer);
+ if (r != idn_success) {
+ errormsg("cannot add normalizer: %s\n",
+ idn_result_tostring(r));
+ exit(1);
+ }
+}
+
+void
+set_prohibit_checkers(idn_resconf_t conf, char **prohibits, int nprohibits) {
+ idn_result_t r;
+
+ r = idn_resconf_addallprohibitcheckernames(conf,
+ (const char **)prohibits,
+ nprohibits);
+ if (r != idn_success) {
+ errormsg("cannot add prohibit checker: %s\n",
+ idn_result_tostring(r));
+ exit(1);
+ }
+}
+
+void
+set_unassigned_checkers(idn_resconf_t conf, char **unassigns, int nunassigns) {
+ idn_result_t r;
+
+ r = idn_resconf_addallunassignedcheckernames(conf,
+ (const char **)unassigns,
+ nunassigns);
+ if (r != idn_success) {
+ errormsg("cannot add unassigned checker: %s\n",
+ idn_result_tostring(r));
+ exit(1);
+ }
+}
+
+void
+errormsg(const char *fmt, ...) {
+ va_list args;
+
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+}
+
+
+/*
+ * Dynamic Stirng Buffer Utility
+ */
+
+void
+strbuf_init(idnconv_strbuf_t *buf) {
+ /*
+ * Initialize the given string buffer.
+ * Caller must allocate the structure (idnconv_strbuf_t)
+ * as an automatic variable or by malloc().
+ */
+ buf->str = buf->local_buf;
+ buf->str[0] = '\0';
+ buf->size = sizeof(buf->local_buf);
+}
+
+void
+strbuf_reset(idnconv_strbuf_t *buf) {
+ /*
+ * Reset the given string buffer.
+ * Free memory allocated by this utility, and
+ * re-initialize.
+ */
+ if (buf->str != NULL && buf->str != buf->local_buf) {
+ free(buf->str);
+ }
+ strbuf_init(buf);
+}
+
+char *
+strbuf_get(idnconv_strbuf_t *buf) {
+ /*
+ * Get the pointer of the buffer.
+ */
+ return (buf->str);
+}
+
+size_t
+strbuf_size(idnconv_strbuf_t *buf) {
+ /*
+ * Get the allocated size of the buffer.
+ */
+ return (buf->size);
+}
+
+char *
+strbuf_copy(idnconv_strbuf_t *buf, const char *str) {
+ /*
+ * Copy STR to BUF.
+ */
+ size_t len = strlen(str);
+
+ if (strbuf_alloc(buf, len + 1) == NULL)
+ return (NULL);
+ strcpy(buf->str, str);
+ return (buf->str);
+}
+
+char *
+strbuf_append(idnconv_strbuf_t *buf, const char *str) {
+ /*
+ * Append STR to the end of BUF.
+ */
+ size_t len1 = strlen(buf->str);
+ size_t len2 = strlen(str);
+ char *p;
+#define MARGIN 50
+
+ p = strbuf_alloc(buf, len1 + len2 + 1 + MARGIN);
+ if (p != NULL)
+ strcpy(buf->str + len1, str);
+ return (p);
+}
+
+char *
+strbuf_alloc(idnconv_strbuf_t *buf, size_t size) {
+ /*
+ * Reallocate the buffer of BUF if needed
+ * so that BUF can hold SIZE bytes of data at least.
+ */
+ char *p;
+
+ if (buf->size >= size)
+ return (buf->str);
+ if (buf->str == buf->local_buf) {
+ if ((p = malloc(size)) == NULL)
+ return (NULL);
+ memcpy(p, buf->local_buf, sizeof(buf->local_buf));
+ } else {
+ if ((p = realloc(buf->str, size)) == NULL)
+ return (NULL);
+ }
+ buf->str = p;
+ buf->size = size;
+ return (buf->str);
+}
+
+char *
+strbuf_double(idnconv_strbuf_t *buf) {
+ /*
+ * Double the size of the buffer of BUF.
+ */
+ return (strbuf_alloc(buf, buf->size * 2));
+}
+
+char *
+strbuf_getline(idnconv_strbuf_t *buf, FILE *fp) {
+ /*
+ * Read a line from FP.
+ */
+ char s[256];
+
+ buf->str[0] = '\0';
+ while (fgets(s, sizeof(s), fp) != NULL) {
+ if (strbuf_append(buf, s) == NULL)
+ return (NULL);
+ if (strlen(s) < sizeof(s) - 1 || s[sizeof(s) - 2] == '\n')
+ return (buf->str);
+ }
+ if (buf->str[0] != '\0')
+ return (buf->str);
+ return (NULL);
+}
diff --git a/contrib/idn/idnkit-1.0-src/tools/idnconv/util.h b/contrib/idn/idnkit-1.0-src/tools/idnconv/util.h
new file mode 100644
index 0000000..43c5b41
--- /dev/null
+++ b/contrib/idn/idnkit-1.0-src/tools/idnconv/util.h
@@ -0,0 +1,96 @@
+/* $Id: util.h,v 1.1.1.1 2003/06/04 00:27:09 marka Exp $ */
+/*
+ * Copyright (c) 2000,2001 Japan Network Information Center.
+ * All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set forth bellow.
+ *
+ * LICENSE TERMS AND CONDITIONS
+ *
+ * The following License Terms and Conditions apply, unless a different
+ * license is obtained from Japan Network Information Center ("JPNIC"),
+ * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
+ * Chiyoda-ku, Tokyo 101-0047, Japan.
+ *
+ * 1. Use, Modification and Redistribution (including distribution of any
+ * modified or derived work) in source and/or binary forms is permitted
+ * under this License Terms and Conditions.
+ *
+ * 2. Redistribution of source code must retain the copyright notices as they
+ * appear in each source code file, this License Terms and Conditions.
+ *
+ * 3. Redistribution in binary form must reproduce the Copyright Notice,
+ * this License Terms and Conditions, in the documentation and/or other
+ * materials provided with the distribution. For the purposes of binary
+ * distribution the "Copyright Notice" refers to the following language:
+ * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
+ *
+ * 4. The name of JPNIC may not be used to endorse or promote products
+ * derived from this Software without specific prior written approval of
+ * JPNIC.
+ *
+ * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifndef IDN_IDNCONV_UTIL_H
+#define IDN_IDNCONV_UTIL_H 1
+
+#include <idn/res.h>
+
+#define IDNCONV_LOCALBUF_SIZE 512
+
+typedef struct {
+ char *str;
+ size_t size;
+ char local_buf[IDNCONV_LOCALBUF_SIZE];
+} idnconv_strbuf_t;
+
+extern idn_result_t selective_encode(idn_resconf_t conf,
+ idn_action_t actions, char *from,
+ char *to, int tolen);
+extern idn_result_t selective_decode(idn_resconf_t conf,
+ idn_action_t actions, char *from,
+ char *to, int tolen);
+extern void set_defaults(idn_resconf_t conf);
+extern void load_conf_file(idn_resconf_t conf, const char *file);
+extern void set_encoding_alias(const char *encoding_alias);
+extern void set_localcode(idn_resconf_t conf, const char *code);
+extern void set_idncode(idn_resconf_t conf, const char *code);
+extern void set_delimitermapper(idn_resconf_t conf,
+ unsigned long *delimiters,
+ int ndelimiters);
+extern void set_localmapper(idn_resconf_t conf,
+ char **mappers, int nmappers);
+extern void set_nameprep(idn_resconf_t conf, char *version);
+extern void set_mapper(idn_resconf_t conf,
+ char **mappers, int nmappers);
+extern void set_normalizer(idn_resconf_t conf,
+ char **normalizer, int nnormalizer);
+extern void set_prohibit_checkers(idn_resconf_t conf,
+ char **prohibits,
+ int nprohibits);
+extern void set_unassigned_checkers(idn_resconf_t conf,
+ char **unassigns,
+ int nunassigns);
+extern void errormsg(const char *fmt, ...);
+extern void strbuf_init(idnconv_strbuf_t *buf);
+extern void strbuf_reset(idnconv_strbuf_t *buf);
+extern char *strbuf_get(idnconv_strbuf_t *buf);
+extern size_t strbuf_size(idnconv_strbuf_t *buf);
+extern char *strbuf_copy(idnconv_strbuf_t *buf, const char *str);
+extern char *strbuf_append(idnconv_strbuf_t *buf, const char *str);
+extern char *strbuf_alloc(idnconv_strbuf_t *buf, size_t size);
+extern char *strbuf_double(idnconv_strbuf_t *buf);
+extern char *strbuf_getline(idnconv_strbuf_t *buf, FILE *fp);
+
+#endif /* IDN_IDNCONV_UTIL_H */