--- ./README.mdnkit.orig	Wed Jan 24 01:22:44 2001
+++ ./README.mdnkit	Wed Jan 24 01:22:44 2001
@@ -0,0 +1,110 @@
+
+			BIND-9 MDN patch
+
+	       Japan Network Information Center (JPNIC)
+
+
+* What is this patch for?
+
+This patch adds multilingual domain name (MDN) support to BIND-9.
+You'll get multilingualized version of light weight resolver and
+dig/host/nslookup commands.
+
+    + multilingualized version of light weight resolver
+	The following APIs accept non-ASCII host name encoded in the
+	local codeset (such as Shift JIS, Big5 or ISO8859-1)
+	determined by the application's current locale, and return
+	host names in the local codeset.
+		lwres_gethostbyname
+		lwres_gethostbyname_r
+		lwres_gethostbyname2
+		lwres_getipnodebyname
+		lwres_getaddrinfo
+		lwres_gethostbyaddr
+		lwres_gethostbyaddr_r
+		lwres_getipnodebyaddr
+		lwres_getnameinfo
+
+    + mulltilingualized dig/host/nslookup
+	dig/host/nslookup accepts non-ASCII domain names in the local
+	codeset.  The domain names are normalized and converted to the
+	encoding on the DNS protocol, and sent to DNS servers.  The
+	replies are converted back to the local codeset and displayed.
+
+
+* Compilation & installation
+
+0. Prerequisite
+
+You have to build and install mDNkit before building this patched version
+of bind-9.
+
+1. Running configure script
+
+Run `configure' in the top directory.  See `README' for the
+configuration options.
+
+This patch adds the following 3 options to `configure'.  You should
+at least specify `--with-mdn' option to enable MDN support.
+
+    --with-mdn[=PREFIX]
+	To enable MDN support, you have to specify `--with-mdn'
+	option.  If you specified installation prefix other than
+	`/usr/local' (which is the default) when conifguring mDNkit,
+	also specify the prefix, like `--with-mdn=/usr/local/mdnkit'.
+
+    --with-iconv=LIBSPEC
+	If your libc doens't provide iconv(), you need to specify the
+	library containing iconv() with this option.  `LIBSPEC' is the
+	argument(s) to `cc' or `ld' to link the library, for example,
+	`--with-iconv="-L/usr/local/lib -liconv"'.
+	You don't need to specify the header file directory for "iconv.h"
+	to the compiler, as it isn't included directly by bind-9 with
+	this patch.
+
+    --with-mdnlib=LIBSPEC
+	With this option, you can explicitly specify the argument(s)
+	to `cc' or `ld' to link the mDNkit's library, `libmdn'.  If
+	this option is not specified, `-L${PREFIX}/lib -lmdn' is
+	assumed, where ${PREFIX} is the installation prefix specified
+	with `--with-mdn' option above.  You may need to use this
+	option to specify extra argments, for example,
+	`--with-mdnlib="-L/usr/local/lib -R/usr/local/lib -lmdn"'.
+
+Please consult `README' for other configuration options.
+
+Note that if you want to specify some extra header file directories,
+you should use the environment variable STD_CINCLUDES instead of
+CFLAGS, as described in README.
+
+2. Compilation and installation
+
+After running "configure", just do
+
+	make
+	make install
+
+for compiling and installing.
+
+3. Resolver configuration
+
+To handle multilingual domain names, you have to specify the
+properties like:
+	+ name encoding used in DNS protocol data
+	+ normalization schemes
+These properties are specified by the mDNkit's resolver configuration
+file, "mdnres.conf".  You have to create and set up the file properly.
+The pathname of the file and contents are described in the manual
+"mdnres.conf".
+
+
+* Contact information
+
+Please see http//www.nic.ad.jp/jp/research/idn/ for the latest news
+about mDNkit and this patch.
+
+Bug reports and comments on this kit should be sent to
+mdnkit-bugs@nic.ad.jp and idn-cmt@nic.ad.jp, respectively.
+
+
+; $Id: README.mdnkit,v 1.5 2000/10/18 04:54:57 ishisone Exp $
--- ./acconfig.h.orig	Wed Jan 24 00:53:00 2001
+++ ./acconfig.h	Wed Jan 24 01:22:44 2001
@@ -116,4 +116,7 @@
 #endif /* SHUTUP_STDARG_CAST && __GNUC__ */
 
+/* define if mDNkit support is to be included. */
+#undef WITH_MDN
+
 /* define if the system has a random number generating device */
 #undef PATH_RANDOMDEV
--- ./config.h.in.orig	Wed Jan 24 00:53:01 2001
+++ ./config.h.in	Wed Jan 24 01:22:44 2001
@@ -133,4 +133,10 @@
 #undef HAVE_PTHREAD_ATTR_GETSTACKSIZE
 
+/* define if mDNkit support is to be included. */
+#undef WITH_MDN
+
+/* Define if you have the setlocale function.  */
+#undef HAVE_SETLOCALE
+
 /* Define if you have the <fcntl.h> header file.  */
 #undef HAVE_FCNTL_H
@@ -141,4 +147,7 @@
 /* Define if you have the <linux/prctl.h> header file.  */
 #undef HAVE_LINUX_PRCTL_H
+
+/* Define if you have the <locale.h> header file.  */
+#undef HAVE_LOCALE_H
 
 /* Define if you have the <sys/sockio.h> header file.  */
--- ./configure.in.orig	Wed Jan 24 01:12:20 2001
+++ ./configure.in	Wed Jan 24 01:22:44 2001
@@ -1324,4 +1324,52 @@
 
 #
+# MDN support
+#
+AC_ARG_WITH(mdn,
+	[  --with-mdn[=PREFIX]    enable MDN support using mDNkit [default prefix /usr/local]],
+	use_mdn="$withval", use_mdn="no")
+case "$use_mdn" in
+yes)
+	mdn_path=/usr/local
+	;;
+no)
+	;;
+*)
+	mdn_path="$use_mdn"
+	;;
+esac
+
+AC_ARG_WITH(iconv,
+	[  --with-iconv[=LIBSPEC]   specify iconv library [default -liconv]],
+	iconvlib="$withval", iconvlib="no")
+case "$iconvlib" in
+no)
+    iconvlib=
+    ;;
+yes)
+    iconvlib=-liconv
+    ;;
+esac
+
+AC_ARG_WITH(mdnlib,
+	[  --with-mdnlib=ARG    specify libmdn],
+	mdnlib="$withval", mdnlib="no")
+if test "$mdnlib" = yes; then
+	AC_MSG_ERROR([You must specify ARG for --with-mdnlib.])
+fi
+
+if test "$use_mdn" != no; then
+	AC_DEFINE(WITH_MDN)
+	STD_CINCLUDES="$STD_CINCLUDES -I$mdn_path/include"
+	if test "$mdnlib" != no; then
+		LIBS="$mdnlib $iconvlib $LIBS"
+	else
+		LIBS="-L$mdn_path/lib -lmdn $iconvlib $LIBS"
+	fi
+fi
+AC_CHECK_HEADERS(locale.h)
+AC_CHECK_FUNCS(setlocale)
+
+#
 # Substitutions
 #
--- ./lib/dns/config/confctx.c.orig	Wed Jan 24 00:55:34 2001
+++ ./lib/dns/config/confctx.c	Wed Jan 24 01:22:44 2001
@@ -1030,4 +1030,7 @@
 	PRINT_AS_BOOLEAN(maintain_ixfr_base, "maintain-ixfr-base");
 	PRINT_AS_BOOLEAN(has_old_clients, "has-old-clients");
+#ifdef WITH_MDN
+	PRINT_AS_BOOLEAN(allow_utf8, "allow-utf8");
+#endif
 	PRINT_AS_BOOLEAN(auth_nx_domain, "auth-nxdomain");
 	PRINT_AS_BOOLEAN(multiple_cnames, "multiple-cnames");
@@ -1565,4 +1568,7 @@
 	opts->maintain_ixfr_base = NULL;
 	opts->has_old_clients = NULL;
+#ifdef WITH_MDN
+	opts->allow_utf8 = NULL;
+#endif
 	opts->auth_nx_domain = NULL;
 	opts->multiple_cnames = NULL;
@@ -1680,4 +1686,7 @@
 	FREEFIELD(maintain_ixfr_base);
 	FREEFIELD(has_old_clients);
+#ifdef WITH_MDN
+	FREEFIELD(allow_utf8);
+#endif
 	FREEFIELD(auth_nx_domain);
 	FREEFIELD(multiple_cnames);
@@ -1858,4 +1867,7 @@
 BOOL_FUNCS(maintainixfrbase, maintain_ixfr_base)
 BOOL_FUNCS(hasoldclients, has_old_clients)
+#ifdef WITH_MDN
+BOOL_FUNCS(allowutf8, allow_utf8)
+#endif
 BOOL_FUNCS(authnxdomain, auth_nx_domain)
 BOOL_FUNCS(multiplecnames, multiple_cnames)
--- ./lib/dns/config/confparser.y.orig	Wed Jan 24 01:12:59 2001
+++ ./lib/dns/config/confparser.y	Wed Jan 24 01:22:44 2001
@@ -275,4 +275,5 @@
 %token		L_ALLOW_UPDATE
 %token		L_ALLOW_UPDATE_FORWARDING
+%token		L_ALLOW_UTF8
 %token		L_ALLOW_V6_SYNTHESIS
 %token		L_ALSO_NOTIFY
@@ -1740,4 +1741,19 @@
 		}
 	}
+	| L_ALLOW_UTF8 yea_or_nay
+	{
+#ifdef WITH_MDN
+		tmpres = dns_c_ctx_setallowutf8(currcfg, $2);
+		if (tmpres == ISC_R_EXISTS) {
+			parser_error(ISC_FALSE,
+				     "cannot redefine allow-utf8");
+			YYABORT;
+		}
+#else
+		parser_error(ISC_FALSE, "must be configured with MDN"
+			     "to use allow-utf8");
+		YYABORT;
+#endif
+	}
 	| L_ADDITIONAL_DATA additional_data
 	{
@@ -6122,4 +6138,7 @@
 	int yaccval;
 };
+#ifdef WITH_MDN
+	{ "allow-utf8",			L_ALLOW_UTF8 },
+#endif
 
 static struct token keyword_tokens [] = {
--- ./lib/dns/include/dns/confctx.h.orig	Wed Jan 24 01:02:45 2001
+++ ./lib/dns/include/dns/confctx.h	Wed Jan 24 01:22:44 2001
@@ -185,4 +185,7 @@
 	isc_sockaddr_t	       *transfer_source_v6;
 	isc_sockaddr_t	       *query_source;
+#ifdef WITH_MDN
+	isc_boolean_t	       *allow_utf8;
+#endif
 	isc_sockaddr_t	       *query_source_v6;
 
@@ -631,4 +634,11 @@
 isc_result_t dns_c_ctx_gettreatcrasspace(dns_c_ctx_t *cfg,
 					 isc_boolean_t *retval);
+#ifdef WITH_MDN
+isc_result_t dns_c_ctx_setallowutf8(dns_c_ctx_t *cfg,
+				    isc_boolean_t newval);
+isc_result_t dns_c_ctx_getallowutf8(dns_c_ctx_t *cfg,
+				    isc_boolean_t *retval);
+isc_result_t dns_c_ctx_unsetallowutf8(dns_c_ctx_t *cfg);
+#endif
 
 
--- ./lib/dns/include/dns/name.h.orig	Wed Jan 24 01:03:27 2001
+++ ./lib/dns/include/dns/name.h	Wed Jan 24 01:22:44 2001
@@ -219,4 +219,15 @@
 #define DNS_NAME_MAXWIRE 255
 
+#ifdef WITH_MDN
+/*
+ * Text output filter procedure.
+ * 'target' is the buffer to be converted.  The region to be converted
+ * is from 'buffer'->base + 'used_org' to the end of the used region.
+ */
+typedef isc_result_t (*dns_name_totextfilter_t)(isc_buffer_t *target,
+						unsigned int used_org,
+						isc_boolean_t absolute);
+#endif
+
 /***
  *** Initialization
@@ -1217,4 +1228,24 @@
  *
  */
+
+#ifdef WITH_MDN
+void
+dns_name_allowutf8(isc_boolean_t allowutf8);
+/*
+ * If 'allowutf8' is true, UTF-8 characters are not translated into
+ * backslash escape format (\DDD) by dns_name_totext().
+ *
+ * XXX:
+ *	Setting this modifies the global state.  Maybe there should be
+ *	a way to set this for each name.
+ */
+
+void
+dns_name_settotextfilter(dns_name_totextfilter_t proc);
+/*
+ * Call 'proc' at the end of dns_name_totext.
+ */
+
+#endif /* WITH_MDN */
 
 #define DNS_NAME_FORMATSIZE (DNS_NAME_MAXTEXT + 1)
--- ./lib/dns/name.c.orig	Wed Jan 24 00:59:40 2001
+++ ./lib/dns/name.c	Wed Jan 24 01:22:44 2001
@@ -32,4 +32,8 @@
 #include <dns/result.h>
 
+#ifdef WITH_MDN
+#include <mdn/utf8.h>
+#endif
+
 #define VALID_NAME(n)	ISC_MAGIC_VALID(n, DNS_NAME_MAGIC)
 
@@ -199,4 +203,17 @@
 	    dns_name_t *set_name);
 
+#ifdef WITH_MDN
+/*
+ * If this flag is true, dns_name_totext() copies UTF-8 characters
+ * as is (ie not backslash-escaped form).
+ */
+static isc_boolean_t allow_utf8 = ISC_FALSE;
+
+/*
+ * dns_name_t to text post-conversion procedure.
+ */
+static dns_name_totextfilter_t totext_filter_proc = NULL;
+#endif
+
 static void
 compact(dns_name_t *name, unsigned char *offsets);
@@ -1683,4 +1700,8 @@
 	isc_boolean_t saw_root = ISC_FALSE;
 	char num[4];
+#ifdef WITH_MDN
+	unsigned int oused = target->used;
+	unsigned int u8len;
+#endif
 
 	/*
@@ -1778,4 +1799,18 @@
 						trem--;
 						nlen--;
+#ifdef WITH_MDN
+					} else if (c >= 0x80 &&
+						   allow_utf8 &&
+						   (u8len =
+						   mdn_utf8_isvalidchar(ndata))
+						   > 0 &&
+						   u8len <= trem) {
+						memcpy(tdata, ndata, u8len);
+						ndata += u8len;
+						tdata += u8len;
+						trem -= u8len;
+						nlen -= u8len;
+						count -= u8len - 1;
+#endif
 					} else {
 						if (trem < 4)
@@ -1859,4 +1894,8 @@
 	isc_buffer_add(target, tlen - trem);
 
+#ifdef WITH_MDN
+	if (totext_filter_proc != NULL)
+		return ((*totext_filter_proc)(target, oused, saw_root));
+#endif
 	return (ISC_R_SUCCESS);
 }
@@ -3137,4 +3176,16 @@
 	dns_offsets_t odata;
 
+
+#ifdef WITH_MDN
+void
+dns_name_allowutf8(isc_boolean_t allowutf8) {
+	allow_utf8 = allowutf8;
+}
+
+void
+dns_name_settotextfilter(dns_name_totextfilter_t proc) {
+	totext_filter_proc = proc;
+}
+#endif
 	/*
 	 * Make dest a copy of source.
--- ./lib/lwres/getaddrinfo.c.orig	Wed Jan 24 01:11:09 2001
+++ ./lib/lwres/getaddrinfo.c	Wed Jan 24 01:22:44 2001
@@ -54,4 +54,12 @@
 #endif
 
+#ifdef WITH_MDN		/* Add 'encodeflag' parameter to 3 functions. */
+static int add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
+    int socktype, int port, int encodeflg);
+static int add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
+    int socktype, int port, int encodeflg);
+static void set_order(int, int (**)(const char *, int, struct addrinfo **,
+         int, int, int));
+#else
 static int add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
     int socktype, int port);
@@ -60,4 +68,5 @@
 static void set_order(int, int (**)(const char *, int, struct addrinfo **,
          int, int));
+#endif /* WITH_MDN */
 
 #define FOUND_IPV4	0x1
@@ -67,7 +76,22 @@
 #define ISC_AI_MASK (AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST)
 
+#ifdef WITH_MDN
 int
 lwres_getaddrinfo(const char *hostname, const char *servname,
+		  const struct addrinfo *hints, struct addrinfo **res)
+{
+	/* The last parameter is a encoding type. Default is local encoding. */
+	return (lwres_getaddrinfo_enc(hostname, servname, hints, res, 0));
+}
+#endif /* WITH_MDN */
+
+int
+#ifdef WITH_MDN
+lwres_getaddrinfo_enc(const char *hostname, const char *servname,
+	const struct addrinfo *hints, struct addrinfo **res, int encodeflg)
+#else
+lwres_getaddrinfo(const char *hostname, const char *servname,
 	const struct addrinfo *hints, struct addrinfo **res)
+#endif /* WITH_MDN */
 {
 	struct servent *sp;
@@ -76,6 +100,11 @@
 	struct addrinfo *ai, *ai_list;
 	int port, err, i;
+#ifdef WITH_MDN
+	int (*net_order[FOUND_MAX+1])(const char *, int, struct addrinfo **,
+		 int, int, int);
+#else
 	int (*net_order[FOUND_MAX+1])(const char *, int, struct addrinfo **,
 		 int, int);
+#endif /* WITH_MDN */
 
 	if (hostname == NULL && servname == NULL)
@@ -354,5 +383,9 @@
 			break;
 		err = (net_order[i])(hostname, flags, &ai_list,
+#ifdef WITH_MDN
+				     socktype, port, encodeflg);
+#else
 				     socktype, port);
+#endif
 		if (err != 0)
 			return (err);
@@ -393,6 +426,11 @@
 
 static void
+#ifdef WITH_MDN
+set_order(int family, int (**net_order)(const char *, int, struct addrinfo **,
+					int, int, int))
+#else
 set_order(int family, int (**net_order)(const char *, int, struct addrinfo **,
 					int, int))
+#endif /* WITH_MDN */
 {
 	char *order, *tok;
@@ -452,6 +490,11 @@
 
 static int
+#ifdef WITH_MDN
+add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
+	int socktype, int port, int encodeflg)
+#else
 add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
 	int socktype, int port)
+#endif /* WITH_MDN */
 {
 	struct addrinfo *ai;
@@ -477,6 +520,12 @@
 		SIN(ai->ai_addr)->sin_port = port;
 		memcpy(&SIN(ai->ai_addr)->sin_addr, v4_loop, 4);
+#ifdef WITH_MDN
+	} else if (lwres_getaddrsbyname_enc(lwrctx, hostname,
+					    LWRES_ADDRTYPE_V4,
+					    &by, encodeflg) == 0) {
+#else
 	} else if (lwres_getaddrsbyname(lwrctx, hostname,
 					LWRES_ADDRTYPE_V4, &by) == 0) {
+#endif /* WITH_MDN */
 		addr = LWRES_LIST_HEAD(by->addrs);
 		while (addr != NULL) {
@@ -512,6 +561,11 @@
 
 static int
+#ifdef WITH_MDN
+add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
+	 int socktype, int port, int encodeflg)
+#else
 add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
 	 int socktype, int port)
+#endif /* WITH_MDN */
 {
 	struct addrinfo *ai;
@@ -538,6 +592,12 @@
 		SIN6(ai->ai_addr)->sin6_port = port;
 		memcpy(&SIN6(ai->ai_addr)->sin6_addr, v6_loop, 16);
+#ifdef WITH_MDN
+	} else if (lwres_getaddrsbyname_enc(lwrctx, hostname,
+					    LWRES_ADDRTYPE_V6,
+					    &by, encodeflg) == 0) {
+#else
 	} else if (lwres_getaddrsbyname(lwrctx, hostname,
 					LWRES_ADDRTYPE_V6, &by) == 0) {
+#endif /* WITH_MDN */
 		addr = LWRES_LIST_HEAD(by->addrs);
 		while (addr != NULL) {
--- ./lib/lwres/gethost.c.orig	Wed Jan 24 01:11:10 2001
+++ ./lib/lwres/gethost.c	Wed Jan 24 01:22:44 2001
@@ -26,4 +26,7 @@
 #include <string.h>
 
+#ifdef WITH_MDN
+#include <lwres/lwres.h>
+#endif /* WITH_MDN */
 #include <lwres/netdb.h>
 
@@ -37,30 +40,81 @@
 static int copytobuf(struct hostent *, struct hostent *, char *, int);
 
+#ifdef WITH_MDN
 struct hostent *
 lwres_gethostbyname(const char *name) {
+	/* The last parameter is a encoding type. Default is local encoding. */
+	return (lwres_gethostbyname_enc(name, LWRES_ENCODING_LOCAL));
+}
+#endif /* WITH_MDN */
+
+struct hostent *
+#ifdef WITH_MDN
+lwres_gethostbyname_enc(const char *name, int encodeflg) {
+#else
+lwres_gethostbyname(const char *name) {
+#endif /* WITH_MDN */
 
 	if (he != NULL)
 		lwres_freehostent(he);
 
+#ifdef WITH_MDN
+	he = lwres_getipnodebyname_enc(name, AF_INET, 0, &lwres_h_errno,
+				       encodeflg);
+#else
 	he = lwres_getipnodebyname(name, AF_INET, 0, &lwres_h_errno);
+#endif /* WITH_MDN */
 	return (he);
 }
 
+#ifdef WITH_MDN
 struct hostent *
 lwres_gethostbyname2(const char *name, int af) {
+	/* The last parameter is a encoding type. Default is local encoding. */
+	return (lwres_gethostbyname2_enc(name, af, LWRES_ENCODING_LOCAL));
+}
+#endif /* WITH_MDN */
+
+struct hostent *
+#ifdef WITH_MDN
+lwres_gethostbyname2_enc(const char *name, int af, int encodeflg) {
+#else
+lwres_gethostbyname2(const char *name, int af) {
+#endif /* WITH_MDN */
 	if (he != NULL)
 		lwres_freehostent(he);
 
+#ifdef WITH_MDN
+	he = lwres_getipnodebyname_enc(name, af, 0, &lwres_h_errno, encodeflg);
+#else
 	he = lwres_getipnodebyname(name, af, 0, &lwres_h_errno);
+#endif /* WITH_MDN */
 	return (he);
 }
 
+#ifdef WITH_MDN
+struct hostent *
+lwres_gethostbyaddr(const char *addr, int len, int type) {
+	/* The last parameter is a encoding type. Default is local encoding. */
+	return (lwres_gethostbyaddr_enc(addr, len, type,
+					LWRES_ENCODING_LOCAL));
+}
+#endif /* WITH_MDN */
+
 struct hostent *
+#ifdef WITH_MDN
+lwres_gethostbyaddr_enc(const char *addr, int len, int type, int encodeflg) {
+#else
 lwres_gethostbyaddr(const char *addr, int len, int type) {
+#endif /* WITH_MDN */
 
 	if (he != NULL)
 		lwres_freehostent(he);
 
+#ifdef WITH_MDN
+	he = lwres_getipnodebyaddr_enc(addr, len, type, &lwres_h_errno,
+				       encodeflg);
+#else
 	he = lwres_getipnodebyaddr(addr, len, type, &lwres_h_errno);
+#endif /* WITH_MDN */
 	return (he);
 }
@@ -89,12 +143,32 @@
 }
 
+#ifdef WITH_MDN
 struct hostent *
 lwres_gethostbyname_r(const char *name, struct hostent *resbuf,
 		char *buf, int buflen, int *error)
 {
+	/* The last parameter is a encoding type. Default is local encoding. */
+	return (lwres_gethostbyname_r_enc(name, resbuf, buf, buflen, error,
+					  LWRES_ENCODING_LOCAL));
+}
+#endif /* WITH_MDN */
+
+struct hostent *
+#ifdef WITH_MDN
+lwres_gethostbyname_r_enc(const char *name, struct hostent *resbuf,
+		char *buf, int buflen, int *error, int encodeflg)
+#else
+lwres_gethostbyname_r(const char *name, struct hostent *resbuf,
+		char *buf, int buflen, int *error)
+#endif /* WITH_MDN */
+{
 	struct hostent *he;
 	int res;
 
+#ifdef WITH_MDN
+	he = lwres_getipnodebyname_enc(name, AF_INET, 0, error, encodeflg);
+#else
 	he = lwres_getipnodebyname(name, AF_INET, 0, error);
+#endif /* WITH_MDN */
 	if (he == NULL)
 		return (NULL);
@@ -108,13 +182,35 @@
 }
 
+#ifdef WITH_MDN
+struct hostent  *
+lwres_gethostbyaddr_r(const char *addr, int len, int type,
+		      struct hostent *resbuf, char *buf, int buflen,
+		      int *error)
+{
+	/* The last parameter is a encoding type. Default is local encoding. */
+	return (lwres_gethostbyaddr_r_enc(addr, len, type, resbuf, buf, buflen,
+					  error, LWRES_ENCODING_LOCAL));
+}
+#endif /* WITH_MDN */
+
 struct hostent  *
+#ifdef WITH_MDN
+lwres_gethostbyaddr_r_enc(const char *addr, int len, int type,
+			  struct hostent *resbuf, char *buf, int buflen,
+			  int *error, int encodeflg)
+#else
 lwres_gethostbyaddr_r(const char *addr, int len, int type,
 		      struct hostent *resbuf, char *buf, int buflen,
 		      int *error)
+#endif /* WITH_MDN */
 {
 	struct hostent *he;
 	int res;
 
+#ifdef WITH_MDN
+	he = lwres_getipnodebyaddr_enc(addr, len, type, error, encodeflg);
+#else
 	he = lwres_getipnodebyaddr(addr, len, type, error);
+#endif /* WITH_MDN */
 	if (he == NULL)
 		return (NULL);
--- ./lib/lwres/getipnode.c.orig	Wed Jan 24 01:11:14 2001
+++ ./lib/lwres/getipnode.c	Wed Jan 24 01:22:44 2001
@@ -99,6 +99,22 @@
  */
 
+#ifdef WITH_MDN
 struct hostent *
+lwres_getipnodebyname(const char *name, int af, int flags, int *error_num)
+{
+	/* The last parameter is a encoding type. Default is local encoding. */
+	return (lwres_getipnodebyname_enc(name, af, flags, error_num,
+					  LWRES_ENCODING_LOCAL));
+}
+#endif /* WITH_MDN */
+
+struct hostent *
+#ifdef WITH_MDN
+lwres_getipnodebyname_enc(const char *name, int af, int flags, int *error_num,
+			  int encodeflg)
+{
+#else
 lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) {
+#endif /* WITH_MDN */
 	int have_v4 = 1, have_v6 = 1;
 	struct in_addr in4;
@@ -171,5 +187,10 @@
 	if (have_v6 && af == AF_INET6) {
 
+#ifdef WITH_MDN		
+		n = lwres_getaddrsbyname_enc(lwrctx, name, LWRES_ADDRTYPE_V6,
+					     &by, encodeflg);
+#else
 		n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V6, &by);
+#endif /* WITH_MDN */
 		if (n == 0) {
 			he1 = hostfromname(by, AF_INET6);
@@ -188,5 +209,10 @@
 	     (af == AF_INET6 && (flags & AI_V4MAPPED) != 0 &&
 	      (he1 == NULL || (flags & AI_ALL) != 0)))) {
+#ifdef WITH_MDN
+		n = lwres_getaddrsbyname_enc(lwrctx, name, LWRES_ADDRTYPE_V4,
+					     &by, encodeflg);
+#else
 		n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V4, &by);
+#endif /* WITH_MDN */
 		if (n == 0) {
 			he2 = hostfromname(by, AF_INET);
@@ -220,6 +246,20 @@
 }
 
+#ifdef WITH_MDN
+struct hostent *
+lwres_getipnodebyaddr(const void *src, size_t len, int af, int *error_num) {
+	/* The last parameter is a encoding type. Default is local encoding. */
+	return (lwres_getipnodebyaddr_enc(src, len, af, error_num,
+					  LWRES_ENCODING_LOCAL));
+}
+#endif /* WITH_MDN */
 struct hostent *
+#ifdef WITH_MDN
+lwres_getipnodebyaddr_enc(const void *src, size_t len, int af, int *error_num,
+			  int encodeflg)
+{
+#else
 lwres_getipnodebyaddr(const void *src, size_t len, int af, int *error_num) {
+#endif /* WITH_MDN */
 	struct hostent *he1, *he2;
 	lwres_context_t *lwrctx = NULL;
@@ -282,6 +322,12 @@
 			(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
 		if (n == LWRES_R_SUCCESS)
+#ifdef WITH_MDN
+			n = lwres_getnamebyaddr_enc(lwrctx, LWRES_ADDRTYPE_V4,
+						    INADDRSZ, cp, &by,
+						    encodeflg);
+#else
 			n = lwres_getnamebyaddr(lwrctx, LWRES_ADDRTYPE_V4,
 						INADDRSZ, cp, &by);
+#endif /* WITH_MDN */
 		if (n != LWRES_R_SUCCESS) {
 			lwres_conf_clear(lwrctx);
@@ -326,6 +372,11 @@
 		(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
 	if (n == LWRES_R_SUCCESS)
+#ifdef WITH_MDN
+		n = lwres_getnamebyaddr_enc(lwrctx, LWRES_ADDRTYPE_V6,
+					    IN6ADDRSZ, src, &by, encodeflg);
+#else
 		n = lwres_getnamebyaddr(lwrctx, LWRES_ADDRTYPE_V6, IN6ADDRSZ,
 					src, &by);
+#endif /* WITH_MDN */
 	if (n != 0) {
 		*error_num = HOST_NOT_FOUND;
--- ./lib/lwres/getnameinfo.c.orig	Wed Jan 24 01:11:15 2001
+++ ./lib/lwres/getnameinfo.c	Wed Jan 24 01:22:44 2001
@@ -106,8 +106,24 @@
 	} while (0)
 
+#ifdef WITH_MDN
 int
 lwres_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
 		  size_t hostlen, char *serv, size_t servlen, int flags)
 {
+	/* The last parameter is a encoding type. Default is local encoding. */
+	return (lwres_getnameinfo_enc(sa, salen, host, hostlen, serv, servlen,
+				      flags, LWRES_ENCODING_LOCAL));
+}
+#endif /* WITH_MDN */
+int
+#ifdef WITH_MDN
+lwres_getnameinfo_enc(const struct sockaddr *sa, size_t salen, char *host,
+		      size_t hostlen, char *serv, size_t servlen, int flags,
+		      int encodeflg)
+#else
+lwres_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
+		  size_t hostlen, char *serv, size_t servlen, int flags)
+#endif /* WITH_MDN */
+{
 	struct afd *afd;
 	struct servent *sp;
@@ -259,6 +275,12 @@
 
 		if (n == 0)
+#ifdef WITH_MDN
+			n = lwres_getnamebyaddr_enc(lwrctx, lwf,
+						    afd->a_addrlen, addr, &by,
+						    encodeflg);
+#else
 			n = lwres_getnamebyaddr(lwrctx, lwf, afd->a_addrlen,
 						addr, &by);
+#endif /* WITH_MDN */
 		if (n == 0) {
 			if (flags & NI_NOFQDN) {
--- ./lib/lwres/include/lwres/lwres.h.orig	Wed Jan 24 01:10:57 2001
+++ ./lib/lwres/include/lwres/lwres.h	Wed Jan 24 01:22:44 2001
@@ -27,4 +27,7 @@
 #include <lwres/list.h>
 #include <lwres/lwpacket.h>
+#ifdef WITH_MDN
+#include <mdn/resconf.h>
+#endif /* WITH_MDN */
 
 /*
@@ -247,4 +250,7 @@
 	lwres_uint8_t	ndots;	       /* set to n in 'options ndots:n' */
 	lwres_uint8_t	no_tld_query;  /* non-zero if 'options no_tld_query' */
+#ifdef WITH_MDN
+	mdn_resconf_t	mdnctx;		/* structure for mdn configuration */
+#endif /* WITH_MDN */
 } lwres_conf_t;
 
@@ -255,4 +261,10 @@
 #define LWRES_MAX_ADDRS			64		/* max # of addrs */
 
+#ifdef WITH_MDN
+/* These are used for specifying encoding of the domain names */
+#define LWRES_ENCODING_LOCAL		0	/* local encoding */
+#define LWRES_ENCODING_UCS		1	/* UTF-8 encoding */
+#endif /* WITH_MDN */
+
 LWRES_LANG_BEGINDECLS
 
@@ -264,4 +276,30 @@
 extern const char *lwres_resolv_conf;
 
+#ifdef WITH_MDN
+/*
+ * Forward declarations
+ */
+struct addrinfo;
+struct sockaddr;
+
+int		lwres_getaddrinfo_enc(const char *, const char *,
+				      const struct addrinfo *,
+				      struct addrinfo **,
+				      int encodeflg);
+int		lwres_getnameinfo_enc(const struct sockaddr *, size_t, char *,
+				      size_t, char *, size_t, int, int);
+struct hostent	*lwres_gethostbyaddr_enc(const char *, int, int, int);
+struct hostent	*lwres_gethostbyname_enc(const char *, int);
+struct hostent	*lwres_gethostbyname2_enc(const char *, int, int);
+struct hostent	*lwres_getipnodebyname_enc(const char *, int, int, int *, int);
+struct hostent	*lwres_getipnodebyaddr_enc(const void *, size_t, int, int *,
+					   int);
+struct hostent	*lwres_gethostbyaddr_r_enc(const char *, int, int,
+					   struct hostent *, char *, int,
+					   int *, int);
+struct hostent	*lwres_gethostbyname_r_enc(const char *, struct hostent *,
+					   char *, int, int *, int);
+#endif /* WITH_MDN */
+
 lwres_result_t
 lwres_gabnrequest_render(lwres_context_t *ctx, lwres_gabnrequest_t *req,
@@ -277,7 +315,13 @@
 
 lwres_result_t
+#ifdef WITH_MDN
+lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+			 lwres_lwpacket_t *pkt,
+			 lwres_gabnresponse_t **structp, int encodeflg);
+#else
 lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
 			 lwres_lwpacket_t *pkt,
 			 lwres_gabnresponse_t **structp);
+#endif /* WITH_MDN */
 
 void
@@ -332,8 +376,15 @@
 			lwres_lwpacket_t *pkt, lwres_gnbarequest_t **structp);
 
+#ifdef WITH_MDN
+lwres_result_t
+lwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+			 lwres_lwpacket_t *pkt,
+			 lwres_gnbaresponse_t **structp, int encodeflg);
+#else
 lwres_result_t
 lwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
 			 lwres_lwpacket_t *pkt,
 			 lwres_gnbaresponse_t **structp);
+#endif /* WITH_MDN */
 
 void
@@ -570,4 +621,10 @@
 lwres_getaddrsbyname(lwres_context_t *ctx, const char *name,
 		     lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp);
+#ifdef WITH_MDN
+lwres_result_t
+lwres_getaddrsbyname_enc(lwres_context_t *ctx, const char *name,
+			 lwres_uint32_t addrtypes,
+			 lwres_gabnresponse_t **structp, int encodeflg);
+#endif /* WITH_MDN */
 
 lwres_result_t
@@ -575,4 +632,10 @@
 		    lwres_uint16_t addrlen, const unsigned char *addr,
 		    lwres_gnbaresponse_t **structp);
+#ifdef WITH_MDN
+lwres_result_t
+lwres_getnamebyaddr_enc(lwres_context_t *ctx, lwres_uint32_t addrtype,
+			lwres_uint16_t addrlen, const unsigned char *addr,
+			lwres_gnbaresponse_t **structp, int encodeflg);
+#endif /* WITH_MDN */
 
 lwres_result_t
@@ -580,4 +643,9 @@
 		     lwres_uint16_t rdclass, lwres_uint16_t rdtype,
 		     lwres_uint32_t flags, lwres_grbnresponse_t **structp);
+
+#ifdef WITH_MDN
+lwres_result_t
+lwres_result_frommdn(mdn_result_t r);
+#endif
 
 LWRES_LANG_ENDDECLS
--- ./lib/lwres/lwconfig.c.orig	Wed Jan 24 01:11:20 2001
+++ ./lib/lwres/lwconfig.c	Wed Jan 24 01:22:45 2001
@@ -56,4 +56,7 @@
 #include <lwres/net.h>
 #include <lwres/result.h>
+#ifdef WITH_MDN
+#include <mdn/result.h>
+#endif /* WITH_MDN */
 
 #include "assert_p.h"
@@ -241,4 +244,13 @@
 		lwres_resetaddr(&confdata->sortlist[i].mask);
 	}
+#ifdef WITH_MDN
+	/*
+	 * Initialize the context for MDN.
+	 */
+	confdata->mdnctx = NULL;
+	if (mdn_resconf_initialize() == mdn_success) {
+		(void)mdn_resconf_create(&confdata->mdnctx);
+	}
+#endif /* WITH_MDN */
 }
 
@@ -606,4 +618,9 @@
 	fclose(fp);
 
+#ifdef WITH_MDN
+	/* Read mdn configuration file. */
+	if (confdata->mdnctx != NULL)
+		(void)mdn_resconf_loadfile(confdata->mdnctx, NULL);
+#endif
 	return (ret);
 }
--- ./lib/lwres/lwres_gabn.c.orig	Wed Jan 24 01:11:25 2001
+++ ./lib/lwres/lwres_gabn.c	Wed Jan 24 01:22:45 2001
@@ -28,4 +28,7 @@
 #include <lwres/lwres.h>
 #include <lwres/result.h>
+#ifdef WITH_MDN
+#include <mdn/res.h>
+#endif /* WITH_MDN */
 
 #include "context_p.h"
@@ -245,6 +248,12 @@
 
 lwres_result_t
+#ifdef WITH_MDN
+lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+			 lwres_lwpacket_t *pkt, lwres_gabnresponse_t **structp,
+			 int encodeflg)
+#else
 lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
 			lwres_lwpacket_t *pkt, lwres_gabnresponse_t **structp)
+#endif /* WITH_MDN */
 {
 	lwres_result_t ret;
@@ -256,4 +265,9 @@
 	lwres_addrlist_t addrlist;
 	lwres_addr_t *addr;
+#ifdef WITH_MDN
+	char *tmp_realname;
+	char *tmp_aliases;
+	mdn_result_t r;
+#endif /* WITH_MDN */
 
 	REQUIRE(ctx != NULL);
@@ -319,4 +333,26 @@
 	if (ret != LWRES_R_SUCCESS)
 		goto out;
+#ifdef WITH_MDN
+	/*
+	 * Convert from UCS to local encoding if needed.
+	 */
+	tmp_realname = (char *)malloc(1024);
+	switch (encodeflg) {
+	case LWRES_ENCODING_LOCAL:	/* from UCS to local encoding */
+		r = mdn_res_ucstolocal(ctx->confdata.mdnctx, gabn->realname,
+				       tmp_realname, 1024);
+		if (r != mdn_success) {
+			free(tmp_realname);
+			tmp_realname = NULL;
+			ret = lwres_result_frommdn(r);
+			goto out;
+		}
+		break;
+	default:
+		strcpy(tmp_realname, gabn->realname);
+		break;
+	}
+	gabn->realname = tmp_realname;
+#endif /* WITH_MDN */
 
 	/*
@@ -328,4 +364,27 @@
 		if (ret != LWRES_R_SUCCESS)
 			goto out;
+#ifdef WITH_MDN
+		/*
+		 * Convert from UCS to local encoding.
+		 */
+		tmp_aliases = (char *)malloc(1024);
+		switch (encodeflg) {
+		case LWRES_ENCODING_LOCAL:     /* from UCS to local encoding */
+			r = mdn_res_ucstolocal(ctx->confdata.mdnctx,
+					       gabn->aliases[x],
+					       tmp_aliases, 1024);
+			if (r != mdn_success) {
+				free(tmp_aliases);
+				tmp_aliases = NULL;
+				ret = lwres_result_frommdn(r);
+				goto out;
+			}
+			break;
+		default:	/* When encoding on DNS protocol */
+			strcpy(tmp_aliases, gabn->aliases[x]);
+			break;
+		}
+		gabn->aliases[x] = tmp_aliases;
+#endif /* WITH_MDN */
 	}
 
@@ -391,4 +450,7 @@
 	lwres_gabnresponse_t *gabn;
 	lwres_addr_t *addr;
+#ifdef WITH_MDN
+	unsigned int x;
+#endif /* WITH_MDN */
 
 	REQUIRE(ctx != NULL);
@@ -398,4 +460,12 @@
 	*structp = NULL;
 
+#ifdef WITH_MDN
+	free(gabn->realname);
+	gabn->realname = NULL;
+	for (x = 0 ; x < gabn->naliases ; x++) {
+		free(gabn->aliases[x]);
+		gabn->aliases[x] = NULL;
+	}
+#endif /* WITH_MDN */
 	if (gabn->naliases > 0) {
 		CTXFREE(gabn->aliases, sizeof(char *) * gabn->naliases);
--- ./lib/lwres/lwres_gnba.c.orig	Wed Jan 24 01:11:26 2001
+++ ./lib/lwres/lwres_gnba.c	Wed Jan 24 01:22:45 2001
@@ -28,4 +28,7 @@
 #include <lwres/lwres.h>
 #include <lwres/result.h>
+#ifdef WITH_MDN
+#include <mdn/res.h>
+#endif /* WITH_MDN */
 
 #include "context_p.h"
@@ -204,6 +207,12 @@
 
 lwres_result_t
+#ifdef WITH_MDN
+lwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+			 lwres_lwpacket_t *pkt, lwres_gnbaresponse_t **structp,
+			 int encodeflg)
+#else
 lwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
 			 lwres_lwpacket_t *pkt, lwres_gnbaresponse_t **structp)
+#endif /* WITH_MDN */
 {
 	int ret;
@@ -212,4 +221,9 @@
 	lwres_uint16_t naliases;
 	lwres_gnbaresponse_t *gnba;
+#ifdef WITH_MDN
+	char *tmp_realname;
+	char *tmp_aliases;
+	mdn_result_t r;
+#endif /* WITH_MDN */
 
 	REQUIRE(ctx != NULL);
@@ -261,4 +275,26 @@
 	if (ret != LWRES_R_SUCCESS)
 		goto out;
+#ifdef WITH_MDN
+	/*
+	 * Convert from UCS to local encoding if needed.
+	 */
+	tmp_realname = (char *)malloc(1024);
+	switch (encodeflg) {
+	case LWRES_ENCODING_LOCAL:	/* from UCS to local encoding */
+		r = mdn_res_ucstolocal(ctx->confdata.mdnctx, gnba->realname,
+				       tmp_realname, 1024);
+		if (r != mdn_success) {
+			free(tmp_realname);
+			tmp_realname = NULL;
+			ret = lwres_result_frommdn(r);
+			goto out;
+		}
+		break;
+	default:
+		strcpy(tmp_realname, gnba->realname);
+		break;
+	}
+	gnba->realname = tmp_realname;
+#endif /* WITH_MDN */
 
 	/*
@@ -270,4 +306,27 @@
 		if (ret != LWRES_R_SUCCESS)
 			goto out;
+#ifdef WITH_MDN
+		/*
+		 * Convert from UCS to local encoding.
+		 */
+		tmp_aliases = (char *)malloc(1024);
+		switch (encodeflg) {
+		case LWRES_ENCODING_LOCAL:     /* from UCS to local encoding */
+			r = mdn_res_ucstolocal(ctx->confdata.mdnctx,
+					       gnba->aliases[x],
+					       tmp_aliases, 1024);
+			if (r != mdn_success) {
+				free(tmp_aliases);
+				tmp_aliases = NULL;
+				ret = lwres_result_frommdn(r);
+				goto out;
+			}
+			break;
+		default:	/* When encoding on DNS protocol */
+			strcpy(tmp_aliases, gnba->aliases[x]);
+			break;
+		}
+		gnba->aliases[x] = tmp_aliases;
+#endif /* WITH_MDN */
 	}
 
@@ -311,4 +370,7 @@
 {
 	lwres_gnbaresponse_t *gnba;
+#ifdef WITH_MDN
+	unsigned int x;
+#endif /* WITH_MDN */
 
 	REQUIRE(ctx != NULL);
@@ -318,4 +380,12 @@
 	*structp = NULL;
 
+#ifdef WITH_MDN
+	free(gnba->realname);
+	gnba->realname = NULL;
+	for (x = 0 ; x < gnba->naliases ; x++) {
+		free(gnba->aliases[x]);
+		gnba->aliases[x] = NULL;
+	}
+#endif /* WITH_MDN */
 	if (gnba->naliases > 0) {
 		CTXFREE(gnba->aliases, sizeof(char *) * gnba->naliases);
--- ./lib/lwres/lwresutil.c.orig	Wed Jan 24 01:11:30 2001
+++ ./lib/lwres/lwresutil.c	Wed Jan 24 01:22:45 2001
@@ -33,4 +33,7 @@
 #include <lwres/lwres.h>
 #include <lwres/result.h>
+#ifdef WITH_MDN
+#include <mdn/res.h>
+#endif /* WITH_MDN */
 
 #include "assert_p.h"
@@ -160,8 +163,24 @@
 }
 
+#ifdef WITH_MDN
 lwres_result_t
 lwres_getaddrsbyname(lwres_context_t *ctx, const char *name,
 		     lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp)
 {
+	/* The last parameter is a encoding type. Default is local encoding. */
+	return (lwres_getaddrsbyname_enc(ctx, name, addrtypes, structp, 0));
+}
+#endif /* WITH_MDN */
+
+lwres_result_t
+#ifdef WITH_MDN
+lwres_getaddrsbyname_enc(lwres_context_t *ctx, const char *name,
+		     lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp,
+		     int encodeflg)
+#else
+lwres_getaddrsbyname(lwres_context_t *ctx, const char *name,
+		     lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp)
+#endif /* WITH_MDN */
+{
 	lwres_gabnrequest_t request;
 	lwres_gabnresponse_t *response;
@@ -174,4 +193,8 @@
 	char target_name[1024];
 	unsigned int target_length;
+#ifdef WITH_MDN
+	mdn_result_t r;
+	char request_name[1024];
+#endif /* WITH_MDN */
 
 	REQUIRE(ctx != NULL);
@@ -201,6 +224,35 @@
 	 */
 	request.addrtypes = addrtypes;
+#ifdef WITH_MDN
+	/*
+	 * Convert from local encoding to UCS, then perform normalization.
+	 */
+	switch (encodeflg) {
+	case LWRES_ENCODING_LOCAL:	/* from local encoding */
+		r = mdn_res_localtoucs(ctx->confdata.mdnctx, target_name,
+				       request_name, sizeof(request_name));
+		if (r == mdn_success) {
+			r = mdn_res_normalize(ctx->confdata.mdnctx,
+					      request_name,
+					      target_name,
+					      sizeof(target_name));
+		}
+		request.name = target_name;
+		break;
+	default:
+		r = mdn_res_normalize(ctx->confdata.mdnctx, target_name,
+				      request_name, sizeof(request_name));
+		request.name = request_name;
+		break;
+	}
+	if (r != mdn_success) {
+		ret = lwres_result_frommdn(r);
+		goto out;
+	}
+	request.namelen = strlen(request.name);
+#else
 	request.name = target_name;
 	request.namelen = target_length;
+#endif /* WITH_MDN */
 	pkt.pktflags = 0;
 	pkt.serial = serial;
@@ -251,5 +303,9 @@
 	 * Parse the response.
 	 */
+#ifdef WITH_MDN
+	ret = lwres_gabnresponse_parse(ctx, &b_in, &pkt, &response, encodeflg);
+#else
 	ret = lwres_gabnresponse_parse(ctx, &b_in, &pkt, &response);
+#endif /* WITH_MDN */
 	if (ret != LWRES_R_SUCCESS)
 		goto out;
@@ -273,8 +329,25 @@
 
 
+#ifdef WITH_MDN
+lwres_result_t
+lwres_getnamebyaddr(lwres_context_t *ctx, lwres_uint32_t addrtype,
+		    lwres_uint16_t addrlen, const unsigned char *addr,
+		    lwres_gnbaresponse_t **structp)
+{
+	/* The last parameter is a encoding type. Default is local encoding. */
+	return (lwres_getnamebyaddr_enc(ctx, addrtype, addrlen, addr, structp,
+					LWRES_ENCODING_LOCAL));
+}
+#endif /* WITH_MDN */
 lwres_result_t
+#ifdef WITH_MDN
+lwres_getnamebyaddr_enc(lwres_context_t *ctx, lwres_uint32_t addrtype,
+			lwres_uint16_t addrlen, const unsigned char *addr,
+			lwres_gnbaresponse_t **structp, int encodeflg)
+#else
 lwres_getnamebyaddr(lwres_context_t *ctx, lwres_uint32_t addrtype,
 		    lwres_uint16_t addrlen, const unsigned char *addr,
 		    lwres_gnbaresponse_t **structp)
+#endif /* WITH_MDN */
 {
 	lwres_gnbarequest_t request;
@@ -359,5 +432,9 @@
 	 * Parse the response.
 	 */
+#ifdef WITH_MDN
+	ret = lwres_gnbaresponse_parse(ctx, &b_in, &pkt, &response, encodeflg);
+#else
 	ret = lwres_gnbaresponse_parse(ctx, &b_in, &pkt, &response);
+#endif /* WITH_MDN */
 	if (ret != LWRES_R_SUCCESS)
 		goto out;
@@ -379,4 +456,21 @@
 	return (ret);
 }
+
+#ifdef WITH_MDN
+lwres_result_t
+lwres_result_frommdn(mdn_result_t r) {
+	/*
+	 * Convert mDNkit's result code to lwres's one.
+	 */
+	switch (r) {
+	case mdn_success:
+		return (LWRES_R_SUCCESS);
+	case mdn_nomemory:
+		return (LWRES_R_NOMEMORY);
+	default:
+		return (LWRES_R_FAILURE);
+	}
+}
+#endif
 
 lwres_result_t
--- ./bin/dig/dighost.c.orig	Wed Jan 24 00:48:34 2001
+++ ./bin/dig/dighost.c	Wed Jan 24 01:24:34 2001
@@ -33,4 +33,14 @@
 #include <string.h>
 #include <limits.h>
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#ifdef WITH_MDN
+#include <mdn/result.h>
+#include <mdn/log.h>
+#include <mdn/resconf.h>
+#include <mdn/res.h>
+#endif
 
 #include <dns/byaddr.h>
@@ -133,4 +143,18 @@
 isc_uint32_t rr_limit = INT_MAX;
 
+#ifdef WITH_MDN
+mdn_resconf_t mdnconf;
+
+static void		initialize_mdn(void);
+static isc_result_t	output_filter(isc_buffer_t *buffer,
+				      unsigned int used_org,
+				      isc_boolean_t absolute);
+static mdn_result_t	append_textname(char *name, const char *origin,
+					size_t namesize);
+static void		mdn_check_result(mdn_result_t r, const char *msg);
+
+#define MAXDLEN		256
+#endif
+
 /*
  * Apply and clear locks at the event level in global task.
@@ -675,4 +699,8 @@
 	}
 
+#ifdef WITH_MDN
+	initialize_mdn();
+#endif
+
 	if (keyfile[0] != 0)
 		setup_file_key();
@@ -1221,4 +1249,9 @@
 	isc_buffer_t b;
 	char store[MXNAME];
+	char *textname;
+#ifdef WITH_MDN
+	mdn_result_t mr;
+	char ucs_name[MXNAME], ucs_tmp[MXNAME];
+#endif
 
 	REQUIRE(lookup != NULL);
@@ -1274,4 +1307,13 @@
 		result = dns_name_fromtext(lookup->oname, &b, dns_rootname,
 					   ISC_FALSE, &lookup->onamebuf);
+#ifdef WITH_MDN
+	mr = mdn_res_localtoucs(mdnconf, lookup->textname, ucs_name,
+				sizeof(ucs_name));
+	mdn_check_result(mr, "local to UCS conversion");
+	textname = ucs_name;
+#else
+	textname = lookup->textname;
+#endif
+
 		if (result != ISC_R_SUCCESS) {
 			dns_message_puttempname(lookup->sendmsg,
@@ -1281,4 +1323,22 @@
 			fatal("'%s' is not in legal name syntax (%s)",
 			      lookup->origin->origin,
+#ifdef WITH_MDN
+		/*
+		 * We cannot convert name and origin separately and combine
+		 * them later, because some encoding scheme (such as UTF-5)
+		 * can be applied only to an entire domain name, not a
+		 * partial one.
+		 */
+		mr = append_textname(ucs_name, lookup->origin->origin,
+				     sizeof(ucs_name));
+		mdn_check_result(mr, "concatenation with origin");
+		mr = mdn_res_normalize(mdnconf, ucs_name, ucs_tmp,
+				       sizeof(ucs_tmp));
+		mdn_check_result(mr, "normalization");
+		mr = mdn_res_ucstodns(mdnconf, ucs_tmp, ucs_name,
+				      sizeof(ucs_name));
+		mdn_check_result(mr, "UCS to DNS encoding conversion");
+		goto no_origin;
+#else
 			      dns_result_totext(result));
 		}
@@ -1302,7 +1362,26 @@
 		}
 		dns_message_puttempname(lookup->sendmsg, &lookup->oname);
+#endif
 	} else {
 		debug("using root origin");
+#ifdef WITH_MDN
+	no_origin:
+#endif
 		if (!lookup->trace_root) {
+#ifdef WITH_MDN
+			mr = mdn_res_normalize(mdnconf, ucs_name, ucs_tmp,
+					       sizeof(ucs_tmp));
+			mdn_check_result(mr, "normalization");
+			mr = mdn_res_ucstodns(mdnconf, ucs_tmp, ucs_name,
+					      sizeof(ucs_name));
+			mdn_check_result(mr, "UCS to DNS encoding conversion");
+			len = strlen(ucs_name);
+			isc_buffer_init(&b, ucs_name, len);
+			isc_buffer_add(&b, len);
+			result = dns_name_fromtext(lookup->name, &b,
+						   dns_rootname,
+						   ISC_FALSE,
+						   &lookup->namebuf);
+#else
 			len = strlen(lookup->textname);
 			isc_buffer_init(&b, lookup->textname, len);
@@ -1312,4 +1391,5 @@
 						   ISC_FALSE,
 						   &lookup->namebuf);
+#endif
 		} else {
 			dns_name_clone(dns_rootname, lookup->name);
@@ -2711,2 +2791,123 @@
 		isc_mem_destroy(&mctx);
 }
+
+#ifdef WITH_MDN
+static void
+initialize_mdn(void) {
+	mdn_result_t r;
+	mdn_converter_t conv;
+
+#ifdef HAVE_SETLOCALE
+	/* Set locale */
+	(void)setlocale(LC_ALL, "");
+#endif
+
+	/* General initialization. */
+	r = mdn_resconf_initialize();
+	if (r != mdn_success)
+		fatal("mdn initialization failed: %s",
+		      mdn_result_tostring(r));
+
+	/* Create configuration context. */
+	r = mdn_resconf_create(&mdnconf);
+	if (r != mdn_success)
+		fatal("mdn resconf initialization failed: %s",
+		      mdn_result_tostring(r));
+
+
+	/* Load mdn configuration file. */
+	r = mdn_resconf_loadfile(mdnconf, NULL);
+	if (r != mdn_success)
+		fatal("mdn configuration loading failed: %s",
+		      mdn_result_tostring(r));
+
+	/* Allow utf-8 characters in domain names if necessary. */
+	if ((conv = mdn_resconf_serverconverter(mdnconf)) != NULL &&
+	    !mdn_converter_isasciicompatible(conv)) {
+		debug("allowing UTF-8 characters in domain names");
+		dns_name_allowutf8(ISC_TRUE);
+	}
+	/* Set domain name -> text post-conversion filter. */
+	dns_name_settotextfilter(output_filter);
+}
+
+static isc_result_t
+output_filter(isc_buffer_t *buffer, unsigned int used_org,
+	      isc_boolean_t absolute)
+{
+	char tmp1[MAXDLEN], tmp2[MAXDLEN];
+	size_t fromlen, tolen;
+	isc_boolean_t end_with_dot;
+
+	/*
+	 * Copy contents of 'buffer' to 'tmp1', supply trailing dot
+	 * if 'absolute' is true, and terminate with NUL.
+	 */
+	fromlen = isc_buffer_usedlength(buffer) - used_org;
+	if (fromlen >= MAXDLEN)
+		return (ISC_R_SUCCESS);
+	memcpy(tmp1, (char *)isc_buffer_base(buffer) + used_org, fromlen);
+	end_with_dot = (tmp1[fromlen - 1] == '.') ? ISC_TRUE : ISC_FALSE;
+	if (absolute && !end_with_dot) {
+		fromlen++;
+		if (fromlen >= MAXDLEN)
+			return (ISC_R_SUCCESS);
+		tmp1[fromlen - 1] = '.';
+	}
+	tmp1[fromlen] = '\0';
+
+	/*
+	 * Convert contents of 'tmp1' to local encoding.
+	 */
+	if (mdn_res_dnstoucs(mdnconf, tmp1, tmp2, MAXDLEN)
+	    != mdn_success ||
+	    mdn_res_ucstolocal(mdnconf, tmp2, tmp1, MAXDLEN)
+	    != mdn_success)
+		return (ISC_R_SUCCESS);
+
+	/*
+	 * Copy the converted contents in 'tmp1' back to 'buffer'.
+	 * If we have appended trailing dot, remove it.
+	 */
+	tolen = strlen(tmp1);
+	if (absolute && !end_with_dot && tmp1[tolen - 1] == '.')
+		tolen--;
+
+	if (isc_buffer_length(buffer) < used_org + tolen)
+		return (ISC_R_NOSPACE);
+
+	isc_buffer_subtract(buffer, isc_buffer_usedlength(buffer) - used_org);
+	memcpy(isc_buffer_used(buffer), tmp1, tolen);
+	isc_buffer_add(buffer, tolen);
+
+	return (ISC_R_SUCCESS);
+}
+
+static mdn_result_t
+append_textname(char *name, const char *origin, size_t namesize) {
+	size_t namelen = strlen(name);
+	size_t originlen = strlen(origin);
+
+	/* Already absolute? */
+	if (namelen > 0 && name[namelen - 1] == '.')
+		return mdn_success;
+
+	/* Append dot and origin */
+
+	if (namelen + 1 + originlen >= namesize)
+		return mdn_buffer_overflow;
+
+	name[namelen++] = '.';
+	(void)strcpy(name + namelen, origin);
+	return mdn_success;
+}
+
+static void
+mdn_check_result(mdn_result_t r, const char *msg) {
+	if (r != mdn_success) {
+		exitcode = 1;
+		fatal("%s: %s", msg, mdn_result_tostring(r));
+	}
+}
+
+#endif /* WITH_MDN */
--- ./bin/named/Makefile.in.orig	Wed Jan 24 00:49:10 2001
+++ ./bin/named/Makefile.in	Wed Jan 24 01:22:45 2001
@@ -34,5 +34,5 @@
 CINCLUDES =	-I${srcdir}/include -I${srcdir}/unix/include \
 		${LWRES_INCLUDES} ${DNS_INCLUDES} ${ISC_INCLUDES} \
-		${OMAPI_INCLUDES} ${DBDRIVER_INCLUDES}
+		${OMAPI_INCLUDES} ${DBDRIVER_INCLUDES} \
 
 CDEFINES =
@@ -52,5 +52,5 @@
 
 LIBS =		${LWRESLIBS} ${OMAPILIBS} ${DNSLIBS} ${ISCLIBS} \
-		${DBDRIVER_LIBS} @LIBS@
+		${DBDRIVER_LIBS} ${ICONVLIB} @LIBS@
 
 SUBDIRS =	unix
@@ -64,5 +64,5 @@
 		zoneconf.@O@ \
 		lwaddr.@O@ lwresd.@O@ lwdclient.@O@ lwderror.@O@ lwdgabn.@O@ \
-		lwdgnba.@O@ lwdgrbn.@O@ lwdnoop.@O@ lwsearch.@O@ \
+		lwdgnba.@O@ lwdgrbn.@O@ lwdmdn.@O@ lwdnoop.@O@ lwsearch.@O@ \
 		$(DBDRIVER_OBJS)
 
@@ -75,5 +75,5 @@
 		zoneconf.c \
 		lwaddr.c lwresd.c lwdclient.c lwderror.c lwdgabn.c \
-		lwdgnba.c lwdgrbn.c lwdnoop.c lwsearch.c \
+		lwdgnba.c lwdgrbn.c lwdmdn.c lwdnoop.c lwsearch.c \
 		$(DBDRIVER_SRCS)
 
--- ./bin/named/include/named/globals.h.orig	Wed Jan 24 00:49:01 2001
+++ ./bin/named/include/named/globals.h	Wed Jan 24 01:22:45 2001
@@ -104,4 +104,12 @@
 EXTERN const char *		ns_g_username		INIT(NULL);
 
+#ifdef WITH_MDN
+/*
+ * MDN configuration.
+ */
+EXTERN char *			lwresd_g_mdnconffile;
+EXTERN isc_boolean_t		lwresd_g_mdnreloadwanted;
+#endif
+
 #undef EXTERN
 #undef INIT
--- ./bin/named/include/named/lwdmdn.h.orig	Wed Jan 24 01:22:45 2001
+++ ./bin/named/include/named/lwdmdn.h	Wed Jan 24 01:22:45 2001
@@ -0,0 +1,23 @@
+/* $Id: lwdmdn.h,v 1.1 2000/08/16 08:55:32 ishisone Exp $ */
+
+#ifndef NAMED_LWDMDN_H
+#define NAMED_LWDMDN_H
+
+#include <isc/types.h>
+#include <mdn/result.h>
+
+ISC_LANG_BEGINDECLS
+
+void
+ns_lwdmdn_initialize(void);
+
+isc_result_t
+ns_lwdmdn_convertfromutf8(isc_buffer_t *from_buffer, isc_buffer_t *to_buffer);
+
+isc_result_t
+ns_lwdmdn_converttoutf8(isc_buffer_t *from_buffer, isc_buffer_t *to_buffer);
+
+ISC_LANG_ENDDECLS
+
+#endif /* NAMED_LWDMDN_H */
+
--- ./bin/named/lwdgabn.c.orig	Wed Jan 24 00:49:30 2001
+++ ./bin/named/lwdgabn.c	Wed Jan 24 01:22:45 2001
@@ -35,4 +35,7 @@
 #include <named/lwaddr.h>
 #include <named/lwdclient.h>
+#ifdef WITH_MDN
+#include <named/lwdmdn.h>
+#endif
 #include <named/lwresd.h>
 #include <named/lwsearch.h>
@@ -277,4 +280,7 @@
 	isc_result_t result;
 	isc_uint16_t naliases;
+#ifdef WITH_MDN
+	isc_buffer_t *tbufp;
+#endif
 
 	b = client->recv_buffer;
@@ -283,8 +289,25 @@
 	 * Render the new name to the buffer.
 	 */
+#ifdef WITH_MDN
+	tbufp = NULL;
+	result = isc_buffer_allocate(client->clientmgr->mctx, &tbufp, 256);
+	if (result != ISC_R_SUCCESS)
+		return (result);
+	result = dns_name_totext(dns_fixedname_name(&client->target_name),
+				 ISC_TRUE, tbufp);
+	if (result != ISC_R_SUCCESS) {
+		isc_buffer_free(&tbufp);
+		return (result);
+	}
+	result = ns_lwdmdn_converttoutf8(tbufp, &client->recv_buffer);
+	isc_buffer_free(&tbufp);
+	if (result != ISC_R_SUCCESS)
+		return (result);
+#else
 	result = dns_name_totext(dns_fixedname_name(&client->target_name),
 				 ISC_TRUE, &client->recv_buffer);
 	if (result != ISC_R_SUCCESS)
 		return (result);
+#endif
 
 	/*
@@ -312,4 +335,7 @@
 	isc_result_t result;
 	dns_name_t *tname;
+#ifdef WITH_MDN
+	isc_buffer_t *tbufp;
+#endif
 
 	b = client->recv_buffer;
@@ -323,5 +349,19 @@
 	 * Render the new name to the buffer.
 	 */
+#ifdef WITH_MDN
+	tbufp = NULL;
+	result = isc_buffer_allocate(client->clientmgr->mctx, &tbufp, 256);
+	if (result != ISC_R_SUCCESS)
+		return (result);
+	result = dns_name_totext(tname, ISC_TRUE, tbufp);
+	if (result != ISC_R_SUCCESS) {
+		isc_buffer_free(&tbufp);
+		return (result);
+	}
+	result = ns_lwdmdn_converttoutf8(tbufp, &client->recv_buffer);
+	isc_buffer_free(&tbufp);
+#else
 	result = dns_name_totext(tname, ISC_TRUE, &client->recv_buffer);
+#endif
 	if (result != ISC_R_SUCCESS)
 		return (result);
@@ -599,4 +639,7 @@
 	ns_lwdclientmgr_t *cm;
 	isc_buffer_t namebuf;
+#ifdef WITH_MDN
+	isc_buffer_t *tnamebufp;
+#endif
 
 	REQUIRE(NS_LWDCLIENT_ISRECVDONE(client));
@@ -612,11 +655,39 @@
 		goto out;
 
+#ifdef WITH_MDN
+	/*
+	 * XXX Assuming allocation size for req->name is larger than
+	 * req->namelen by at least one, which is true in the current
+	 * implementation.
+	 */
+	isc_buffer_init(&namebuf, req->name, req->namelen + 1);
+	isc_buffer_add(&namebuf, req->namelen);
+	tnamebufp = NULL;
+	result = isc_buffer_allocate(client->clientmgr->mctx, &tnamebufp, 256);
+	if (result != ISC_R_SUCCESS)
+		goto out;
+	/*
+	 * Convert UTF-8 string in namebuf into DNS protocol encoding.
+	 */
+	result = ns_lwdmdn_convertfromutf8(&namebuf, tnamebufp);
+	if (result != ISC_R_SUCCESS) {
+		isc_buffer_free(&tnamebufp);
+		goto out;
+	}
+#else
 	isc_buffer_init(&namebuf, req->name, req->namelen);
 	isc_buffer_add(&namebuf, req->namelen);
+#endif
 
 	dns_fixedname_init(&client->target_name);
 	dns_fixedname_init(&client->query_name);
+#ifdef WITH_MDN
+	result = dns_name_fromtext(dns_fixedname_name(&client->query_name),
+				   tnamebufp, dns_rootname, ISC_FALSE, NULL);
+	isc_buffer_free(&tnamebufp);
+#else
 	result = dns_name_fromtext(dns_fixedname_name(&client->query_name),
 				   &namebuf, NULL, ISC_FALSE, NULL);
+#endif
 	if (result != ISC_R_SUCCESS)
 		goto out;
--- ./bin/named/lwdgnba.c.orig	Wed Jan 24 00:49:32 2001
+++ ./bin/named/lwdgnba.c	Wed Jan 24 01:22:45 2001
@@ -30,4 +30,7 @@
 #include <named/types.h>
 #include <named/lwdclient.h>
+#ifdef WITH_MDN
+#include <named/lwdmdn.h>
+#endif
 
 static void start_byaddr(ns_lwdclient_t *);
@@ -48,4 +51,7 @@
 	isc_uint16_t naliases;
 
+#ifdef WITH_MDN
+	isc_buffer_t *tbufp;
+#endif
 	UNUSED(task);
 
@@ -95,7 +101,23 @@
 		b = client->recv_buffer;
 
+#ifdef WITH_MDN
+		tbufp = NULL;
+		result = isc_buffer_allocate(cm->mctx, &tbufp, 256);
+		if (result != ISC_R_SUCCESS)
+			goto out;
+		result = dns_name_totext(name, ISC_TRUE, tbufp);
+		if (result != ISC_R_SUCCESS) {
+			isc_buffer_free(&tbufp);
+			goto out;
+		}
+		result = ns_lwdmdn_converttoutf8(tbufp, &client->recv_buffer);
+		isc_buffer_free(&tbufp);
+		if (result != ISC_R_SUCCESS)
+			goto out;
+#else
 		result = dns_name_totext(name, ISC_TRUE, &client->recv_buffer);
 		if (result != ISC_R_SUCCESS)
 			goto out;
+#endif
 		ns_lwdclient_log(50, "found name '%.*s'",
 				 client->recv_buffer.used - b.used,
--- ./bin/named/lwdmdn.c.orig	Wed Jan 24 01:22:45 2001
+++ ./bin/named/lwdmdn.c	Wed Jan 24 01:22:45 2001
@@ -0,0 +1,283 @@
+/* $Id: lwdmdn.c,v 1.6 2000/09/07 06:27:40 ishisone Exp $ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#ifdef WITH_MDN
+#include <mdn/result.h>
+#include <mdn/log.h>
+#include <mdn/resconf.h>
+#include <mdn/res.h>
+#endif
+
+#include <isc/result.h>
+#include <isc/rwlock.h>
+#include <isc/util.h>
+
+#include <named/types.h>
+#include <named/log.h>
+#ifdef WITH_MDN
+#include <named/lwdmdn.h>
+#endif
+#include <named/lwdclient.h>
+#include <named/globals.h>
+
+#ifdef WITH_MDN
+
+typedef enum {
+	convert_from_utf8,
+	convert_to_utf8
+} convert_direction_t;
+
+static isc_logmodule_t modules[] = {
+	{ "mdn",		0 },
+	{ NULL,			0 }
+};
+#define NS_LOGMODULE_MDN	(&modules[0])
+
+static isc_rwlock_t	mdnconflock;
+static mdn_resconf_t	mdnconf = NULL;
+
+static isc_result_t	convert_buffer(isc_buffer_t *from_buffer,
+				       isc_buffer_t *to_buffer,
+				       convert_direction_t dir);
+static isc_result_t	load_mdnconfiguration(const char *filename);
+static isc_result_t	mdnresult_to_iscresult(mdn_result_t r);
+static void		set_log_level(int level);
+static void		logger(int level, const char *msg);
+static void		logwrite(int level, const char *fmt, ...);
+
+void
+ns_lwdmdn_initialize(void) {
+	mdn_result_t r;
+	isc_result_t result;
+
+	logwrite(ISC_LOG_DEBUG(50), "initializing mdn");
+
+	/* Register MDN module for logging. */
+	isc_log_registermodules(ns_g_lctx, modules);
+
+	/* Set libmdn log hander. */
+	mdn_log_setproc(logger);
+
+	/* Set log level. */
+	set_log_level(ns_g_debuglevel);
+
+	/* General initialization. */
+	r = mdn_resconf_initialize();
+	RUNTIME_CHECK(r == mdn_success);
+
+	/* Create configuration context. */
+	r = mdn_resconf_create(&mdnconf);
+	RUNTIME_CHECK(r == mdn_success);
+
+	/* Initialize configuration lock variable. */
+	result = isc_rwlock_init(&mdnconflock, 1, 1);
+	RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+	/* Load configuration file. */
+	lwresd_g_mdnreloadwanted = 1;
+	(void)load_mdnconfiguration(lwresd_g_mdnconffile);
+}
+
+isc_result_t
+ns_lwdmdn_convertfromutf8(isc_buffer_t *from_buffer, isc_buffer_t *to_buffer) {
+	return convert_buffer(from_buffer, to_buffer, convert_from_utf8);
+}
+
+isc_result_t
+ns_lwdmdn_converttoutf8(isc_buffer_t *from_buffer, isc_buffer_t *to_buffer) {
+	return convert_buffer(from_buffer, to_buffer, convert_to_utf8);
+}
+
+static isc_result_t
+convert_buffer(isc_buffer_t *from_buffer, isc_buffer_t *to_buffer,
+	       convert_direction_t dir)
+{
+	isc_result_t result;
+	mdn_result_t r;
+	char *fromstr, *tostr;
+	char tmp[256];
+	size_t tolen;
+
+	/*
+	 * Reload MDN configuration file, if necessary.
+	 */
+	if (lwresd_g_mdnreloadwanted) {
+		result = load_mdnconfiguration(lwresd_g_mdnconffile);
+	}
+
+	/*
+	 * Since libmdn assumes all the strings are NUL-terminated,
+	 * teminate the input string.  If the buffer has some free space,
+	 * utilize it.  Otherwise, make a local copy.
+	 */
+	if (isc_buffer_remaininglength(from_buffer) > 0) {
+		fromstr = isc_buffer_used(from_buffer); /* temporary */
+		*fromstr = '\0';
+		fromstr = isc_buffer_base(from_buffer);
+	} else {
+		size_t fromlen = isc_buffer_usedlength(from_buffer);
+
+		if (fromlen >= sizeof(tmp))
+			fromlen = sizeof(tmp) - 1;
+		fromstr = tmp;
+		memcpy(fromstr, isc_buffer_base(from_buffer), fromlen);
+		fromstr[fromlen] = '\0';
+	}
+	tostr = isc_buffer_used(to_buffer);
+	tolen = isc_buffer_availablelength(to_buffer);
+
+	RWLOCK(&mdnconflock, isc_rwlocktype_read);
+
+	if (dir == convert_from_utf8)
+		r = mdn_res_ucstodns(mdnconf, fromstr, tostr, tolen);
+	else
+		r = mdn_res_dnstoucs(mdnconf, fromstr, tostr, tolen);
+
+	RWUNLOCK(&mdnconflock, isc_rwlocktype_read);
+
+	if (r != mdn_success)
+		return (mdnresult_to_iscresult(r));
+
+	isc_buffer_add(to_buffer, strlen(tostr));
+
+	return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+load_mdnconfiguration(const char *filename) {
+	isc_result_t result = ISC_R_SUCCESS;
+	mdn_result_t r;
+	mdn_converter_t conv;
+	isc_boolean_t loaded = ISC_FALSE;
+	isc_boolean_t allow_utf8;
+
+	RWLOCK(&mdnconflock, isc_rwlocktype_write);
+
+	logwrite(ISC_LOG_DEBUG(50), "loading mdn configuration %s",
+		 filename == NULL ? mdn_resconf_defaultfile() : filename);
+
+	if (lwresd_g_mdnreloadwanted) {
+		r = mdn_resconf_loadfile(mdnconf, filename);
+		if (r == mdn_success)
+			loaded = ISC_TRUE;
+		else
+			result = mdnresult_to_iscresult(r);
+	}
+	lwresd_g_mdnreloadwanted = 0;
+	logwrite(ISC_LOG_DEBUG(100), "finish loading mdn configuration");
+
+	RWUNLOCK(&mdnconflock, isc_rwlocktype_write);
+
+	if (loaded) {
+		if ((conv = mdn_resconf_serverconverter(mdnconf)) != NULL &&
+		    !mdn_converter_isasciicompatible(conv)) {
+			logwrite(ISC_LOG_DEBUG(50),
+				 "allowing UTF-8 domain names");
+			allow_utf8 = ISC_TRUE;
+		} else {
+			allow_utf8 = ISC_FALSE;
+		}
+		dns_name_allowutf8(allow_utf8);
+	}
+
+	return (result);
+}
+
+static isc_result_t
+mdnresult_to_iscresult(mdn_result_t r) {
+	switch (r) {
+	case mdn_success:
+		return (ISC_R_SUCCESS);
+        case mdn_notfound:
+        case mdn_noentry:
+        case mdn_invalid_name:
+		return (ISC_R_NOTFOUND);
+        case mdn_buffer_overflow:
+		return (ISC_R_NOSPACE);
+        case mdn_nomemory:
+		return (ISC_R_NOMEMORY);
+        case mdn_nofile:
+		return (ISC_R_FILENOTFOUND);
+	default:
+		return (ISC_R_FAILURE);
+	}
+}
+
+static void
+set_log_level(int level) {
+	int loglevel;
+
+	if (level < ISC_LOG_ERROR) {
+		loglevel = mdn_log_level_fatal;
+	} else if (level < ISC_LOG_WARNING) {
+		loglevel = mdn_log_level_error;
+	} else if (level < ISC_LOG_INFO) {
+		loglevel = mdn_log_level_warning;
+	} else if (level < ISC_LOG_DEBUG(50)) {
+		loglevel = mdn_log_level_info;
+	} else if (level < ISC_LOG_DEBUG(100)) {
+		loglevel = mdn_log_level_trace;
+	} else {
+		loglevel = mdn_log_level_dump;
+	}
+	mdn_log_setlevel(loglevel);
+}
+
+static void
+logger(int level, const char *msg) {
+	int loglevel;
+	int msglen;
+
+	/*
+	 * Convert libmdn's log level to bind's log level.
+	 */
+	switch (level) {
+	case mdn_log_level_fatal:
+		loglevel = ISC_LOG_CRITICAL;
+		break;
+	case mdn_log_level_error:
+		loglevel = ISC_LOG_ERROR;
+		break;
+	case mdn_log_level_warning:
+		loglevel = ISC_LOG_WARNING;
+		break;
+	case mdn_log_level_info:
+		loglevel = ISC_LOG_INFO;
+		break;
+	case mdn_log_level_trace:
+		loglevel = ISC_LOG_DEBUG(50);	/* XXX */
+		break;
+	case mdn_log_level_dump:
+	default:
+		loglevel = ISC_LOG_DEBUG(100);	/* XXX */
+		break;
+	}
+
+	/*
+	 * Since libmdn's messages are end with newline, we have to
+	 * remove it.
+	 */
+	msglen = strlen(msg);
+	if (msglen > 0 && msg[msglen - 1] == '\n')
+		msglen--;
+
+	isc_log_write(ns_g_lctx, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_MDN,
+		      loglevel, "%.*s", msglen, msg);
+}
+
+static void
+logwrite(int level, const char *fmt, ...) {
+	va_list args;
+	
+	va_start(args, fmt);
+	isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_MDN,
+		       level, fmt, args);
+	va_end(args);
+}
+
+#endif /* WITH_MDN */
--- ./bin/named/lwresd.c.orig	Wed Jan 24 00:49:36 2001
+++ ./bin/named/lwresd.c	Wed Jan 24 01:22:45 2001
@@ -47,4 +47,7 @@
 #include <named/log.h>
 #include <named/lwaddr.h>
+#ifdef WITH_MDN
+#include <named/lwdmdn.h>
+#endif
 #include <named/lwresd.h>
 #include <named/lwdclient.h>
@@ -351,4 +354,11 @@
 		goto fail;
 	}
+
+#ifdef WITH_MDN
+	/*
+	 * Initialize MDN stuff.
+	 */
+	ns_lwdmdn_initialize();
+#endif
 
 	if (lwres->searchlist != NULL) {
--- ./bin/named/main.c.orig	Wed Jan 24 00:49:40 2001
+++ ./bin/named/main.c	Wed Jan 24 01:22:45 2001
@@ -278,5 +278,9 @@
 	isc_commandline_errprint = ISC_FALSE;
 	while ((ch = isc_commandline_parse(argc, argv,
+#ifdef WITH_MDN				/* Additional option 'M'. */
+					   "c:C:d:fgi:lM:n:N:p:P:st:u:vx:")) !=
+#else
 					   "c:C:d:fgi:ln:N:p:P:st:u:vx:")) !=
+#endif
 	       -1) {
 		switch (ch) {
@@ -312,4 +316,9 @@
 			ns_g_lwresdonly = ISC_TRUE;
 			break;
+#ifdef WITH_MDN
+		case 'M':
+			lwresd_g_mdnconffile = isc_commandline_argument;
+			break;
+#endif
 		case 'N': /* Deprecated. */
 		case 'n':
