Bug 694325: Add files for DNS Multithreading on Android; avoid undefined, unexposed libc symbols r=mwu
authorSteve Workman <sworkman@mozilla.com>
Mon, 05 Dec 2011 10:41:11 -0800
changeset 81481 7047e1d7c6de16a926bc8d3a3079a9563be77090
parent 81480 0706bf7b450804047fcf03d52c28d6a6a64fac65
child 81482 6bd88cb2f66551bd24b10faf679bd4eed2805be4
push idunknown
push userunknown
push dateunknown
reviewersmwu
bugs694325
milestone11.0a1
Bug 694325: Add files for DNS Multithreading on Android; avoid undefined, unexposed libc symbols r=mwu
configure.in
netwerk/dns/nsHostResolver.h
other-licenses/android/Makefile.in
other-licenses/android/arpa_nameser.h
other-licenses/android/arpa_nameser_compat.h
other-licenses/android/assertions.h
other-licenses/android/dst.h
other-licenses/android/ev_streams.c
other-licenses/android/ev_timers.c
other-licenses/android/eventlib.h
other-licenses/android/eventlib_p.h
other-licenses/android/getaddrinfo.c
other-licenses/android/heap.h
other-licenses/android/list.h
other-licenses/android/memcluster.h
other-licenses/android/ns_name.c
other-licenses/android/ns_netint.c
other-licenses/android/ns_parse.c
other-licenses/android/ns_print.c
other-licenses/android/ns_samedomain.c
other-licenses/android/ns_ttl.c
other-licenses/android/res_comp.c
other-licenses/android/res_data.c
other-licenses/android/res_debug.c
other-licenses/android/res_debug.h
other-licenses/android/res_init.c
other-licenses/android/res_mkquery.c
other-licenses/android/res_private.h
other-licenses/android/res_send.c
other-licenses/android/res_state.c
other-licenses/android/resolv_cache.h
other-licenses/android/resolv_private.h
other-licenses/android/resolv_static.h
xpcom/base/nsSystemInfo.cpp
--- a/configure.in
+++ b/configure.in
@@ -7274,17 +7274,17 @@ AC_SUBST(WIN32_CRT_LIBS)
 dnl Need to set this for make because NSS doesn't have configure
 AC_SUBST(DLLFLAGS)
 
 dnl We need to wrap dlopen and related functions on Android because we use
 dnl our own linker.
 if test "$OS_TARGET" = Android; then
     WRAP_LDFLAGS="${WRAP_LDFLAGS} -L$_objdir/dist/lib -lmozutils"
     if test "$MOZ_WIDGET_TOOLKIT" = android; then
-        WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=dlopen,--wrap=dlclose,--wrap=dlerror,--wrap=dlsym,--wrap=dladdr"
+        WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=dlopen,--wrap=dlclose,--wrap=dlerror,--wrap=dlsym,--wrap=dladdr,--wrap=getaddrinfo,--wrap=freeaddrinfo,--wrap=gai_strerror"
     fi
 fi
 
 dnl ========================================================
 dnl = Use malloc wrapper lib
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(wrap-malloc,
 [  --enable-wrap-malloc    Wrap malloc calls (gnu linker only)],
--- a/netwerk/dns/nsHostResolver.h
+++ b/netwerk/dns/nsHostResolver.h
@@ -66,29 +66,19 @@ class nsResolveHostCallback;
     PRInt32 Release() {                                                      \
         PRInt32 n = NS_AtomicDecrementRefcnt(_refc);                         \
         NS_LOG_RELEASE(this, n, #classname);                                 \
         if (n == 0)                                                          \
             delete this;                                                     \
         return n;                                                            \
     }
 
-#ifdef ANDROID
-// See bug 687367 - pre gingerbread android has race conditions involving stdio.
-// stdio is used as part of the getaddrinfo() implementation. In order to reduce
-// that race window limit ourselves to 1 lookup at a time on android.
-
-#define MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY  0
-#define MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY 1
-#define MAX_NON_PRIORITY_REQUESTS 0
-#else
 #define MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY  3
 #define MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY 5
 #define MAX_NON_PRIORITY_REQUESTS 150
-#endif
 
 #define MAX_RESOLVER_THREADS (MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY + \
                               MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY)
 
 struct nsHostKey
 {
     const char *host;
     PRUint16    flags;
--- a/other-licenses/android/Makefile.in
+++ b/other-licenses/android/Makefile.in
@@ -66,18 +66,34 @@ CPPSRCS = \
   nsGeckoUtils.cpp \
   APKOpen.cpp \
   $(NULL)
 
 CSRCS = \
   ba.c \
   debugger.c \
   dlfcn.c \
+  ev_streams.c \
+  ev_timers.c \
+  getaddrinfo.c \
   linker.c \
   linker_format.c \
+  ns_name.c \
+  ns_netint.c \
+  ns_parse.c \
+  ns_print.c \
+  ns_samedomain.c \
+  ns_ttl.c \
+  res_comp.c \
+  res_data.c \
+  res_debug.c \
+  res_init.c \
+  res_mkquery.c \
+  res_send.c \
+  res_state.c \
   rt.c \
   $(NULL)
 
 LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/components/startup
 
 EXPORTS = APKOpen.h
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/arpa_nameser.h
@@ -0,0 +1,587 @@
+/*	$NetBSD: nameser.h,v 1.19 2005/12/26 19:01:47 perry Exp $	*/
+
+/*
+ * Copyright (c) 1983, 1989, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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 DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ *	Id: nameser.h,v 1.2.2.4.4.1 2004/03/09 08:33:30 marka Exp
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#ifndef _ARPA_NAMESER_H_
+#define _ARPA_NAMESER_H_
+
+#define BIND_4_COMPAT
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+
+/*
+ * Revision information.  This is the release date in YYYYMMDD format.
+ * It can change every day so the right thing to do with it is use it
+ * in preprocessor commands such as "#if (__NAMESER > 19931104)".  Do not
+ * compare for equality; rather, use it to determine whether your libbind.a
+ * contains a new enough lib/nameser/ to support the feature you need.
+ */
+
+#define __NAMESER	19991006	/* New interface version stamp. */
+
+/*
+ * Define constants based on RFC 883, RFC 1034, RFC 1035
+ */
+#define NS_PACKETSZ	512	/* default UDP packet size */
+#define NS_MAXDNAME	1025	/* maximum domain name */
+#define NS_MAXMSG	65535	/* maximum message size */
+#define NS_MAXCDNAME	255	/* maximum compressed domain name */
+#define NS_MAXLABEL	63	/* maximum length of domain label */
+#define NS_HFIXEDSZ	12	/* #/bytes of fixed data in header */
+#define NS_QFIXEDSZ	4	/* #/bytes of fixed data in query */
+#define NS_RRFIXEDSZ	10	/* #/bytes of fixed data in r record */
+#define NS_INT32SZ	4	/* #/bytes of data in a uint32_t */
+#define NS_INT16SZ	2	/* #/bytes of data in a uint16_t */
+#define NS_INT8SZ	1	/* #/bytes of data in a uint8_t */
+#define NS_INADDRSZ	4	/* IPv4 T_A */
+#define NS_IN6ADDRSZ	16	/* IPv6 T_AAAA */
+#define NS_CMPRSFLGS	0xc0	/* Flag bits indicating name compression. */
+#define NS_DEFAULTPORT	53	/* For both TCP and UDP. */
+
+/*
+ * These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord()
+ * in synch with it.
+ */
+typedef enum __ns_sect {
+	ns_s_qd = 0,		/* Query: Question. */
+	ns_s_zn = 0,		/* Update: Zone. */
+	ns_s_an = 1,		/* Query: Answer. */
+	ns_s_pr = 1,		/* Update: Prerequisites. */
+	ns_s_ns = 2,		/* Query: Name servers. */
+	ns_s_ud = 2,		/* Update: Update. */
+	ns_s_ar = 3,		/* Query|Update: Additional records. */
+	ns_s_max = 4
+} ns_sect;
+
+/*
+ * This is a message handle.  It is caller allocated and has no dynamic data.
+ * This structure is intended to be opaque to all but ns_parse.c, thus the
+ * leading _'s on the member names.  Use the accessor functions, not the _'s.
+ */
+typedef struct __ns_msg {
+	const u_char	*_msg, *_eom;
+	uint16_t	_id, _flags, _counts[ns_s_max];
+	const u_char	*_sections[ns_s_max];
+	ns_sect		_sect;
+	int		_rrnum;
+	const u_char	*_msg_ptr;
+} ns_msg;
+
+/* Private data structure - do not use from outside library. */
+struct _ns_flagdata {  int mask, shift;  };
+extern const struct _ns_flagdata _ns_flagdata[];
+
+/* Accessor macros - this is part of the public interface. */
+
+#define ns_msg_id(handle) ((handle)._id + 0)
+#define ns_msg_base(handle) ((handle)._msg + 0)
+#define ns_msg_end(handle) ((handle)._eom + 0)
+#define ns_msg_size(handle) ((size_t)((handle)._eom - (handle)._msg))
+#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
+
+/*
+ * This is a parsed record.  It is caller allocated and has no dynamic data.
+ */
+typedef	struct __ns_rr {
+	char		name[NS_MAXDNAME];
+	uint16_t	type;
+	uint16_t	rr_class;
+	uint32_t	ttl;
+	uint16_t	rdlength;
+	const u_char *	rdata;
+} ns_rr;
+
+/* Accessor macros - this is part of the public interface. */
+#define ns_rr_name(rr)	(((rr).name[0] != '\0') ? (rr).name : ".")
+#define ns_rr_type(rr)	((ns_type)((rr).type + 0))
+#define ns_rr_class(rr)	((ns_class)((rr).rr_class + 0))
+#define ns_rr_ttl(rr)	((u_long)(rr).ttl + 0)
+#define ns_rr_rdlen(rr)	((size_t)(rr).rdlength + 0)
+#define ns_rr_rdata(rr)	((rr).rdata + 0)
+
+/*
+ * These don't have to be in the same order as in the packet flags word,
+ * and they can even overlap in some cases, but they will need to be kept
+ * in synch with ns_parse.c:ns_flagdata[].
+ */
+typedef enum __ns_flag {
+	ns_f_qr,		/* Question/Response. */
+	ns_f_opcode,		/* Operation code. */
+	ns_f_aa,		/* Authoritative Answer. */
+	ns_f_tc,		/* Truncation occurred. */
+	ns_f_rd,		/* Recursion Desired. */
+	ns_f_ra,		/* Recursion Available. */
+	ns_f_z,			/* MBZ. */
+	ns_f_ad,		/* Authentic Data (DNSSEC). */
+	ns_f_cd,		/* Checking Disabled (DNSSEC). */
+	ns_f_rcode,		/* Response code. */
+	ns_f_max
+} ns_flag;
+
+/*
+ * Currently defined opcodes.
+ */
+typedef enum __ns_opcode {
+	ns_o_query = 0,		/* Standard query. */
+	ns_o_iquery = 1,	/* Inverse query (deprecated/unsupported). */
+	ns_o_status = 2,	/* Name server status query (unsupported). */
+				/* Opcode 3 is undefined/reserved. */
+	ns_o_notify = 4,	/* Zone change notification. */
+	ns_o_update = 5,	/* Zone update message. */
+	ns_o_max = 6
+} ns_opcode;
+
+/*
+ * Currently defined response codes.
+ */
+typedef	enum __ns_rcode {
+	ns_r_noerror = 0,	/* No error occurred. */
+	ns_r_formerr = 1,	/* Format error. */
+	ns_r_servfail = 2,	/* Server failure. */
+	ns_r_nxdomain = 3,	/* Name error. */
+	ns_r_notimpl = 4,	/* Unimplemented. */
+	ns_r_refused = 5,	/* Operation refused. */
+	/* these are for BIND_UPDATE */
+	ns_r_yxdomain = 6,	/* Name exists */
+	ns_r_yxrrset = 7,	/* RRset exists */
+	ns_r_nxrrset = 8,	/* RRset does not exist */
+	ns_r_notauth = 9,	/* Not authoritative for zone */
+	ns_r_notzone = 10,	/* Zone of record different from zone section */
+	ns_r_max = 11,
+	/* The following are EDNS extended rcodes */
+	ns_r_badvers = 16,
+	/* The following are TSIG errors */
+	ns_r_badsig = 16,
+	ns_r_badkey = 17,
+	ns_r_badtime = 18
+} ns_rcode;
+
+/* BIND_UPDATE */
+typedef enum __ns_update_operation {
+	ns_uop_delete = 0,
+	ns_uop_add = 1,
+	ns_uop_max = 2
+} ns_update_operation;
+
+/*
+ * This structure is used for TSIG authenticated messages
+ */
+struct ns_tsig_key {
+        char name[NS_MAXDNAME], alg[NS_MAXDNAME];
+        unsigned char *data;
+        int len;
+};
+typedef struct ns_tsig_key ns_tsig_key;
+
+/*
+ * This structure is used for TSIG authenticated TCP messages
+ */
+struct ns_tcp_tsig_state {
+	int counter;
+	struct dst_key *key;
+	void *ctx;
+	unsigned char sig[NS_PACKETSZ];
+	int siglen;
+};
+typedef struct ns_tcp_tsig_state ns_tcp_tsig_state;
+
+#define NS_TSIG_FUDGE 300
+#define NS_TSIG_TCP_COUNT 100
+#define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT"
+
+#define NS_TSIG_ERROR_NO_TSIG -10
+#define NS_TSIG_ERROR_NO_SPACE -11
+#define NS_TSIG_ERROR_FORMERR -12
+
+/*
+ * Currently defined type values for resources and queries.
+ */
+typedef enum __ns_type {
+	ns_t_invalid = 0,	/* Cookie. */
+	ns_t_a = 1,		/* Host address. */
+	ns_t_ns = 2,		/* Authoritative server. */
+	ns_t_md = 3,		/* Mail destination. */
+	ns_t_mf = 4,		/* Mail forwarder. */
+	ns_t_cname = 5,		/* Canonical name. */
+	ns_t_soa = 6,		/* Start of authority zone. */
+	ns_t_mb = 7,		/* Mailbox domain name. */
+	ns_t_mg = 8,		/* Mail group member. */
+	ns_t_mr = 9,		/* Mail rename name. */
+	ns_t_null = 10,		/* Null resource record. */
+	ns_t_wks = 11,		/* Well known service. */
+	ns_t_ptr = 12,		/* Domain name pointer. */
+	ns_t_hinfo = 13,	/* Host information. */
+	ns_t_minfo = 14,	/* Mailbox information. */
+	ns_t_mx = 15,		/* Mail routing information. */
+	ns_t_txt = 16,		/* Text strings. */
+	ns_t_rp = 17,		/* Responsible person. */
+	ns_t_afsdb = 18,	/* AFS cell database. */
+	ns_t_x25 = 19,		/* X_25 calling address. */
+	ns_t_isdn = 20,		/* ISDN calling address. */
+	ns_t_rt = 21,		/* Router. */
+	ns_t_nsap = 22,		/* NSAP address. */
+	ns_t_nsap_ptr = 23,	/* Reverse NSAP lookup (deprecated). */
+	ns_t_sig = 24,		/* Security signature. */
+	ns_t_key = 25,		/* Security key. */
+	ns_t_px = 26,		/* X.400 mail mapping. */
+	ns_t_gpos = 27,		/* Geographical position (withdrawn). */
+	ns_t_aaaa = 28,		/* Ip6 Address. */
+	ns_t_loc = 29,		/* Location Information. */
+	ns_t_nxt = 30,		/* Next domain (security). */
+	ns_t_eid = 31,		/* Endpoint identifier. */
+	ns_t_nimloc = 32,	/* Nimrod Locator. */
+	ns_t_srv = 33,		/* Server Selection. */
+	ns_t_atma = 34,		/* ATM Address */
+	ns_t_naptr = 35,	/* Naming Authority PoinTeR */
+	ns_t_kx = 36,		/* Key Exchange */
+	ns_t_cert = 37,		/* Certification record */
+	ns_t_a6 = 38,		/* IPv6 address (deprecates AAAA) */
+	ns_t_dname = 39,	/* Non-terminal DNAME (for IPv6) */
+	ns_t_sink = 40,		/* Kitchen sink (experimentatl) */
+	ns_t_opt = 41,		/* EDNS0 option (meta-RR) */
+	ns_t_apl = 42,		/* Address prefix list (RFC 3123) */
+	ns_t_tkey = 249,	/* Transaction key */
+	ns_t_tsig = 250,	/* Transaction signature. */
+	ns_t_ixfr = 251,	/* Incremental zone transfer. */
+	ns_t_axfr = 252,	/* Transfer zone of authority. */
+	ns_t_mailb = 253,	/* Transfer mailbox records. */
+	ns_t_maila = 254,	/* Transfer mail agent records. */
+	ns_t_any = 255,		/* Wildcard match. */
+	ns_t_zxfr = 256,	/* BIND-specific, nonstandard. */
+	ns_t_max = 65536
+} ns_type;
+
+/* Exclusively a QTYPE? (not also an RTYPE) */
+#define	ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \
+		      (t) == ns_t_mailb || (t) == ns_t_maila)
+/* Some kind of meta-RR? (not a QTYPE, but also not an RTYPE) */
+#define	ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt)
+/* Exclusively an RTYPE? (not also a QTYPE or a meta-RR) */
+#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t))
+#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr)
+#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \
+		       (t) == ns_t_zxfr)
+
+/*
+ * Values for class field
+ */
+typedef enum __ns_class {
+	ns_c_invalid = 0,	/* Cookie. */
+	ns_c_in = 1,		/* Internet. */
+	ns_c_2 = 2,		/* unallocated/unsupported. */
+	ns_c_chaos = 3,		/* MIT Chaos-net. */
+	ns_c_hs = 4,		/* MIT Hesiod. */
+	/* Query class values which do not appear in resource records */
+	ns_c_none = 254,	/* for prereq. sections in update requests */
+	ns_c_any = 255,		/* Wildcard match. */
+	ns_c_max = 65536
+} ns_class;
+
+/* DNSSEC constants. */
+
+typedef enum __ns_key_types {
+	ns_kt_rsa = 1,		/* key type RSA/MD5 */
+	ns_kt_dh  = 2,		/* Diffie Hellman */
+	ns_kt_dsa = 3,		/* Digital Signature Standard (MANDATORY) */
+	ns_kt_private = 254	/* Private key type starts with OID */
+} ns_key_types;
+
+typedef enum __ns_cert_types {
+	cert_t_pkix = 1,	/* PKIX (X.509v3) */
+	cert_t_spki = 2,	/* SPKI */
+	cert_t_pgp  = 3,	/* PGP */
+	cert_t_url  = 253,	/* URL private type */
+	cert_t_oid  = 254	/* OID private type */
+} ns_cert_types;
+
+/* Flags field of the KEY RR rdata. */
+#define	NS_KEY_TYPEMASK		0xC000	/* Mask for "type" bits */
+#define	NS_KEY_TYPE_AUTH_CONF	0x0000	/* Key usable for both */
+#define	NS_KEY_TYPE_CONF_ONLY	0x8000	/* Key usable for confidentiality */
+#define	NS_KEY_TYPE_AUTH_ONLY	0x4000	/* Key usable for authentication */
+#define	NS_KEY_TYPE_NO_KEY	0xC000	/* No key usable for either; no key */
+/* The type bits can also be interpreted independently, as single bits: */
+#define	NS_KEY_NO_AUTH		0x8000	/* Key unusable for authentication */
+#define	NS_KEY_NO_CONF		0x4000	/* Key unusable for confidentiality */
+#define	NS_KEY_RESERVED2	0x2000	/* Security is *mandatory* if bit=0 */
+#define	NS_KEY_EXTENDED_FLAGS	0x1000	/* reserved - must be zero */
+#define	NS_KEY_RESERVED4	0x0800  /* reserved - must be zero */
+#define	NS_KEY_RESERVED5	0x0400  /* reserved - must be zero */
+#define	NS_KEY_NAME_TYPE	0x0300	/* these bits determine the type */
+#define	NS_KEY_NAME_USER	0x0000	/* key is assoc. with user */
+#define	NS_KEY_NAME_ENTITY	0x0200	/* key is assoc. with entity eg host */
+#define	NS_KEY_NAME_ZONE	0x0100	/* key is zone key */
+#define	NS_KEY_NAME_RESERVED	0x0300	/* reserved meaning */
+#define	NS_KEY_RESERVED8	0x0080  /* reserved - must be zero */
+#define	NS_KEY_RESERVED9	0x0040  /* reserved - must be zero */
+#define	NS_KEY_RESERVED10	0x0020  /* reserved - must be zero */
+#define	NS_KEY_RESERVED11	0x0010  /* reserved - must be zero */
+#define	NS_KEY_SIGNATORYMASK	0x000F	/* key can sign RR's of same name */
+#define	NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \
+				  NS_KEY_RESERVED4 | \
+				  NS_KEY_RESERVED5 | \
+				  NS_KEY_RESERVED8 | \
+				  NS_KEY_RESERVED9 | \
+				  NS_KEY_RESERVED10 | \
+				  NS_KEY_RESERVED11 )
+#define NS_KEY_RESERVED_BITMASK2 0xFFFF /* no bits defined here */
+
+/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */
+#define	NS_ALG_MD5RSA		1	/* MD5 with RSA */
+#define	NS_ALG_DH               2	/* Diffie Hellman KEY */
+#define	NS_ALG_DSA              3	/* DSA KEY */
+#define	NS_ALG_DSS              NS_ALG_DSA
+#define	NS_ALG_EXPIRE_ONLY	253	/* No alg, no security */
+#define	NS_ALG_PRIVATE_OID	254	/* Key begins with OID giving alg */
+
+/* Protocol values  */
+/* value 0 is reserved */
+#define NS_KEY_PROT_TLS         1
+#define NS_KEY_PROT_EMAIL       2
+#define NS_KEY_PROT_DNSSEC      3
+#define NS_KEY_PROT_IPSEC       4
+#define NS_KEY_PROT_ANY		255
+
+/* Signatures */
+#define	NS_MD5RSA_MIN_BITS	 512	/* Size of a mod or exp in bits */
+#define	NS_MD5RSA_MAX_BITS	4096
+	/* Total of binary mod and exp */
+#define	NS_MD5RSA_MAX_BYTES	((NS_MD5RSA_MAX_BITS+7/8)*2+3)
+	/* Max length of text sig block */
+#define	NS_MD5RSA_MAX_BASE64	(((NS_MD5RSA_MAX_BYTES+2)/3)*4)
+#define NS_MD5RSA_MIN_SIZE	((NS_MD5RSA_MIN_BITS+7)/8)
+#define NS_MD5RSA_MAX_SIZE	((NS_MD5RSA_MAX_BITS+7)/8)
+
+#define NS_DSA_SIG_SIZE         41
+#define NS_DSA_MIN_SIZE         213
+#define NS_DSA_MAX_BYTES        405
+
+/* Offsets into SIG record rdata to find various values */
+#define	NS_SIG_TYPE	0	/* Type flags */
+#define	NS_SIG_ALG	2	/* Algorithm */
+#define	NS_SIG_LABELS	3	/* How many labels in name */
+#define	NS_SIG_OTTL	4	/* Original TTL */
+#define	NS_SIG_EXPIR	8	/* Expiration time */
+#define	NS_SIG_SIGNED	12	/* Signature time */
+#define	NS_SIG_FOOT	16	/* Key footprint */
+#define	NS_SIG_SIGNER	18	/* Domain name of who signed it */
+
+/* How RR types are represented as bit-flags in NXT records */
+#define	NS_NXT_BITS 8
+#define	NS_NXT_BIT_SET(  n,p) (p[(n)/NS_NXT_BITS] |=  (0x80>>((n)%NS_NXT_BITS)))
+#define	NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS)))
+#define	NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] &   (0x80>>((n)%NS_NXT_BITS)))
+#define NS_NXT_MAX 127
+
+/*
+ * EDNS0 extended flags, host order.
+ */
+#define NS_OPT_DNSSEC_OK	0x8000U
+
+/*
+ * Inline versions of get/put short/long.  Pointer is advanced.
+ */
+#define NS_GET16(s, cp) do { \
+	const u_char *t_cp = (const u_char *)(cp); \
+	(s) = ((uint16_t)t_cp[0] << 8) \
+	    | ((uint16_t)t_cp[1]) \
+	    ; \
+	(cp) += NS_INT16SZ; \
+} while (/*CONSTCOND*/0)
+
+#define NS_GET32(l, cp) do { \
+	const u_char *t_cp = (const u_char *)(cp); \
+	(l) = ((uint32_t)t_cp[0] << 24) \
+	    | ((uint32_t)t_cp[1] << 16) \
+	    | ((uint32_t)t_cp[2] << 8) \
+	    | ((uint32_t)t_cp[3]) \
+	    ; \
+	(cp) += NS_INT32SZ; \
+} while (/*CONSTCOND*/0)
+
+#define NS_PUT16(s, cp) do { \
+	uint32_t t_s = (uint32_t)(s); \
+	u_char *t_cp = (u_char *)(cp); \
+	*t_cp++ = t_s >> 8; \
+	*t_cp   = t_s; \
+	(cp) += NS_INT16SZ; \
+} while (/*CONSTCOND*/0)
+
+#define NS_PUT32(l, cp) do { \
+	uint32_t t_l = (uint32_t)(l); \
+	u_char *t_cp = (u_char *)(cp); \
+	*t_cp++ = t_l >> 24; \
+	*t_cp++ = t_l >> 16; \
+	*t_cp++ = t_l >> 8; \
+	*t_cp   = t_l; \
+	(cp) += NS_INT32SZ; \
+} while (/*CONSTCOND*/0)
+
+/*
+ * ANSI C identifier hiding for bind's lib/nameser.
+ */
+#define	ns_msg_getflag		__ns_msg_getflag
+#define ns_get16		__ns_get16
+#define ns_get32		__ns_get32
+#define ns_put16		__ns_put16
+#define ns_put32		__ns_put32
+#define ns_initparse		__ns_initparse
+#define ns_skiprr		__ns_skiprr
+#define ns_parserr		__ns_parserr
+#define	ns_sprintrr		__ns_sprintrr
+#define	ns_sprintrrf		__ns_sprintrrf
+#define	ns_format_ttl		__ns_format_ttl
+#define	ns_parse_ttl		__ns_parse_ttl
+#define ns_datetosecs		__ns_datetosecs
+#define	ns_name_ntol		__ns_name_ntol
+#define	ns_name_ntop		__ns_name_ntop
+#define	ns_name_pton		__ns_name_pton
+#define	ns_name_unpack		__ns_name_unpack
+#define	ns_name_pack		__ns_name_pack
+#define	ns_name_compress	__ns_name_compress
+#define	ns_name_uncompress	__ns_name_uncompress
+#define	ns_name_skip		__ns_name_skip
+#define	ns_name_rollback	__ns_name_rollback
+#define	ns_sign			__ns_sign
+#define	ns_sign2		__ns_sign2
+#define	ns_sign_tcp		__ns_sign_tcp
+#define	ns_sign_tcp2		__ns_sign_tcp2
+#define	ns_sign_tcp_init	__ns_sign_tcp_init
+#define ns_find_tsig		__ns_find_tsig
+#define	ns_verify		__ns_verify
+#define	ns_verify_tcp		__ns_verify_tcp
+#define	ns_verify_tcp_init	__ns_verify_tcp_init
+#define	ns_samedomain		__ns_samedomain
+#define	ns_subdomain		__ns_subdomain
+#define	ns_makecanon		__ns_makecanon
+#define	ns_samename		__ns_samename
+
+__BEGIN_DECLS
+int		ns_msg_getflag(ns_msg, int);
+uint16_t	ns_get16(const u_char *);
+uint32_t	ns_get32(const u_char *);
+void		ns_put16(uint16_t, u_char *);
+void		ns_put32(uint32_t, u_char *);
+int		ns_initparse(const u_char *, int, ns_msg *);
+int		ns_skiprr(const u_char *, const u_char *, ns_sect, int);
+int		ns_parserr(ns_msg *, ns_sect, int, ns_rr *);
+int		ns_sprintrr(const ns_msg *, const ns_rr *,
+				 const char *, const char *, char *, size_t);
+int		ns_sprintrrf(const u_char *, size_t, const char *,
+				  ns_class, ns_type, u_long, const u_char *,
+				  size_t, const char *, const char *,
+				  char *, size_t);
+int		ns_format_ttl(u_long, char *, size_t);
+int		ns_parse_ttl(const char *, u_long *);
+uint32_t	ns_datetosecs(const char *cp, int *errp);
+int		ns_name_ntol(const u_char *, u_char *, size_t);
+int		ns_name_ntop(const u_char *, char *, size_t);
+int		ns_name_pton(const char *, u_char *, size_t);
+int		ns_name_unpack(const u_char *, const u_char *,
+				    const u_char *, u_char *, size_t);
+int		ns_name_pack(const u_char *, u_char *, int,
+				  const u_char **, const u_char **);
+int		ns_name_uncompress(const u_char *, const u_char *,
+					const u_char *, char *, size_t);
+int		ns_name_compress(const char *, u_char *, size_t,
+				      const u_char **, const u_char **);
+int		ns_name_skip(const u_char **, const u_char *);
+void		ns_name_rollback(const u_char *, const u_char **,
+				      const u_char **);
+int		ns_sign(u_char *, int *, int, int, void *,
+			     const u_char *, int, u_char *, int *, time_t);
+int		ns_sign2(u_char *, int *, int, int, void *,
+			      const u_char *, int, u_char *, int *, time_t,
+			      u_char **, u_char **);
+int		ns_sign_tcp(u_char *, int *, int, int,
+				 ns_tcp_tsig_state *, int);
+int		ns_sign_tcp2(u_char *, int *, int, int,
+				  ns_tcp_tsig_state *, int,
+				  u_char **, u_char **);
+int		ns_sign_tcp_init(void *, const u_char *, int,
+					ns_tcp_tsig_state *);
+u_char		*ns_find_tsig(u_char *, u_char *);
+int		ns_verify(u_char *, int *, void *,
+			       const u_char *, int, u_char *, int *,
+			       time_t *, int);
+int		ns_verify_tcp(u_char *, int *, ns_tcp_tsig_state *, int);
+int		ns_verify_tcp_init(void *, const u_char *, int,
+					ns_tcp_tsig_state *);
+int		ns_samedomain(const char *, const char *);
+int		ns_subdomain(const char *, const char *);
+int		ns_makecanon(const char *, char *, size_t);
+int		ns_samename(const char *, const char *);
+__END_DECLS
+
+#ifdef BIND_4_COMPAT
+#include "arpa_nameser_compat.h"
+#endif
+
+#if 0
+#  include <logd.h>
+#  define  XLOG(...)   \
+    __libc_android_log_print(ANDROID_LOG_DEBUG,"libc",__VA_ARGS__)
+#else
+#define  XLOG(...)   do {} while (0)
+#endif
+
+#endif /* !_ARPA_NAMESER_H_ */
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/arpa_nameser_compat.h
@@ -0,0 +1,246 @@
+/*	$NetBSD: nameser_compat.h,v 1.1.1.2 2004/11/07 01:28:27 christos Exp $	*/
+
+/* Copyright (c) 1983, 1989
+ *    The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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 DAMAGE.
+ */
+
+/*
+ *      from nameser.h	8.1 (Berkeley) 6/2/93
+ *	Id: nameser_compat.h,v 1.1.2.3.4.2 2004/07/01 04:43:41 marka Exp
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#ifndef _ARPA_NAMESER_COMPAT_
+#define	_ARPA_NAMESER_COMPAT_
+
+#define	__BIND		19950621	/* (DEAD) interface version stamp. */
+
+#include <endian.h>
+
+#ifndef BYTE_ORDER
+#if (BSD >= 199103)
+# include <machine/endian.h>
+#else
+#ifdef __linux
+# include <endian.h>
+#else
+#define	LITTLE_ENDIAN	1234	/* least-significant byte first (vax, pc) */
+#define	BIG_ENDIAN	4321	/* most-significant byte first (IBM, net) */
+#define	PDP_ENDIAN	3412	/* LSB first in word, MSW first in long (pdp)*/
+
+#if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \
+    defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \
+    defined(__alpha__) || defined(__alpha) || \
+    (defined(__Lynx__) && defined(__x86__))
+#define BYTE_ORDER	LITTLE_ENDIAN
+#endif
+
+#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \
+    defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \
+    defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\
+    defined(apollo) || defined(__convex__) || defined(_CRAY) || \
+    defined(__hppa) || defined(__hp9000) || \
+    defined(__hp9000s300) || defined(__hp9000s700) || \
+    defined(__hp3000s900) || defined(__hpux) || defined(MPE) || \
+    defined (BIT_ZERO_ON_LEFT) || defined(m68k) || defined(__sparc) ||  \
+    (defined(__Lynx__) && \
+     (defined(__68k__) || defined(__sparc__) || defined(__powerpc__)))
+#define BYTE_ORDER	BIG_ENDIAN
+#endif
+#endif /* __linux */
+#endif /* BSD */
+#endif /* BYTE_ORDER */
+
+#if !defined(BYTE_ORDER) || \
+    (BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN && \
+    BYTE_ORDER != PDP_ENDIAN)
+	/* you must determine what the correct bit order is for
+	 * your compiler - the next line is an intentional error
+	 * which will force your compiles to bomb until you fix
+	 * the above macros.
+	 */
+  #error "Undefined or invalid BYTE_ORDER";
+#endif
+
+/*
+ * Structure for query header.  The order of the fields is machine- and
+ * compiler-dependent, depending on the byte/bit order and the layout
+ * of bit fields.  We use bit fields only in int variables, as this
+ * is all ANSI requires.  This requires a somewhat confusing rearrangement.
+ */
+
+typedef struct {
+	unsigned	id :16;		/* query identification number */
+#if BYTE_ORDER == BIG_ENDIAN
+			/* fields in third byte */
+	unsigned	qr: 1;		/* response flag */
+	unsigned	opcode: 4;	/* purpose of message */
+	unsigned	aa: 1;		/* authoritive answer */
+	unsigned	tc: 1;		/* truncated message */
+	unsigned	rd: 1;		/* recursion desired */
+			/* fields in fourth byte */
+	unsigned	ra: 1;		/* recursion available */
+	unsigned	unused :1;	/* unused bits (MBZ as of 4.9.3a3) */
+	unsigned	ad: 1;		/* authentic data from named */
+	unsigned	cd: 1;		/* checking disabled by resolver */
+	unsigned	rcode :4;	/* response code */
+#endif
+#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
+			/* fields in third byte */
+	unsigned	rd :1;		/* recursion desired */
+	unsigned	tc :1;		/* truncated message */
+	unsigned	aa :1;		/* authoritive answer */
+	unsigned	opcode :4;	/* purpose of message */
+	unsigned	qr :1;		/* response flag */
+			/* fields in fourth byte */
+	unsigned	rcode :4;	/* response code */
+	unsigned	cd: 1;		/* checking disabled by resolver */
+	unsigned	ad: 1;		/* authentic data from named */
+	unsigned	unused :1;	/* unused bits (MBZ as of 4.9.3a3) */
+	unsigned	ra :1;		/* recursion available */
+#endif
+			/* remaining bytes */
+	unsigned	qdcount :16;	/* number of question entries */
+	unsigned	ancount :16;	/* number of answer entries */
+	unsigned	nscount :16;	/* number of authority entries */
+	unsigned	arcount :16;	/* number of resource entries */
+} HEADER;
+
+#define PACKETSZ	NS_PACKETSZ
+#define MAXDNAME	NS_MAXDNAME
+#define MAXCDNAME	NS_MAXCDNAME
+#define MAXLABEL	NS_MAXLABEL
+#define	HFIXEDSZ	NS_HFIXEDSZ
+#define QFIXEDSZ	NS_QFIXEDSZ
+#define RRFIXEDSZ	NS_RRFIXEDSZ
+#define	INT32SZ		NS_INT32SZ
+#define	INT16SZ		NS_INT16SZ
+#define	INT8SZ		NS_INT8SZ
+#define	INADDRSZ	NS_INADDRSZ
+#define	IN6ADDRSZ	NS_IN6ADDRSZ
+#define	INDIR_MASK	NS_CMPRSFLGS
+#define NAMESERVER_PORT	NS_DEFAULTPORT
+
+#define S_ZONE		ns_s_zn
+#define S_PREREQ	ns_s_pr
+#define S_UPDATE	ns_s_ud
+#define S_ADDT		ns_s_ar
+
+#define QUERY		ns_o_query
+#define IQUERY		ns_o_iquery
+#define STATUS		ns_o_status
+#define	NS_NOTIFY_OP	ns_o_notify
+#define	NS_UPDATE_OP	ns_o_update
+
+#define NOERROR		ns_r_noerror
+#define FORMERR		ns_r_formerr
+#define SERVFAIL	ns_r_servfail
+#define NXDOMAIN	ns_r_nxdomain
+#define NOTIMP		ns_r_notimpl
+#define REFUSED		ns_r_refused
+#define YXDOMAIN	ns_r_yxdomain
+#define YXRRSET		ns_r_yxrrset
+#define NXRRSET		ns_r_nxrrset
+#define NOTAUTH		ns_r_notauth
+#define NOTZONE		ns_r_notzone
+/*#define BADSIG		ns_r_badsig*/
+/*#define BADKEY		ns_r_badkey*/
+/*#define BADTIME		ns_r_badtime*/
+
+
+#define DELETE		ns_uop_delete
+#define ADD		ns_uop_add
+
+#define T_A		ns_t_a
+#define T_NS		ns_t_ns
+#define T_MD		ns_t_md
+#define T_MF		ns_t_mf
+#define T_CNAME		ns_t_cname
+#define T_SOA		ns_t_soa
+#define T_MB		ns_t_mb
+#define T_MG		ns_t_mg
+#define T_MR		ns_t_mr
+#define T_NULL		ns_t_null
+#define T_WKS		ns_t_wks
+#define T_PTR		ns_t_ptr
+#define T_HINFO		ns_t_hinfo
+#define T_MINFO		ns_t_minfo
+#define T_MX		ns_t_mx
+#define T_TXT		ns_t_txt
+#define	T_RP		ns_t_rp
+#define T_AFSDB		ns_t_afsdb
+#define T_X25		ns_t_x25
+#define T_ISDN		ns_t_isdn
+#define T_RT		ns_t_rt
+#define T_NSAP		ns_t_nsap
+#define T_NSAP_PTR	ns_t_nsap_ptr
+#define	T_SIG		ns_t_sig
+#define	T_KEY		ns_t_key
+#define	T_PX		ns_t_px
+#define	T_GPOS		ns_t_gpos
+#define	T_AAAA		ns_t_aaaa
+#define	T_LOC		ns_t_loc
+#define	T_NXT		ns_t_nxt
+#define	T_EID		ns_t_eid
+#define	T_NIMLOC	ns_t_nimloc
+#define	T_SRV		ns_t_srv
+#define T_ATMA		ns_t_atma
+#define T_NAPTR		ns_t_naptr
+#define T_A6		ns_t_a6
+#define	T_TSIG		ns_t_tsig
+#define	T_IXFR		ns_t_ixfr
+#define T_AXFR		ns_t_axfr
+#define T_MAILB		ns_t_mailb
+#define T_MAILA		ns_t_maila
+#define T_ANY		ns_t_any
+
+#define C_IN		ns_c_in
+#define C_CHAOS		ns_c_chaos
+#define C_HS		ns_c_hs
+/* BIND_UPDATE */
+#define C_NONE		ns_c_none
+#define C_ANY		ns_c_any
+
+#define	GETSHORT		NS_GET16
+#define	GETLONG			NS_GET32
+#define	PUTSHORT		NS_PUT16
+#define	PUTLONG			NS_PUT32
+
+#endif /* _ARPA_NAMESER_COMPAT_ */
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/assertions.h
@@ -0,0 +1,134 @@
+/*	$NetBSD: assertions.h,v 1.1.1.1 2004/05/20 19:49:41 christos Exp $	*/
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1997-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Id: assertions.h,v 1.1.206.1 2004/03/09 08:33:30 marka Exp
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#ifndef ASSERTIONS_H
+#define ASSERTIONS_H		1
+
+typedef enum {
+	assert_require, assert_ensure, assert_insist, assert_invariant
+} assertion_type;
+
+typedef void (*assertion_failure_callback)(const char *, int, assertion_type,
+					   const char *, int);
+
+extern assertion_failure_callback __assertion_failed;
+void set_assertion_failure_callback(assertion_failure_callback f);
+const char *assertion_type_to_text(assertion_type type);
+
+#ifdef CHECK_ALL
+#define CHECK_REQUIRE		1
+#define CHECK_ENSURE		1
+#define CHECK_INSIST		1
+#define CHECK_INVARIANT		1
+#endif
+
+#ifdef CHECK_NONE
+#define CHECK_REQUIRE		0
+#define CHECK_ENSURE		0
+#define CHECK_INSIST		0
+#define CHECK_INVARIANT		0
+#endif
+
+#ifndef CHECK_REQUIRE
+#define CHECK_REQUIRE		1
+#endif
+
+#ifndef CHECK_ENSURE
+#define CHECK_ENSURE		1
+#endif
+
+#ifndef CHECK_INSIST
+#define CHECK_INSIST		1
+#endif
+
+#ifndef CHECK_INVARIANT
+#define CHECK_INVARIANT		1
+#endif
+
+#if CHECK_REQUIRE != 0
+#define REQUIRE(cond) \
+	((void) ((cond) || \
+		 ((__assertion_failed)(__FILE__, __LINE__, assert_require, \
+				       #cond, 0), 0)))
+#define REQUIRE_ERR(cond) \
+	((void) ((cond) || \
+		 ((__assertion_failed)(__FILE__, __LINE__, assert_require, \
+				       #cond, 1), 0)))
+#else
+#define REQUIRE(cond)		((void) (cond))
+#define REQUIRE_ERR(cond)	((void) (cond))
+#endif /* CHECK_REQUIRE */
+
+#if CHECK_ENSURE != 0
+#define ENSURE(cond) \
+	((void) ((cond) || \
+		 ((__assertion_failed)(__FILE__, __LINE__, assert_ensure, \
+				       #cond, 0), 0)))
+#define ENSURE_ERR(cond) \
+	((void) ((cond) || \
+		 ((__assertion_failed)(__FILE__, __LINE__, assert_ensure, \
+				       #cond, 1), 0)))
+#else
+#define ENSURE(cond)		((void) (cond))
+#define ENSURE_ERR(cond)	((void) (cond))
+#endif /* CHECK_ENSURE */
+
+#if CHECK_INSIST != 0
+#define INSIST(cond) \
+	((void) ((cond) || \
+		 ((__assertion_failed)(__FILE__, __LINE__, assert_insist, \
+				       #cond, 0), 0)))
+#define INSIST_ERR(cond) \
+	((void) ((cond) || \
+		 ((__assertion_failed)(__FILE__, __LINE__, assert_insist, \
+				       #cond, 1), 0)))
+#else
+#define INSIST(cond)		((void) (cond))
+#define INSIST_ERR(cond)	((void) (cond))
+#endif /* CHECK_INSIST */
+
+#if CHECK_INVARIANT != 0
+#define INVARIANT(cond) \
+	((void) ((cond) || \
+		 ((__assertion_failed)(__FILE__, __LINE__, assert_invariant, \
+				       #cond, 0), 0)))
+#define INVARIANT_ERR(cond) \
+	((void) ((cond) || \
+		 ((__assertion_failed)(__FILE__, __LINE__, assert_invariant, \
+				       #cond, 1), 0)))
+#else
+#define INVARIANT(cond)		((void) (cond))
+#define INVARIANT_ERR(cond)	((void) (cond))
+#endif /* CHECK_INVARIANT */
+
+#endif /* ASSERTIONS_H */
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/dst.h
@@ -0,0 +1,192 @@
+/*	$NetBSD: dst.h,v 1.1.1.1 2004/05/20 19:49:41 christos Exp $	*/
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#ifndef DST_H
+#define DST_H
+
+#ifndef HAS_DST_KEY
+typedef struct dst_key {
+	char	*dk_key_name;   /* name of the key */
+	int	dk_key_size;    /* this is the size of the key in bits */
+	int	dk_proto;       /* what protocols this key can be used for */
+	int	dk_alg;         /* algorithm number from key record */
+	u_int32_t dk_flags;     /* and the flags of the public key */
+	u_int16_t dk_id;        /* identifier of the key */
+} DST_KEY;
+#endif /* HAS_DST_KEY */
+
+/*
+ * do not taint namespace
+ */
+#define	dst_bsafe_init		__dst_bsafe_init
+#define	dst_buffer_to_key	__dst_buffer_to_key
+#define	dst_check_algorithm	__dst_check_algorithm
+#define	dst_compare_keys	__dst_compare_keys
+#define	dst_cylink_init		__dst_cylink_init
+#define	dst_dnskey_to_key	__dst_dnskey_to_key
+#define	dst_eay_dss_init	__dst_eay_dss_init
+#define	dst_free_key		__dst_free_key
+#define	dst_generate_key	__dst_generate_key
+#define	dst_hmac_md5_init	__dst_hmac_md5_init
+#define	dst_init		__dst_init
+#define	dst_key_to_buffer	__dst_key_to_buffer
+#define	dst_key_to_dnskey	__dst_key_to_dnskey
+#define	dst_read_key		__dst_read_key
+#define	dst_rsaref_init		__dst_rsaref_init
+#define	dst_s_build_filename	__dst_s_build_filename
+#define	dst_s_calculate_bits	__dst_s_calculate_bits
+#define	dst_s_conv_bignum_b64_to_u8	__dst_s_conv_bignum_b64_to_u8
+#define	dst_s_conv_bignum_u8_to_b64	__dst_s_conv_bignum_u8_to_b64
+#define	dst_s_dns_key_id	__dst_s_dns_key_id
+#define	dst_s_dump		__dst_s_dump
+#define	dst_s_filename_length	__dst_s_filename_length
+#define	dst_s_fopen		__dst_s_fopen
+#define	dst_s_get_int16		__dst_s_get_int16
+#define	dst_s_get_int32		__dst_s_get_int32
+#define	dst_s_id_calc		__dst_s_id_calc
+#define	dst_s_put_int16		__dst_s_put_int16
+#define	dst_s_put_int32		__dst_s_put_int32
+#define	dst_s_quick_random	__dst_s_quick_random
+#define	dst_s_quick_random_set	__dst_s_quick_random_set
+#define	dst_s_random		__dst_s_random
+#define	dst_s_semi_random	__dst_s_semi_random
+#define	dst_s_verify_str	__dst_s_verify_str
+#define	dst_sig_size		__dst_sig_size
+#define	dst_sign_data		__dst_sign_data
+#define	dst_verify_data		__dst_verify_data
+#define	dst_write_key		__dst_write_key
+
+/* 
+ * DST Crypto API defintions 
+ */
+void     dst_init(void);
+int      dst_check_algorithm(const int);
+
+int dst_sign_data(const int,	 	/* specifies INIT/UPDATE/FINAL/ALL */
+		  DST_KEY *,	 	/* the key to use */
+		  void **,	 	/* pointer to state structure */
+		  const u_char *,	/* data to be signed */
+		  const int,	 	/* length of input data */
+		  u_char *,	 	/* buffer to write signature to */
+		  const int);	 	/* size of output buffer */
+
+int dst_verify_data(const int,	 	/* specifies INIT/UPDATE/FINAL/ALL */
+		    DST_KEY *,	 	/* the key to use */
+		    void **,	 	/* pointer to state structure */
+		    const u_char *,	/* data to be verified */
+		    const int,	 	/* length of input data */
+		    const u_char *,	/* buffer containing signature */
+		    const int);	 	/* length of signature */
+
+
+DST_KEY *dst_read_key(const char *,	/* name of key */
+		      const u_int16_t,	/* key tag identifier */
+		      const int,	/* key algorithm */
+		      const int);	/* Private/PublicKey wanted*/
+
+int      dst_write_key(const DST_KEY *,	/* key to write out */
+		       const int); 	/* Public/Private */
+
+DST_KEY *dst_dnskey_to_key(const char *,	/* KEY record name */
+			   const u_char *,	/* KEY RDATA */
+			   const int);		/* size of input buffer*/
+
+
+int      dst_key_to_dnskey(const DST_KEY *,	/* key to translate */
+			   u_char *,		/* output buffer */
+			   const int);		/* size of out_storage*/
+
+
+DST_KEY *dst_buffer_to_key(const char *,  	/* name of the key */
+			   const int,	  	/* algorithm */
+			   const int,	  	/* dns flags */
+			   const int,	  	/* dns protocol */
+			   const u_char *, 	/* key in dns wire fmt */
+			   const int);	  	/* size of key */
+
+
+int     dst_key_to_buffer(DST_KEY *, u_char *, int);
+
+DST_KEY *dst_generate_key(const char *,    	/* name of new key */
+			  const int,       	/* key algorithm to generate */
+			  const int,      	/* size of new key */
+			  const int,       	/* alg dependent parameter*/
+			  const int,     	/* key DNS flags */
+			  const int);		/* key DNS protocol */
+
+DST_KEY *dst_free_key(DST_KEY *);
+int      dst_compare_keys(const DST_KEY *, const DST_KEY *);
+
+int	dst_sig_size(DST_KEY *);
+
+
+/* support for dns key tags/ids */
+u_int16_t dst_s_dns_key_id(const u_char *, const int);
+u_int16_t dst_s_id_calc(const u_char *, const int);
+
+/* Used by callers as well as by the library.  */
+#define RAW_KEY_SIZE    8192        /* large enough to store any key */
+
+/* DST_API control flags */
+/* These are used used in functions dst_sign_data and dst_verify_data */
+#define SIG_MODE_INIT		1  /* initialize digest */
+#define SIG_MODE_UPDATE		2  /* add data to digest */
+#define SIG_MODE_FINAL		4  /* generate/verify signature */
+#define SIG_MODE_ALL		(SIG_MODE_INIT|SIG_MODE_UPDATE|SIG_MODE_FINAL)
+
+/* Flags for dst_read_private_key()  */
+#define DST_FORCE_READ		0x1000000
+#define DST_CAN_SIGN		0x010F
+#define DST_NO_AUTHEN		0x8000
+#define DST_EXTEND_FLAG         0x1000
+#define DST_STANDARD		0
+#define DST_PRIVATE             0x2000000
+#define DST_PUBLIC              0x4000000
+#define DST_RAND_SEMI           1
+#define DST_RAND_STD            2
+#define DST_RAND_KEY            3
+#define DST_RAND_DSS            4
+
+
+/* DST algorithm codes */
+#define KEY_RSA			1
+#define KEY_DH			2
+#define KEY_DSA			3
+#define KEY_PRIVATE		254
+#define KEY_EXPAND		255
+#define KEY_HMAC_MD5		157
+#define KEY_HMAC_SHA1		158
+#define UNKNOWN_KEYALG		0
+#define DST_MAX_ALGS            KEY_HMAC_SHA1
+
+/* DST constants to locations in KEY record  changes in new KEY record */
+#define DST_FLAGS_SIZE		2
+#define DST_KEY_PROT		2
+#define DST_KEY_ALG		3
+#define DST_EXT_FLAG            4
+#define DST_KEY_START		4
+
+#ifndef SIGN_F_NOKEY 
+#define SIGN_F_NOKEY		0xC000
+#endif
+
+/* error codes from dst routines */
+#define SIGN_INIT_FAILURE	(-23)
+#define SIGN_UPDATE_FAILURE	(-24)
+#define SIGN_FINAL_FAILURE	(-25)
+#define VERIFY_INIT_FAILURE	(-26)
+#define VERIFY_UPDATE_FAILURE	(-27)
+#define VERIFY_FINAL_FAILURE	(-28)
+#define MISSING_KEY_OR_SIGNATURE (-30)
+#define UNSUPPORTED_KEYALG	(-31)
+
+#endif /* DST_H */
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/ev_streams.c
@@ -0,0 +1,328 @@
+/*	$NetBSD: ev_streams.c,v 1.2 2004/05/20 19:52:31 christos Exp $	*/
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996-1999 by Internet Software Consortium
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* ev_streams.c - implement asynch stream file IO for the eventlib
+ * vix 04mar96 [initial]
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#define ANDROID_CHANGES 1
+#define MOZILLA_NECKO_EXCLUDE_CODE 1
+
+#include <sys/cdefs.h>
+#if !defined(LINT) && !defined(CODECENTER) && !defined(lint)
+#ifdef notdef
+static const char rcsid[] = "Id: ev_streams.c,v 1.2.206.2 2004/03/17 00:29:51 marka Exp";
+#else
+__RCSID("$NetBSD: ev_streams.c,v 1.2 2004/05/20 19:52:31 christos Exp $");
+#endif
+#endif
+
+#include <sys/types.h>
+#include <sys/uio.h>
+
+#include <errno.h>
+
+#include "eventlib.h"
+#include "eventlib_p.h"
+
+#ifndef MOZILLA_NECKO_EXCLUDE_CODE
+#ifndef _LIBC
+static int	copyvec(evStream *str, const struct iovec *iov, int iocnt);
+static void	consume(evStream *str, size_t bytes);
+static void	done(evContext opaqueCtx, evStream *str);
+static void	writable(evContext opaqueCtx, void *uap, int fd, int evmask);
+static void	readable(evContext opaqueCtx, void *uap, int fd, int evmask);
+#endif
+#endif
+
+struct iovec
+evConsIovec(void *buf, size_t cnt) {
+	struct iovec ret;
+
+	memset(&ret, 0xf5, sizeof ret);
+	ret.iov_base = buf;
+	ret.iov_len = cnt;
+	return (ret);
+}
+
+#ifndef MOZILLA_NECKO_EXCLUDE_CODE
+#ifndef _LIBC
+int
+evWrite(evContext opaqueCtx, int fd, const struct iovec *iov, int iocnt,
+	evStreamFunc func, void *uap, evStreamID *id)
+{
+	evContext_p *ctx = opaqueCtx.opaque;
+	evStream *new;
+	int save;
+
+	OKNEW(new);
+	new->func = func;
+	new->uap = uap;
+	new->fd = fd;
+	new->flags = 0;
+	if (evSelectFD(opaqueCtx, fd, EV_WRITE, writable, new, &new->file) < 0)
+		goto free;
+	if (copyvec(new, iov, iocnt) < 0)
+		goto free;
+	new->prevDone = NULL;
+	new->nextDone = NULL;
+	if (ctx->streams != NULL)
+		ctx->streams->prev = new;
+	new->prev = NULL;
+	new->next = ctx->streams;
+	ctx->streams = new;
+	if (id != NULL)
+		id->opaque = new;
+	return (0);
+ free:
+	save = errno;
+	FREE(new);
+	errno = save;
+	return (-1);
+}
+
+int
+evRead(evContext opaqueCtx, int fd, const struct iovec *iov, int iocnt,
+       evStreamFunc func, void *uap, evStreamID *id)
+{
+	evContext_p *ctx = opaqueCtx.opaque;
+	evStream *new;
+	int save;
+
+	OKNEW(new);
+	new->func = func;
+	new->uap = uap;
+	new->fd = fd;
+	new->flags = 0;
+	if (evSelectFD(opaqueCtx, fd, EV_READ, readable, new, &new->file) < 0)
+		goto free;
+	if (copyvec(new, iov, iocnt) < 0)
+		goto free;
+	new->prevDone = NULL;
+	new->nextDone = NULL;
+	if (ctx->streams != NULL)
+		ctx->streams->prev = new;
+	new->prev = NULL;
+	new->next = ctx->streams;
+	ctx->streams = new;
+	if (id)
+		id->opaque = new;
+	return (0);
+ free:
+	save = errno;
+	FREE(new);
+	errno = save;
+	return (-1);
+}
+
+int
+evTimeRW(evContext opaqueCtx, evStreamID id, evTimerID timer) /*ARGSUSED*/ {
+	evStream *str = id.opaque;
+
+	UNUSED(opaqueCtx);
+
+	str->timer = timer;
+	str->flags |= EV_STR_TIMEROK;
+	return (0);
+}
+
+int
+evUntimeRW(evContext opaqueCtx, evStreamID id) /*ARGSUSED*/ {
+	evStream *str = id.opaque;
+
+	UNUSED(opaqueCtx);
+
+	str->flags &= ~EV_STR_TIMEROK;
+	return (0);
+}
+
+int
+evCancelRW(evContext opaqueCtx, evStreamID id) {
+	evContext_p *ctx = opaqueCtx.opaque;
+	evStream *old = id.opaque;
+
+	/*
+	 * The streams list is doubly threaded.  First, there's ctx->streams
+	 * that's used by evDestroy() to find and cancel all streams.  Second,
+	 * there's ctx->strDone (head) and ctx->strLast (tail) which thread
+	 * through the potentially smaller number of "IO completed" streams,
+	 * used in evGetNext() to avoid scanning the entire list.
+	 */
+
+	/* Unlink from ctx->streams. */
+	if (old->prev != NULL)
+		old->prev->next = old->next;
+	else
+		ctx->streams = old->next;
+	if (old->next != NULL)
+		old->next->prev = old->prev;
+
+	/*
+	 * If 'old' is on the ctx->strDone list, remove it.  Update
+	 * ctx->strLast if necessary.
+	 */
+	if (old->prevDone == NULL && old->nextDone == NULL) {
+		/*
+		 * Either 'old' is the only item on the done list, or it's
+		 * not on the done list.  If the former, then we unlink it
+		 * from the list.  If the latter, we leave the list alone.
+		 */
+		if (ctx->strDone == old) {
+			ctx->strDone = NULL;
+			ctx->strLast = NULL;
+		}
+	} else {
+		if (old->prevDone != NULL)
+			old->prevDone->nextDone = old->nextDone;
+		else
+			ctx->strDone = old->nextDone;
+		if (old->nextDone != NULL)
+			old->nextDone->prevDone = old->prevDone;
+		else
+			ctx->strLast = old->prevDone;
+	}
+
+	/* Deallocate the stream. */
+	if (old->file.opaque)
+		evDeselectFD(opaqueCtx, old->file);
+	memput(old->iovOrig, sizeof (struct iovec) * old->iovOrigCount);
+	FREE(old);
+	return (0);
+}
+
+/* Copy a scatter/gather vector and initialize a stream handler's IO. */
+static int
+copyvec(evStream *str, const struct iovec *iov, int iocnt) {
+	int i;
+
+	str->iovOrig = (struct iovec *)memget(sizeof(struct iovec) * iocnt);
+	if (str->iovOrig == NULL) {
+		errno = ENOMEM;
+		return (-1);
+	}
+	str->ioTotal = 0;
+	for (i = 0; i < iocnt; i++) {
+		str->iovOrig[i] = iov[i];
+		str->ioTotal += iov[i].iov_len;
+	}
+	str->iovOrigCount = iocnt;
+	str->iovCur = str->iovOrig;
+	str->iovCurCount = str->iovOrigCount;
+	str->ioDone = 0;
+	return (0);
+}
+
+/* Pull off or truncate lead iovec(s). */
+static void
+consume(evStream *str, size_t bytes) {
+	while (bytes > 0U) {
+		if (bytes < (size_t)str->iovCur->iov_len) {
+			str->iovCur->iov_len -= bytes;
+			str->iovCur->iov_base = (void *)
+				((u_char *)str->iovCur->iov_base + bytes);
+			str->ioDone += bytes;
+			bytes = 0;
+		} else {
+			bytes -= str->iovCur->iov_len;
+			str->ioDone += str->iovCur->iov_len;
+			str->iovCur++;
+			str->iovCurCount--;
+		}
+	}
+}
+
+/* Add a stream to Done list and deselect the FD. */
+static void
+done(evContext opaqueCtx, evStream *str) {
+	evContext_p *ctx = opaqueCtx.opaque;
+
+	if (ctx->strLast != NULL) {
+		str->prevDone = ctx->strLast;
+		ctx->strLast->nextDone = str;
+		ctx->strLast = str;
+	} else {
+		INSIST(ctx->strDone == NULL);
+		ctx->strDone = ctx->strLast = str;
+	}
+	evDeselectFD(opaqueCtx, str->file);
+	str->file.opaque = NULL;
+	/* evDrop() will call evCancelRW() on us. */
+}
+
+/* Dribble out some bytes on the stream.  (Called by evDispatch().) */
+static void
+writable(evContext opaqueCtx, void *uap, int fd, int evmask) {
+	evStream *str = uap;
+	int bytes;
+
+	UNUSED(evmask);
+
+	bytes = writev(fd, str->iovCur, str->iovCurCount);
+	if (bytes > 0) {
+		if ((str->flags & EV_STR_TIMEROK) != 0)
+			evTouchIdleTimer(opaqueCtx, str->timer);
+		consume(str, bytes);
+	} else {
+		if (bytes < 0 && errno != EINTR) {
+			str->ioDone = -1;
+			str->ioErrno = errno;
+		}
+	}
+	if (str->ioDone == -1 || str->ioDone == str->ioTotal)
+		done(opaqueCtx, str);
+}
+
+/* Scoop up some bytes from the stream.  (Called by evDispatch().) */
+static void
+readable(evContext opaqueCtx, void *uap, int fd, int evmask) {
+	evStream *str = uap;
+	int bytes;
+
+	UNUSED(evmask);
+
+	bytes = readv(fd, str->iovCur, str->iovCurCount);
+	if (bytes > 0) {
+		if ((str->flags & EV_STR_TIMEROK) != 0)
+			evTouchIdleTimer(opaqueCtx, str->timer);
+		consume(str, bytes);
+	} else {
+		if (bytes == 0)
+			str->ioDone = 0;
+		else {
+			if (errno != EINTR) {
+				str->ioDone = -1;
+				str->ioErrno = errno;
+			}
+		}
+	}
+	if (str->ioDone <= 0 || str->ioDone == str->ioTotal)
+		done(opaqueCtx, str);
+}
+#endif
+#endif
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/ev_timers.c
@@ -0,0 +1,522 @@
+/*	$NetBSD: ev_timers.c,v 1.2 2004/05/20 19:52:31 christos Exp $	*/
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995-1999 by Internet Software Consortium
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* ev_timers.c - implement timers for the eventlib
+ * vix 09sep95 [initial]
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#define ANDROID_CHANGES 1
+#define MOZILLA_NECKO_EXCLUDE_CODE 1
+
+#include <sys/cdefs.h>
+#if !defined(LINT) && !defined(CODECENTER) && !defined(lint)
+#ifdef notdef
+static const char rcsid[] = "Id: ev_timers.c,v 1.2.2.1.4.5 2004/03/17 02:39:13 marka Exp";
+#else
+__RCSID("$NetBSD: ev_timers.c,v 1.2 2004/05/20 19:52:31 christos Exp $");
+#endif
+#endif
+
+/* Import. */
+
+#include <errno.h>
+#include <time.h>
+
+#include "assertions.h"
+#include "eventlib.h"
+#include "eventlib_p.h"
+
+/* Constants. */
+
+#define	MILLION 1000000
+#define BILLION 1000000000
+
+/* Forward. */
+
+#ifndef _LIBC
+static int due_sooner(void *, void *);
+static void set_index(void *, int);
+static void free_timer(void *, void *);
+static void print_timer(void *, void *);
+static void idle_timeout(evContext, void *, struct timespec, struct timespec);
+
+/* Private type. */
+
+typedef struct {
+	evTimerFunc	func;
+	void *		uap;
+	struct timespec	lastTouched;
+	struct timespec	max_idle;
+	evTimer *	timer;
+} idle_timer;
+#endif
+
+/* Public. */
+
+struct timespec
+evConsTime(time_t sec, long nsec) {
+	struct timespec x;
+
+	x.tv_sec = sec;
+	x.tv_nsec = nsec;
+	return (x);
+}
+
+struct timespec
+evAddTime(struct timespec addend1, struct timespec addend2) {
+	struct timespec x;
+
+	x.tv_sec = addend1.tv_sec + addend2.tv_sec;
+	x.tv_nsec = addend1.tv_nsec + addend2.tv_nsec;
+	if (x.tv_nsec >= BILLION) {
+		x.tv_sec++;
+		x.tv_nsec -= BILLION;
+	}
+	return (x);
+}
+
+struct timespec
+evSubTime(struct timespec minuend, struct timespec subtrahend) {
+	struct timespec x;
+
+	x.tv_sec = minuend.tv_sec - subtrahend.tv_sec;
+	if (minuend.tv_nsec >= subtrahend.tv_nsec)
+		x.tv_nsec = minuend.tv_nsec - subtrahend.tv_nsec;
+	else {
+		x.tv_nsec = BILLION - subtrahend.tv_nsec + minuend.tv_nsec;
+		x.tv_sec--;
+	}
+	return (x);
+}
+
+int
+evCmpTime(struct timespec a, struct timespec b) {
+	long x = a.tv_sec - b.tv_sec;
+
+	if (x == 0L)
+		x = a.tv_nsec - b.tv_nsec;
+	return (x < 0L ? (-1) : x > 0L ? (1) : (0));
+}
+
+struct timespec
+evNowTime() {
+	struct timeval now;
+#ifdef CLOCK_REALTIME
+	struct timespec tsnow;
+	int m = CLOCK_REALTIME;
+
+#ifdef CLOCK_MONOTONIC
+	if (__evOptMonoTime)
+		m = CLOCK_MONOTONIC;
+#endif
+	if (clock_gettime(m, &tsnow) == 0)
+		return (tsnow);
+#endif
+	if (gettimeofday(&now, NULL) < 0)
+		return (evConsTime(0L, 0L));
+	return (evTimeSpec(now));
+}
+
+#ifndef MOZILLA_NECKO_EXCLUDE_CODE
+struct timespec
+evUTCTime(void) {
+	struct timeval now;
+#ifdef CLOCK_REALTIME
+	struct timespec tsnow;
+	if (clock_gettime(CLOCK_REALTIME, &tsnow) == 0)
+		return (tsnow);
+#endif
+	if (gettimeofday(&now, NULL) < 0)
+		return (evConsTime(0L, 0L));
+	return (evTimeSpec(now));
+}
+
+#ifndef _LIBC
+struct timespec
+evLastEventTime(evContext opaqueCtx) {
+	evContext_p *ctx = opaqueCtx.opaque;
+
+	return (ctx->lastEventTime);
+}
+#endif
+#endif
+
+struct timespec
+evTimeSpec(struct timeval tv) {
+	struct timespec ts;
+
+	ts.tv_sec = tv.tv_sec;
+	ts.tv_nsec = tv.tv_usec * 1000;
+	return (ts);
+}
+
+#ifndef MOZILLA_NECKO_EXCLUDE_CODE
+struct timeval
+evTimeVal(struct timespec ts) {
+	struct timeval tv;
+
+	tv.tv_sec = ts.tv_sec;
+	tv.tv_usec = ts.tv_nsec / 1000;
+	return (tv);
+}
+
+#ifndef _LIBC
+int
+evSetTimer(evContext opaqueCtx,
+	   evTimerFunc func,
+	   void *uap,
+	   struct timespec due,
+	   struct timespec inter,
+	   evTimerID *opaqueID
+) {
+	evContext_p *ctx = opaqueCtx.opaque;
+	evTimer *id;
+
+	printf("evSetTimer(ctx %p, func %p, uap %p, due %ld.%09ld, inter %ld.%09ld)\n",
+		 ctx, func, uap,
+		 (long)due.tv_sec, due.tv_nsec,
+		 (long)inter.tv_sec, inter.tv_nsec);
+
+#ifdef __hpux
+	/*
+	 * tv_sec and tv_nsec are unsigned.
+	 */
+	if (due.tv_nsec >= BILLION)
+		EV_ERR(EINVAL);
+
+	if (inter.tv_nsec >= BILLION)
+		EV_ERR(EINVAL);
+#else
+	if (due.tv_sec < 0 || due.tv_nsec < 0 || due.tv_nsec >= BILLION)
+		EV_ERR(EINVAL);
+
+	if (inter.tv_sec < 0 || inter.tv_nsec < 0 || inter.tv_nsec >= BILLION)
+		EV_ERR(EINVAL);
+#endif
+
+	/* due={0,0} is a magic cookie meaning "now." */
+	if (due.tv_sec == (time_t)0 && due.tv_nsec == 0L)
+		due = evNowTime();
+
+	/* Allocate and fill. */
+	OKNEW(id);
+	id->func = func;
+	id->uap = uap;
+	id->due = due;
+	id->inter = inter;
+
+	if (heap_insert(ctx->timers, id) < 0)
+		return (-1);
+
+	/* Remember the ID if the caller provided us a place for it. */
+	if (opaqueID)
+		opaqueID->opaque = id;
+
+	if (ctx->debug > 7) {
+		printf("timers after evSetTimer:\n");
+		(void) heap_for_each(ctx->timers, print_timer, (void *)ctx);
+	}
+
+	return (0);
+}
+
+int
+evClearTimer(evContext opaqueCtx, evTimerID id) {
+	evContext_p *ctx = opaqueCtx.opaque;
+	evTimer *del = id.opaque;
+
+	if (ctx->cur != NULL &&
+	    ctx->cur->type == Timer &&
+	    ctx->cur->u.timer.this == del) {
+		printf("deferring delete of timer (executing)\n");
+		/*
+		 * Setting the interval to zero ensures that evDrop() will
+		 * clean up the timer.
+		 */
+		del->inter = evConsTime(0, 0);
+		return (0);
+	}
+
+	if (heap_element(ctx->timers, del->index) != del)
+		EV_ERR(ENOENT);
+
+	if (heap_delete(ctx->timers, del->index) < 0)
+		return (-1);
+	FREE(del);
+
+	if (ctx->debug > 7) {
+		printf("timers after evClearTimer:\n");
+		(void) heap_for_each(ctx->timers, print_timer, (void *)ctx);
+	}
+
+	return (0);
+}
+
+int
+evConfigTimer(evContext opaqueCtx,
+	     evTimerID id,
+	     const char *param,
+	     int value
+) {
+	evContext_p *ctx = opaqueCtx.opaque;
+	evTimer *timer = id.opaque;
+	int result=0;
+
+	UNUSED(value);
+
+	if (heap_element(ctx->timers, timer->index) != timer)
+		EV_ERR(ENOENT);
+
+	if (strcmp(param, "rate") == 0)
+		timer->mode |= EV_TMR_RATE;
+	else if (strcmp(param, "interval") == 0)
+		timer->mode &= ~EV_TMR_RATE;
+	else
+		EV_ERR(EINVAL);
+
+	return (result);
+}
+
+int
+evResetTimer(evContext opaqueCtx,
+	     evTimerID id,
+	     evTimerFunc func,
+	     void *uap,
+	     struct timespec due,
+	     struct timespec inter
+) {
+	evContext_p *ctx = opaqueCtx.opaque;
+	evTimer *timer = id.opaque;
+	struct timespec old_due;
+	int result=0;
+
+	if (heap_element(ctx->timers, timer->index) != timer)
+		EV_ERR(ENOENT);
+
+#ifdef __hpux
+	/*
+	 * tv_sec and tv_nsec are unsigned.
+	 */
+	if (due.tv_nsec >= BILLION)
+		EV_ERR(EINVAL);
+
+	if (inter.tv_nsec >= BILLION)
+		EV_ERR(EINVAL);
+#else
+	if (due.tv_sec < 0 || due.tv_nsec < 0 || due.tv_nsec >= BILLION)
+		EV_ERR(EINVAL);
+
+	if (inter.tv_sec < 0 || inter.tv_nsec < 0 || inter.tv_nsec >= BILLION)
+		EV_ERR(EINVAL);
+#endif
+
+	old_due = timer->due;
+
+	timer->func = func;
+	timer->uap = uap;
+	timer->due = due;
+	timer->inter = inter;
+
+	switch (evCmpTime(due, old_due)) {
+	case -1:
+		result = heap_increased(ctx->timers, timer->index);
+		break;
+	case 0:
+		result = 0;
+		break;
+	case 1:
+		result = heap_decreased(ctx->timers, timer->index);
+		break;
+	}
+
+	if (ctx->debug > 7) {
+		printf("timers after evResetTimer:\n");
+		(void) heap_for_each(ctx->timers, print_timer, (void *)ctx);
+	}
+
+	return (result);
+}
+
+int
+evSetIdleTimer(evContext opaqueCtx,
+		evTimerFunc func,
+		void *uap,
+		struct timespec max_idle,
+		evTimerID *opaqueID
+) {
+	evContext_p *ctx = opaqueCtx.opaque;
+	idle_timer *tt;
+
+	/* Allocate and fill. */
+	OKNEW(tt);
+	tt->func = func;
+	tt->uap = uap;
+	tt->lastTouched = ctx->lastEventTime;
+	tt->max_idle = max_idle;
+
+	if (evSetTimer(opaqueCtx, idle_timeout, tt,
+		       evAddTime(ctx->lastEventTime, max_idle),
+		       max_idle, opaqueID) < 0) {
+		FREE(tt);
+		return (-1);
+	}
+
+	tt->timer = opaqueID->opaque;
+
+	return (0);
+}
+
+int
+evClearIdleTimer(evContext opaqueCtx, evTimerID id) {
+	evTimer *del = id.opaque;
+	idle_timer *tt = del->uap;
+
+	FREE(tt);
+	return (evClearTimer(opaqueCtx, id));
+}
+
+int
+evResetIdleTimer(evContext opaqueCtx,
+		 evTimerID opaqueID,
+		 evTimerFunc func,
+		 void *uap,
+		 struct timespec max_idle
+) {
+	evContext_p *ctx = opaqueCtx.opaque;
+	evTimer *timer = opaqueID.opaque;
+	idle_timer *tt = timer->uap;
+
+	tt->func = func;
+	tt->uap = uap;
+	tt->lastTouched = ctx->lastEventTime;
+	tt->max_idle = max_idle;
+
+	return (evResetTimer(opaqueCtx, opaqueID, idle_timeout, tt,
+			     evAddTime(ctx->lastEventTime, max_idle),
+			     max_idle));
+}
+
+int
+evTouchIdleTimer(evContext opaqueCtx, evTimerID id) {
+	evContext_p *ctx = opaqueCtx.opaque;
+	evTimer *t = id.opaque;
+	idle_timer *tt = t->uap;
+
+	tt->lastTouched = ctx->lastEventTime;
+
+	return (0);
+}
+
+/* Public to the rest of eventlib. */
+
+heap_context
+evCreateTimers(const evContext_p *ctx) {
+
+	UNUSED(ctx);
+
+	return (heap_new(due_sooner, set_index, 2048));
+}
+
+void
+evDestroyTimers(const evContext_p *ctx) {
+	(void) heap_for_each(ctx->timers, free_timer, NULL);
+	(void) heap_free(ctx->timers);
+}
+
+/* Private. */
+
+static int
+due_sooner(void *a, void *b) {
+	evTimer *a_timer, *b_timer;
+
+	a_timer = a;
+	b_timer = b;
+	return (evCmpTime(a_timer->due, b_timer->due) < 0);
+}
+
+static void
+set_index(void *what, int idx) {
+	evTimer *timer;
+
+	timer = what;
+	timer->index = idx;
+}
+
+static void
+free_timer(void *what, void *uap) {
+	evTimer *t = what;
+
+	UNUSED(uap);
+
+	FREE(t);
+}
+
+static void
+print_timer(void *what, void *uap) {
+	evTimer *cur = what;
+	evContext_p *ctx = uap;
+
+	cur = what;
+	evPrintf(ctx, 7,
+	    "  func %p, uap %p, due %ld.%09ld, inter %ld.%09ld\n",
+		 cur->func, cur->uap,
+		 (long)cur->due.tv_sec, cur->due.tv_nsec,
+		 (long)cur->inter.tv_sec, cur->inter.tv_nsec);
+}
+
+static void
+idle_timeout(evContext opaqueCtx,
+	     void *uap,
+	     struct timespec due,
+	     struct timespec inter
+) {
+	evContext_p *ctx = opaqueCtx.opaque;
+	idle_timer *this = uap;
+	struct timespec idle;
+
+	UNUSED(due);
+	UNUSED(inter);
+	
+	idle = evSubTime(ctx->lastEventTime, this->lastTouched);
+	if (evCmpTime(idle, this->max_idle) >= 0) {
+		(this->func)(opaqueCtx, this->uap, this->timer->due,
+			     this->max_idle);
+		/*
+		 * Setting the interval to zero will cause the timer to
+		 * be cleaned up in evDrop().
+		 */
+		this->timer->inter = evConsTime(0L, 0L);
+		FREE(this);
+	} else {
+		/* evDrop() will reschedule the timer. */
+		this->timer->inter = evSubTime(this->max_idle, idle);
+	}
+}
+#endif
+#endif
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/eventlib.h
@@ -0,0 +1,214 @@
+/*	$NetBSD: eventlib.h,v 1.1.1.3 2005/12/21 23:15:22 christos Exp $	*/
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995-1999 by Internet Software Consortium
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* eventlib.h - exported interfaces for eventlib
+ * vix 09sep95 [initial]
+ *
+ * Id: eventlib.h,v 1.1.2.1.4.2 2005/07/28 07:43:18 marka Exp
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#ifndef _EVENTLIB_H
+#define _EVENTLIB_H
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/time.h>
+#include <stdio.h>
+
+#ifndef __P
+# define __EVENTLIB_P_DEFINED
+# ifdef __STDC__
+#  define __P(x) x
+# else
+#  define __P(x) ()
+# endif
+#endif
+
+/* In the absence of branded types... */
+typedef struct { void *opaque; } evConnID;
+typedef struct { void *opaque; } evFileID;
+typedef struct { void *opaque; } evStreamID;
+typedef struct { void *opaque; } evTimerID;
+typedef struct { void *opaque; } evWaitID;
+typedef struct { void *opaque; } evContext;
+typedef struct { void *opaque; } evEvent;
+
+#define	evInitID(id) ((id)->opaque = NULL)
+#define	evTestID(id) ((id).opaque != NULL)
+
+typedef void (*evConnFunc)__P((evContext, void *, int, const void *, int,
+			       const void *, int));
+typedef void (*evFileFunc)__P((evContext, void *, int, int));
+typedef	void (*evStreamFunc)__P((evContext, void *, int, int));
+typedef void (*evTimerFunc)__P((evContext, void *,
+				struct timespec, struct timespec));
+typedef	void (*evWaitFunc)__P((evContext, void *, const void *));
+
+typedef	struct { unsigned char mask[256/8]; } evByteMask;
+#define	EV_BYTEMASK_BYTE(b) ((b) / 8)
+#define	EV_BYTEMASK_MASK(b) (1 << ((b) % 8))
+#define	EV_BYTEMASK_SET(bm, b) \
+	((bm).mask[EV_BYTEMASK_BYTE(b)] |= EV_BYTEMASK_MASK(b))
+#define	EV_BYTEMASK_CLR(bm, b) \
+	((bm).mask[EV_BYTEMASK_BYTE(b)] &= ~EV_BYTEMASK_MASK(b))
+#define	EV_BYTEMASK_TST(bm, b) \
+	((bm).mask[EV_BYTEMASK_BYTE(b)] & EV_BYTEMASK_MASK(b))
+
+#define	EV_POLL		1
+#define	EV_WAIT		2
+#define	EV_NULL		4
+
+#define	EV_READ		1
+#define	EV_WRITE	2
+#define	EV_EXCEPT	4
+
+#define EV_WASNONBLOCKING 8	/* Internal library use. */
+
+/* eventlib.c */
+#define evCreate	__evCreate
+#define evSetDebug	__evSetDebug
+#define evDestroy	__evDestroy
+#define evGetNext	__evGetNext
+#define evDispatch	__evDispatch
+#define evDrop		__evDrop
+#define evMainLoop	__evMainLoop
+#define evHighestFD	__evHighestFD
+#define evGetOption	__evGetOption
+#define evSetOption	__evSetOption
+
+int  evCreate __P((evContext *));
+void evSetDebug __P((evContext, int, FILE *));
+int  evDestroy __P((evContext));
+int  evGetNext __P((evContext, evEvent *, int));
+int  evDispatch __P((evContext, evEvent));
+void evDrop __P((evContext, evEvent));
+int  evMainLoop __P((evContext));
+int  evHighestFD __P((evContext));
+int  evGetOption __P((evContext *, const char *, int *));
+int  evSetOption __P((evContext *, const char *, int));
+
+/* ev_connects.c */
+#define evListen	__evListen
+#define evConnect	__evConnect
+#define evCancelConn	__evCancelConn
+#define evHold		__evHold
+#define evUnhold	__evUnhold
+#define evTryAccept	__evTryAccept
+
+int evListen __P((evContext, int, int, evConnFunc, void *, evConnID *));
+int evConnect __P((evContext, int, const void *, int,
+		   evConnFunc, void *, evConnID *));
+int evCancelConn __P((evContext, evConnID));
+int evHold __P((evContext, evConnID));
+int evUnhold __P((evContext, evConnID));
+int evTryAccept __P((evContext, evConnID, int *));
+
+/* ev_files.c */
+#define evSelectFD	__evSelectFD
+#define evDeselectFD	__evDeselectFD
+
+int evSelectFD __P((evContext, int, int, evFileFunc, void *, evFileID *));
+int evDeselectFD __P((evContext, evFileID));
+
+/* ev_streams.c */
+#define evConsIovec	__evConsIovec
+#define evWrite		__evWrite
+#define evRead		__evRead
+#define evTimeRW	__evTimeRW
+#define evUntimeRW	__evUntimeRW
+#define	evCancelRW	__evCancelRW
+
+struct iovec evConsIovec __P((void *, size_t));
+int evWrite __P((evContext, int, const struct iovec *, int,
+		 evStreamFunc func, void *, evStreamID *));
+int evRead __P((evContext, int, const struct iovec *, int,
+		evStreamFunc func, void *, evStreamID *));
+int evTimeRW __P((evContext, evStreamID, evTimerID timer));
+int evUntimeRW __P((evContext, evStreamID));
+int evCancelRW __P((evContext, evStreamID));
+
+/* ev_timers.c */
+#define evConsTime	__evConsTime
+#define evAddTime	__evAddTime
+#define evSubTime	__evSubTime
+#define evCmpTime	__evCmpTime
+#define	evTimeSpec	__evTimeSpec
+#define	evTimeVal	__evTimeVal
+
+#define evNowTime		__evNowTime
+#define evUTCTime		__evUTCTime
+#define evLastEventTime		__evLastEventTime
+#define evSetTimer		__evSetTimer
+#define evClearTimer		__evClearTimer
+#define evConfigTimer		__evConfigTimer
+#define evResetTimer		__evResetTimer
+#define evSetIdleTimer		__evSetIdleTimer
+#define evClearIdleTimer	__evClearIdleTimer
+#define evResetIdleTimer	__evResetIdleTimer
+#define evTouchIdleTimer	__evTouchIdleTimer
+
+struct timespec evConsTime __P((time_t sec, long nsec));
+struct timespec evAddTime __P((struct timespec, struct timespec));
+struct timespec evSubTime __P((struct timespec, struct timespec));
+struct timespec evNowTime __P((void));
+struct timespec evUTCTime __P((void));
+struct timespec evLastEventTime __P((evContext));
+struct timespec evTimeSpec __P((struct timeval));
+struct timeval evTimeVal __P((struct timespec));
+int evCmpTime __P((struct timespec, struct timespec));
+int evSetTimer __P((evContext, evTimerFunc, void *, struct timespec,
+		    struct timespec, evTimerID *));
+int evClearTimer __P((evContext, evTimerID));
+int evConfigTimer __P((evContext, evTimerID, const char *param,
+		      int value));
+int evResetTimer __P((evContext, evTimerID, evTimerFunc, void *,
+		      struct timespec, struct timespec));
+int evSetIdleTimer __P((evContext, evTimerFunc, void *, struct timespec,
+			evTimerID *));
+int evClearIdleTimer __P((evContext, evTimerID));
+int evResetIdleTimer __P((evContext, evTimerID, evTimerFunc, void *,
+			  struct timespec));
+int evTouchIdleTimer __P((evContext, evTimerID));
+
+/* ev_waits.c */
+#define evWaitFor	__evWaitFor
+#define evDo		__evDo
+#define evUnwait	__evUnwait
+#define evDefer		__evDefer
+
+int evWaitFor __P((evContext, const void *, evWaitFunc, void *, evWaitID *));
+int evDo __P((evContext, const void *));
+int evUnwait __P((evContext, evWaitID));
+int evDefer __P((evContext, evWaitFunc, void *));
+
+#ifdef __EVENTLIB_P_DEFINED
+# undef __P
+#endif
+
+#endif /*_EVENTLIB_H*/
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/eventlib_p.h
@@ -0,0 +1,243 @@
+/*	$NetBSD: eventlib_p.h,v 1.1.1.1 2004/05/20 19:34:32 christos Exp $	*/
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995-1999 by Internet Software Consortium
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* eventlib_p.h - private interfaces for eventlib
+ * vix 09sep95 [initial]
+ *
+ * Id: eventlib_p.h,v 1.3.2.1.4.1 2004/03/09 08:33:43 marka Exp
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#ifndef _EVENTLIB_P_H
+#define _EVENTLIB_P_H
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+
+#define EVENTLIB_DEBUG 1
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "heap.h"
+#include "list.h"
+#include "memcluster.h"
+
+
+#define	EV_MASK_ALL	(EV_READ | EV_WRITE | EV_EXCEPT)
+#define EV_ERR(e)		return (errno = (e), -1)
+#define OK(x)		if ((x) < 0) EV_ERR(errno); else (void)NULL
+
+
+#if HAVE_MEM_GET_SET
+#define	NEW(p)		if (((p) = memget(sizeof *(p))) != NULL) \
+				FILL(p); \
+			else \
+				(void)NULL;
+#define OKNEW(p)	if (!((p) = memget(sizeof *(p)))) { \
+				errno = ENOMEM; \
+				return (-1); \
+			} else \
+				FILL(p)
+#define FREE(p)		memput((p), sizeof *(p))
+
+#if EVENTLIB_DEBUG
+#define FILL(p)		memset((p), 0xF5, sizeof *(p))
+#else
+#define FILL(p)
+#endif
+
+#else
+
+#define	NEW(p) 	p = malloc(sizeof *(p));
+#define OKNEW(p) if (!((p) = malloc(sizeof *(p)))) { errno = ENOMEM; return (-1); }
+#define FREE(p)	free(p)
+#define FILL(p)
+
+#endif
+
+
+typedef struct evConn {
+	evConnFunc	func;
+	void *		uap;
+	int		fd;
+	int		flags;
+#define EV_CONN_LISTEN		0x0001		/* Connection is a listener. */
+#define EV_CONN_SELECTED	0x0002		/* evSelectFD(conn->file). */
+#define EV_CONN_BLOCK		0x0004		/* Listener fd was blocking. */
+	evFileID	file;
+	struct evConn *	prev;
+	struct evConn *	next;
+} evConn;
+
+typedef struct evAccept {
+	int		fd;
+	union {
+		struct sockaddr		sa;
+		struct sockaddr_in	in;
+#ifndef NO_SOCKADDR_UN
+		struct sockaddr_un	un;
+#endif
+	}		la;
+	socklen_t	lalen;
+	union {
+		struct sockaddr		sa;
+		struct sockaddr_in	in;
+#ifndef NO_SOCKADDR_UN
+		struct sockaddr_un	un;
+#endif
+	}		ra;
+	socklen_t	ralen;
+	int		ioErrno;
+	evConn *	conn;
+	LINK(struct evAccept) link;
+} evAccept;
+
+typedef struct evFile {
+	evFileFunc	func;
+	void *		uap;
+	int		fd;
+	int		eventmask;
+	int		preemptive;
+	struct evFile *	prev;
+	struct evFile *	next;
+	struct evFile *	fdprev;
+	struct evFile *	fdnext;
+} evFile;
+
+typedef struct evStream {
+	evStreamFunc	func;
+	void *		uap;
+	evFileID	file;
+	evTimerID	timer;
+	int		flags;
+#define EV_STR_TIMEROK	0x0001	/* IFF timer valid. */
+	int		fd;
+	struct iovec *	iovOrig;
+	int		iovOrigCount;
+	struct iovec *	iovCur;
+	int		iovCurCount;
+	int		ioTotal;
+	int		ioDone;
+	int		ioErrno;
+	struct evStream	*prevDone, *nextDone;
+	struct evStream	*prev, *next;
+} evStream;
+
+typedef struct evTimer {
+	evTimerFunc	func;
+	void *		uap;
+	struct timespec	due, inter;
+	int		index;
+	int		mode;
+#define EV_TMR_RATE	1
+} evTimer;
+
+typedef struct evWait {
+	evWaitFunc	func;
+	void *		uap;
+	const void *	tag;
+	struct evWait *	next;
+} evWait;
+
+typedef struct evWaitList {
+	evWait *		first;
+	evWait *		last;
+	struct evWaitList *	prev;
+	struct evWaitList *	next;
+} evWaitList;
+
+typedef struct evEvent_p {
+	enum {  Accept, File, Stream, Timer, Wait, Free, Null  } type;
+	union {
+		struct {  evAccept *this;  }			accept;
+		struct {  evFile *this; int eventmask;  }	file;
+		struct {  evStream *this;  }			stream;
+		struct {  evTimer *this;  }			timer;
+		struct {  evWait *this;  }			wait;
+		struct {  struct evEvent_p *next;  }		free;
+		struct {  const void *placeholder;  }		null;
+	} u;
+} evEvent_p;
+
+typedef struct {
+	/* Global. */
+	const evEvent_p	*cur;
+	/* Debugging. */
+	int		debug;
+	FILE		*output;
+	/* Connections. */
+	evConn		*conns;
+	LIST(evAccept)	accepts;
+	/* Files. */
+	evFile		*files, *fdNext;
+	fd_set		rdLast, rdNext;
+	fd_set		wrLast, wrNext;
+	fd_set		exLast, exNext;
+	fd_set		nonblockBefore;
+	int		fdMax, fdCount, highestFD;
+	evFile		*fdTable[FD_SETSIZE];
+#ifdef EVENTLIB_TIME_CHECKS
+	struct timespec	lastSelectTime;
+	int		lastFdCount;
+#endif
+	/* Streams. */
+	evStream	*streams;
+	evStream	*strDone, *strLast;
+	/* Timers. */
+	struct timespec	lastEventTime;
+	heap_context	timers;
+	/* Waits. */
+	evWaitList	*waitLists;
+	evWaitList	waitDone;
+} evContext_p;
+
+/* eventlib.c */
+#define evPrintf __evPrintf
+void evPrintf(const evContext_p *ctx, int level, const char *fmt, ...);
+
+/* ev_timers.c */
+#define evCreateTimers __evCreateTimers
+heap_context evCreateTimers(const evContext_p *);
+#define evDestroyTimers __evDestroyTimers
+void evDestroyTimers(const evContext_p *);
+
+/* ev_waits.c */
+#define evFreeWait __evFreeWait
+evWait *evFreeWait(evContext_p *ctx, evWait *old);
+
+/* Global options */
+int		__evOptMonoTime;
+
+#endif /*_EVENTLIB_P_H*/
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/getaddrinfo.c
@@ -0,0 +1,2355 @@
+/*	$NetBSD: getaddrinfo.c,v 1.82 2006/03/25 12:09:40 rpaulo Exp $	*/
+/*	$KAME: getaddrinfo.c,v 1.29 2000/08/31 17:26:57 itojun Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 THE PROJECT OR CONTRIBUTORS 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 DAMAGE.
+ */
+
+/*
+ * This version of getaddrinfo.c is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+#define ANDROID_CHANGES 1
+
+/*
+ * Issues to be discussed:
+ * - Return values.  There are nonstandard return values defined and used
+ *   in the source code.  This is because RFC2553 is silent about which error
+ *   code must be returned for which situation.
+ * - IPv4 classful (shortened) form.  RFC2553 is silent about it.  XNET 5.2
+ *   says to use inet_aton() to convert IPv4 numeric to binary (alows
+ *   classful form as a result).
+ *   current code - disallow classful form for IPv4 (due to use of inet_pton).
+ * - freeaddrinfo(NULL).  RFC2553 is silent about it.  XNET 5.2 says it is
+ *   invalid.
+ *   current code - SEGV on freeaddrinfo(NULL)
+ * Note:
+ * - We use getipnodebyname() just for thread-safeness.  There's no intent
+ *   to let it do PF_UNSPEC (actually we never pass PF_UNSPEC to
+ *   getipnodebyname().
+ * - MOZILLA: Thread safeness for pre-Honeycomb Android versions implemented by
+ *   way of open/gets/close and mmap rather than fopen/fgets/fclose.  Affects
+ *   _files_getaddrinfo for hosts file.  Note: Honeycomb and later versions use
+ *   a thread-safe stdio, so for those versions normal Bionic libc getaddrinfo
+ *   is used.
+ * - The code filters out AFs that are not supported by the kernel,
+ *   when globbing NULL hostname (to loopback, or wildcard).  Is it the right
+ *   thing to do?  What is the relationship with post-RFC2553 AI_ADDRCONFIG
+ *   in ai_flags?
+ * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague.
+ *   (1) what should we do against numeric hostname (2) what should we do
+ *   against NULL hostname (3) what is AI_ADDRCONFIG itself.  AF not ready?
+ *   non-loopback address configured?  global address configured?
+ * - To avoid search order issue, we have a big amount of code duplicate
+ *   from gethnamaddr.c and some other places.  The issues that there's no
+ *   lower layer function to lookup "IPv4 or IPv6" record.  Calling
+ *   gethostbyname2 from getaddrinfo will end up in wrong search order, as
+ *   follows:
+ *	- The code makes use of following calls when asked to resolver with
+ *	  ai_family  = PF_UNSPEC:
+ *		getipnodebyname(host, AF_INET6);
+ *		getipnodebyname(host, AF_INET);
+ *	  This will result in the following queries if the node is configure to
+ *	  prefer /etc/hosts than DNS:
+ *		lookup /etc/hosts for IPv6 address
+ *		lookup DNS for IPv6 address
+ *		lookup /etc/hosts for IPv4 address
+ *		lookup DNS for IPv4 address
+ *	  which may not meet people's requirement.
+ *	  The right thing to happen is to have underlying layer which does
+ *	  PF_UNSPEC lookup (lookup both) and return chain of addrinfos.
+ *	  This would result in a bit of code duplicate with _dns_ghbyname() and
+ *	  friends.
+ */
+
+#include <fcntl.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/mman.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include "arpa_nameser.h"
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include "resolv_private.h"
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <syslog.h>
+#include <stdarg.h>
+#include "nsswitch.h"
+
+#ifdef MOZ_GETADDRINFO_LOG_VERBOSE
+#include <android/log.h>
+#endif
+
+#ifdef ANDROID_CHANGES
+#include <sys/system_properties.h>
+#endif /* ANDROID_CHANGES */
+
+typedef struct _pseudo_FILE {
+    int fd;
+    off_t maplen;
+    void* mapping;
+    off_t offset;
+} _pseudo_FILE;
+
+#define _PSEUDO_FILE_INITIALIZER { -1, 0, MAP_FAILED, 0 }
+
+static void
+_pseudo_fclose(_pseudo_FILE * __restrict__ fp)
+{
+    assert(fp);
+    fp->offset = 0;
+    if (fp->mapping != MAP_FAILED) {
+        (void) munmap(fp->mapping, fp->maplen);
+        fp->mapping = MAP_FAILED;
+    }
+    fp->maplen = 0;
+    if (fp->fd != -1) {
+        (void) close(fp->fd);
+        fp->fd = -1;
+    }
+}
+
+static _pseudo_FILE *
+_pseudo_fopen_r(_pseudo_FILE * __restrict__ fp, const char* fname)
+{
+    struct stat statbuf;
+    assert(fp);
+    fp->fd = open(fname, O_RDONLY);
+    if (fp->fd < 0) {
+        fp->fd = -1;
+        return NULL;
+    }
+    if ((0 != fstat(fp->fd, &statbuf)) || (statbuf.st_size <= 0)) {
+        close(fp->fd);
+        fp->fd = -1;
+        return NULL;
+    }
+    fp->maplen = statbuf.st_size;
+    fp->mapping = mmap(NULL, fp->maplen, PROT_READ, MAP_PRIVATE, fp->fd, 0);
+    if (fp->mapping == MAP_FAILED) {
+        close(fp->fd);
+        fp->fd = -1;
+        return NULL;
+    }
+    fp->offset = 0;
+    return fp;
+}
+
+static void
+_pseudo_rewind(_pseudo_FILE * __restrict__ fp)
+{
+    assert(fp);
+    fp->offset = 0;
+}
+
+static char*
+_pseudo_fgets(char* buf, int bufsize, _pseudo_FILE * __restrict__ fp)
+{
+    char* current;
+    char* endp;
+    int maxcopy;
+    assert(fp);
+    maxcopy = fp->maplen - fp->offset;
+    if (fp->mapping == MAP_FAILED)
+        return NULL;
+    if (maxcopy > bufsize - 1)
+        maxcopy = bufsize - 1;
+    if (maxcopy <= 0)
+        return NULL;
+    current = ((char*) fp->mapping) + fp->offset;
+    endp = memccpy(buf, current, '\n', maxcopy);
+    if (endp)
+        maxcopy = endp - buf;
+    buf[maxcopy] = '\0';
+    fp->offset += maxcopy;
+    return buf;
+}
+
+typedef union sockaddr_union {
+    struct sockaddr     generic;
+    struct sockaddr_in  in;
+    struct sockaddr_in6 in6;
+} sockaddr_union;
+
+#define SUCCESS 0
+#define ANY 0
+#define YES 1
+#define NO  0
+
+static const char in_addrany[] = { 0, 0, 0, 0 };
+static const char in_loopback[] = { 127, 0, 0, 1 };
+#ifdef INET6
+static const char in6_addrany[] = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+static const char in6_loopback[] = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
+};
+#endif
+
+static const struct afd {
+	int a_af;
+	int a_addrlen;
+	int a_socklen;
+	int a_off;
+	const char *a_addrany;
+	const char *a_loopback;
+	int a_scoped;
+} afdl [] = {
+#ifdef INET6
+	{PF_INET6, sizeof(struct in6_addr),
+	 sizeof(struct sockaddr_in6),
+	 offsetof(struct sockaddr_in6, sin6_addr),
+	 in6_addrany, in6_loopback, 1},
+#endif
+	{PF_INET, sizeof(struct in_addr),
+	 sizeof(struct sockaddr_in),
+	 offsetof(struct sockaddr_in, sin_addr),
+	 in_addrany, in_loopback, 0},
+	{0, 0, 0, 0, NULL, NULL, 0},
+};
+
+struct explore {
+	int e_af;
+	int e_socktype;
+	int e_protocol;
+	const char *e_protostr;
+	int e_wild;
+#define WILD_AF(ex)		((ex)->e_wild & 0x01)
+#define WILD_SOCKTYPE(ex)	((ex)->e_wild & 0x02)
+#define WILD_PROTOCOL(ex)	((ex)->e_wild & 0x04)
+};
+
+static const struct explore explore[] = {
+#if 0
+	{ PF_LOCAL, 0, ANY, ANY, NULL, 0x01 },
+#endif
+#ifdef INET6
+	{ PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
+	{ PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
+	{ PF_INET6, SOCK_RAW, ANY, NULL, 0x05 },
+#endif
+	{ PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
+	{ PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
+	{ PF_INET, SOCK_RAW, ANY, NULL, 0x05 },
+	{ PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
+	{ PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
+	{ PF_UNSPEC, SOCK_RAW, ANY, NULL, 0x05 },
+	{ -1, 0, 0, NULL, 0 },
+};
+
+#ifdef INET6
+#define PTON_MAX	16
+#else
+#define PTON_MAX	4
+#endif
+
+static const ns_src default_dns_files[] = {
+	{ NSSRC_FILES, 	NS_SUCCESS },
+	{ NSSRC_DNS, 	NS_SUCCESS },
+	{ 0, 0 }
+};
+
+#define MAXPACKET	(64*1024)
+
+typedef union {
+	HEADER hdr;
+	u_char buf[MAXPACKET];
+} querybuf;
+
+struct res_target {
+	struct res_target *next;
+	const char *name;	/* domain name */
+	int qclass, qtype;	/* class and type of query */
+	u_char *answer;		/* buffer to put answer */
+	int anslen;		/* size of answer buffer */
+	int n;			/* result length */
+};
+
+static int str2number(const char *);
+static int explore_fqdn(const struct addrinfo *, const char *,
+	const char *, struct addrinfo **);
+static int explore_null(const struct addrinfo *,
+	const char *, struct addrinfo **);
+static int explore_numeric(const struct addrinfo *, const char *,
+	const char *, struct addrinfo **, const char *);
+static int explore_numeric_scope(const struct addrinfo *, const char *,
+	const char *, struct addrinfo **);
+static int get_canonname(const struct addrinfo *,
+	struct addrinfo *, const char *);
+static struct addrinfo *get_ai(const struct addrinfo *,
+	const struct afd *, const char *);
+static int get_portmatch(const struct addrinfo *, const char *);
+static int get_port(const struct addrinfo *, const char *, int);
+static const struct afd *find_afd(int);
+#ifdef INET6
+static int ip6_str2scopeid(char *, struct sockaddr_in6 *, u_int32_t *);
+#endif
+
+static struct addrinfo *getanswer(const querybuf *, int, const char *, int,
+	const struct addrinfo *);
+static int _dns_getaddrinfo(void *, void *, va_list);
+static void _sethtent(_pseudo_FILE * __restrict__);
+static void _endhtent(_pseudo_FILE * __restrict__);
+static struct addrinfo *_gethtent(_pseudo_FILE * __restrict__, const char *,
+    const struct addrinfo *);
+static int _files_getaddrinfo(void *, void *, va_list);
+
+static int res_queryN(const char *, struct res_target *, res_state);
+static int res_searchN(const char *, struct res_target *, res_state);
+static int res_querydomainN(const char *, const char *,
+	struct res_target *, res_state);
+
+static const char * const ai_errlist[] = {
+	"Success",
+	"Address family for hostname not supported",	/* EAI_ADDRFAMILY */
+	"Temporary failure in name resolution",		/* EAI_AGAIN      */
+	"Invalid value for ai_flags",		       	/* EAI_BADFLAGS   */
+	"Non-recoverable failure in name resolution", 	/* EAI_FAIL       */
+	"ai_family not supported",			/* EAI_FAMILY     */
+	"Memory allocation failure", 			/* EAI_MEMORY     */
+	"No address associated with hostname", 		/* EAI_NODATA     */
+	"hostname nor servname provided, or not known",	/* EAI_NONAME     */
+	"servname not supported for ai_socktype",	/* EAI_SERVICE    */
+	"ai_socktype not supported", 			/* EAI_SOCKTYPE   */
+	"System error returned in errno", 		/* EAI_SYSTEM     */
+	"Invalid value for hints",			/* EAI_BADHINTS	  */
+	"Resolved protocol is unknown",			/* EAI_PROTOCOL   */
+	"Argument buffer overflow",			/* EAI_OVERFLOW   */
+	"Unknown error", 				/* EAI_MAX        */
+};
+
+/* XXX macros that make external reference is BAD. */
+
+#define GET_AI(ai, afd, addr) 					\
+do { 								\
+	/* external reference: pai, error, and label free */ 	\
+	(ai) = get_ai(pai, (afd), (addr)); 			\
+	if ((ai) == NULL) { 					\
+		error = EAI_MEMORY; 				\
+		goto free; 					\
+	} 							\
+} while (/*CONSTCOND*/0)
+
+#define GET_PORT(ai, serv) 					\
+do { 								\
+	/* external reference: error and label free */ 		\
+	error = get_port((ai), (serv), 0); 			\
+	if (error != 0) 					\
+		goto free; 					\
+} while (/*CONSTCOND*/0)
+
+#define GET_CANONNAME(ai, str) 					\
+do { 								\
+	/* external reference: pai, error and label free */ 	\
+	error = get_canonname(pai, (ai), (str)); 		\
+	if (error != 0) 					\
+		goto free; 					\
+} while (/*CONSTCOND*/0)
+
+#define ERR(err) 						\
+do { 								\
+	/* external reference: error, and label bad */ 		\
+	error = (err); 						\
+	goto bad; 						\
+	/*NOTREACHED*/ 						\
+} while (/*CONSTCOND*/0)
+
+#define MATCH_FAMILY(x, y, w) 						\
+	((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || 	\
+	    (y) == PF_UNSPEC)))
+#define MATCH(x, y, w) 							\
+	((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY)))
+
+#pragma GCC visibility push(default)
+
+extern const char *
+__wrap_gai_strerror(int ecode);
+extern void
+__wrap_freeaddrinfo(struct addrinfo *ai);
+extern int
+__wrap_getaddrinfo(const char *hostname, const char *servname,
+    const struct addrinfo *hints, struct addrinfo **res);
+
+int android_sdk_version;
+
+#pragma GCC visibility pop
+
+int android_sdk_version = -1;
+
+static int honeycomb_or_later()
+{
+#ifdef MOZ_GETADDRINFO_LOG_VERBOSE
+	__android_log_print(ANDROID_LOG_INFO, "getaddrinfo",
+		"I am%s Honeycomb\n",
+		(android_sdk_version >= 11) ? "" : " not");
+#endif
+	return android_sdk_version >= 11;
+}
+
+const char *
+__wrap_gai_strerror(int ecode)
+{
+	if (honeycomb_or_later())
+		return gai_strerror(ecode);
+	if (ecode < 0 || ecode > EAI_MAX)
+		ecode = EAI_MAX;
+	return ai_errlist[ecode];
+}
+
+void
+__wrap_freeaddrinfo(struct addrinfo *ai)
+{
+	struct addrinfo *next;
+
+	if (honeycomb_or_later()) {
+		freeaddrinfo(ai);
+		return;
+	}
+
+	assert(ai != NULL);
+
+	do {
+		next = ai->ai_next;
+		if (ai->ai_canonname)
+			free(ai->ai_canonname);
+		/* no need to free(ai->ai_addr) */
+		free(ai);
+		ai = next;
+	} while (ai);
+}
+
+static int
+str2number(const char *p)
+{
+	char *ep;
+	unsigned long v;
+
+	assert(p != NULL);
+
+	if (*p == '\0')
+		return -1;
+	ep = NULL;
+	errno = 0;
+	v = strtoul(p, &ep, 10);
+	if (errno == 0 && ep && *ep == '\0' && v <= UINT_MAX)
+		return v;
+	else
+		return -1;
+}
+
+/*
+ * Connect a UDP socket to a given unicast address. This will cause no network
+ * traffic, but will fail fast if the system has no or limited reachability to
+ * the destination (e.g., no IPv4 address, no IPv6 default route, ...).
+ */
+static int
+_test_connect(int pf, struct sockaddr *addr, size_t addrlen) {
+	int s = socket(pf, SOCK_DGRAM, IPPROTO_UDP);
+	if (s < 0)
+		return 0;
+	int ret;
+	do {
+		ret = connect(s, addr, addrlen);
+	} while (ret < 0 && errno == EINTR);
+	int success = (ret == 0);
+	do {
+		ret = close(s);
+	} while (ret < 0 && errno == EINTR);
+	return success;
+}
+
+/*
+ * The following functions determine whether IPv4 or IPv6 connectivity is
+ * available in order to implement AI_ADDRCONFIG.
+ *
+ * Strictly speaking, AI_ADDRCONFIG should not look at whether connectivity is
+ * available, but whether addresses of the specified family are "configured
+ * on the local system". However, bionic doesn't currently support getifaddrs,
+ * so checking for connectivity is the next best thing.
+ */
+static int
+_have_ipv6() {
+	static const struct sockaddr_in6 sin6_test = {
+		.sin6_family = AF_INET6,
+		.sin6_addr.s6_addr = {  // 2000::
+			0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+		};
+        sockaddr_union addr = { .in6 = sin6_test };
+	return _test_connect(PF_INET6, &addr.generic, sizeof(addr.in6));
+}
+
+static int
+_have_ipv4() {
+	static const struct sockaddr_in sin_test = {
+		.sin_family = AF_INET,
+		.sin_addr.s_addr = __constant_htonl(0x08080808L)  // 8.8.8.8
+	};
+        sockaddr_union addr = { .in = sin_test };
+        return _test_connect(PF_INET, &addr.generic, sizeof(addr.in));
+}
+
+int
+__wrap_getaddrinfo(const char *hostname, const char *servname,
+    const struct addrinfo *hints, struct addrinfo **res)
+{
+	struct addrinfo sentinel;
+	struct addrinfo *cur;
+	int error = 0;
+	struct addrinfo ai;
+	struct addrinfo ai0;
+	struct addrinfo *pai;
+	const struct explore *ex;
+
+	if (honeycomb_or_later())
+		return getaddrinfo(hostname, servname, hints, res);
+
+	/* hostname is allowed to be NULL */
+	/* servname is allowed to be NULL */
+	/* hints is allowed to be NULL */
+	assert(res != NULL);
+
+	memset(&sentinel, 0, sizeof(sentinel));
+	cur = &sentinel;
+	pai = &ai;
+	pai->ai_flags = 0;
+	pai->ai_family = PF_UNSPEC;
+	pai->ai_socktype = ANY;
+	pai->ai_protocol = ANY;
+	pai->ai_addrlen = 0;
+	pai->ai_canonname = NULL;
+	pai->ai_addr = NULL;
+	pai->ai_next = NULL;
+
+	if (hostname == NULL && servname == NULL)
+		return EAI_NONAME;
+	if (hints) {
+		/* error check for hints */
+		if (hints->ai_addrlen || hints->ai_canonname ||
+		    hints->ai_addr || hints->ai_next)
+			ERR(EAI_BADHINTS); /* xxx */
+		if (hints->ai_flags & ~AI_MASK)
+			ERR(EAI_BADFLAGS);
+		switch (hints->ai_family) {
+		case PF_UNSPEC:
+		case PF_INET:
+#ifdef INET6
+		case PF_INET6:
+#endif
+			break;
+		default:
+			ERR(EAI_FAMILY);
+		}
+		memcpy(pai, hints, sizeof(*pai));
+
+		/*
+		 * if both socktype/protocol are specified, check if they
+		 * are meaningful combination.
+		 */
+		if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) {
+			for (ex = explore; ex->e_af >= 0; ex++) {
+				if (pai->ai_family != ex->e_af)
+					continue;
+				if (ex->e_socktype == ANY)
+					continue;
+				if (ex->e_protocol == ANY)
+					continue;
+				if (pai->ai_socktype == ex->e_socktype
+				 && pai->ai_protocol != ex->e_protocol) {
+					ERR(EAI_BADHINTS);
+				}
+			}
+		}
+	}
+
+	/*
+	 * check for special cases.  (1) numeric servname is disallowed if
+	 * socktype/protocol are left unspecified. (2) servname is disallowed
+	 * for raw and other inet{,6} sockets.
+	 */
+	if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)
+#ifdef PF_INET6
+	 || MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
+#endif
+	    ) {
+		ai0 = *pai;	/* backup *pai */
+
+		if (pai->ai_family == PF_UNSPEC) {
+#ifdef PF_INET6
+			pai->ai_family = PF_INET6;
+#else
+			pai->ai_family = PF_INET;
+#endif
+		}
+		error = get_portmatch(pai, servname);
+		if (error)
+			ERR(error);
+
+		*pai = ai0;
+	}
+
+	ai0 = *pai;
+
+	/* NULL hostname, or numeric hostname */
+	for (ex = explore; ex->e_af >= 0; ex++) {
+		*pai = ai0;
+
+		/* PF_UNSPEC entries are prepared for DNS queries only */
+		if (ex->e_af == PF_UNSPEC)
+			continue;
+
+		if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
+			continue;
+		if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex)))
+			continue;
+		if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))
+			continue;
+
+		if (pai->ai_family == PF_UNSPEC)
+			pai->ai_family = ex->e_af;
+		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
+			pai->ai_socktype = ex->e_socktype;
+		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
+			pai->ai_protocol = ex->e_protocol;
+
+		if (hostname == NULL)
+			error = explore_null(pai, servname, &cur->ai_next);
+		else
+			error = explore_numeric_scope(pai, hostname, servname,
+			    &cur->ai_next);
+
+		if (error)
+			goto free;
+
+		while (cur->ai_next)
+			cur = cur->ai_next;
+	}
+
+	/*
+	 * XXX
+	 * If numeric representation of AF1 can be interpreted as FQDN
+	 * representation of AF2, we need to think again about the code below.
+	 */
+	if (sentinel.ai_next)
+		goto good;
+
+	if (hostname == NULL)
+		ERR(EAI_NODATA);
+	if (pai->ai_flags & AI_NUMERICHOST)
+		ERR(EAI_NONAME);
+
+	/*
+	 * hostname as alphabetical name.
+	 * we would like to prefer AF_INET6 than AF_INET, so we'll make a
+	 * outer loop by AFs.
+	 */
+	for (ex = explore; ex->e_af >= 0; ex++) {
+		*pai = ai0;
+
+		/* require exact match for family field */
+		if (pai->ai_family != ex->e_af)
+			continue;
+
+		if (!MATCH(pai->ai_socktype, ex->e_socktype,
+				WILD_SOCKTYPE(ex))) {
+			continue;
+		}
+		if (!MATCH(pai->ai_protocol, ex->e_protocol,
+				WILD_PROTOCOL(ex))) {
+			continue;
+		}
+
+		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
+			pai->ai_socktype = ex->e_socktype;
+		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
+			pai->ai_protocol = ex->e_protocol;
+
+		error = explore_fqdn(pai, hostname, servname,
+			&cur->ai_next);
+
+		while (cur && cur->ai_next)
+			cur = cur->ai_next;
+	}
+
+	/* XXX */
+	if (sentinel.ai_next)
+		error = 0;
+
+	if (error)
+		goto free;
+	if (error == 0) {
+		if (sentinel.ai_next) {
+ good:
+			*res = sentinel.ai_next;
+			return SUCCESS;
+		} else
+			error = EAI_FAIL;
+	}
+ free:
+ bad:
+	if (sentinel.ai_next)
+		__wrap_freeaddrinfo(sentinel.ai_next);
+	*res = NULL;
+	return error;
+}
+
+/*
+ * FQDN hostname, DNS lookup
+ */
+static int
+explore_fqdn(const struct addrinfo *pai, const char *hostname,
+    const char *servname, struct addrinfo **res)
+{
+	struct addrinfo *result;
+	struct addrinfo *cur;
+	int error = 0;
+	static const ns_dtab dtab[] = {
+		NS_FILES_CB(_files_getaddrinfo, NULL)
+		{ NSSRC_DNS, _dns_getaddrinfo, NULL },	/* force -DHESIOD */
+		NS_NIS_CB(_yp_getaddrinfo, NULL)
+		{ 0, 0, 0 }
+	};
+
+	assert(pai != NULL);
+	/* hostname may be NULL */
+	/* servname may be NULL */
+	assert(res != NULL);
+
+	result = NULL;
+
+	/*
+	 * if the servname does not match socktype/protocol, ignore it.
+	 */
+	if (get_portmatch(pai, servname) != 0)
+		return 0;
+
+	switch (nsdispatch(&result, dtab, NSDB_HOSTS, "getaddrinfo",
+			default_dns_files, hostname, pai)) {
+	case NS_TRYAGAIN:
+		error = EAI_AGAIN;
+		goto free;
+	case NS_UNAVAIL:
+		error = EAI_FAIL;
+		goto free;
+	case NS_NOTFOUND:
+		error = EAI_NODATA;
+		goto free;
+	case NS_SUCCESS:
+		error = 0;
+		for (cur = result; cur; cur = cur->ai_next) {
+			GET_PORT(cur, servname);
+			/* canonname should be filled already */
+		}
+		break;
+	}
+
+	*res = result;
+
+	return 0;
+
+free:
+	if (result)
+		__wrap_freeaddrinfo(result);
+	return error;
+}
+
+/*
+ * hostname == NULL.
+ * passive socket -> anyaddr (0.0.0.0 or ::)
+ * non-passive socket -> localhost (127.0.0.1 or ::1)
+ */
+static int
+explore_null(const struct addrinfo *pai, const char *servname,
+    struct addrinfo **res)
+{
+	int s;
+	const struct afd *afd;
+	struct addrinfo *cur;
+	struct addrinfo sentinel;
+	int error;
+
+	assert(pai != NULL);
+	/* servname may be NULL */
+	assert(res != NULL);
+
+	*res = NULL;
+	sentinel.ai_next = NULL;
+	cur = &sentinel;
+
+	/*
+	 * filter out AFs that are not supported by the kernel
+	 * XXX errno?
+	 */
+	s = socket(pai->ai_family, SOCK_DGRAM, 0);
+	if (s < 0) {
+		if (errno != EMFILE)
+			return 0;
+	} else
+		close(s);
+
+	/*
+	 * if the servname does not match socktype/protocol, ignore it.
+	 */
+	if (get_portmatch(pai, servname) != 0)
+		return 0;
+
+	afd = find_afd(pai->ai_family);
+	if (afd == NULL)
+		return 0;
+
+	if (pai->ai_flags & AI_PASSIVE) {
+		GET_AI(cur->ai_next, afd, afd->a_addrany);
+		/* xxx meaningless?
+		 * GET_CANONNAME(cur->ai_next, "anyaddr");
+		 */
+		GET_PORT(cur->ai_next, servname);
+	} else {
+		GET_AI(cur->ai_next, afd, afd->a_loopback);
+		/* xxx meaningless?
+		 * GET_CANONNAME(cur->ai_next, "localhost");
+		 */
+		GET_PORT(cur->ai_next, servname);
+	}
+	cur = cur->ai_next;
+
+	*res = sentinel.ai_next;
+	return 0;
+
+free:
+	if (sentinel.ai_next)
+		__wrap_freeaddrinfo(sentinel.ai_next);
+	return error;
+}
+
+/*
+ * numeric hostname
+ */
+static int
+explore_numeric(const struct addrinfo *pai, const char *hostname,
+    const char *servname, struct addrinfo **res, const char *canonname)
+{
+	const struct afd *afd;
+	struct addrinfo *cur;
+	struct addrinfo sentinel;
+	int error;
+	char pton[PTON_MAX];
+
+	assert(pai != NULL);
+	/* hostname may be NULL */
+	/* servname may be NULL */
+	assert(res != NULL);
+
+	*res = NULL;
+	sentinel.ai_next = NULL;
+	cur = &sentinel;
+
+	/*
+	 * if the servname does not match socktype/protocol, ignore it.
+	 */
+	if (get_portmatch(pai, servname) != 0)
+		return 0;
+
+	afd = find_afd(pai->ai_family);
+	if (afd == NULL)
+		return 0;
+
+	switch (afd->a_af) {
+#if 0 /*X/Open spec*/
+	case AF_INET:
+		if (inet_aton(hostname, (struct in_addr *)pton) == 1) {
+			if (pai->ai_family == afd->a_af ||
+			    pai->ai_family == PF_UNSPEC /*?*/) {
+				GET_AI(cur->ai_next, afd, pton);
+				GET_PORT(cur->ai_next, servname);
+				if ((pai->ai_flags & AI_CANONNAME)) {
+					/*
+					 * Set the numeric address itself as
+					 * the canonical name, based on a
+					 * clarification in rfc2553bis-03.
+					 */
+					GET_CANONNAME(cur->ai_next, canonname);
+				}
+				while (cur && cur->ai_next)
+					cur = cur->ai_next;
+			} else
+				ERR(EAI_FAMILY);	/*xxx*/
+		}
+		break;
+#endif
+	default:
+		if (inet_pton(afd->a_af, hostname, pton) == 1) {
+			if (pai->ai_family == afd->a_af ||
+			    pai->ai_family == PF_UNSPEC /*?*/) {
+				GET_AI(cur->ai_next, afd, pton);
+				GET_PORT(cur->ai_next, servname);
+				if ((pai->ai_flags & AI_CANONNAME)) {
+					/*
+					 * Set the numeric address itself as
+					 * the canonical name, based on a
+					 * clarification in rfc2553bis-03.
+					 */
+					GET_CANONNAME(cur->ai_next, canonname);
+				}
+				while (cur->ai_next)
+					cur = cur->ai_next;
+			} else
+				ERR(EAI_FAMILY);	/*xxx*/
+		}
+		break;
+	}
+
+	*res = sentinel.ai_next;
+	return 0;
+
+free:
+bad:
+	if (sentinel.ai_next)
+		__wrap_freeaddrinfo(sentinel.ai_next);
+	return error;
+}
+
+/*
+ * numeric hostname with scope
+ */
+static int
+explore_numeric_scope(const struct addrinfo *pai, const char *hostname,
+    const char *servname, struct addrinfo **res)
+{
+#if !defined(SCOPE_DELIMITER) || !defined(INET6)
+	return explore_numeric(pai, hostname, servname, res, hostname);
+#else
+	const struct afd *afd;
+	struct addrinfo *cur;
+	int error;
+	char *cp, *hostname2 = NULL, *scope, *addr;
+	struct sockaddr_in6 *sin6;
+
+	assert(pai != NULL);
+	/* hostname may be NULL */
+	/* servname may be NULL */
+	assert(res != NULL);
+
+	/*
+	 * if the servname does not match socktype/protocol, ignore it.
+	 */
+	if (get_portmatch(pai, servname) != 0)
+		return 0;
+
+	afd = find_afd(pai->ai_family);
+	if (afd == NULL)
+		return 0;
+
+	if (!afd->a_scoped)
+		return explore_numeric(pai, hostname, servname, res, hostname);
+
+	cp = strchr(hostname, SCOPE_DELIMITER);
+	if (cp == NULL)
+		return explore_numeric(pai, hostname, servname, res, hostname);
+
+	/*
+	 * Handle special case of <scoped_address><delimiter><scope id>
+	 */
+	hostname2 = strdup(hostname);
+	if (hostname2 == NULL)
+		return EAI_MEMORY;
+	/* terminate at the delimiter */
+	hostname2[cp - hostname] = '\0';
+	addr = hostname2;
+	scope = cp + 1;
+
+	error = explore_numeric(pai, addr, servname, res, hostname);
+	if (error == 0) {
+		u_int32_t scopeid;
+
+		for (cur = *res; cur; cur = cur->ai_next) {
+			if (cur->ai_family != AF_INET6)
+				continue;
+			sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr;
+			if (ip6_str2scopeid(scope, sin6, &scopeid) == -1) {
+				free(hostname2);
+				return(EAI_NODATA); /* XXX: is return OK? */
+			}
+			sin6->sin6_scope_id = scopeid;
+		}
+	}
+
+	free(hostname2);
+
+	return error;
+#endif
+}
+
+static int
+get_canonname(const struct addrinfo *pai, struct addrinfo *ai, const char *str)
+{
+
+	assert(pai != NULL);
+	assert(ai != NULL);
+	assert(str != NULL);
+
+	if ((pai->ai_flags & AI_CANONNAME) != 0) {
+		ai->ai_canonname = strdup(str);
+		if (ai->ai_canonname == NULL)
+			return EAI_MEMORY;
+	}
+	return 0;
+}
+
+static struct addrinfo *
+get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr)
+{
+	char *p;
+	struct addrinfo *ai;
+
+	assert(pai != NULL);
+	assert(afd != NULL);
+	assert(addr != NULL);
+
+	ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)
+		+ (afd->a_socklen));
+	if (ai == NULL)
+		return NULL;
+
+	memcpy(ai, pai, sizeof(struct addrinfo));
+	ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);
+	memset(ai->ai_addr, 0, (size_t)afd->a_socklen);
+
+#ifdef HAVE_SA_LEN
+	ai->ai_addr->sa_len = afd->a_socklen;
+#endif
+
+	ai->ai_addrlen = afd->a_socklen;
+#if defined (__alpha__) || (defined(__i386__) && defined(_LP64)) || defined(__sparc64__)
+	ai->__ai_pad0 = 0;
+#endif
+	ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
+	p = (char *)(void *)(ai->ai_addr);
+	memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen);
+	return ai;
+}
+
+static int
+get_portmatch(const struct addrinfo *ai, const char *servname)
+{
+
+	assert(ai != NULL);
+	/* servname may be NULL */
+
+	return get_port(ai, servname, 1);
+}
+
+static int
+get_port(const struct addrinfo *ai, const char *servname, int matchonly)
+{
+	const char *proto;
+	struct servent *sp;
+	int port;
+	int allownumeric;
+
+	assert(ai != NULL);
+	/* servname may be NULL */
+
+	if (servname == NULL)
+		return 0;
+	switch (ai->ai_family) {
+	case AF_INET:
+#ifdef AF_INET6
+	case AF_INET6:
+#endif
+		break;
+	default:
+		return 0;
+	}
+
+	switch (ai->ai_socktype) {
+	case SOCK_RAW:
+		return EAI_SERVICE;
+	case SOCK_DGRAM:
+	case SOCK_STREAM:
+		allownumeric = 1;
+		break;
+	case ANY:
+#if 1  /* ANDROID-SPECIFIC CHANGE TO MATCH GLIBC */
+		allownumeric = 1;
+#else
+		allownumeric = 0;
+#endif
+		break;
+	default:
+		return EAI_SOCKTYPE;
+	}
+
+	port = str2number(servname);
+	if (port >= 0) {
+		if (!allownumeric)
+			return EAI_SERVICE;
+		if (port < 0 || port > 65535)
+			return EAI_SERVICE;
+		port = htons(port);
+	} else {
+		if (ai->ai_flags & AI_NUMERICSERV)
+			return EAI_NONAME;
+
+		switch (ai->ai_socktype) {
+		case SOCK_DGRAM:
+			proto = "udp";
+			break;
+		case SOCK_STREAM:
+			proto = "tcp";
+			break;
+		default:
+			proto = NULL;
+			break;
+		}
+
+		if ((sp = getservbyname(servname, proto)) == NULL)
+			return EAI_SERVICE;
+		port = sp->s_port;
+	}
+
+	if (!matchonly) {
+		switch (ai->ai_family) {
+		case AF_INET:
+			((struct sockaddr_in *)(void *)
+			    ai->ai_addr)->sin_port = port;
+			break;
+#ifdef INET6
+		case AF_INET6:
+			((struct sockaddr_in6 *)(void *)
+			    ai->ai_addr)->sin6_port = port;
+			break;
+#endif
+		}
+	}
+
+	return 0;
+}
+
+static const struct afd *
+find_afd(int af)
+{
+	const struct afd *afd;
+
+	if (af == PF_UNSPEC)
+		return NULL;
+	for (afd = afdl; afd->a_af; afd++) {
+		if (afd->a_af == af)
+			return afd;
+	}
+	return NULL;
+}
+
+#ifdef INET6
+/* convert a string to a scope identifier. XXX: IPv6 specific */
+static int
+ip6_str2scopeid(char *scope, struct sockaddr_in6 *sin6, u_int32_t *scopeid)
+{
+	u_long lscopeid;
+	struct in6_addr *a6;
+	char *ep;
+
+	assert(scope != NULL);
+	assert(sin6 != NULL);
+	assert(scopeid != NULL);
+
+	a6 = &sin6->sin6_addr;
+
+	/* empty scopeid portion is invalid */
+	if (*scope == '\0')
+		return -1;
+
+	if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) {
+		/*
+		 * We currently assume a one-to-one mapping between links
+		 * and interfaces, so we simply use interface indices for
+		 * like-local scopes.
+		 */
+		*scopeid = if_nametoindex(scope);
+		if (*scopeid == 0)
+			goto trynumeric;
+		return 0;
+	}
+
+	/* still unclear about literal, allow numeric only - placeholder */
+	if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6))
+		goto trynumeric;
+	if (IN6_IS_ADDR_MC_ORGLOCAL(a6))
+		goto trynumeric;
+	else
+		goto trynumeric;	/* global */
+
+	/* try to convert to a numeric id as a last resort */
+  trynumeric:
+	errno = 0;
+	lscopeid = strtoul(scope, &ep, 10);
+	*scopeid = (u_int32_t)(lscopeid & 0xffffffffUL);
+	if (errno == 0 && ep && *ep == '\0' && *scopeid == lscopeid)
+		return 0;
+	else
+		return -1;
+}
+#endif
+
+/* code duplicate with gethnamaddr.c */
+
+static const char AskedForGot[] =
+	"gethostby*.getanswer: asked for \"%s\", got \"%s\"";
+
+static struct addrinfo *
+getanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
+    const struct addrinfo *pai)
+{
+	struct addrinfo sentinel, *cur;
+	struct addrinfo ai;
+	const struct afd *afd;
+	char *canonname;
+	const HEADER *hp;
+	const u_char *cp;
+	int n;
+	const u_char *eom;
+	char *bp, *ep;
+	int type, class, ancount, qdcount;
+	int haveanswer, had_error;
+	char tbuf[MAXDNAME];
+	int (*name_ok) (const char *);
+	char hostbuf[8*1024];
+
+	assert(answer != NULL);
+	assert(qname != NULL);
+	assert(pai != NULL);
+
+	memset(&sentinel, 0, sizeof(sentinel));
+	cur = &sentinel;
+
+	canonname = NULL;
+	eom = answer->buf + anslen;
+	switch (qtype) {
+	case T_A:
+	case T_AAAA:
+	case T_ANY:	/*use T_ANY only for T_A/T_AAAA lookup*/
+		name_ok = res_hnok;
+		break;
+	default:
+		return NULL;	/* XXX should be abort(); */
+	}
+	/*
+	 * find first satisfactory answer
+	 */
+	hp = &answer->hdr;
+	ancount = ntohs(hp->ancount);
+	qdcount = ntohs(hp->qdcount);
+	bp = hostbuf;
+	ep = hostbuf + sizeof hostbuf;
+	cp = answer->buf + HFIXEDSZ;
+	if (qdcount != 1) {
+		h_errno = NO_RECOVERY;
+		return (NULL);
+	}
+	n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
+	if ((n < 0) || !(*name_ok)(bp)) {
+		h_errno = NO_RECOVERY;
+		return (NULL);
+	}
+	cp += n + QFIXEDSZ;
+	if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) {
+		/* res_send() has already verified that the query name is the
+		 * same as the one we sent; this just gets the expanded name
+		 * (i.e., with the succeeding search-domain tacked on).
+		 */
+		n = strlen(bp) + 1;		/* for the \0 */
+		if (n >= MAXHOSTNAMELEN) {
+			h_errno = NO_RECOVERY;
+			return (NULL);
+		}
+		canonname = bp;
+		bp += n;
+		/* The qname can be abbreviated, but h_name is now absolute. */
+		qname = canonname;
+	}
+	haveanswer = 0;
+	had_error = 0;
+	while (ancount-- > 0 && cp < eom && !had_error) {
+		n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
+		if ((n < 0) || !(*name_ok)(bp)) {
+			had_error++;
+			continue;
+		}
+		cp += n;			/* name */
+		type = _getshort(cp);
+ 		cp += INT16SZ;			/* type */
+		class = _getshort(cp);
+ 		cp += INT16SZ + INT32SZ;	/* class, TTL */
+		n = _getshort(cp);
+		cp += INT16SZ;			/* len */
+		if (class != C_IN) {
+			/* XXX - debug? syslog? */
+			cp += n;
+			continue;		/* XXX - had_error++ ? */
+		}
+		if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) &&
+		    type == T_CNAME) {
+			n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
+			if ((n < 0) || !(*name_ok)(tbuf)) {
+				had_error++;
+				continue;
+			}
+			cp += n;
+			/* Get canonical name. */
+			n = strlen(tbuf) + 1;	/* for the \0 */
+			if (n > ep - bp || n >= MAXHOSTNAMELEN) {
+				had_error++;
+				continue;
+			}
+			strlcpy(bp, tbuf, (size_t)(ep - bp));
+			canonname = bp;
+			bp += n;
+			continue;
+		}
+		if (qtype == T_ANY) {
+			if (!(type == T_A || type == T_AAAA)) {
+				cp += n;
+				continue;
+			}
+		} else if (type != qtype) {
+			if (type != T_KEY && type != T_SIG)
+				syslog(LOG_NOTICE|LOG_AUTH,
+	       "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
+				       qname, p_class(C_IN), p_type(qtype),
+				       p_type(type));
+			cp += n;
+			continue;		/* XXX - had_error++ ? */
+		}
+		switch (type) {
+		case T_A:
+		case T_AAAA:
+			if (strcasecmp(canonname, bp) != 0) {
+				syslog(LOG_NOTICE|LOG_AUTH,
+				       AskedForGot, canonname, bp);
+				cp += n;
+				continue;	/* XXX - had_error++ ? */
+			}
+			if (type == T_A && n != INADDRSZ) {
+				cp += n;
+				continue;
+			}
+			if (type == T_AAAA && n != IN6ADDRSZ) {
+				cp += n;
+				continue;
+			}
+			if (type == T_AAAA) {
+				struct in6_addr in6;
+				memcpy(&in6, cp, IN6ADDRSZ);
+				if (IN6_IS_ADDR_V4MAPPED(&in6)) {
+					cp += n;
+					continue;
+				}
+			}
+			if (!haveanswer) {
+				int nn;
+
+				canonname = bp;
+				nn = strlen(bp) + 1;	/* for the \0 */
+				bp += nn;
+			}
+
+			/* don't overwrite pai */
+			ai = *pai;
+			ai.ai_family = (type == T_A) ? AF_INET : AF_INET6;
+			afd = find_afd(ai.ai_family);
+			if (afd == NULL) {
+				cp += n;
+				continue;
+			}
+			cur->ai_next = get_ai(&ai, afd, (const char *)cp);
+			if (cur->ai_next == NULL)
+				had_error++;
+			while (cur && cur->ai_next)
+				cur = cur->ai_next;
+			cp += n;
+			break;
+		default:
+			abort();
+		}
+		if (!had_error)
+			haveanswer++;
+	}
+	if (haveanswer) {
+		if (!canonname)
+			(void)get_canonname(pai, sentinel.ai_next, qname);
+		else
+			(void)get_canonname(pai, sentinel.ai_next, canonname);
+		h_errno = NETDB_SUCCESS;
+		return sentinel.ai_next;
+	}
+
+	h_errno = NO_RECOVERY;
+	return NULL;
+}
+
+struct addrinfo_sort_elem {
+	struct addrinfo *ai;
+	int has_src_addr;
+	sockaddr_union src_addr;
+	int original_order;
+};
+
+/*ARGSUSED*/
+static int
+_get_scope(const struct sockaddr *addr)
+{
+	if (addr->sa_family == AF_INET6) {
+		const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
+		if (IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr)) {
+			return IPV6_ADDR_MC_SCOPE(&addr6->sin6_addr);
+		} else if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr) ||
+			   IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr)) {
+			/*
+			 * RFC 4291 section 2.5.3 says loopback is to be treated as having
+			 * link-local scope.
+			 */
+			return IPV6_ADDR_SCOPE_LINKLOCAL;
+		} else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) {
+			return IPV6_ADDR_SCOPE_SITELOCAL;
+		} else {
+			return IPV6_ADDR_SCOPE_GLOBAL;
+		}
+	} else if (addr->sa_family == AF_INET) {
+		const struct sockaddr_in *addr4 = (const struct sockaddr_in *)addr;
+		unsigned long int na = ntohl(addr4->sin_addr.s_addr);
+
+		if (IN_LOOPBACK(na) ||                          /* 127.0.0.0/8 */
+		    (na & 0xffff0000) == 0xa9fe0000) {          /* 169.254.0.0/16 */
+			return IPV6_ADDR_SCOPE_LINKLOCAL;
+		} else {
+			/*
+			 * According to draft-ietf-6man-rfc3484-revise-01 section 2.3,
+			 * it is best not to treat the private IPv4 ranges
+			 * (10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16) as being
+			 * in a special scope, so we don't.
+			 */
+			return IPV6_ADDR_SCOPE_GLOBAL;
+		}
+	} else {
+		/*
+		 * This should never happen.
+		 * Return a scope with low priority as a last resort.
+		 */
+		return IPV6_ADDR_SCOPE_NODELOCAL;
+	}
+}
+
+/* These macros are modelled after the ones in <netinet/in6.h>. */
+
+/* RFC 4380, section 2.6 */
+#define IN6_IS_ADDR_TEREDO(a)	 \
+	((*(const uint32_t *)(const void *)(&(a)->s6_addr[0]) == ntohl(0x20010000)))
+
+/* RFC 3056, section 2. */
+#define IN6_IS_ADDR_6TO4(a)	 \
+	(((a)->s6_addr[0] == 0x20) && ((a)->s6_addr[1] == 0x02))
+
+/* 6bone testing address area (3ffe::/16), deprecated in RFC 3701. */
+#define IN6_IS_ADDR_6BONE(a)      \
+	(((a)->s6_addr[0] == 0x3f) && ((a)->s6_addr[1] == 0xfe))
+
+/*
+ * Get the label for a given IPv4/IPv6 address.
+ * RFC 3484, section 2.1, plus changes from draft-ietf-6man-rfc3484-revise-01.
+ */
+
+/*ARGSUSED*/
+static int
+_get_label(const struct sockaddr *addr)
+{
+	if (addr->sa_family == AF_INET) {
+		return 3;
+	} else if (addr->sa_family == AF_INET6) {
+		const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
+		if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) {
+			return 0;
+		} else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
+			return 3;
+		} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
+			return 4;
+		} else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) {
+			return 5;
+		} else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) {
+			return 10;
+		} else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) {
+			return 11;
+		} else if (IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) {
+			return 12;
+		} else {
+			return 2;
+		}
+	} else {
+		/*
+		 * This should never happen.
+		 * Return a semi-random label as a last resort.
+		 */
+		return 1;
+	}
+}
+
+/*
+ * Get the precedence for a given IPv4/IPv6 address.
+ * RFC 3484, section 2.1, plus changes from draft-ietf-6man-rfc3484-revise-01.
+ */
+
+/*ARGSUSED*/
+static int
+_get_precedence(const struct sockaddr *addr)
+{
+	if (addr->sa_family == AF_INET) {
+		return 30;
+	} else if (addr->sa_family == AF_INET6) {
+		const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
+		if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) {
+			return 60;
+		} else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
+			return 30;
+		} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
+			return 20;
+		} else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) {
+			return 10;
+		} else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr) ||
+		           IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr) ||
+		           IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) {
+			return 1;
+		} else {
+			return 40;
+		}
+	} else {
+		return 1;
+	}
+}
+
+/*
+ * Find number of matching initial bits between the two addresses a1 and a2.
+ */
+
+/*ARGSUSED*/
+static int
+_common_prefix_len(const struct in6_addr *a1, const struct in6_addr *a2)
+{
+	const char *p1 = (const char *)a1;
+	const char *p2 = (const char *)a2;
+	unsigned i;
+
+	for (i = 0; i < sizeof(*a1); ++i) {
+		int x, j;
+
+		if (p1[i] == p2[i]) {
+			continue;
+		}
+		x = p1[i] ^ p2[i];
+		for (j = 0; j < CHAR_BIT; ++j) {
+			if (x & (1 << (CHAR_BIT - 1))) {
+				return i * CHAR_BIT + j;
+			}
+			x <<= 1;
+		}
+	}
+	return sizeof(*a1) * CHAR_BIT;
+}
+
+/*
+ * Compare two source/destination address pairs.
+ * RFC 3484, section 6.
+ */
+
+/*ARGSUSED*/
+static int
+_rfc3484_compare(const void *ptr1, const void* ptr2)
+{
+	const struct addrinfo_sort_elem *a1 = (const struct addrinfo_sort_elem *)ptr1;
+	const struct addrinfo_sort_elem *a2 = (const struct addrinfo_sort_elem *)ptr2;
+	int scope_src1, scope_dst1, scope_match1;
+	int scope_src2, scope_dst2, scope_match2;
+	int label_src1, label_dst1, label_match1;
+	int label_src2, label_dst2, label_match2;
+	int precedence1, precedence2;
+	int prefixlen1, prefixlen2;
+
+	/* Rule 1: Avoid unusable destinations. */
+	if (a1->has_src_addr != a2->has_src_addr) {
+		return a2->has_src_addr - a1->has_src_addr;
+	}
+
+	/* Rule 2: Prefer matching scope. */
+	scope_src1 = _get_scope(&a1->src_addr.generic);
+	scope_dst1 = _get_scope(a1->ai->ai_addr);
+	scope_match1 = (scope_src1 == scope_dst1);
+
+	scope_src2 = _get_scope(&a2->src_addr.generic);
+	scope_dst2 = _get_scope(a2->ai->ai_addr);
+	scope_match2 = (scope_src2 == scope_dst2);
+
+	if (scope_match1 != scope_match2) {
+		return scope_match2 - scope_match1;
+	}
+
+	/*
+	 * Rule 3: Avoid deprecated addresses.
+	 * TODO(sesse): We don't currently have a good way of finding this.
+	 */
+
+	/*
+	 * Rule 4: Prefer home addresses.
+	 * TODO(sesse): We don't currently have a good way of finding this.
+	 */
+
+	/* Rule 5: Prefer matching label. */
+	label_src1 = _get_label(&a1->src_addr.generic);
+	label_dst1 = _get_label(a1->ai->ai_addr);
+	label_match1 = (label_src1 == label_dst1);
+
+	label_src2 = _get_label(&a2->src_addr.generic);
+	label_dst2 = _get_label(a2->ai->ai_addr);
+	label_match2 = (label_src2 == label_dst2);
+
+	if (label_match1 != label_match2) {
+		return label_match2 - label_match1;
+	}
+
+	/* Rule 6: Prefer higher precedence. */
+	precedence1 = _get_precedence(a1->ai->ai_addr);
+	precedence2 = _get_precedence(a2->ai->ai_addr);
+	if (precedence1 != precedence2) {
+		return precedence2 - precedence1;
+	}
+
+	/*
+	 * Rule 7: Prefer native transport.
+	 * TODO(sesse): We don't currently have a good way of finding this.
+	 */
+
+	/* Rule 8: Prefer smaller scope. */
+	if (scope_dst1 != scope_dst2) {
+		return scope_dst1 - scope_dst2;
+	}
+
+	/*
+	 * Rule 9: Use longest matching prefix.
+         * We implement this for IPv6 only, as the rules in RFC 3484 don't seem
+         * to work very well directly applied to IPv4. (glibc uses information from
+         * the routing table for a custom IPv4 implementation here.)
+	 */
+	if (a1->has_src_addr && a1->ai->ai_addr->sa_family == AF_INET6 &&
+	    a2->has_src_addr && a2->ai->ai_addr->sa_family == AF_INET6) {
+		const struct sockaddr_in6 *a1_src = &a1->src_addr.in6;
+		const struct sockaddr_in6 *a1_dst = (const struct sockaddr_in6 *)a1->ai->ai_addr;
+		const struct sockaddr_in6 *a2_src = &a2->src_addr.in6;
+		const struct sockaddr_in6 *a2_dst = (const struct sockaddr_in6 *)a2->ai->ai_addr;
+		prefixlen1 = _common_prefix_len(&a1_src->sin6_addr, &a1_dst->sin6_addr);
+		prefixlen2 = _common_prefix_len(&a2_src->sin6_addr, &a2_dst->sin6_addr);
+		if (prefixlen1 != prefixlen2) {
+			return prefixlen2 - prefixlen1;
+		}
+	}
+
+	/*
+	 * Rule 10: Leave the order unchanged.
+	 * We need this since qsort() is not necessarily stable.
+	 */
+	return a1->original_order - a2->original_order;
+}
+
+/*
+ * Find the source address that will be used if trying to connect to the given
+ * address. src_addr must be large enough to hold a struct sockaddr_in6.
+ *
+ * Returns 1 if a source address was found, 0 if the address is unreachable,
+ * and -1 if a fatal error occurred. If 0 or 1, the contents of src_addr are
+ * undefined.
+ */
+
+/*ARGSUSED*/
+static int
+_find_src_addr(const struct sockaddr *addr, struct sockaddr *src_addr)
+{
+	int sock;
+	int ret;
+	socklen_t len;
+
+	switch (addr->sa_family) {
+	case AF_INET:
+		len = sizeof(struct sockaddr_in);
+		break;
+	case AF_INET6:
+		len = sizeof(struct sockaddr_in6);
+		break;
+	default:
+		/* No known usable source address for non-INET families. */
+		return 0;
+	}
+
+	sock = socket(addr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
+	if (sock == -1) {
+		if (errno == EAFNOSUPPORT) {
+			return 0;
+		} else {
+			return -1;
+		}
+	}
+
+	do {
+		ret = connect(sock, addr, len);
+	} while (ret == -1 && errno == EINTR);
+
+	if (ret == -1) {
+		close(sock);
+		return 0;
+	}
+
+	if (getsockname(sock, src_addr, &len) == -1) {
+		close(sock);
+		return -1;
+	}
+	close(sock);
+	return 1;
+}
+
+/*
+ * Sort the linked list starting at sentinel->ai_next in RFC3484 order.
+ * Will leave the list unchanged if an error occurs.
+ */
+
+/*ARGSUSED*/
+static void
+_rfc3484_sort(struct addrinfo *list_sentinel)
+{
+	struct addrinfo *cur;
+	int nelem = 0, i;
+	struct addrinfo_sort_elem *elems;
+
+	cur = list_sentinel->ai_next;
+	while (cur) {
+		++nelem;
+		cur = cur->ai_next;
+	}
+
+	elems = (struct addrinfo_sort_elem *)malloc(nelem * sizeof(struct addrinfo_sort_elem));
+	if (elems == NULL) {
+		goto error;
+	}
+
+	/*
+	 * Convert the linked list to an array that also contains the candidate
+	 * source address for each destination address.
+	 */
+	for (i = 0, cur = list_sentinel->ai_next; i < nelem; ++i, cur = cur->ai_next) {
+		int has_src_addr;
+		assert(cur != NULL);
+		elems[i].ai = cur;
+		elems[i].original_order = i;
+
+		has_src_addr = _find_src_addr(cur->ai_addr, &elems[i].src_addr.generic);
+		if (has_src_addr == -1) {
+			goto error;
+		}
+		elems[i].has_src_addr = has_src_addr;
+	}
+
+	/* Sort the addresses, and rearrange the linked list so it matches the sorted order. */
+	qsort((void *)elems, nelem, sizeof(struct addrinfo_sort_elem), _rfc3484_compare);
+
+	list_sentinel->ai_next = elems[0].ai;
+	for (i = 0; i < nelem - 1; ++i) {
+		elems[i].ai->ai_next = elems[i + 1].ai;
+	}
+	elems[nelem - 1].ai->ai_next = NULL;
+
+error:
+	free(elems);
+}
+
+/*ARGSUSED*/
+static int
+_dns_getaddrinfo(void *rv, void	*cb_data, va_list ap)
+{
+	struct addrinfo *ai;
+	querybuf *buf, *buf2;
+	const char *name;
+	const struct addrinfo *pai;
+	struct addrinfo sentinel, *cur;
+	struct res_target q, q2;
+	res_state res;
+
+	name = va_arg(ap, char *);
+	pai = va_arg(ap, const struct addrinfo *);
+	//fprintf(stderr, "_dns_getaddrinfo() name = '%s'\n", name);
+
+	memset(&q, 0, sizeof(q));
+	memset(&q2, 0, sizeof(q2));
+	memset(&sentinel, 0, sizeof(sentinel));
+	cur = &sentinel;
+
+	buf = malloc(sizeof(*buf));
+	if (buf == NULL) {
+		h_errno = NETDB_INTERNAL;
+		return NS_NOTFOUND;
+	}
+	buf2 = malloc(sizeof(*buf2));
+	if (buf2 == NULL) {
+		free(buf);
+		h_errno = NETDB_INTERNAL;
+		return NS_NOTFOUND;
+	}
+
+	switch (pai->ai_family) {
+	case AF_UNSPEC:
+		/* prefer IPv6 */
+		q.name = name;
+		q.qclass = C_IN;
+		q.answer = buf->buf;
+		q.anslen = sizeof(buf->buf);
+		int query_ipv6 = 1, query_ipv4 = 1;
+		if (pai->ai_flags & AI_ADDRCONFIG) {
+			query_ipv6 = _have_ipv6();
+			query_ipv4 = _have_ipv4();
+		}
+		if (query_ipv6) {
+			q.qtype = T_AAAA;
+			if (query_ipv4) {
+				q.next = &q2;
+				q2.name = name;
+				q2.qclass = C_IN;
+				q2.qtype = T_A;
+				q2.answer = buf2->buf;
+				q2.anslen = sizeof(buf2->buf);
+			}
+		} else if (query_ipv4) {
+			q.qtype = T_A;
+		} else {
+			free(buf);
+			free(buf2);
+			return NS_NOTFOUND;
+		}
+		break;
+	case AF_INET:
+		q.name = name;
+		q.qclass = C_IN;
+		q.qtype = T_A;
+		q.answer = buf->buf;
+		q.anslen = sizeof(buf->buf);
+		break;
+	case AF_INET6:
+		q.name = name;
+		q.qclass = C_IN;
+		q.qtype = T_AAAA;
+		q.answer = buf->buf;
+		q.anslen = sizeof(buf->buf);
+		break;
+	default:
+		free(buf);
+		free(buf2);
+		return NS_UNAVAIL;
+	}
+
+	res = __res_get_state();
+	if (res == NULL) {
+		free(buf);
+		free(buf2);
+		return NS_NOTFOUND;
+	}
+
+	if (res_searchN(name, &q, res) < 0) {
+		__res_put_state(res);
+		free(buf);
+		free(buf2);
+		return NS_NOTFOUND;
+	}
+	ai = getanswer(buf, q.n, q.name, q.qtype, pai);
+	if (ai) {
+		cur->ai_next = ai;
+		while (cur && cur->ai_next)
+			cur = cur->ai_next;
+	}
+	if (q.next) {
+		ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai);
+		if (ai)
+			cur->ai_next = ai;
+	}
+	free(buf);
+	free(buf2);
+	if (sentinel.ai_next == NULL) {
+		__res_put_state(res);
+		switch (h_errno) {
+		case HOST_NOT_FOUND:
+			return NS_NOTFOUND;
+		case TRY_AGAIN:
+			return NS_TRYAGAIN;
+		default:
+			return NS_UNAVAIL;
+		}
+	}
+
+	_rfc3484_sort(&sentinel);
+
+	__res_put_state(res);
+
+	*((struct addrinfo **)rv) = sentinel.ai_next;
+	return NS_SUCCESS;
+}
+
+static void
+_sethtent(_pseudo_FILE * __restrict__ hostf)
+{
+	assert(hostf);
+	if (hostf->mapping == MAP_FAILED)
+		(void) _pseudo_fopen_r(hostf, _PATH_HOSTS);
+	else
+		_pseudo_rewind(hostf);
+}
+
+static void
+_endhtent(_pseudo_FILE * __restrict__ hostf)
+{
+	assert(hostf);
+	(void) _pseudo_fclose(hostf);
+}
+
+static struct addrinfo *
+_gethtent(_pseudo_FILE * __restrict__ hostf, const char *name, const struct addrinfo *pai)
+{
+	char *p;
+	char *cp, *tname, *cname;
+	struct addrinfo hints, *res0, *res;
+	int error;
+	const char *addr;
+	char hostbuf[8*1024];
+
+	assert(hostf);
+//	fprintf(stderr, "_gethtent() name = '%s'\n", name);
+	assert(name != NULL);
+	assert(pai != NULL);
+
+	if (hostf->mapping == MAP_FAILED)
+		(void) _pseudo_fopen_r(hostf, _PATH_HOSTS);
+	if (hostf->mapping == MAP_FAILED)
+		return (NULL);
+ again:
+	if (!(p = _pseudo_fgets(hostbuf, sizeof hostbuf, hostf)))
+		return (NULL);
+	if (*p == '#')
+		goto again;
+	if (!(cp = strpbrk(p, "#\n")))
+		goto again;
+	*cp = '\0';
+	if (!(cp = strpbrk(p, " \t")))
+		goto again;
+	*cp++ = '\0';
+	addr = p;
+	/* if this is not something we're looking for, skip it. */
+	cname = NULL;
+	while (cp && *cp) {
+		if (*cp == ' ' || *cp == '\t') {
+			cp++;
+			continue;
+		}
+		if (!cname)
+			cname = cp;
+		tname = cp;
+		if ((cp = strpbrk(cp, " \t")) != NULL)
+			*cp++ = '\0';
+//		fprintf(stderr, "\ttname = '%s'", tname);
+		if (strcasecmp(name, tname) == 0)
+			goto found;
+	}
+	goto again;
+
+found:
+	hints = *pai;
+	hints.ai_flags = AI_NUMERICHOST;
+	error = __wrap_getaddrinfo(addr, NULL, &hints, &res0);
+	if (error)
+		goto again;
+	for (res = res0; res; res = res->ai_next) {
+		/* cover it up */
+		res->ai_flags = pai->ai_flags;
+
+		if (pai->ai_flags & AI_CANONNAME) {
+			if (get_canonname(pai, res, cname) != 0) {
+				__wrap_freeaddrinfo(res0);
+				goto again;
+			}
+		}
+	}
+	return res0;
+}
+
+/*ARGSUSED*/
+static int
+_files_getaddrinfo(void *rv, void *cb_data, va_list ap)
+{
+	const char *name;
+	const struct addrinfo *pai;
+	struct addrinfo sentinel, *cur;
+	struct addrinfo *p;
+	_pseudo_FILE hostf = _PSEUDO_FILE_INITIALIZER;
+
+	name = va_arg(ap, char *);
+	pai = va_arg(ap, struct addrinfo *);
+
+//	fprintf(stderr, "_files_getaddrinfo() name = '%s'\n", name);
+	memset(&sentinel, 0, sizeof(sentinel));
+	cur = &sentinel;
+
+	_sethtent(&hostf);
+	while ((p = _gethtent(&hostf, name, pai)) != NULL) {
+		cur->ai_next = p;
+		while (cur && cur->ai_next)
+			cur = cur->ai_next;
+	}
+	_endhtent(&hostf);
+
+	*((struct addrinfo **)rv) = sentinel.ai_next;
+	if (sentinel.ai_next == NULL)
+		return NS_NOTFOUND;
+	return NS_SUCCESS;
+}
+
+/* resolver logic */
+
+/*
+ * Formulate a normal query, send, and await answer.
+ * Returned answer is placed in supplied buffer "answer".
+ * Perform preliminary check of answer, returning success only
+ * if no error is indicated and the answer count is nonzero.
+ * Return the size of the response on success, -1 on error.
+ * Error number is left in h_errno.
+ *
+ * Caller must parse answer and determine whether it answers the question.
+ */
+static int
+res_queryN(const char *name, /* domain name */ struct res_target *target,
+    res_state res)
+{
+	u_char buf[MAXPACKET];
+	HEADER *hp;
+	int n;
+	struct res_target *t;
+	int rcode;
+	int ancount;
+
+	assert(name != NULL);
+	/* XXX: target may be NULL??? */
+
+	rcode = NOERROR;
+	ancount = 0;
+
+	for (t = target; t; t = t->next) {
+		int class, type;
+		u_char *answer;
+		int anslen;
+
+		hp = (HEADER *)(void *)t->answer;
+		hp->rcode = NOERROR;	/* default */
+
+		/* make it easier... */
+		class = t->qclass;
+		type = t->qtype;
+		answer = t->answer;
+		anslen = t->anslen;
+#ifdef DEBUG
+		if (res->options & RES_DEBUG)
+			printf(";; res_nquery(%s, %d, %d)\n", name, class, type);
+#endif
+
+		n = res_nmkquery(res, QUERY, name, class, type, NULL, 0, NULL,
+		    buf, sizeof(buf));
+#ifdef RES_USE_EDNS0
+		if (n > 0 && (res->options & RES_USE_EDNS0) != 0)
+			n = res_nopt(res, n, buf, sizeof(buf), anslen);
+#endif
+		if (n <= 0) {
+#ifdef DEBUG
+			if (res->options & RES_DEBUG)
+				printf(";; res_nquery: mkquery failed\n");
+#endif
+			h_errno = NO_RECOVERY;
+			return n;
+		}
+		n = res_nsend(res, buf, n, answer, anslen);
+#if 0
+		if (n < 0) {
+#ifdef DEBUG
+			if (res->options & RES_DEBUG)
+				printf(";; res_query: send error\n");
+#endif
+			h_errno = TRY_AGAIN;
+			return n;
+		}
+#endif
+
+		if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
+			rcode = hp->rcode;	/* record most recent error */
+#ifdef DEBUG
+			if (res->options & RES_DEBUG)
+				printf(";; rcode = %u, ancount=%u\n", hp->rcode,
+				    ntohs(hp->ancount));
+#endif
+			continue;
+		}
+
+		ancount += ntohs(hp->ancount);
+
+		t->n = n;
+	}
+
+	if (ancount == 0) {
+		switch (rcode) {
+		case NXDOMAIN:
+			h_errno = HOST_NOT_FOUND;
+			break;
+		case SERVFAIL:
+			h_errno = TRY_AGAIN;
+			break;
+		case NOERROR:
+			h_errno = NO_DATA;
+			break;
+		case FORMERR:
+		case NOTIMP:
+		case REFUSED:
+		default:
+			h_errno = NO_RECOVERY;
+			break;
+		}
+		return -1;
+	}
+	return ancount;
+}
+
+/*
+ * Formulate a normal query, send, and retrieve answer in supplied buffer.
+ * Return the size of the response on success, -1 on error.
+ * If enabled, implement search rules until answer or unrecoverable failure
+ * is detected.  Error code, if any, is left in h_errno.
+ */
+static int
+res_searchN(const char *name, struct res_target *target, res_state res)
+{
+	const char *cp, * const *domain;
+	HEADER *hp;
+	u_int dots;
+	int trailing_dot, ret, saved_herrno;
+	int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
+
+	assert(name != NULL);
+	assert(target != NULL);
+
+	hp = (HEADER *)(void *)target->answer;	/*XXX*/
+
+	errno = 0;
+	h_errno = HOST_NOT_FOUND;	/* default, if we never query */
+	dots = 0;
+	for (cp = name; *cp; cp++)
+		dots += (*cp == '.');
+	trailing_dot = 0;
+	if (cp > name && *--cp == '.')
+		trailing_dot++;
+
+
+        //fprintf(stderr, "res_searchN() name = '%s'\n", name);
+
+	/*
+	 * if there aren't any dots, it could be a user-level alias
+	 */
+	if (!dots && (cp = __hostalias(name)) != NULL) {
+		ret = res_queryN(cp, target, res);
+		return ret;
+	}
+
+	/*
+	 * If there are dots in the name already, let's just give it a try
+	 * 'as is'.  The threshold can be set with the "ndots" option.
+	 */
+	saved_herrno = -1;
+	if (dots >= res->ndots) {
+		ret = res_querydomainN(name, NULL, target, res);
+		if (ret > 0)
+			return (ret);
+		saved_herrno = h_errno;
+		tried_as_is++;
+	}
+
+	/*
+	 * We do at least one level of search if
+	 *	- there is no dot and RES_DEFNAME is set, or
+	 *	- there is at least one dot, there is no trailing dot,
+	 *	  and RES_DNSRCH is set.
+	 */
+	if ((!dots && (res->options & RES_DEFNAMES)) ||
+	    (dots && !trailing_dot && (res->options & RES_DNSRCH))) {
+		int done = 0;
+
+		for (domain = (const char * const *)res->dnsrch;
+		   *domain && !done;
+		   domain++) {
+
+			ret = res_querydomainN(name, *domain, target, res);
+			if (ret > 0)
+				return ret;
+
+			/*
+			 * If no server present, give up.
+			 * If name isn't found in this domain,
+			 * keep trying higher domains in the search list
+			 * (if that's enabled).
+			 * On a NO_DATA error, keep trying, otherwise
+			 * a wildcard entry of another type could keep us
+			 * from finding this entry higher in the domain.
+			 * If we get some other error (negative answer or
+			 * server failure), then stop searching up,
+			 * but try the input name below in case it's
+			 * fully-qualified.
+			 */
+			if (errno == ECONNREFUSED) {
+				h_errno = TRY_AGAIN;
+				return -1;
+			}
+
+			switch (h_errno) {
+			case NO_DATA:
+				got_nodata++;
+				/* FALLTHROUGH */
+			case HOST_NOT_FOUND:
+				/* keep trying */
+				break;
+			case TRY_AGAIN:
+				if (hp->rcode == SERVFAIL) {
+					/* try next search element, if any */
+					got_servfail++;
+					break;
+				}
+				/* FALLTHROUGH */
+			default:
+				/* anything else implies that we're done */
+				done++;
+			}
+			/*
+			 * if we got here for some reason other than DNSRCH,
+			 * we only wanted one iteration of the loop, so stop.
+			 */
+			if (!(res->options & RES_DNSRCH))
+			        done++;
+		}
+	}
+
+	/*
+	 * if we have not already tried the name "as is", do that now.
+	 * note that we do this regardless of how many dots were in the
+	 * name or whether it ends with a dot.
+	 */
+	if (!tried_as_is) {
+		ret = res_querydomainN(name, NULL, target, res);
+		if (ret > 0)
+			return ret;
+	}
+
+	/*
+	 * if we got here, we didn't satisfy the search.
+	 * if we did an initial full query, return that query's h_errno
+	 * (note that we wouldn't be here if that query had succeeded).
+	 * else if we ever got a nodata, send that back as the reason.
+	 * else send back meaningless h_errno, that being the one from
+	 * the last DNSRCH we did.
+	 */
+	if (saved_herrno != -1)
+		h_errno = saved_herrno;
+	else if (got_nodata)
+		h_errno = NO_DATA;
+	else if (got_servfail)
+		h_errno = TRY_AGAIN;
+	return -1;
+}
+
+/*
+ * Perform a call on res_query on the concatenation of name and domain,
+ * removing a trailing dot from name if domain is NULL.
+ */
+static int
+res_querydomainN(const char *name, const char *domain,
+    struct res_target *target, res_state res)
+{
+	char nbuf[MAXDNAME];
+	const char *longname = nbuf;
+	size_t n, d;
+
+	assert(name != NULL);
+	/* XXX: target may be NULL??? */
+
+#ifdef DEBUG
+	if (res->options & RES_DEBUG)
+		printf(";; res_querydomain(%s, %s)\n",
+			name, domain?domain:"<Nil>");
+#endif
+	if (domain == NULL) {
+		/*
+		 * Check for trailing '.';
+		 * copy without '.' if present.
+		 */
+		n = strlen(name);
+		if (n + 1 > sizeof(nbuf)) {
+			h_errno = NO_RECOVERY;
+			return -1;
+		}
+		if (n > 0 && name[--n] == '.') {
+			strncpy(nbuf, name, n);
+			nbuf[n] = '\0';
+		} else
+			longname = name;
+	} else {
+		n = strlen(name);
+		d = strlen(domain);
+		if (n + 1 + d + 1 > sizeof(nbuf)) {
+			h_errno = NO_RECOVERY;
+			return -1;
+		}
+		snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
+	}
+	return res_queryN(longname, target, res);
+}
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/heap.h
@@ -0,0 +1,59 @@
+/*	$NetBSD: heap.h,v 1.1.1.1 2004/05/20 19:49:41 christos Exp $	*/
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1997,1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+typedef int (*heap_higher_priority_func)(void *, void *);
+typedef void (*heap_index_func)(void *, int);
+typedef void (*heap_for_each_func)(void *, void *);
+
+typedef struct heap_context {
+	int array_size;
+	int array_size_increment;
+	int heap_size;
+	void **heap;
+	heap_higher_priority_func higher_priority;
+	heap_index_func index;
+} *heap_context;
+
+#define heap_new	__heap_new
+#define heap_free	__heap_free
+#define heap_insert	__heap_insert
+#define heap_delete	__heap_delete
+#define heap_increased	__heap_increased
+#define heap_decreased	__heap_decreased
+#define heap_element	__heap_element
+#define heap_for_each	__heap_for_each
+
+heap_context	heap_new(heap_higher_priority_func, heap_index_func, int);
+int		heap_free(heap_context);
+int		heap_insert(heap_context, void *);
+int		heap_delete(heap_context, int);
+int		heap_increased(heap_context, int);
+int		heap_decreased(heap_context, int);
+void *		heap_element(heap_context, int);
+int		heap_for_each(heap_context, heap_for_each_func, void *);
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/list.h
@@ -0,0 +1,124 @@
+/*	$NetBSD: list.h,v 1.2 2004/05/20 19:51:55 christos Exp $	*/
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1997,1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#ifndef LIST_H
+#define LIST_H 1
+#include "assertions.h"
+
+#define LIST(type) struct { type *head, *tail; }
+#define INIT_LIST(list) \
+	do { (list).head = NULL; (list).tail = NULL; } while (/*CONSTCOND*/0)
+
+#define LINK(type) struct { type *prev, *next; }
+#define INIT_LINK_TYPE(elt, link, type) \
+	do { \
+		(elt)->link.prev = (type *)(-1); \
+		(elt)->link.next = (type *)(-1); \
+	} while (/*CONSTCOND*/0)
+#define INIT_LINK(elt, link) \
+	INIT_LINK_TYPE(elt, link, void)
+#define LINKED(elt, link) ((void *)((elt)->link.prev) != (void *)(-1))
+
+#define HEAD(list) ((list).head)
+#define TAIL(list) ((list).tail)
+#define EMPTY(list) ((list).head == NULL)
+
+#define PREPEND(list, elt, link) \
+	do { \
+		INSIST(!LINKED(elt, link));\
+		if ((list).head != NULL) \
+			(list).head->link.prev = (elt); \
+		else \
+			(list).tail = (elt); \
+		(elt)->link.prev = NULL; \
+		(elt)->link.next = (list).head; \
+		(list).head = (elt); \
+	} while (/*CONSTCOND*/0)
+
+#define APPEND(list, elt, link) \
+	do { \
+		INSIST(!LINKED(elt, link));\
+		if ((list).tail != NULL) \
+			(list).tail->link.next = (elt); \
+		else \
+			(list).head = (elt); \
+		(elt)->link.prev = (list).tail; \
+		(elt)->link.next = NULL; \
+		(list).tail = (elt); \
+	} while (/*CONSTCOND*/0)
+
+#define UNLINK_TYPE(list, elt, link, type) \
+	do { \
+		INSIST(LINKED(elt, link));\
+		if ((elt)->link.next != NULL) \
+			(elt)->link.next->link.prev = (elt)->link.prev; \
+		else \
+			(list).tail = (elt)->link.prev; \
+		if ((elt)->link.prev != NULL) \
+			(elt)->link.prev->link.next = (elt)->link.next; \
+		else \
+			(list).head = (elt)->link.next; \
+		INIT_LINK_TYPE(elt, link, type); \
+	} while (/*CONSTCOND*/0)
+#define UNLINK(list, elt, link) \
+	UNLINK_TYPE(list, elt, link, void)
+
+#define PREV(elt, link) ((elt)->link.prev)
+#define NEXT(elt, link) ((elt)->link.next)
+
+#define INSERT_BEFORE(list, before, elt, link) \
+	do { \
+		INSIST(!LINKED(elt, link));\
+		if ((before)->link.prev == NULL) \
+			PREPEND(list, elt, link); \
+		else { \
+			(elt)->link.prev = (before)->link.prev; \
+			(before)->link.prev = (elt); \
+			(elt)->link.prev->link.next = (elt); \
+			(elt)->link.next = (before); \
+		} \
+	} while (/*CONSTCOND*/0)
+
+#define INSERT_AFTER(list, after, elt, link) \
+	do { \
+		INSIST(!LINKED(elt, link));\
+		if ((after)->link.next == NULL) \
+			APPEND(list, elt, link); \
+		else { \
+			(elt)->link.next = (after)->link.next; \
+			(after)->link.next = (elt); \
+			(elt)->link.next->link.prev = (elt); \
+			(elt)->link.prev = (after); \
+		} \
+	} while (/*CONSTCOND*/0)
+
+#define ENQUEUE(list, elt, link) APPEND(list, elt, link)
+#define DEQUEUE(list, elt, link) UNLINK(list, elt, link)
+
+#endif /* LIST_H */
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/memcluster.h
@@ -0,0 +1,61 @@
+/*	$NetBSD: memcluster.h,v 1.1.1.1 2004/05/20 19:49:41 christos Exp $	*/
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1997,1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#ifndef MEMCLUSTER_H
+#define MEMCLUSTER_H
+
+#include <stdio.h>
+
+#define meminit		__meminit
+#ifdef MEMCLUSTER_DEBUG
+#define memget(s)	__memget_debug(s, __FILE__, __LINE__)
+#define memput(p, s)	__memput_debug(p, s, __FILE__, __LINE__)
+#else /*MEMCLUSTER_DEBUG*/
+#ifdef MEMCLUSTER_RECORD
+#define memget(s)	__memget_record(s, __FILE__, __LINE__)
+#define memput(p, s)	__memput_record(p, s, __FILE__, __LINE__)
+#else /*MEMCLUSTER_RECORD*/
+#define memget		__memget
+#define memput		__memput
+#endif /*MEMCLUSTER_RECORD*/
+#endif /*MEMCLUSTER_DEBUG*/
+#define memstats	__memstats
+#define memactive	__memactive
+
+int	meminit(size_t, size_t);
+void *	__memget(size_t);
+void 	__memput(void *, size_t);
+void *	__memget_debug(size_t, const char *, int);
+void 	__memput_debug(void *, size_t, const char *, int);
+void *	__memget_record(size_t, const char *, int);
+void 	__memput_record(void *, size_t, const char *, int);
+void 	memstats(FILE *);
+int	memactive(void);
+
+#endif /* MEMCLUSTER_H */
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/ns_name.c
@@ -0,0 +1,987 @@
+/*	$NetBSD: ns_name.c,v 1.3 2004/11/07 02:19:49 christos Exp $	*/
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#define ANDROID_CHANGES 1
+#define MOZILLA_NECKO_EXCLUDE_CODE 1
+
+#include <sys/cdefs.h>
+#ifndef lint
+#ifdef notdef
+static const char rcsid[] = "Id: ns_name.c,v 1.3.2.4.4.2 2004/05/04 03:27:47 marka Exp";
+#else
+__RCSID("$NetBSD: ns_name.c,v 1.3 2004/11/07 02:19:49 christos Exp $");
+#endif
+#endif
+
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include "arpa_nameser.h"
+
+#include <errno.h>
+#ifdef ANDROID_CHANGES
+#include "resolv_private.h"
+#else
+#include <resolv.h>
+#endif
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+#define NS_TYPE_ELT			0x40 /* EDNS0 extended label type */
+#define DNS_LABELTYPE_BITSTRING		0x41
+
+/* Data. */
+
+static const char	digits[] = "0123456789";
+
+static const char digitvalue[256] = {
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	/*16*/
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
+	 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1, /*64*/
+	-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
+	-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
+};
+
+/* Forward. */
+
+static int		special(int);
+static int		printable(int);
+static int		dn_find(const u_char *, const u_char *,
+				const u_char * const *,
+				const u_char * const *);
+static int		encode_bitsring(const char **, const char *,
+					unsigned char **, unsigned char **,
+					unsigned const char *);
+static int		labellen(const u_char *);
+static int		decode_bitstring(const unsigned char **,
+					 char *, const char *);
+
+/* Public. */
+
+/*
+ * ns_name_ntop(src, dst, dstsiz)
+ *	Convert an encoded domain name to printable ascii as per RFC1035.
+ * return:
+ *	Number of bytes written to buffer, or -1 (with errno set)
+ * notes:
+ *	The root is returned as "."
+ *	All other domains are returned in non absolute form
+ */
+int
+ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
+{
+	const u_char *cp;
+	char *dn, *eom;
+	u_char c;
+	u_int n;
+	int l;
+
+	cp = src;
+	dn = dst;
+	eom = dst + dstsiz;
+
+	while ((n = *cp++) != 0) {
+		if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
+			/* Some kind of compression pointer. */
+			errno = EMSGSIZE;
+			return (-1);
+		}
+		if (dn != dst) {
+			if (dn >= eom) {
+				errno = EMSGSIZE;
+				return (-1);
+			}
+			*dn++ = '.';
+		}
+		if ((l = labellen(cp - 1)) < 0) {
+			errno = EMSGSIZE; /* XXX */
+			return(-1);
+		}
+		if (dn + l >= eom) {
+			errno = EMSGSIZE;
+			return (-1);
+		}
+		if ((n & NS_CMPRSFLGS) == NS_TYPE_ELT) {
+			int m;
+
+			if (n != DNS_LABELTYPE_BITSTRING) {
+				/* XXX: labellen should reject this case */
+				errno = EINVAL;
+				return(-1);
+			}
+			if ((m = decode_bitstring(&cp, dn, eom)) < 0)
+			{
+				errno = EMSGSIZE;
+				return(-1);
+			}
+			dn += m;
+			continue;
+		}
+		for (; l > 0; l--) {
+			c = *cp++;
+			if (special(c)) {
+				if (dn + 1 >= eom) {
+					errno = EMSGSIZE;
+					return (-1);
+				}
+				*dn++ = '\\';
+				*dn++ = (char)c;
+			} else if (!printable(c)) {
+				if (dn + 3 >= eom) {
+					errno = EMSGSIZE;
+					return (-1);
+				}
+				*dn++ = '\\';
+				*dn++ = digits[c / 100];
+				*dn++ = digits[(c % 100) / 10];
+				*dn++ = digits[c % 10];
+			} else {
+				if (dn >= eom) {
+					errno = EMSGSIZE;
+					return (-1);
+				}
+				*dn++ = (char)c;
+			}
+		}
+	}
+	if (dn == dst) {
+		if (dn >= eom) {
+			errno = EMSGSIZE;
+			return (-1);
+		}
+		*dn++ = '.';
+	}
+	if (dn >= eom) {
+		errno = EMSGSIZE;
+		return (-1);
+	}
+	*dn++ = '\0';
+	return (dn - dst);
+}
+
+/*
+ * ns_name_pton(src, dst, dstsiz)
+ *	Convert a ascii string into an encoded domain name as per RFC1035.
+ * return:
+ *	-1 if it fails
+ *	1 if string was fully qualified
+ *	0 is string was not fully qualified
+ * notes:
+ *	Enforces label and domain length limits.
+ */
+
+int
+ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
+{
+	u_char *label, *bp, *eom;
+	int c, n, escaped, e = 0;
+	char *cp;
+
+	escaped = 0;
+	bp = dst;
+	eom = dst + dstsiz;
+	label = bp++;
+
+	while ((c = *src++) != 0) {
+		if (escaped) {
+			if (c == '[') { /* start a bit string label */
+				if ((cp = strchr(src, ']')) == NULL) {
+					errno = EINVAL; /* ??? */
+					return(-1);
+				}
+				if ((e = encode_bitsring(&src, cp + 2,
+							 &label, &bp, eom))
+				    != 0) {
+					errno = e;
+					return(-1);
+				}
+				escaped = 0;
+				label = bp++;
+				if ((c = *src++) == 0)
+					goto done;
+				else if (c != '.') {
+					errno = EINVAL;
+					return(-1);
+				}
+				continue;
+			}
+			else if ((cp = strchr(digits, c)) != NULL) {
+				n = (cp - digits) * 100;
+				if ((c = *src++) == 0 ||
+				    (cp = strchr(digits, c)) == NULL) {
+					errno = EMSGSIZE;
+					return (-1);
+				}
+				n += (cp - digits) * 10;
+				if ((c = *src++) == 0 ||
+				    (cp = strchr(digits, c)) == NULL) {
+					errno = EMSGSIZE;
+					return (-1);
+				}
+				n += (cp - digits);
+				if (n > 255) {
+					errno = EMSGSIZE;
+					return (-1);
+				}
+				c = n;
+			}
+			escaped = 0;
+		} else if (c == '\\') {
+			escaped = 1;
+			continue;
+		} else if (c == '.') {
+			c = (bp - label - 1);
+			if ((c & NS_CMPRSFLGS) != 0) {	/* Label too big. */
+				errno = EMSGSIZE;
+				return (-1);
+			}
+			if (label >= eom) {
+				errno = EMSGSIZE;
+				return (-1);
+			}
+			*label = c;
+			/* Fully qualified ? */
+			if (*src == '\0') {
+				if (c != 0) {
+					if (bp >= eom) {
+						errno = EMSGSIZE;
+						return (-1);
+					}
+					*bp++ = '\0';
+				}
+				if ((bp - dst) > MAXCDNAME) {
+					errno = EMSGSIZE;
+					return (-1);
+				}
+				return (1);
+			}
+			if (c == 0 || *src == '.') {
+				errno = EMSGSIZE;
+				return (-1);
+			}
+			label = bp++;
+			continue;
+		}
+		if (bp >= eom) {
+			errno = EMSGSIZE;
+			return (-1);
+		}
+		*bp++ = (u_char)c;
+	}
+	c = (bp - label - 1);
+	if ((c & NS_CMPRSFLGS) != 0) {		/* Label too big. */
+		errno = EMSGSIZE;
+		return (-1);
+	}
+  done:
+	if (label >= eom) {
+		errno = EMSGSIZE;
+		return (-1);
+	}
+	*label = c;
+	if (c != 0) {
+		if (bp >= eom) {
+			errno = EMSGSIZE;
+			return (-1);
+		}
+		*bp++ = 0;
+	}
+	if ((bp - dst) > MAXCDNAME) {	/* src too big */
+		errno = EMSGSIZE;
+		return (-1);
+	}
+	return (0);
+}
+
+#ifndef MOZILLA_NECKO_EXCLUDE_CODE
+/*
+ * ns_name_ntol(src, dst, dstsiz)
+ *	Convert a network strings labels into all lowercase.
+ * return:
+ *	Number of bytes written to buffer, or -1 (with errno set)
+ * notes:
+ *	Enforces label and domain length limits.
+ */
+
+int
+ns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz)
+{
+	const u_char *cp;
+	u_char *dn, *eom;
+	u_char c;
+	u_int n;
+	int l;
+
+	cp = src;
+	dn = dst;
+	eom = dst + dstsiz;
+
+	if (dn >= eom) {
+		errno = EMSGSIZE;
+		return (-1);
+	}
+	while ((n = *cp++) != 0) {
+		if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
+			/* Some kind of compression pointer. */
+			errno = EMSGSIZE;
+			return (-1);
+		}
+		*dn++ = n;
+		if ((l = labellen(cp - 1)) < 0) {
+			errno = EMSGSIZE;
+			return (-1);
+		}
+		if (dn + l >= eom) {
+			errno = EMSGSIZE;
+			return (-1);
+		}
+		for (; l > 0; l--) {
+			c = *cp++;
+			if (isupper(c))
+				*dn++ = tolower(c);
+			else
+				*dn++ = c;
+		}
+	}
+	*dn++ = '\0';
+	return (dn - dst);
+}
+#endif
+
+/*
+ * ns_name_unpack(msg, eom, src, dst, dstsiz)
+ *	Unpack a domain name from a message, source may be compressed.
+ * return:
+ *	-1 if it fails, or consumed octets if it succeeds.
+ */
+int
+ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
+	       u_char *dst, size_t dstsiz)
+{
+	const u_char *srcp, *dstlim;
+	u_char *dstp;
+	int n, len, checked, l;
+
+	len = -1;
+	checked = 0;
+	dstp = dst;
+	srcp = src;
+	dstlim = dst + dstsiz;
+	if (srcp < msg || srcp >= eom) {
+		errno = EMSGSIZE;
+		return (-1);
+	}
+	/* Fetch next label in domain name. */
+	while ((n = *srcp++) != 0) {
+		/* Check for indirection. */
+		switch (n & NS_CMPRSFLGS) {
+		case 0:
+		case NS_TYPE_ELT:
+			/* Limit checks. */
+			if ((l = labellen(srcp - 1)) < 0) {
+				errno = EMSGSIZE;
+				return(-1);
+			}
+			if (dstp + l + 1 >= dstlim || srcp + l >= eom) {
+				errno = EMSGSIZE;
+				return (-1);
+			}
+			checked += l + 1;
+			*dstp++ = n;
+			memcpy(dstp, srcp, (size_t)l);
+			dstp += l;
+			srcp += l;
+			break;
+
+		case NS_CMPRSFLGS:
+			if (srcp >= eom) {
+				errno = EMSGSIZE;
+				return (-1);
+			}
+			if (len < 0)
+				len = srcp - src + 1;
+			srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
+			if (srcp < msg || srcp >= eom) {  /* Out of range. */
+				errno = EMSGSIZE;
+				return (-1);
+			}
+			checked += 2;
+			/*
+			 * Check for loops in the compressed name;
+			 * if we've looked at the whole message,
+			 * there must be a loop.
+			 */
+			if (checked >= eom - msg) {
+				errno = EMSGSIZE;
+				return (-1);
+			}
+			break;
+
+		default:
+			errno = EMSGSIZE;
+			return (-1);			/* flag error */
+		}
+	}
+	*dstp = '\0';
+	if (len < 0)
+		len = srcp - src;
+	return (len);
+}
+
+/*
+ * ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr)
+ *	Pack domain name 'domain' into 'comp_dn'.
+ * return:
+ *	Size of the compressed name, or -1.
+ * notes:
+ *	'dnptrs' is an array of pointers to previous compressed names.
+ *	dnptrs[0] is a pointer to the beginning of the message. The array
+ *	ends with NULL.
+ *	'lastdnptr' is a pointer to the end of the array pointed to
+ *	by 'dnptrs'.
+ * Side effects:
+ *	The list of pointers in dnptrs is updated for labels inserted into
+ *	the message as we compress the name.  If 'dnptr' is NULL, we don't
+ *	try to compress names. If 'lastdnptr' is NULL, we don't update the
+ *	list.
+ */
+int
+ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
+	     const u_char **dnptrs, const u_char **lastdnptr)
+{
+	u_char *dstp;
+	const u_char **cpp, **lpp, *eob, *msg;
+	const u_char *srcp;
+	int n, l, first = 1;
+
+	srcp = src;
+	dstp = dst;
+	eob = dstp + dstsiz;
+	lpp = cpp = NULL;
+	if (dnptrs != NULL) {
+		if ((msg = *dnptrs++) != NULL) {
+			for (cpp = dnptrs; *cpp != NULL; cpp++)
+				;
+			lpp = cpp;	/* end of list to search */
+		}
+	} else
+		msg = NULL;
+
+	/* make sure the domain we are about to add is legal */
+	l = 0;
+	do {
+		int l0;
+
+		n = *srcp;
+		if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
+			errno = EMSGSIZE;
+			return (-1);
+		}
+		if ((l0 = labellen(srcp)) < 0) {
+			errno = EINVAL;
+			return(-1);
+		}
+		l += l0 + 1;
+		if (l > MAXCDNAME) {
+			errno = EMSGSIZE;
+			return (-1);
+		}
+		srcp += l0 + 1;
+	} while (n != 0);
+
+	/* from here on we need to reset compression pointer array on error */
+	srcp = src;
+	do {
+		/* Look to see if we can use pointers. */
+		n = *srcp;
+		if (n != 0 && msg != NULL) {
+			l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
+				    (const u_char * const *)lpp);
+			if (l >= 0) {
+				if (dstp + 1 >= eob) {
+					goto cleanup;
+				}
+				*dstp++ = ((u_int32_t)l >> 8) | NS_CMPRSFLGS;
+				*dstp++ = l % 256;
+				return (dstp - dst);
+			}
+			/* Not found, save it. */
+			if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
+			    (dstp - msg) < 0x4000 && first) {
+				*cpp++ = dstp;
+				*cpp = NULL;
+				first = 0;
+			}
+		}
+		/* copy label to buffer */
+		if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
+			/* Should not happen. */
+			goto cleanup;
+		}
+		n = labellen(srcp);
+		if (dstp + 1 + n >= eob) {
+			goto cleanup;
+		}
+		memcpy(dstp, srcp, (size_t)(n + 1));
+		srcp += n + 1;
+		dstp += n + 1;
+	} while (n != 0);
+
+	if (dstp > eob) {
+cleanup:
+		if (msg != NULL)
+			*lpp = NULL;
+		errno = EMSGSIZE;
+		return (-1);
+	}
+	return (dstp - dst);
+}
+
+/*
+ * ns_name_uncompress(msg, eom, src, dst, dstsiz)
+ *	Expand compressed domain name to presentation format.
+ * return:
+ *	Number of bytes read out of `src', or -1 (with errno set).
+ * note:
+ *	Root domain returns as "." not "".
+ */
+int
+ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src,
+		   char *dst, size_t dstsiz)
+{
+	u_char tmp[NS_MAXCDNAME];
+	int n;
+
+	if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
+		return (-1);
+	if (ns_name_ntop(tmp, dst, dstsiz) == -1)
+		return (-1);
+	return (n);
+}
+
+/*
+ * ns_name_compress(src, dst, dstsiz, dnptrs, lastdnptr)
+ *	Compress a domain name into wire format, using compression pointers.
+ * return:
+ *	Number of bytes consumed in `dst' or -1 (with errno set).
+ * notes:
+ *	'dnptrs' is an array of pointers to previous compressed names.
+ *	dnptrs[0] is a pointer to the beginning of the message.
+ *	The list ends with NULL.  'lastdnptr' is a pointer to the end of the
+ *	array pointed to by 'dnptrs'. Side effect is to update the list of
+ *	pointers for labels inserted into the message as we compress the name.
+ *	If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
+ *	is NULL, we don't update the list.
+ */
+int
+ns_name_compress(const char *src, u_char *dst, size_t dstsiz,
+		 const u_char **dnptrs, const u_char **lastdnptr)
+{
+	u_char tmp[NS_MAXCDNAME];
+
+	if (ns_name_pton(src, tmp, sizeof tmp) == -1)
+		return (-1);
+	return (ns_name_pack(tmp, dst, (int)dstsiz, dnptrs, lastdnptr));
+}
+
+#ifndef MOZILLA_NECKO_EXCLUDE_CODE
+/*
+ * Reset dnptrs so that there are no active references to pointers at or
+ * after src.
+ */
+void
+ns_name_rollback(const u_char *src, const u_char **dnptrs,
+		 const u_char **lastdnptr)
+{
+	while (dnptrs < lastdnptr && *dnptrs != NULL) {
+		if (*dnptrs >= src) {
+			*dnptrs = NULL;
+			break;
+		}
+		dnptrs++;
+	}
+}
+#endif
+
+/*
+ * ns_name_skip(ptrptr, eom)
+ *	Advance *ptrptr to skip over the compressed name it points at.
+ * return:
+ *	0 on success, -1 (with errno set) on failure.
+ */
+int
+ns_name_skip(const u_char **ptrptr, const u_char *eom)
+{
+	const u_char *cp;
+	u_int n;
+	int l;
+
+	cp = *ptrptr;
+	while (cp < eom && (n = *cp++) != 0) {
+		/* Check for indirection. */
+		switch (n & NS_CMPRSFLGS) {
+		case 0:			/* normal case, n == len */
+			cp += n;
+			continue;
+		case NS_TYPE_ELT: /* EDNS0 extended label */
+			if ((l = labellen(cp - 1)) < 0) {
+				errno = EMSGSIZE; /* XXX */
+				return(-1);
+			}
+			cp += l;
+			continue;
+		case NS_CMPRSFLGS:	/* indirection */
+			cp++;
+			break;
+		default:		/* illegal type */
+			errno = EMSGSIZE;
+			return (-1);
+		}
+		break;
+	}
+	if (cp > eom) {
+		errno = EMSGSIZE;
+		return (-1);
+	}
+	*ptrptr = cp;
+	return (0);
+}
+
+/* Private. */
+
+/*
+ * special(ch)
+ *	Thinking in noninternationalized USASCII (per the DNS spec),
+ *	is this characted special ("in need of quoting") ?
+ * return:
+ *	boolean.
+ */
+static int
+special(int ch) {
+	switch (ch) {
+	case 0x22: /* '"' */
+	case 0x2E: /* '.' */
+	case 0x3B: /* ';' */
+	case 0x5C: /* '\\' */
+	case 0x28: /* '(' */
+	case 0x29: /* ')' */
+	/* Special modifiers in zone files. */
+	case 0x40: /* '@' */
+	case 0x24: /* '$' */
+		return (1);
+	default:
+		return (0);
+	}
+}
+
+/*
+ * printable(ch)
+ *	Thinking in noninternationalized USASCII (per the DNS spec),
+ *	is this character visible and not a space when printed ?
+ * return:
+ *	boolean.
+ */
+static int
+printable(int ch) {
+	return (ch > 0x20 && ch < 0x7f);
+}
+
+/*
+ *	Thinking in noninternationalized USASCII (per the DNS spec),
+ *	convert this character to lower case if it's upper case.
+ */
+static int
+mklower(int ch) {
+	if (ch >= 0x41 && ch <= 0x5A)
+		return (ch + 0x20);
+	return (ch);
+}
+
+/*
+ * dn_find(domain, msg, dnptrs, lastdnptr)
+ *	Search for the counted-label name in an array of compressed names.
+ * return:
+ *	offset from msg if found, or -1.
+ * notes:
+ *	dnptrs is the pointer to the first name on the list,
+ *	not the pointer to the start of the message.
+ */
+static int
+dn_find(const u_char *domain, const u_char *msg,
+	const u_char * const *dnptrs,
+	const u_char * const *lastdnptr)
+{
+	const u_char *dn, *cp, *sp;
+	const u_char * const *cpp;
+	u_int n;
+
+	for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
+		sp = *cpp;
+		/*
+		 * terminate search on:
+		 * root label
+		 * compression pointer
+		 * unusable offset
+		 */
+		while (*sp != 0 && (*sp & NS_CMPRSFLGS) == 0 &&
+		       (sp - msg) < 0x4000) {
+			dn = domain;
+			cp = sp;
+			while ((n = *cp++) != 0) {
+				/*
+				 * check for indirection
+				 */
+				switch (n & NS_CMPRSFLGS) {
+				case 0:		/* normal case, n == len */
+					n = labellen(cp - 1); /* XXX */
+
+					if (n != *dn++)
+						goto next;
+
+					for (; n > 0; n--)
+						if (mklower(*dn++) !=
+						    mklower(*cp++))
+							goto next;
+					/* Is next root for both ? */
+					if (*dn == '\0' && *cp == '\0')
+						return (sp - msg);
+					if (*dn)
+						continue;
+					goto next;
+				case NS_CMPRSFLGS:	/* indirection */
+					cp = msg + (((n & 0x3f) << 8) | *cp);
+					break;
+
+				default:	/* illegal type */
+					errno = EMSGSIZE;
+					return (-1);
+				}
+			}
+ next: ;
+			sp += *sp + 1;
+		}
+	}
+	errno = ENOENT;
+	return (-1);
+}
+
+static int
+decode_bitstring(const unsigned char **cpp, char *dn, const char *eom)
+{
+	const unsigned char *cp = *cpp;
+	char *beg = dn, tc;
+	int b, blen, plen, i;
+
+	if ((blen = (*cp & 0xff)) == 0)
+		blen = 256;
+	plen = (blen + 3) / 4;
+	plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1);
+	if (dn + plen >= eom)
+		return(-1);
+
+	cp++;
+	i = SPRINTF((dn, "\\[x"));
+	if (i < 0)
+		return (-1);
+	dn += i;
+	for (b = blen; b > 7; b -= 8, cp++) {
+		i = SPRINTF((dn, "%02x", *cp & 0xff));
+		if (i < 0)
+			return (-1);
+		dn += i;
+	}
+	if (b > 4) {
+		tc = *cp++;
+		i = SPRINTF((dn, "%02x", tc & (0xff << (8 - b))));
+		if (i < 0)
+			return (-1);
+		dn += i;
+	} else if (b > 0) {
+		tc = *cp++;
+		i = SPRINTF((dn, "%1x",
+			       (((u_int32_t)tc >> 4) & 0x0f) & (0x0f << (4 - b))));
+		if (i < 0)
+			return (-1);
+		dn += i;
+	}
+	i = SPRINTF((dn, "/%d]", blen));
+	if (i < 0)
+		return (-1);
+	dn += i;
+
+	*cpp = cp;
+	return(dn - beg);
+}
+
+static int
+encode_bitsring(const char **bp, const char *end, unsigned char **labelp,
+	        unsigned char ** dst, unsigned const char *eom)
+{
+	int afterslash = 0;
+	const char *cp = *bp;
+	unsigned char *tp;
+	char c;
+	const char *beg_blen;
+	char *end_blen = NULL;
+	int value = 0, count = 0, tbcount = 0, blen = 0;
+
+	beg_blen = end_blen = NULL;
+
+	/* a bitstring must contain at least 2 characters */
+	if (end - cp < 2)
+		return(EINVAL);
+
+	/* XXX: currently, only hex strings are supported */
+	if (*cp++ != 'x')
+		return(EINVAL);
+	if (!isxdigit((*cp) & 0xff)) /* reject '\[x/BLEN]' */
+		return(EINVAL);
+
+	for (tp = *dst + 1; cp < end && tp < eom; cp++) {
+		switch((c = *cp)) {
+		case ']':	/* end of the bitstring */
+			if (afterslash) {
+				if (beg_blen == NULL)
+					return(EINVAL);
+				blen = (int)strtol(beg_blen, &end_blen, 10);
+				if (*end_blen != ']')
+					return(EINVAL);
+			}
+			if (count)
+				*tp++ = ((value << 4) & 0xff);
+			cp++;	/* skip ']' */
+			goto done;
+		case '/':
+			afterslash = 1;
+			break;
+		default:
+			if (afterslash) {
+				if (!isdigit(c&0xff))
+					return(EINVAL);
+				if (beg_blen == NULL) {
+
+					if (c == '0') {
+						/* blen never begings with 0 */
+						return(EINVAL);
+					}
+					beg_blen = cp;
+				}
+			} else {
+				if (!isxdigit(c&0xff))
+					return(EINVAL);
+				value <<= 4;
+				value += digitvalue[(int)c];
+				count += 4;
+				tbcount += 4;
+				if (tbcount > 256)
+					return(EINVAL);
+				if (count == 8) {
+					*tp++ = value;
+					count = 0;
+				}
+			}
+			break;
+		}
+	}
+  done:
+	if (cp >= end || tp >= eom)
+		return(EMSGSIZE);
+
+	/*
+	 * bit length validation:
+	 * If a <length> is present, the number of digits in the <bit-data>
+	 * MUST be just sufficient to contain the number of bits specified
+	 * by the <length>. If there are insignificant bits in a final
+	 * hexadecimal or octal digit, they MUST be zero.
+	 * RFC 2673, Section 3.2.
+	 */
+	if (blen > 0) {
+		int traillen;
+
+		if (((blen + 3) & ~3) != tbcount)
+			return(EINVAL);
+		traillen = tbcount - blen; /* between 0 and 3 */
+		if (((value << (8 - traillen)) & 0xff) != 0)
+			return(EINVAL);
+	}
+	else
+		blen = tbcount;
+	if (blen == 256)
+		blen = 0;
+
+	/* encode the type and the significant bit fields */
+	**labelp = DNS_LABELTYPE_BITSTRING;
+	**dst = blen;
+
+	*bp = cp;
+	*dst = tp;
+
+	return(0);
+}
+
+static int
+labellen(const u_char *lp)
+{
+	int bitlen;
+	u_char l = *lp;
+
+	if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
+		/* should be avoided by the caller */
+		return(-1);
+	}
+
+	if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) {
+		if (l == DNS_LABELTYPE_BITSTRING) {
+			if ((bitlen = *(lp + 1)) == 0)
+				bitlen = 256;
+			return((bitlen + 7 ) / 8 + 1);
+		}
+		return(-1);	/* unknwon ELT */
+	}
+	return(l);
+}
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/ns_netint.c
@@ -0,0 +1,72 @@
+/*	$NetBSD: ns_netint.c,v 1.2 2004/05/20 20:19:00 christos Exp $	*/
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#define ANDROID_CHANGES 1
+#define MOZILLA_NECKO_EXCLUDE_CODE 1
+
+#include <sys/cdefs.h>
+#ifndef lint
+#ifdef notdef
+static const char rcsid[] = "Id: ns_netint.c,v 1.1.206.1 2004/03/09 08:33:44 marka Exp";
+#else
+__RCSID("$NetBSD: ns_netint.c,v 1.2 2004/05/20 20:19:00 christos Exp $");
+#endif
+#endif
+
+/* Import. */
+
+#include "arpa_nameser.h"
+
+/* Public. */
+
+u_int16_t
+ns_get16(const u_char *src) {
+	u_int dst;
+
+	NS_GET16(dst, src);
+	return (dst);
+}
+
+u_int32_t
+ns_get32(const u_char *src) {
+	u_long dst;
+
+	NS_GET32(dst, src);
+	return (dst);
+}
+
+void
+ns_put16(u_int16_t src, u_char *dst) {
+	NS_PUT16(src, dst);
+}
+
+void
+ns_put32(u_int32_t src, u_char *dst) {
+	NS_PUT32(src, dst);
+}
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/ns_parse.c
@@ -0,0 +1,222 @@
+/*	$NetBSD: ns_parse.c,v 1.2 2004/05/20 20:35:05 christos Exp $	*/
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#define ANDROID_CHANGES 1
+#define MOZILLA_NECKO_EXCLUDE_CODE 1
+
+#include <sys/cdefs.h>
+#ifndef lint
+#ifdef notdef
+static const char rcsid[] = "Id: ns_parse.c,v 1.3.2.1.4.1 2004/03/09 08:33:44 marka Exp";
+#else
+__RCSID("$NetBSD: ns_parse.c,v 1.2 2004/05/20 20:35:05 christos Exp $");
+#endif
+#endif
+
+/* Import. */
+
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include "arpa_nameser.h"
+
+#include <errno.h>
+#ifdef ANDROID_CHANGES
+#include "resolv_private.h"
+#else
+#include <resolv.h>
+#endif
+#include <string.h>
+
+/* Forward. */
+
+static void	setsection(ns_msg *msg, ns_sect sect);
+
+/* Macros. */
+
+#define RETERR(err) do { errno = (err); return (-1); } while (/*NOTREACHED*//*CONSTCOND*/0)
+
+/* Public. */
+
+/* These need to be in the same order as the nres.h:ns_flag enum. */
+const struct _ns_flagdata _ns_flagdata[16] = {
+	{ 0x8000, 15 },		/* qr. */
+	{ 0x7800, 11 },		/* opcode. */
+	{ 0x0400, 10 },		/* aa. */
+	{ 0x0200, 9 },		/* tc. */
+	{ 0x0100, 8 },		/* rd. */
+	{ 0x0080, 7 },		/* ra. */
+	{ 0x0040, 6 },		/* z. */
+	{ 0x0020, 5 },		/* ad. */
+	{ 0x0010, 4 },		/* cd. */
+	{ 0x000f, 0 },		/* rcode. */
+	{ 0x0000, 0 },		/* expansion (1/6). */
+	{ 0x0000, 0 },		/* expansion (2/6). */
+	{ 0x0000, 0 },		/* expansion (3/6). */
+	{ 0x0000, 0 },		/* expansion (4/6). */
+	{ 0x0000, 0 },		/* expansion (5/6). */
+	{ 0x0000, 0 },		/* expansion (6/6). */
+};
+
+int ns_msg_getflag(ns_msg handle, int flag) {
+	return((u_int32_t)((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift);
+}
+
+int
+ns_skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) {
+	const u_char *optr = ptr;
+
+	for (; count > 0; count--) {
+		int b, rdlength;
+
+		b = dn_skipname(ptr, eom);
+		if (b < 0)
+			RETERR(EMSGSIZE);
+		ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
+		if (section != ns_s_qd) {
+			if (ptr + NS_INT32SZ + NS_INT16SZ > eom)
+				RETERR(EMSGSIZE);
+			ptr += NS_INT32SZ/*TTL*/;
+			NS_GET16(rdlength, ptr);
+			ptr += rdlength/*RData*/;
+		}
+	}
+	if (ptr > eom)
+		RETERR(EMSGSIZE);
+	return (ptr - optr);
+}
+
+int
+ns_initparse(const u_char *msg, int msglen, ns_msg *handle) {
+	const u_char *eom = msg + msglen;
+	int i;
+
+	memset(handle, 0x5e, sizeof *handle);
+	handle->_msg = msg;
+	handle->_eom = eom;
+	if (msg + NS_INT16SZ > eom)
+		RETERR(EMSGSIZE);
+	NS_GET16(handle->_id, msg);
+	if (msg + NS_INT16SZ > eom)
+		RETERR(EMSGSIZE);
+	NS_GET16(handle->_flags, msg);
+	for (i = 0; i < ns_s_max; i++) {
+		if (msg + NS_INT16SZ > eom)
+			RETERR(EMSGSIZE);
+		NS_GET16(handle->_counts[i], msg);
+	}
+	for (i = 0; i < ns_s_max; i++)
+		if (handle->_counts[i] == 0)
+			handle->_sections[i] = NULL;
+		else {
+			int b = ns_skiprr(msg, eom, (ns_sect)i,
+					  handle->_counts[i]);
+
+			if (b < 0)
+				return (-1);
+			handle->_sections[i] = msg;
+			msg += b;
+		}
+	if (msg != eom)
+		RETERR(EMSGSIZE);
+	setsection(handle, ns_s_max);
+	return (0);
+}
+
+int
+ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) {
+	int b;
+
+	/* Make section right. */
+	if ((unsigned)section >= (unsigned)ns_s_max)
+		RETERR(ENODEV);
+	if (section != handle->_sect)
+		setsection(handle, section);
+
+	/* Make rrnum right. */
+	if (rrnum == -1)
+		rrnum = handle->_rrnum;
+	if (rrnum < 0 || rrnum >= handle->_counts[(int)section])
+		RETERR(ENODEV);
+	if (rrnum < handle->_rrnum)
+		setsection(handle, section);
+	if (rrnum > handle->_rrnum) {
+		b = ns_skiprr(handle->_msg_ptr, handle->_eom, section,
+			      rrnum - handle->_rrnum);
+
+		if (b < 0)
+			return (-1);
+		handle->_msg_ptr += b;
+		handle->_rrnum = rrnum;
+	}
+
+	/* Do the parse. */
+	b = dn_expand(handle->_msg, handle->_eom,
+		      handle->_msg_ptr, rr->name, NS_MAXDNAME);
+	if (b < 0)
+		return (-1);
+	handle->_msg_ptr += b;
+	if (handle->_msg_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom)
+		RETERR(EMSGSIZE);
+	NS_GET16(rr->type, handle->_msg_ptr);
+	NS_GET16(rr->rr_class, handle->_msg_ptr);
+	if (section == ns_s_qd) {
+		rr->ttl = 0;
+		rr->rdlength = 0;
+		rr->rdata = NULL;
+	} else {
+		if (handle->_msg_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom)
+			RETERR(EMSGSIZE);
+		NS_GET32(rr->ttl, handle->_msg_ptr);
+		NS_GET16(rr->rdlength, handle->_msg_ptr);
+		if (handle->_msg_ptr + rr->rdlength > handle->_eom)
+			RETERR(EMSGSIZE);
+		rr->rdata = handle->_msg_ptr;
+		handle->_msg_ptr += rr->rdlength;
+	}
+	if (++handle->_rrnum > handle->_counts[(int)section])
+		setsection(handle, (ns_sect)((int)section + 1));
+
+	/* All done. */
+	return (0);
+}
+
+/* Private. */
+
+static void
+setsection(ns_msg *msg, ns_sect sect) {
+	msg->_sect = sect;
+	if (sect == ns_s_max) {
+		msg->_rrnum = -1;
+		msg->_msg_ptr = NULL;
+	} else {
+		msg->_rrnum = 0;
+		msg->_msg_ptr = msg->_sections[(int)sect];
+	}
+}
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/ns_print.c
@@ -0,0 +1,928 @@
+/*	$NetBSD: ns_print.c,v 1.5 2004/11/07 02:19:49 christos Exp $	*/
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#define ANDROID_CHANGES 1
+#define MOZILLA_NECKO_EXCLUDE_CODE 1 
+
+#include <sys/cdefs.h>
+#ifndef lint
+#ifdef notdef
+static const char rcsid[] = "Id: ns_print.c,v 1.3.2.1.4.5 2004/07/28 20:16:45 marka Exp";
+#else
+__RCSID("$NetBSD: ns_print.c,v 1.5 2004/11/07 02:19:49 christos Exp $");
+#endif
+#endif
+
+/* Import. */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include "arpa_nameser.h"
+#include <arpa/inet.h>
+
+#include "assertions.h"
+#include "dst.h"
+#include <errno.h>
+#ifdef ANDROID_CHANGES
+#include "resolv_private.h"
+#else
+#include <resolv.h>
+#endif
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+#ifndef MIN
+#define	MIN(x,y)	((x)<(y)?(x):(y))
+#endif
+
+/* Forward. */
+
+static size_t	prune_origin(const char *name, const char *origin);
+static int	charstr(const u_char *rdata, const u_char *edata,
+			char **buf, size_t *buflen);
+static int	addname(const u_char *msg, size_t msglen,
+			const u_char **p, const char *origin,
+			char **buf, size_t *buflen);
+static void	addlen(size_t len, char **buf, size_t *buflen);
+static int	addstr(const char *src, size_t len,
+		       char **buf, size_t *buflen);
+static int	addtab(size_t len, size_t target, int spaced,
+		       char **buf, size_t *buflen);
+
+/* Macros. */
+
+#define	T(x) \
+	do { \
+		if ((x) < 0) \
+			return (-1); \
+	} while (/*CONSTCOND*/0)
+
+/* Public. */
+
+/*
+ * int
+ * ns_sprintrr(handle, rr, name_ctx, origin, buf, buflen)
+ *	Convert an RR to presentation format.
+ * return:
+ *	Number of characters written to buf, or -1 (check errno).
+ */
+int
+ns_sprintrr(const ns_msg *handle, const ns_rr *rr,
+	    const char *name_ctx, const char *origin,
+	    char *buf, size_t buflen)
+{
+	int n;
+
+	n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle),
+			 ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr),
+			 ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr),
+			 name_ctx, origin, buf, buflen);
+	return (n);
+}
+
+/*
+ * int
+ * ns_sprintrrf(msg, msglen, name, class, type, ttl, rdata, rdlen,
+ *	       name_ctx, origin, buf, buflen)
+ *	Convert the fields of an RR into presentation format.
+ * return:
+ *	Number of characters written to buf, or -1 (check errno).
+ */
+int
+ns_sprintrrf(const u_char *msg, size_t msglen,
+	    const char *name, ns_class class, ns_type type,
+	    u_long ttl, const u_char *rdata, size_t rdlen,
+	    const char *name_ctx, const char *origin,
+	    char *buf, size_t buflen)
+{
+	const char *obuf = buf;
+	const u_char *edata = rdata + rdlen;
+	int spaced = 0;
+
+	const char *comment;
+	char tmp[100];
+	int len, x;
+
+	/*
+	 * Owner.
+	 */
+	if (name_ctx != NULL && ns_samename(name_ctx, name) == 1) {
+		T(addstr("\t\t\t", (size_t)3, &buf, &buflen));
+	} else {
+		len = prune_origin(name, origin);
+		if (*name == '\0') {
+			goto root;
+		} else if (len == 0) {
+			T(addstr("@\t\t\t", (size_t)4, &buf, &buflen));
+		} else {
+			T(addstr(name, (size_t)len, &buf, &buflen));
+			/* Origin not used or not root, and no trailing dot? */
+			if (((origin == NULL || origin[0] == '\0') ||
+			    (origin[0] != '.' && origin[1] != '\0' &&
+			    name[len] == '\0')) && name[len - 1] != '.') {
+ root:
+				T(addstr(".", (size_t)1, &buf, &buflen));
+				len++;
+			}
+			T(spaced = addtab((size_t)len, 24, spaced, &buf, &buflen));
+		}
+	}
+
+	/*
+	 * TTL, Class, Type.
+	 */
+	T(x = ns_format_ttl(ttl, buf, buflen));
+	addlen((size_t)x, &buf, &buflen);
+	len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type)));
+	T(addstr(tmp, (size_t)len, &buf, &buflen));
+	T(spaced = addtab((size_t)(x + len), (size_t)16, spaced, &buf, &buflen));
+
+	/*
+	 * RData.
+	 */
+	switch (type) {
+	case ns_t_a:
+		if (rdlen != (size_t)NS_INADDRSZ)
+			goto formerr;
+		(void) inet_ntop(AF_INET, rdata, buf, buflen);
+		addlen(strlen(buf), &buf, &buflen);
+		break;
+
+	case ns_t_cname:
+	case ns_t_mb:
+	case ns_t_mg:
+	case ns_t_mr:
+	case ns_t_ns:
+	case ns_t_ptr:
+	case ns_t_dname:
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+		break;
+
+	case ns_t_hinfo:
+	case ns_t_isdn:
+		/* First word. */
+		T(len = charstr(rdata, edata, &buf, &buflen));
+		if (len == 0)
+			goto formerr;
+		rdata += len;
+		T(addstr(" ", (size_t)1, &buf, &buflen));
+
+
+		/* Second word, optional in ISDN records. */
+		if (type == ns_t_isdn && rdata == edata)
+			break;
+
+		T(len = charstr(rdata, edata, &buf, &buflen));
+		if (len == 0)
+			goto formerr;
+		rdata += len;
+		break;
+
+	case ns_t_soa: {
+		u_long t;
+
+		/* Server name. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+		T(addstr(" ", (size_t)1, &buf, &buflen));
+
+		/* Administrator name. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+		T(addstr(" (\n", (size_t)3, &buf, &buflen));
+		spaced = 0;
+
+		if ((edata - rdata) != 5*NS_INT32SZ)
+			goto formerr;
+
+		/* Serial number. */
+		t = ns_get32(rdata);  rdata += NS_INT32SZ;
+		T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
+		len = SPRINTF((tmp, "%lu", t));
+		T(addstr(tmp, (size_t)len, &buf, &buflen));
+		T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
+		T(addstr("; serial\n", (size_t)9, &buf, &buflen));
+		spaced = 0;
+
+		/* Refresh interval. */
+		t = ns_get32(rdata);  rdata += NS_INT32SZ;
+		T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
+		T(len = ns_format_ttl(t, buf, buflen));
+		addlen((size_t)len, &buf, &buflen);
+		T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
+		T(addstr("; refresh\n", (size_t)10, &buf, &buflen));
+		spaced = 0;
+
+		/* Retry interval. */
+		t = ns_get32(rdata);  rdata += NS_INT32SZ;
+		T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
+		T(len = ns_format_ttl(t, buf, buflen));
+		addlen((size_t)len, &buf, &buflen);
+		T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
+		T(addstr("; retry\n", (size_t)8, &buf, &buflen));
+		spaced = 0;
+
+		/* Expiry. */
+		t = ns_get32(rdata);  rdata += NS_INT32SZ;
+		T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
+		T(len = ns_format_ttl(t, buf, buflen));
+		addlen((size_t)len, &buf, &buflen);
+		T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
+		T(addstr("; expiry\n", (size_t)9, &buf, &buflen));
+		spaced = 0;
+
+		/* Minimum TTL. */
+		t = ns_get32(rdata);  rdata += NS_INT32SZ;
+		T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
+		T(len = ns_format_ttl(t, buf, buflen));
+		addlen((size_t)len, &buf, &buflen);
+		T(addstr(" )", (size_t)2, &buf, &buflen));
+		T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
+		T(addstr("; minimum\n", (size_t)10, &buf, &buflen));
+
+		break;
+	    }
+
+	case ns_t_mx:
+	case ns_t_afsdb:
+	case ns_t_rt: {
+		u_int t;
+
+		if (rdlen < (size_t)NS_INT16SZ)
+			goto formerr;
+
+		/* Priority. */
+		t = ns_get16(rdata);
+		rdata += NS_INT16SZ;
+		len = SPRINTF((tmp, "%u ", t));
+		T(addstr(tmp, (size_t)len, &buf, &buflen));
+
+		/* Target. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+		break;
+	    }
+
+	case ns_t_px: {
+		u_int t;
+
+		if (rdlen < (size_t)NS_INT16SZ)
+			goto formerr;
+
+		/* Priority. */
+		t = ns_get16(rdata);
+		rdata += NS_INT16SZ;
+		len = SPRINTF((tmp, "%u ", t));
+		T(addstr(tmp, (size_t)len, &buf, &buflen));
+
+		/* Name1. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+		T(addstr(" ", (size_t)1, &buf, &buflen));
+
+		/* Name2. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+		break;
+	    }
+
+	case ns_t_x25:
+		T(len = charstr(rdata, edata, &buf, &buflen));
+		if (len == 0)
+			goto formerr;
+		rdata += len;
+		break;
+
+	case ns_t_txt:
+		while (rdata < edata) {
+			T(len = charstr(rdata, edata, &buf, &buflen));
+			if (len == 0)
+				goto formerr;
+			rdata += len;
+			if (rdata < edata)
+				T(addstr(" ", (size_t)1, &buf, &buflen));
+		}
+		break;
+
+	case ns_t_nsap: {
+		char t[2+255*3];
+
+		(void) inet_nsap_ntoa((int)rdlen, rdata, t);
+		T(addstr(t, strlen(t), &buf, &buflen));
+		break;
+	    }
+
+	case ns_t_aaaa:
+		if (rdlen != (size_t)NS_IN6ADDRSZ)
+			goto formerr;
+		(void) inet_ntop(AF_INET6, rdata, buf, buflen);
+		addlen(strlen(buf), &buf, &buflen);
+		break;
+
+	case ns_t_loc: {
+		char t[255];
+
+		/* XXX protocol format checking? */
+		(void) loc_ntoa(rdata, t);
+		T(addstr(t, strlen(t), &buf, &buflen));
+		break;
+	    }
+
+	case ns_t_naptr: {
+		u_int order, preference;
+		char t[50];
+
+		if (rdlen < 2U*NS_INT16SZ)
+			goto formerr;
+
+		/* Order, Precedence. */
+		order = ns_get16(rdata);	rdata += NS_INT16SZ;
+		preference = ns_get16(rdata);	rdata += NS_INT16SZ;
+		len = SPRINTF((t, "%u %u ", order, preference));
+		T(addstr(t, (size_t)len, &buf, &buflen));
+
+		/* Flags. */
+		T(len = charstr(rdata, edata, &buf, &buflen));
+		if (len == 0)
+			goto formerr;
+		rdata += len;
+		T(addstr(" ", (size_t)1, &buf, &buflen));
+
+		/* Service. */
+		T(len = charstr(rdata, edata, &buf, &buflen));
+		if (len == 0)
+			goto formerr;
+		rdata += len;
+		T(addstr(" ", (size_t)1, &buf, &buflen));
+
+		/* Regexp. */
+		T(len = charstr(rdata, edata, &buf, &buflen));
+		if (len < 0)
+			return (-1);
+		if (len == 0)
+			goto formerr;
+		rdata += len;
+		T(addstr(" ", (size_t)1, &buf, &buflen));
+
+		/* Server. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+		break;
+	    }
+
+	case ns_t_srv: {
+		u_int priority, weight, port;
+		char t[50];
+
+		if (rdlen < 3U*NS_INT16SZ)
+			goto formerr;
+
+		/* Priority, Weight, Port. */
+		priority = ns_get16(rdata);  rdata += NS_INT16SZ;
+		weight   = ns_get16(rdata);  rdata += NS_INT16SZ;
+		port     = ns_get16(rdata);  rdata += NS_INT16SZ;
+		len = SPRINTF((t, "%u %u %u ", priority, weight, port));
+		T(addstr(t, (size_t)len, &buf, &buflen));
+
+		/* Server. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+		break;
+	    }
+
+	case ns_t_minfo:
+	case ns_t_rp:
+		/* Name1. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+		T(addstr(" ", (size_t)1, &buf, &buflen));
+
+		/* Name2. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+		break;
+
+	case ns_t_wks: {
+		int n, lcnt;
+
+		if (rdlen < 1U + NS_INT32SZ)
+			goto formerr;
+
+		/* Address. */
+		(void) inet_ntop(AF_INET, rdata, buf, buflen);
+		addlen(strlen(buf), &buf, &buflen);
+		rdata += NS_INADDRSZ;
+
+		/* Protocol. */
+		len = SPRINTF((tmp, " %u ( ", *rdata));
+		T(addstr(tmp, (size_t)len, &buf, &buflen));
+		rdata += NS_INT8SZ;
+
+		/* Bit map. */
+		n = 0;
+		lcnt = 0;
+		while (rdata < edata) {
+			u_int c = *rdata++;
+			do {
+				if (c & 0200) {
+					if (lcnt == 0) {
+						T(addstr("\n\t\t\t\t", (size_t)5,
+							 &buf, &buflen));
+						lcnt = 10;
+						spaced = 0;
+					}
+					len = SPRINTF((tmp, "%d ", n));
+					T(addstr(tmp, (size_t)len, &buf, &buflen));
+					lcnt--;
+				}
+				c <<= 1;
+			} while (++n & 07);
+		}
+		T(addstr(")", (size_t)1, &buf, &buflen));
+
+		break;
+	    }
+
+	case ns_t_key: {
+		char base64_key[NS_MD5RSA_MAX_BASE64];
+		u_int keyflags, protocol, algorithm, key_id;
+		const char *leader;
+		int n;
+
+		if (rdlen < 0U + NS_INT16SZ + NS_INT8SZ + NS_INT8SZ)
+			goto formerr;
+
+		/* Key flags, Protocol, Algorithm. */
+#if !defined(MOZILLA_NECKO_EXCLUDE_CODE) && !defined(_LIBC)
+		key_id = dst_s_dns_key_id(rdata, edata-rdata);
+#else
+		key_id = 0;
+#endif
+		keyflags = ns_get16(rdata);  rdata += NS_INT16SZ;
+		protocol = *rdata++;
+		algorithm = *rdata++;
+		len = SPRINTF((tmp, "0x%04x %u %u",
+			       keyflags, protocol, algorithm));
+		T(addstr(tmp, (size_t)len, &buf, &buflen));
+
+		/* Public key data. */
+		len = b64_ntop(rdata, (size_t)(edata - rdata),
+			       base64_key, sizeof base64_key);
+		if (len < 0)
+			goto formerr;
+		if (len > 15) {
+			T(addstr(" (", (size_t)2, &buf, &buflen));
+			leader = "\n\t\t";
+			spaced = 0;
+		} else
+			leader = " ";
+		for (n = 0; n < len; n += 48) {
+			T(addstr(leader, strlen(leader), &buf, &buflen));
+			T(addstr(base64_key + n, (size_t)MIN(len - n, 48),
+				 &buf, &buflen));
+		}
+		if (len > 15)
+			T(addstr(" )", (size_t)2, &buf, &buflen));
+		n = SPRINTF((tmp, " ; key_tag= %u", key_id));
+		T(addstr(tmp, (size_t)n, &buf, &buflen));
+
+		break;
+	    }
+
+	case ns_t_sig: {
+		char base64_key[NS_MD5RSA_MAX_BASE64];
+		u_int typ, algorithm, labels, footprint;
+		const char *leader;
+		u_long t;
+		int n;
+
+		if (rdlen < 22U)
+			goto formerr;
+
+		/* Type covered, Algorithm, Label count, Original TTL. */
+	        typ = ns_get16(rdata);  rdata += NS_INT16SZ;
+		algorithm = *rdata++;
+		labels = *rdata++;
+		t = ns_get32(rdata);  rdata += NS_INT32SZ;
+		len = SPRINTF((tmp, "%s %d %d %lu ",
+			       p_type((int)typ), algorithm, labels, t));
+		T(addstr(tmp, (size_t)len, &buf, &buflen));
+		if (labels > (u_int)dn_count_labels(name))
+			goto formerr;
+
+		/* Signature expiry. */
+		t = ns_get32(rdata);  rdata += NS_INT32SZ;
+		len = SPRINTF((tmp, "%s ", p_secstodate(t)));
+		T(addstr(tmp, (size_t)len, &buf, &buflen));
+
+		/* Time signed. */
+		t = ns_get32(rdata);  rdata += NS_INT32SZ;
+		len = SPRINTF((tmp, "%s ", p_secstodate(t)));
+		T(addstr(tmp, (size_t)len, &buf, &buflen));
+
+		/* Signature Footprint. */
+		footprint = ns_get16(rdata);  rdata += NS_INT16SZ;
+		len = SPRINTF((tmp, "%u ", footprint));
+		T(addstr(tmp, (size_t)len, &buf, &buflen));
+
+		/* Signer's name. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+		/* Signature. */
+		len = b64_ntop(rdata, (size_t)(edata - rdata),
+			       base64_key, sizeof base64_key);
+		if (len > 15) {
+			T(addstr(" (", (size_t)2, &buf, &buflen));
+			leader = "\n\t\t";
+			spaced = 0;
+		} else
+			leader = " ";
+		if (len < 0)
+			goto formerr;
+		for (n = 0; n < len; n += 48) {
+			T(addstr(leader, strlen(leader), &buf, &buflen));
+			T(addstr(base64_key + n, (size_t)MIN(len - n, 48),
+				 &buf, &buflen));
+		}
+		if (len > 15)
+			T(addstr(" )", (size_t)2, &buf, &buflen));
+		break;
+	    }
+
+	case ns_t_nxt: {
+		int n, c;
+
+		/* Next domain name. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+		/* Type bit map. */
+		n = edata - rdata;
+		for (c = 0; c < n*8; c++)
+			if (NS_NXT_BIT_ISSET(c, rdata)) {
+				len = SPRINTF((tmp, " %s", p_type(c)));
+				T(addstr(tmp, (size_t)len, &buf, &buflen));
+			}
+		break;
+	    }
+
+	case ns_t_cert: {
+		u_int c_type, key_tag, alg;
+		int n;
+		unsigned int siz;
+		char base64_cert[8192], tmp1[40];
+		const char *leader;
+
+		c_type  = ns_get16(rdata); rdata += NS_INT16SZ;
+		key_tag = ns_get16(rdata); rdata += NS_INT16SZ;
+		alg = (u_int) *rdata++;
+
+		len = SPRINTF((tmp1, "%d %d %d ", c_type, key_tag, alg));
+		T(addstr(tmp1, (size_t)len, &buf, &buflen));
+		siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */
+		if (siz > sizeof(base64_cert) * 3/4) {
+			const char *str = "record too long to print";
+			T(addstr(str, strlen(str), &buf, &buflen));
+		}
+		else {
+			len = b64_ntop(rdata, (size_t)(edata-rdata),
+			    base64_cert, siz);
+
+			if (len < 0)
+				goto formerr;
+			else if (len > 15) {
+				T(addstr(" (", (size_t)2, &buf, &buflen));
+				leader = "\n\t\t";
+				spaced = 0;
+			}
+			else
+				leader = " ";
+
+			for (n = 0; n < len; n += 48) {
+				T(addstr(leader, strlen(leader),
+					 &buf, &buflen));
+				T(addstr(base64_cert + n, (size_t)MIN(len - n, 48),
+					 &buf, &buflen));
+			}
+			if (len > 15)
+				T(addstr(" )", (size_t)2, &buf, &buflen));
+		}
+		break;
+	    }
+
+	case ns_t_tkey: {
+		/* KJD - need to complete this */
+		u_long t;
+		int mode, err, keysize;
+
+		/* Algorithm name. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+		T(addstr(" ", (size_t)1, &buf, &buflen));
+
+		/* Inception. */
+		t = ns_get32(rdata);  rdata += NS_INT32SZ;
+		len = SPRINTF((tmp, "%s ", p_secstodate(t)));
+		T(addstr(tmp, (size_t)len, &buf, &buflen));
+
+		/* Experation. */
+		t = ns_get32(rdata);  rdata += NS_INT32SZ;
+		len = SPRINTF((tmp, "%s ", p_secstodate(t)));
+		T(addstr(tmp, (size_t)len, &buf, &buflen));
+
+		/* Mode , Error, Key Size. */
+		/* Priority, Weight, Port. */
+		mode = ns_get16(rdata);  rdata += NS_INT16SZ;
+		err  = ns_get16(rdata);  rdata += NS_INT16SZ;
+		keysize  = ns_get16(rdata);  rdata += NS_INT16SZ;
+		len = SPRINTF((tmp, "%u %u %u ", mode, err, keysize));
+		T(addstr(tmp, (size_t)len, &buf, &buflen));
+
+		/* XXX need to dump key, print otherdata length & other data */
+		break;
+	    }
+
+	case ns_t_tsig: {
+		/* BEW - need to complete this */
+		int n;
+
+		T(len = addname(msg, msglen, &rdata, origin, &buf, &buflen));
+		T(addstr(" ", (size_t)1, &buf, &buflen));
+		rdata += 8; /* time */
+		n = ns_get16(rdata); rdata += INT16SZ;
+		rdata += n; /* sig */
+		n = ns_get16(rdata); rdata += INT16SZ; /* original id */
+		sprintf(buf, "%d", ns_get16(rdata));
+		rdata += INT16SZ;
+		addlen(strlen(buf), &buf, &buflen);
+		break;
+	    }
+
+	case ns_t_a6: {
+		struct in6_addr a;
+		int pbyte, pbit;
+
+		/* prefix length */
+		if (rdlen == 0U) goto formerr;
+		len = SPRINTF((tmp, "%d ", *rdata));
+		T(addstr(tmp, (size_t)len, &buf, &buflen));
+		pbit = *rdata;
+		if (pbit > 128) goto formerr;
+		pbyte = (pbit & ~7) / 8;
+		rdata++;
+
+		/* address suffix: provided only when prefix len != 128 */
+		if (pbit < 128) {
+			if (rdata + pbyte >= edata) goto formerr;
+			memset(&a, 0, sizeof(a));
+			memcpy(&a.s6_addr[pbyte], rdata, sizeof(a) - pbyte);
+			(void) inet_ntop(AF_INET6, &a, buf, buflen);
+			addlen(strlen(buf), &buf, &buflen);
+			rdata += sizeof(a) - pbyte;
+		}
+
+		/* prefix name: provided only when prefix len > 0 */
+		if (pbit == 0)
+			break;
+		if (rdata >= edata) goto formerr;
+		T(addstr(" ", (size_t)1, &buf, &buflen));
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+		break;
+	    }
+
+	case ns_t_opt: {
+		len = SPRINTF((tmp, "%u bytes", class));
+		T(addstr(tmp, (size_t)len, &buf, &buflen));
+		break;
+	    }
+
+	default:
+		comment = "unknown RR type";
+		goto hexify;
+	}
+	return (buf - obuf);
+ formerr:
+	comment = "RR format error";
+ hexify: {
+	int n, m;
+	char *p;
+
+	len = SPRINTF((tmp, "\\# %tu%s\t; %s", edata - rdata,
+		       rdlen != 0 ? " (" : "", comment));
+	T(addstr(tmp, (size_t)len, &buf, &buflen));
+	while (rdata < edata) {
+		p = tmp;
+		p += SPRINTF((p, "\n\t"));
+		spaced = 0;
+		n = MIN(16, edata - rdata);
+		for (m = 0; m < n; m++)
+			p += SPRINTF((p, "%02x ", rdata[m]));
+		T(addstr(tmp, (size_t)(p - tmp), &buf, &buflen));
+		if (n < 16) {
+			T(addstr(")", (size_t)1, &buf, &buflen));
+			T(addtab((size_t)(p - tmp + 1), (size_t)48, spaced, &buf, &buflen));
+		}
+		p = tmp;
+		p += SPRINTF((p, "; "));
+		for (m = 0; m < n; m++)
+			*p++ = (isascii(rdata[m]) && isprint(rdata[m]))
+				? rdata[m]
+				: '.';
+		T(addstr(tmp, (size_t)(p - tmp), &buf, &buflen));
+		rdata += n;
+	}
+	return (buf - obuf);
+    }
+}
+
+/* Private. */
+
+/*
+ * size_t
+ * prune_origin(name, origin)
+ *	Find out if the name is at or under the current origin.
+ * return:
+ *	Number of characters in name before start of origin,
+ *	or length of name if origin does not match.
+ * notes:
+ *	This function should share code with samedomain().
+ */
+static size_t
+prune_origin(const char *name, const char *origin) {
+	const char *oname = name;
+
+	while (*name != '\0') {
+		if (origin != NULL && ns_samename(name, origin) == 1)
+			return (name - oname - (name > oname));
+		while (*name != '\0') {
+			if (*name == '\\') {
+				name++;
+				/* XXX need to handle \nnn form. */
+				if (*name == '\0')
+					break;
+			} else if (*name == '.') {
+				name++;
+				break;
+			}
+			name++;
+		}
+	}
+	return (name - oname);
+}
+
+/*
+ * int
+ * charstr(rdata, edata, buf, buflen)
+ *	Format a <character-string> into the presentation buffer.
+ * return:
+ *	Number of rdata octets consumed
+ *	0 for protocol format error
+ *	-1 for output buffer error
+ * side effects:
+ *	buffer is advanced on success.
+ */
+static int
+charstr(const u_char *rdata, const u_char *edata, char **buf, size_t *buflen) {
+	const u_char *odata = rdata;
+	size_t save_buflen = *buflen;
+	char *save_buf = *buf;
+
+	if (addstr("\"", (size_t)1, buf, buflen) < 0)
+		goto enospc;
+	if (rdata < edata) {
+		int n = *rdata;
+
+		if (rdata + 1 + n <= edata) {
+			rdata++;
+			while (n-- > 0) {
+				if (strchr("\n\"\\", *rdata) != NULL)
+					if (addstr("\\", (size_t)1, buf, buflen) < 0)
+						goto enospc;
+				if (addstr((const char *)rdata, (size_t)1,
+					   buf, buflen) < 0)
+					goto enospc;
+				rdata++;
+			}
+		}
+	}
+	if (addstr("\"", (size_t)1, buf, buflen) < 0)
+		goto enospc;
+	return (rdata - odata);
+ enospc:
+	errno = ENOSPC;
+	*buf = save_buf;
+	*buflen = save_buflen;
+	return (-1);
+}
+
+static int
+addname(const u_char *msg, size_t msglen,
+	const u_char **pp, const char *origin,
+	char **buf, size_t *buflen)
+{
+	size_t newlen, save_buflen = *buflen;
+	char *save_buf = *buf;
+	int n;
+
+	n = dn_expand(msg, msg + msglen, *pp, *buf, (int)*buflen);
+	if (n < 0)
+		goto enospc;	/* Guess. */
+	newlen = prune_origin(*buf, origin);
+	if (**buf == '\0') {
+		goto root;
+	} else if (newlen == 0U) {
+		/* Use "@" instead of name. */
+		if (newlen + 2 > *buflen)
+			goto enospc;        /* No room for "@\0". */
+		(*buf)[newlen++] = '@';
+		(*buf)[newlen] = '\0';
+	} else {
+		if (((origin == NULL || origin[0] == '\0') ||
+		    (origin[0] != '.' && origin[1] != '\0' &&
+		    (*buf)[newlen] == '\0')) && (*buf)[newlen - 1] != '.') {
+			/* No trailing dot. */
+ root:
+			if (newlen + 2 > *buflen)
+				goto enospc;	/* No room for ".\0". */
+			(*buf)[newlen++] = '.';
+			(*buf)[newlen] = '\0';
+		}
+	}
+	*pp += n;
+	addlen(newlen, buf, buflen);
+	**buf = '\0';
+	return (newlen);
+ enospc:
+	errno = ENOSPC;
+	*buf = save_buf;
+	*buflen = save_buflen;
+	return (-1);
+}
+
+static void
+addlen(size_t len, char **buf, size_t *buflen) {
+	assert(len <= *buflen);
+	*buf += len;
+	*buflen -= len;
+}
+
+static int
+addstr(const char *src, size_t len, char **buf, size_t *buflen) {
+	if (len >= *buflen) {
+		errno = ENOSPC;
+		return (-1);
+	}
+	memcpy(*buf, src, len);
+	addlen(len, buf, buflen);
+	**buf = '\0';
+	return (0);
+}
+
+static int
+addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) {
+	size_t save_buflen = *buflen;
+	char *save_buf = *buf;
+	int t;
+
+	if (spaced || len >= target - 1) {
+		T(addstr("  ", (size_t)2, buf, buflen));
+		spaced = 1;
+	} else {
+		for (t = (target - len - 1) / 8; t >= 0; t--)
+			if (addstr("\t", (size_t)1, buf, buflen) < 0) {
+				*buflen = save_buflen;
+				*buf = save_buf;
+				return (-1);
+			}
+		spaced = 0;
+	}
+	return (spaced);
+}
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/ns_samedomain.c
@@ -0,0 +1,226 @@
+/*	$NetBSD: ns_samedomain.c,v 1.2 2004/05/20 20:35:05 christos Exp $	*/
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995,1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#define ANDROID_CHANGES 1
+#define MOZILLA_NECKO_EXCLUDE_CODE 1
+
+#include <sys/cdefs.h>
+#ifndef lint
+#ifdef notdef
+static const char rcsid[] = "Id: ns_samedomain.c,v 1.1.2.2.4.2 2004/03/16 12:34:17 marka Exp";
+#else
+__RCSID("$NetBSD: ns_samedomain.c,v 1.2 2004/05/20 20:35:05 christos Exp $");
+#endif
+#endif
+
+#include <sys/types.h>
+#include "arpa_nameser.h"
+#include <errno.h>
+#include <string.h>
+
+#ifndef MOZILLA_NECKO_EXCLUDE_CODE
+#ifndef _LIBC
+/*
+ * int
+ * ns_samedomain(a, b)
+ *	Check whether a name belongs to a domain.
+ * Inputs:
+ *	a - the domain whose ancestory is being verified
+ *	b - the potential ancestor we're checking against
+ * Return:
+ *	boolean - is a at or below b?
+ * Notes:
+ *	Trailing dots are first removed from name and domain.
+ *	Always compare complete subdomains, not only whether the
+ *	domain name is the trailing string of the given name.
+ *
+ *	"host.foobar.top" lies in "foobar.top" and in "top" and in ""
+ *	but NOT in "bar.top"
+ */
+
+int
+ns_samedomain(const char *a, const char *b) {
+	size_t la, lb;
+	int diff, i, escaped;
+	const char *cp;
+
+	la = strlen(a);
+	lb = strlen(b);
+
+	/* Ignore a trailing label separator (i.e. an unescaped dot) in 'a'. */
+	if (la != 0U && a[la - 1] == '.') {
+		escaped = 0;
+		/* Note this loop doesn't get executed if la==1. */
+		for (i = la - 2; i >= 0; i--)
+			if (a[i] == '\\') {
+				if (escaped)
+					escaped = 0;
+				else
+					escaped = 1;
+			} else
+				break;
+		if (!escaped)
+			la--;
+	}
+
+	/* Ignore a trailing label separator (i.e. an unescaped dot) in 'b'. */
+	if (lb != 0U && b[lb - 1] == '.') {
+		escaped = 0;
+		/* note this loop doesn't get executed if lb==1 */
+		for (i = lb - 2; i >= 0; i--)
+			if (b[i] == '\\') {
+				if (escaped)
+					escaped = 0;
+				else
+					escaped = 1;
+			} else
+				break;
+		if (!escaped)
+			lb--;
+	}
+
+	/* lb == 0 means 'b' is the root domain, so 'a' must be in 'b'. */
+	if (lb == 0U)
+		return (1);
+
+	/* 'b' longer than 'a' means 'a' can't be in 'b'. */
+	if (lb > la)
+		return (0);
+
+	/* 'a' and 'b' being equal at this point indicates sameness. */
+	if (lb == la)
+		return (strncasecmp(a, b, lb) == 0);
+
+	/* Ok, we know la > lb. */
+
+	diff = la - lb;
+
+	/*
+	 * If 'a' is only 1 character longer than 'b', then it can't be
+	 * a subdomain of 'b' (because of the need for the '.' label
+	 * separator).
+	 */
+	if (diff < 2)
+		return (0);
+
+	/*
+	 * If the character before the last 'lb' characters of 'b'
+	 * isn't '.', then it can't be a match (this lets us avoid
+	 * having "foobar.com" match "bar.com").
+	 */
+	if (a[diff - 1] != '.')
+		return (0);
+
+	/*
+	 * We're not sure about that '.', however.  It could be escaped
+         * and thus not a really a label separator.
+	 */
+	escaped = 0;
+	for (i = diff - 2; i >= 0; i--)
+		if (a[i] == '\\') {
+			if (escaped)
+				escaped = 0;
+			else
+				escaped = 1;
+		} else
+			break;
+	if (escaped)
+		return (0);
+
+	/* Now compare aligned trailing substring. */
+	cp = a + diff;
+	return (strncasecmp(cp, b, lb) == 0);
+}
+
+/*
+ * int
+ * ns_subdomain(a, b)
+ *	is "a" a subdomain of "b"?
+ */
+int
+ns_subdomain(const char *a, const char *b) {
+	return (ns_samename(a, b) != 1 && ns_samedomain(a, b));
+}
+#endif
+#endif
+
+/*
+ * int
+ * ns_makecanon(src, dst, dstsize)
+ *	make a canonical copy of domain name "src"
+ * notes:
+ *	foo -> foo.
+ *	foo. -> foo.
+ *	foo.. -> foo.
+ *	foo\. -> foo\..
+ *	foo\\. -> foo\\.
+ */
+
+int
+ns_makecanon(const char *src, char *dst, size_t dstsize) {
+	size_t n = strlen(src);
+
+	if (n + sizeof "." > dstsize) {			/* Note: sizeof == 2 */
+		errno = EMSGSIZE;
+		return (-1);
+	}
+	strcpy(dst, src);
+	while (n >= 1U && dst[n - 1] == '.')		/* Ends in "." */
+		if (n >= 2U && dst[n - 2] == '\\' &&	/* Ends in "\." */
+		    (n < 3U || dst[n - 3] != '\\'))	/* But not "\\." */
+			break;
+		else
+			dst[--n] = '\0';
+	dst[n++] = '.';
+	dst[n] = '\0';
+	return (0);
+}
+
+/*
+ * int
+ * ns_samename(a, b)
+ *	determine whether domain name "a" is the same as domain name "b"
+ * return:
+ *	-1 on error
+ *	0 if names differ
+ *	1 if names are the same
+ */
+
+int
+ns_samename(const char *a, const char *b) {
+	char ta[NS_MAXDNAME], tb[NS_MAXDNAME];
+
+	if (ns_makecanon(a, ta, sizeof ta) < 0 ||
+	    ns_makecanon(b, tb, sizeof tb) < 0)
+		return (-1);
+	if (strcasecmp(ta, tb) == 0)
+		return (1);
+	else
+		return (0);
+}
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/ns_ttl.c
@@ -0,0 +1,179 @@
+/*	$NetBSD: ns_ttl.c,v 1.2 2004/05/20 20:35:05 christos Exp $	*/
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#define ANDROID_CHANGES 1
+#define MOZILLA_NECKO_EXCLUDE_CODE 1
+
+#include <sys/cdefs.h>
+#ifndef lint
+#ifdef notdef
+static const char rcsid[] = "Id: ns_ttl.c,v 1.1.206.1 2004/03/09 08:33:45 marka Exp";
+#else
+__RCSID("$NetBSD: ns_ttl.c,v 1.2 2004/05/20 20:35:05 christos Exp $");
+#endif
+#endif
+
+/* Import. */
+
+#include "arpa_nameser.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+/* Forward. */
+
+static int	fmt1(int t, char s, char **buf, size_t *buflen);
+
+/* Macros. */
+
+#define T(x) do { if ((x) < 0) return (-1); } while(0)
+
+/* Public. */
+
+int
+ns_format_ttl(u_long src, char *dst, size_t dstlen) {
+	char *odst = dst;
+	int secs, mins, hours, days, weeks, x;
+	char *p;
+
+	secs = src % 60;   src /= 60;
+	mins = src % 60;   src /= 60;
+	hours = src % 24;  src /= 24;
+	days = src % 7;    src /= 7;
+	weeks = src;       src = 0;
+
+	x = 0;
+	if (weeks) {
+		T(fmt1(weeks, 'W', &dst, &dstlen));
+		x++;
+	}
+	if (days) {
+		T(fmt1(days, 'D', &dst, &dstlen));
+		x++;
+	}
+	if (hours) {
+		T(fmt1(hours, 'H', &dst, &dstlen));
+		x++;
+	}
+	if (mins) {
+		T(fmt1(mins, 'M', &dst, &dstlen));
+		x++;
+	}
+	if (secs || !(weeks || days || hours || mins)) {
+		T(fmt1(secs, 'S', &dst, &dstlen));
+		x++;
+	}
+
+	if (x > 1) {
+		int ch;
+
+		for (p = odst; (ch = *p) != '\0'; p++)
+			if (isascii(ch) && isupper(ch))
+				*p = tolower(ch);
+	}
+
+	return (dst - odst);
+}
+
+#ifndef MOZILLA_NECKO_EXCLUDE_CODE
+#ifndef _LIBC
+int
+ns_parse_ttl(const char *src, u_long *dst) {
+	u_long ttl, tmp;
+	int ch, digits, dirty;
+
+	ttl = 0;
+	tmp = 0;
+	digits = 0;
+	dirty = 0;
+	while ((ch = *src++) != '\0') {
+		if (!isascii(ch) || !isprint(ch))
+			goto einval;
+		if (isdigit(ch)) {
+			tmp *= 10;
+			tmp += (ch - '0');
+			digits++;
+			continue;
+		}
+		if (digits == 0)
+			goto einval;
+		if (islower(ch))
+			ch = toupper(ch);
+		switch (ch) {
+		case 'W':  tmp *= 7;	/*FALLTHROUGH*/
+		case 'D':  tmp *= 24;	/*FALLTHROUGH*/
+		case 'H':  tmp *= 60;	/*FALLTHROUGH*/
+		case 'M':  tmp *= 60;	/*FALLTHROUGH*/
+		case 'S':  break;
+		default:   goto einval;
+		}
+		ttl += tmp;
+		tmp = 0;
+		digits = 0;
+		dirty = 1;
+	}
+	if (digits > 0) {
+		if (dirty)
+			goto einval;
+		else
+			ttl += tmp;
+	}
+	*dst = ttl;
+	return (0);
+
+ einval:
+	errno = EINVAL;
+	return (-1);
+}
+#endif
+#endif
+
+/* Private. */
+
+static int
+fmt1(int t, char s, char **buf, size_t *buflen) {
+	char tmp[50];
+	size_t len;
+
+	len = SPRINTF((tmp, "%d%c", t, s));
+	if (len + 1 > *buflen)
+		return (-1);
+	strcpy(*buf, tmp);
+	*buf += len;
+	*buflen -= len;
+	return (0);
+}
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/res_comp.c
@@ -0,0 +1,282 @@
+/*	$NetBSD: res_comp.c,v 1.6 2004/05/22 23:47:09 christos Exp $	*/
+
+/*
+ * Copyright (c) 1985, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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 DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#define ANDROID_CHANGES 1
+#define MOZILLA_NECKO_EXCLUDE_CODE 1
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#ifdef notdef
+static const char sccsid[] = "@(#)res_comp.c	8.1 (Berkeley) 6/4/93";
+static const char rcsid[] = "Id: res_comp.c,v 1.1.2.1.4.1 2004/03/09 08:33:54 marka Exp";
+#else
+__RCSID("$NetBSD: res_comp.c,v 1.6 2004/05/22 23:47:09 christos Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include "arpa_nameser.h"
+#include <ctype.h>
+#ifdef ANDROID_CHANGES
+#include "resolv_private.h"
+#else
+#include <resolv.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * Expand compressed domain name 'src' to full domain name.
+ * 'msg' is a pointer to the begining of the message,
+ * 'eom' points to the first location after the message,
+ * 'dst' is a pointer to a buffer of size 'dstsiz' for the result.
+ * Return size of compressed name or -1 if there was an error.
+ */
+int
+dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
+	  char *dst, int dstsiz)
+{
+	int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);
+
+	if (n > 0 && dst[0] == '.')
+		dst[0] = '\0';
+	return (n);
+}
+
+/*
+ * Pack domain name 'exp_dn' in presentation form into 'comp_dn'.
+ * Return the size of the compressed name or -1.
+ * 'length' is the size of the array pointed to by 'comp_dn'.
+ */
+int
+dn_comp(const char *src, u_char *dst, int dstsiz,
+	u_char **dnptrs, u_char **lastdnptr)
+{
+	return (ns_name_compress(src, dst, (size_t)dstsiz,
+				 (const u_char **)dnptrs,
+				 (const u_char **)lastdnptr));
+}
+
+/*
+ * Skip over a compressed domain name. Return the size or -1.
+ */
+int
+dn_skipname(const u_char *ptr, const u_char *eom) {
+	const u_char *saveptr = ptr;
+
+	if (ns_name_skip(&ptr, eom) == -1)
+		return (-1);
+	return (ptr - saveptr);
+}
+
+/*
+ * Verify that a domain name uses an acceptable character set.
+ */
+
+/*
+ * Note the conspicuous absence of ctype macros in these definitions.  On
+ * non-ASCII hosts, we can't depend on string literals or ctype macros to
+ * tell us anything about network-format data.  The rest of the BIND system
+ * is not careful about this, but for some reason, we're doing it right here.
+ */
+
+/* BIONIC: We also accept underscores in the middle of labels.
+ *         This extension is needed to make resolution on some VPN networks
+ *         work properly.
+ */
+
+#define PERIOD 0x2e
+#define	hyphenchar(c) ((c) == 0x2d)
+#define bslashchar(c) ((c) == 0x5c)
+#define periodchar(c) ((c) == PERIOD)
+#define asterchar(c) ((c) == 0x2a)
+#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
+		   || ((c) >= 0x61 && (c) <= 0x7a))
+#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
+#define underscorechar(c)  ((c) == 0x5f)
+
+#define borderchar(c) (alphachar(c) || digitchar(c))
+#define middlechar(c) (borderchar(c) || hyphenchar(c) || underscorechar(c))
+#define	domainchar(c) ((c) > 0x20 && (c) < 0x7f)
+
+int
+res_hnok(const char *dn) {
+	int pch = PERIOD, ch = *dn++;
+
+	while (ch != '\0') {
+		int nch = *dn++;
+
+		if (periodchar(ch)) {
+			;
+		} else if (periodchar(pch)) {
+			if (!borderchar(ch))
+				return (0);
+		} else if (periodchar(nch) || nch == '\0') {
+			if (!borderchar(ch))
+				return (0);
+		} else {
+			if (!middlechar(ch))
+				return (0);
+		}
+		pch = ch, ch = nch;
+	}
+	return (1);
+}
+
+#ifndef MOZILLA_NECKO_EXCLUDE_CODE
+/*
+ * hostname-like (A, MX, WKS) owners can have "*" as their first label
+ * but must otherwise be as a host name.
+ */
+int
+res_ownok(const char *dn) {
+	if (asterchar(dn[0])) {
+		if (periodchar(dn[1]))
+			return (res_hnok(dn+2));
+		if (dn[1] == '\0')
+			return (1);
+	}
+	return (res_hnok(dn));
+}
+
+/*
+ * SOA RNAMEs and RP RNAMEs can have any printable character in their first
+ * label, but the rest of the name has to look like a host name.
+ */
+int
+res_mailok(const char *dn) {
+	int ch, escaped = 0;
+
+	/* "." is a valid missing representation */
+	if (*dn == '\0')
+		return (1);
+
+	/* otherwise <label>.<hostname> */
+	while ((ch = *dn++) != '\0') {
+		if (!domainchar(ch))
+			return (0);
+		if (!escaped && periodchar(ch))
+			break;
+		if (escaped)
+			escaped = 0;
+		else if (bslashchar(ch))
+			escaped = 1;
+	}
+	if (periodchar(ch))
+		return (res_hnok(dn));
+	return (0);
+}
+
+/*
+ * This function is quite liberal, since RFC 1034's character sets are only
+ * recommendations.
+ */
+int
+res_dnok(const char *dn) {
+	int ch;
+
+	while ((ch = *dn++) != '\0')
+		if (!domainchar(ch))
+			return (0);
+	return (1);
+}
+#endif
+
+#ifdef BIND_4_COMPAT
+/*
+ * This module must export the following externally-visible symbols:
+ *	___putlong
+ *	___putshort
+ *	__getlong
+ *	__getshort
+ * Note that one _ comes from C and the others come from us.
+ */
+void __putlong(u_int32_t src, u_char *dst) { ns_put32(src, dst); }
+void __putshort(u_int16_t src, u_char *dst) { ns_put16(src, dst); }
+#ifndef __ultrix__
+u_int32_t _getlong(const u_char *src) { return (ns_get32(src)); }
+u_int16_t _getshort(const u_char *src) { return (ns_get16(src)); }
+#endif /*__ultrix__*/
+#endif /*BIND_4_COMPAT*/
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/res_data.c
@@ -0,0 +1,348 @@
+/*	$NetBSD: res_data.c,v 1.8 2004/06/09 18:07:03 christos Exp $	*/
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#define ANDROID_CHANGES 1
+#define MOZILLA_NECKO_EXCLUDE_CODE 1
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#ifdef notdef
+static const char rcsid[] = "Id: res_data.c,v 1.1.206.2 2004/03/16 12:34:18 marka Exp";
+#else
+__RCSID("$NetBSD: res_data.c,v 1.8 2004/06/09 18:07:03 christos Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include "arpa_nameser.h"
+
+#include <ctype.h>
+#include <netdb.h>
+#include "resolv_private.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+const char * const _res_opcodes[] = {
+	"QUERY",
+	"IQUERY",
+	"CQUERYM",
+	"CQUERYU",	/* experimental */
+	"NOTIFY",	/* experimental */
+	"UPDATE",
+	"6",
+	"7",
+	"8",
+	"9",
+	"10",
+	"11",
+	"12",
+	"13",
+	"ZONEINIT",
+	"ZONEREF",
+};
+
+#ifdef BIND_UPDATE
+const char * const _res_sectioncodes[] = {
+	"ZONE",
+	"PREREQUISITES",
+	"UPDATE",
+	"ADDITIONAL",
+};
+#endif
+
+#ifndef MOZILLA_NECKO_EXCLUDE_CODE
+#ifndef __BIND_NOSTATIC
+extern struct __res_state _nres;
+
+/* Proto. */
+
+int  res_ourserver_p(const res_state, const struct sockaddr *);
+
+#ifdef ANDROID_CHANGES
+int res_need_init() {
+	return ((_nres.options & RES_INIT) == 0U) || res_get_dns_changed();
+}
+#else
+#define res_need_init()   ((_nres.options & RES_INIT) == 0U)
+#endif
+
+int
+res_init(void) {
+	int rv;
+	extern int __res_vinit(res_state, int);
+#ifdef COMPAT__RES
+	/*
+	 * Compatibility with program that were accessing _res directly
+	 * to set options. We keep another struct res that is the same
+	 * size as the original res structure, and then copy fields to
+	 * it so that we achieve the same initialization
+	 */
+	extern void *__res_get_old_state(void);
+	extern void __res_put_old_state(void *);
+	res_state ores = __res_get_old_state();
+
+	if (ores->options != 0)
+		_nres.options = ores->options;
+	if (ores->retrans != 0)
+		_nres.retrans = ores->retrans;
+	if (ores->retry != 0)
+		_nres.retry = ores->retry;
+#endif
+
+	/*
+	 * These three fields used to be statically initialized.  This made
+	 * it hard to use this code in a shared library.  It is necessary,
+	 * now that we're doing dynamic initialization here, that we preserve
+	 * the old semantics: if an application modifies one of these three
+	 * fields of _res before res_init() is called, res_init() will not
+	 * alter them.  Of course, if an application is setting them to
+	 * _zero_ before calling res_init(), hoping to override what used
+	 * to be the static default, we can't detect it and unexpected results
+	 * will follow.  Zero for any of these fields would make no sense,
+	 * so one can safely assume that the applications were already getting
+	 * unexpected results.
+	 *
+	 * _nres.options is tricky since some apps were known to diddle the bits
+	 * before res_init() was first called. We can't replicate that semantic
+	 * with dynamic initialization (they may have turned bits off that are
+	 * set in RES_DEFAULT).  Our solution is to declare such applications
+	 * "broken".  They could fool us by setting RES_INIT but none do (yet).
+	 */
+	if (!_nres.retrans)
+		_nres.retrans = RES_TIMEOUT;
+	if (!_nres.retry)
+		_nres.retry = 4;
+	if (!(_nres.options & RES_INIT))
+		_nres.options = RES_DEFAULT;
+
+	/*
+	 * This one used to initialize implicitly to zero, so unless the app
+	 * has set it to something in particular, we can randomize it now.
+	 */
+	if (!_nres.id)
+		_nres.id = res_randomid();
+
+	rv = __res_vinit(&_nres, 1);
+#ifdef COMPAT__RES
+	__res_put_old_state(&_nres);
+#endif
+	return rv;
+}
+
+void
+p_query(const u_char *msg) {
+	fp_query(msg, stdout);
+}
+
+void
+fp_query(const u_char *msg, FILE *file) {
+	fp_nquery(msg, PACKETSZ, file);
+}
+
+void
+fp_nquery(const u_char *msg, int len, FILE *file) {
+	if (res_need_init() && res_init() == -1)
+		return;
+
+	res_pquery(&_nres, msg, len, file);
+}
+
+int
+res_mkquery(int op,			/* opcode of query */
+	    const char *dname,		/* domain name */
+	    int class, int type,	/* class and type of query */
+	    const u_char *data,		/* resource record data */
+	    int datalen,		/* length of data */
+	    const u_char *newrr_in,	/* new rr for modify or append */
+	    u_char *buf,		/* buffer to put query */
+	    int buflen)			/* size of buffer */
+{
+	if (res_need_init() && res_init() == -1) {
+		RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
+		return (-1);
+	}
+	return (res_nmkquery(&_nres, op, dname, class, type,
+			     data, datalen,
+			     newrr_in, buf, buflen));
+}
+
+#ifdef _LIBRESOLV
+int
+res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
+	if (res_need_init() && res_init() == -1) {
+		RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
+		return (-1);
+	}
+
+	return (res_nmkupdate(&_nres, rrecp_in, buf, buflen));
+}
+#endif
+
+int
+res_query(const char *name,	/* domain name */
+	  int class, int type,	/* class and type of query */
+	  u_char *answer,	/* buffer to put answer */
+	  int anslen)		/* size of answer buffer */
+{
+	if (res_need_init() && res_init() == -1) {
+		RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
+		return (-1);
+	}
+	return (res_nquery(&_nres, name, class, type, answer, anslen));
+}
+
+void
+res_send_setqhook(res_send_qhook hook) {
+	_nres.qhook = hook;
+}
+
+void
+res_send_setrhook(res_send_rhook hook) {
+	_nres.rhook = hook;
+}
+
+int
+res_isourserver(const struct sockaddr_in *inp) {
+	return (res_ourserver_p(&_nres, (const struct sockaddr *)(const void *)inp));
+}
+
+int
+res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) {
+	if (res_need_init() && res_init() == -1) {
+		/* errno should have been set by res_init() in this case. */
+		return (-1);
+	}
+
+	return (res_nsend(&_nres, buf, buflen, ans, anssiz));
+}
+
+#ifdef _LIBRESOLV
+int
+res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key,
+	       u_char *ans, int anssiz)
+{
+	if (res_need_init() && res_init() == -1) {
+		/* errno should have been set by res_init() in this case. */
+		return (-1);
+	}
+
+	return (res_nsendsigned(&_nres, buf, buflen, key, ans, anssiz));
+}
+#endif
+
+void
+res_close(void) {
+	res_nclose(&_nres);
+}
+
+#ifdef _LIBRESOLV
+int
+res_update(ns_updrec *rrecp_in) {
+	if (res_need_init() && res_init() == -1) {
+		RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
+		return (-1);
+	}
+
+	return (res_nupdate(&_nres, rrecp_in, NULL));
+}
+#endif
+
+int
+res_search(const char *name,	/* domain name */
+	   int class, int type,	/* class and type of query */
+	   u_char *answer,	/* buffer to put answer */
+	   int anslen)		/* size of answer */
+{
+	if (res_need_init() && res_init() == -1) {
+		RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
+		return (-1);
+	}
+
+	return (res_nsearch(&_nres, name, class, type, answer, anslen));
+}
+
+int
+res_querydomain(const char *name,
+		const char *domain,
+		int class, int type,	/* class and type of query */
+		u_char *answer,		/* buffer to put answer */
+		int anslen)		/* size of answer */
+{
+	if (res_need_init() && res_init() == -1) {
+		RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
+		return (-1);
+	}
+
+	return (res_nquerydomain(&_nres, name, domain,
+				 class, type,
+				 answer, anslen));
+}
+
+int
+res_opt(int a, u_char *b, int c, int d)
+{
+	return res_nopt(&_nres, a, b, c, d);
+}
+#endif
+#endif
+
+const char *
+hostalias(const char *name) {
+	return NULL;
+}
+
+#ifndef MOZILLA_NECKO_EXCLUDE_CODE
+#ifdef ultrix
+int
+local_hostname_length(const char *hostname) {
+	int len_host, len_domain;
+
+	if (!*_nres.defdname)
+		res_init();
+	len_host = strlen(hostname);
+	len_domain = strlen(_nres.defdname);
+	if (len_host > len_domain &&
+	    !strcasecmp(hostname + len_host - len_domain, _nres.defdname) &&
+	    hostname[len_host - len_domain - 1] == '.')
+		return (len_host - len_domain - 1);
+	return (0);
+}
+#endif /*ultrix*/
+#endif
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/res_debug.c
@@ -0,0 +1,1201 @@
+/*	$NetBSD: res_debug.c,v 1.7 2004/11/07 02:25:01 christos Exp $	*/
+
+/*
+ * Copyright (c) 1985
+ *    The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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 DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#define ANDROID_CHANGES 1
+#define MOZILLA_NECKO_EXCLUDE_CODE 1
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#ifdef notdef
+static const char sccsid[] = "@(#)res_debug.c	8.1 (Berkeley) 6/4/93";
+static const char rcsid[] = "Id: res_debug.c,v 1.3.2.5.4.5 2004/07/28 20:16:46 marka Exp";
+#else
+__RCSID("$NetBSD: res_debug.c,v 1.7 2004/11/07 02:25:01 christos Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include "arpa_nameser.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <math.h>
+#include <netdb.h>
+#include "resolv_private.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) sprintf x
+#endif
+
+#ifndef MOZILLA_NECKO_EXCLUDE_CODE
+static const char *precsize_ntoa(u_int32_t);
+#endif
+
+extern const char * const _res_opcodes[];
+extern const char * const _res_sectioncodes[];
+
+#ifndef MOZILLA_NECKO_EXCLUDE_CODE
+#ifndef _LIBC
+/*
+ * Print the current options.
+ */
+void
+fp_resstat(const res_state statp, FILE *file) {
+	u_long mask;
+
+	fprintf(file, ";; res options:");
+	for (mask = 1;  mask != 0U;  mask <<= 1)
+		if (statp->options & mask)
+			fprintf(file, " %s", p_option(mask));
+	putc('\n', file);
+}
+#endif
+#endif
+
+static void
+do_section(const res_state statp,
+	   ns_msg *handle, ns_sect section,
+	   int pflag, FILE *file)
+{
+	int n, sflag, rrnum;
+	int buflen = 2048;
+	char *buf;
+	ns_opcode opcode;
+	ns_rr rr;
+
+	/*
+	 * Print answer records.
+	 */
+	sflag = (statp->pfcode & pflag);
+	if (statp->pfcode && !sflag)
+		return;
+
+	buf = malloc((size_t)buflen);
+	if (buf == NULL) {
+		fprintf(file, ";; memory allocation failure\n");
+		return;
+	}
+
+	opcode = (ns_opcode) ns_msg_getflag(*handle, ns_f_opcode);
+	rrnum = 0;
+	for (;;) {
+		if (ns_parserr(handle, section, rrnum, &rr)) {
+			if (errno != ENODEV)
+				fprintf(file, ";; ns_parserr: %s\n",
+					strerror(errno));
+			else if (rrnum > 0 && sflag != 0 &&
+				 (statp->pfcode & RES_PRF_HEAD1))
+				putc('\n', file);
+			goto cleanup;
+		}
+		if (rrnum == 0 && sflag != 0 && (statp->pfcode & RES_PRF_HEAD1))
+			fprintf(file, ";; %s SECTION:\n",
+				p_section(section, opcode));
+		if (section == ns_s_qd)
+			fprintf(file, ";;\t%s, type = %s, class = %s\n",
+				ns_rr_name(rr),
+				p_type(ns_rr_type(rr)),
+				p_class(ns_rr_class(rr)));
+		else if (section == ns_s_ar && ns_rr_type(rr) == ns_t_opt) {
+			u_int32_t ttl = ns_rr_ttl(rr);
+			fprintf(file,
+				"; EDNS: version: %u, udp=%u, flags=%04x\n",
+				(ttl>>16)&0xff, ns_rr_class(rr), ttl&0xffff);
+		} else {
+			n = ns_sprintrr(handle, &rr, NULL, NULL,
+					buf, (u_int)buflen);
+			if (n < 0) {
+				if (errno == ENOSPC) {
+					free(buf);
+					buf = NULL;
+					if (buflen < 131072)
+						buf = malloc((size_t)(buflen += 1024));
+					if (buf == NULL) {
+						fprintf(file,
+				              ";; memory allocation failure\n");
+					      return;
+					}
+					continue;
+				}
+				fprintf(file, ";; ns_sprintrr: %s\n",
+					strerror(errno));
+				goto cleanup;
+			}
+			fputs(buf, file);
+			fputc('\n', file);
+		}
+		rrnum++;
+	}
+ cleanup:
+	if (buf != NULL)
+		free(buf);
+}
+
+/*
+ * Print the contents of a query.
+ * This is intended to be primarily a debugging routine.
+ */
+void
+res_pquery(const res_state statp, const u_char *msg, int len, FILE *file) {
+	ns_msg handle;
+	int qdcount, ancount, nscount, arcount;
+	u_int opcode, rcode, id;
+
+	if (ns_initparse(msg, len, &handle) < 0) {
+		fprintf(file, ";; ns_initparse: %s\n", strerror(errno));
+		return;
+	}
+	opcode = ns_msg_getflag(handle, ns_f_opcode);
+	rcode = ns_msg_getflag(handle, ns_f_rcode);
+	id = ns_msg_id(handle);
+	qdcount = ns_msg_count(handle, ns_s_qd);
+	ancount = ns_msg_count(handle, ns_s_an);
+	nscount = ns_msg_count(handle, ns_s_ns);
+	arcount = ns_msg_count(handle, ns_s_ar);
+
+	/*
+	 * Print header fields.
+	 */
+	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX) || rcode)
+		fprintf(file,
+			";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n",
+			_res_opcodes[opcode], p_rcode((int)rcode), id);
+	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX))
+		putc(';', file);
+	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD2)) {
+		fprintf(file, "; flags:");
+		if (ns_msg_getflag(handle, ns_f_qr))
+			fprintf(file, " qr");
+		if (ns_msg_getflag(handle, ns_f_aa))
+			fprintf(file, " aa");
+		if (ns_msg_getflag(handle, ns_f_tc))
+			fprintf(file, " tc");
+		if (ns_msg_getflag(handle, ns_f_rd))
+			fprintf(file, " rd");
+		if (ns_msg_getflag(handle, ns_f_ra))
+			fprintf(file, " ra");
+		if (ns_msg_getflag(handle, ns_f_z))
+			fprintf(file, " ??");
+		if (ns_msg_getflag(handle, ns_f_ad))
+			fprintf(file, " ad");
+		if (ns_msg_getflag(handle, ns_f_cd))
+			fprintf(file, " cd");
+	}
+	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD1)) {
+		fprintf(file, "; %s: %d",
+			p_section(ns_s_qd, (int)opcode), qdcount);
+		fprintf(file, ", %s: %d",
+			p_section(ns_s_an, (int)opcode), ancount);
+		fprintf(file, ", %s: %d",
+			p_section(ns_s_ns, (int)opcode), nscount);
+		fprintf(file, ", %s: %d",
+			p_section(ns_s_ar, (int)opcode), arcount);
+	}
+	if ((!statp->pfcode) || (statp->pfcode &
+		(RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
+		putc('\n',file);
+	}
+	/*
+	 * Print the various sections.
+	 */
+	do_section(statp, &handle, ns_s_qd, RES_PRF_QUES, file);
+	do_section(statp, &handle, ns_s_an, RES_PRF_ANS, file);
+	do_section(statp, &handle, ns_s_ns, RES_PRF_AUTH, file);
+	do_section(statp, &handle, ns_s_ar, RES_PRF_ADD, file);
+	if (qdcount == 0 && ancount == 0 &&
+	    nscount == 0 && arcount == 0)
+		putc('\n', file);
+}
+
+#ifndef MOZILLA_NECKO_EXCLUDE_CODE
+const u_char *
+p_cdnname(const u_char *cp, const u_char *msg, int len, FILE *file) {
+	char name[MAXDNAME];
+	int n;
+
+	if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
+		return (NULL);
+	if (name[0] == '\0')
+		putc('.', file);
+	else
+		fputs(name, file);
+	return (cp + n);
+}
+
+const u_char *
+p_cdname(const u_char *cp, const u_char *msg, FILE *file) {
+	return (p_cdnname(cp, msg, PACKETSZ, file));
+}
+
+/* Return a fully-qualified domain name from a compressed name (with
+   length supplied).  */
+
+const u_char *
+p_fqnname(cp, msg, msglen, name, namelen)
+	const u_char *cp, *msg;
+	int msglen;
+	char *name;
+	int namelen;
+{
+	int n, newlen;
+
+	if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
+		return (NULL);
+	newlen = strlen(name);
+	if (newlen == 0 || name[newlen - 1] != '.') {
+		if (newlen + 1 >= namelen)	/* Lack space for final dot */
+			return (NULL);
+		else
+			strcpy(name + newlen, ".");
+	}
+	return (cp + n);
+}
+
+/* XXX:	the rest of these functions need to become length-limited, too. */
+
+const u_char *
+p_fqname(const u_char *cp, const u_char *msg, FILE *file) {
+	char name[MAXDNAME];
+	const u_char *n;
+
+	n = p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
+	if (n == NULL)
+		return (NULL);
+	fputs(name, file);
+	return (n);
+}
+#endif
+
+/*
+ * Names of RR classes and qclasses.  Classes and qclasses are the same, except
+ * that C_ANY is a qclass but not a class.  (You can ask for records of class
+ * C_ANY, but you can't have any records of that class in the database.)
+ */
+const struct res_sym __p_class_syms[] = {
+	{C_IN,		"IN",		(char *)0},
+	{C_CHAOS,	"CH",		(char *)0},
+	{C_CHAOS,	"CHAOS",	(char *)0},
+	{C_HS,		"HS",		(char *)0},
+	{C_HS,		"HESIOD",	(char *)0},
+	{C_ANY,		"ANY",		(char *)0},
+	{C_NONE,	"NONE",		(char *)0},
+	{C_IN, 		(char *)0,	(char *)0}
+};
+
+/*
+ * Names of message sections.
+ */
+const struct res_sym __p_default_section_syms[] = {
+	{ns_s_qd,	"QUERY",	(char *)0},
+	{ns_s_an,	"ANSWER",	(char *)0},
+	{ns_s_ns,	"AUTHORITY",	(char *)0},
+	{ns_s_ar,	"ADDITIONAL",	(char *)0},
+	{0,             (char *)0,	(char *)0}
+};
+
+const struct res_sym __p_update_section_syms[] = {
+	{S_ZONE,	"ZONE",		(char *)0},
+	{S_PREREQ,	"PREREQUISITE",	(char *)0},
+	{S_UPDATE,	"UPDATE",	(char *)0},
+	{S_ADDT,	"ADDITIONAL",	(char *)0},
+	{0,             (char *)0,	(char *)0}
+};
+
+const struct res_sym __p_key_syms[] = {
+	{NS_ALG_MD5RSA,		"RSA",		"RSA KEY with MD5 hash"},
+	{NS_ALG_DH,		"DH",		"Diffie Hellman"},
+	{NS_ALG_DSA,		"DSA",		"Digital Signature Algorithm"},
+	{NS_ALG_EXPIRE_ONLY,	"EXPIREONLY",	"No algorithm"},
+	{NS_ALG_PRIVATE_OID,	"PRIVATE",	"Algorithm obtained from OID"},
+	{0,			NULL,		NULL}
+};
+
+const struct res_sym __p_cert_syms[] = {
+	{cert_t_pkix,	"PKIX",		"PKIX (X.509v3) Certificate"},
+	{cert_t_spki,	"SPKI",		"SPKI certificate"},
+	{cert_t_pgp,	"PGP",		"PGP certificate"},
+	{cert_t_url,	"URL",		"URL Private"},
+	{cert_t_oid,	"OID",		"OID Private"},
+	{0,		NULL,		NULL}
+};
+
+/*
+ * Names of RR types and qtypes.  Types and qtypes are the same, except
+ * that T_ANY is a qtype but not a type.  (You can ask for records of type
+ * T_ANY, but you can't have any records of that type in the database.)
+ */
+const struct res_sym __p_type_syms[] = {
+	{ns_t_a,	"A",		"address"},
+	{ns_t_ns,	"NS",		"name server"},
+	{ns_t_md,	"MD",		"mail destination (deprecated)"},
+	{ns_t_mf,	"MF",		"mail forwarder (deprecated)"},
+	{ns_t_cname,	"CNAME",	"canonical name"},
+	{ns_t_soa,	"SOA",		"start of authority"},
+	{ns_t_mb,	"MB",		"mailbox"},
+	{ns_t_mg,	"MG",		"mail group member"},
+	{ns_t_mr,	"MR",		"mail rename"},
+	{ns_t_null,	"NULL",		"null"},
+	{ns_t_wks,	"WKS",		"well-known service (deprecated)"},
+	{ns_t_ptr,	"PTR",		"domain name pointer"},
+	{ns_t_hinfo,	"HINFO",	"host information"},
+	{ns_t_minfo,	"MINFO",	"mailbox information"},
+	{ns_t_mx,	"MX",		"mail exchanger"},
+	{ns_t_txt,	"TXT",		"text"},
+	{ns_t_rp,	"RP",		"responsible person"},
+	{ns_t_afsdb,	"AFSDB",	"DCE or AFS server"},
+	{ns_t_x25,	"X25",		"X25 address"},
+	{ns_t_isdn,	"ISDN",		"ISDN address"},
+	{ns_t_rt,	"RT",		"router"},
+	{ns_t_nsap,	"NSAP",		"nsap address"},
+	{ns_t_nsap_ptr,	"NSAP_PTR",	"domain name pointer"},
+	{ns_t_sig,	"SIG",		"signature"},
+	{ns_t_key,	"KEY",		"key"},
+	{ns_t_px,	"PX",		"mapping information"},
+	{ns_t_gpos,	"GPOS",		"geographical position (withdrawn)"},
+	{ns_t_aaaa,	"AAAA",		"IPv6 address"},
+	{ns_t_loc,	"LOC",		"location"},
+	{ns_t_nxt,	"NXT",		"next valid name (unimplemented)"},
+	{ns_t_eid,	"EID",		"endpoint identifier (unimplemented)"},
+	{ns_t_nimloc,	"NIMLOC",	"NIMROD locator (unimplemented)"},
+	{ns_t_srv,	"SRV",		"server selection"},
+	{ns_t_atma,	"ATMA",		"ATM address (unimplemented)"},
+	{ns_t_tkey,	"TKEY",		"tkey"},
+	{ns_t_tsig,	"TSIG",		"transaction signature"},
+	{ns_t_ixfr,	"IXFR",		"incremental zone transfer"},
+	{ns_t_axfr,	"AXFR",		"zone transfer"},
+	{ns_t_zxfr,	"ZXFR",		"compressed zone transfer"},
+	{ns_t_mailb,	"MAILB",	"mailbox-related data (deprecated)"},
+	{ns_t_maila,	"MAILA",	"mail agent (deprecated)"},
+	{ns_t_naptr,	"NAPTR",	"URN Naming Authority"},
+	{ns_t_kx,	"KX",		"Key Exchange"},
+	{ns_t_cert,	"CERT",		"Certificate"},
+	{ns_t_a6,	"A6",		"IPv6 Address"},
+	{ns_t_dname,	"DNAME",	"dname"},
+	{ns_t_sink,	"SINK",		"Kitchen Sink (experimental)"},
+	{ns_t_opt,	"OPT",		"EDNS Options"},
+	{ns_t_any,	"ANY",		"\"any\""},
+	{0, 		NULL,		NULL}
+};
+
+/*
+ * Names of DNS rcodes.
+ */
+const struct res_sym __p_rcode_syms[] = {
+	{ns_r_noerror,	"NOERROR",		"no error"},
+	{ns_r_formerr,	"FORMERR",		"format error"},
+	{ns_r_servfail,	"SERVFAIL",		"server failed"},
+	{ns_r_nxdomain,	"NXDOMAIN",		"no such domain name"},
+	{ns_r_notimpl,	"NOTIMP",		"not implemented"},
+	{ns_r_refused,	"REFUSED",		"refused"},
+	{ns_r_yxdomain,	"YXDOMAIN",		"domain name exists"},
+	{ns_r_yxrrset,	"YXRRSET",		"rrset exists"},
+	{ns_r_nxrrset,	"NXRRSET",		"rrset doesn't exist"},
+	{ns_r_notauth,	"NOTAUTH",		"not authoritative"},
+	{ns_r_notzone,	"NOTZONE",		"Not in zone"},
+	{ns_r_max,	"",			""},
+	{ns_r_badsig,	"BADSIG",		"bad signature"},
+	{ns_r_badkey,	"BADKEY",		"bad key"},
+	{ns_r_badtime,	"BADTIME",		"bad time"},
+	{0, 		NULL,			NULL}
+};
+
+int
+sym_ston(const struct res_sym *syms, const char *name, int *success) {
+	for (; syms->name != 0; syms++) {
+		if (strcasecmp (name, syms->name) == 0) {
+			if (success)
+				*success = 1;
+			return (syms->number);
+		}
+	}
+	if (success)
+		*success = 0;
+	return (syms->number);		/* The default value. */
+}
+
+const char *
+sym_ntos(const struct res_sym *syms, int number, int *success) {
+	static char unname[20];
+
+	for (; syms->name != 0; syms++) {
+		if (number == syms->number) {
+			if (success)
+				*success = 1;
+			return (syms->name);
+		}
+	}
+
+	sprintf(unname, "%d", number);		/* XXX nonreentrant */
+	if (success)
+		*success = 0;
+	return (unname);
+}
+
+const char *
+sym_ntop(const struct res_sym *syms, int number, int *success) {
+	static char unname[20];
+
+	for (; syms->name != 0; syms++) {
+		if (number == syms->number) {
+			if (success)
+				*success = 1;
+			return (syms->humanname);
+		}
+	}
+	sprintf(unname, "%d", number);		/* XXX nonreentrant */
+	if (success)
+		*success = 0;
+	return (unname);
+}
+
+/*
+ * Return a string for the type.
+ */
+const char *
+p_type(int type) {
+	int success;
+	const char *result;
+	static char typebuf[20];
+
+	result = sym_ntos(__p_type_syms, type, &success);
+	if (success)
+		return (result);
+	if (type < 0 || type > 0xffff)
+		return ("BADTYPE");
+	sprintf(typebuf, "TYPE%d", type);
+	return (typebuf);
+}
+
+/*
+ * Return a string for the type.
+ */
+const char *
+p_section(int section, int opcode) {
+	const struct res_sym *symbols;
+
+	switch (opcode) {
+	case ns_o_update:
+		symbols = __p_update_section_syms;
+		break;
+	default:
+		symbols = __p_default_section_syms;
+		break;
+	}
+	return (sym_ntos(symbols, section, (int *)0));
+}
+
+/*
+ * Return a mnemonic for class.
+ */
+const char *
+p_class(int class) {
+	int success;
+	const char *result;
+	static char classbuf[20];
+
+	result = sym_ntos(__p_class_syms, class, &success);
+	if (success)
+		return (result);
+	if (class < 0 || class > 0xffff)
+		return ("BADCLASS");
+	sprintf(classbuf, "CLASS%d", class);
+	return (classbuf);
+}
+
+/*
+ * Return a mnemonic for an option
+ */
+const char *
+p_option(u_long option) {
+	static char nbuf[40];
+
+	switch (option) {
+	case RES_INIT:		return "init";
+	case RES_DEBUG:		return "debug";
+	case RES_AAONLY:	return "aaonly(unimpl)";
+	case RES_USEVC:		return "usevc";
+	case RES_PRIMARY:	return "primry(unimpl)";
+	case RES_IGNTC:		return "igntc";
+	case RES_RECURSE:	return "recurs";
+	case RES_DEFNAMES:	return "defnam";
+	case RES_STAYOPEN:	return "styopn";
+	case RES_DNSRCH:	return "dnsrch";
+	case RES_INSECURE1:	return "insecure1";
+	case RES_INSECURE2:	return "insecure2";
+	case RES_NOALIASES:	return "noaliases";
+	case RES_USE_INET6:	return "inet6";
+#ifdef RES_USE_EDNS0	/* KAME extension */
+	case RES_USE_EDNS0:	return "edns0";
+#endif
+#ifdef RES_USE_DNAME
+	case RES_USE_DNAME:	return "dname";
+#endif
+#ifdef RES_USE_DNSSEC
+	case RES_USE_DNSSEC:	return "dnssec";
+#endif
+#ifdef RES_NOTLDQUERY
+	case RES_NOTLDQUERY:	return "no-tld-query";
+#endif
+#ifdef RES_NO_NIBBLE2
+	case RES_NO_NIBBLE2:	return "no-nibble2";
+#endif
+				/* XXX nonreentrant */
+	default:		sprintf(nbuf, "?0x%lx?", (u_long)option);
+				return (nbuf);
+	}
+}
+
+#ifndef MOZILLA_NECKO_EXCLUDE_CODE
+/*
+ * Return a mnemonic for a time to live.
+ */
+const char *
+p_time(u_int32_t value) {
+	static char nbuf[40];		/* XXX nonreentrant */
+
+	if (ns_format_ttl((u_long)value, nbuf, sizeof nbuf) < 0)
+		sprintf(nbuf, "%u", value);
+	return (nbuf);
+}
+#endif
+
+/*
+ * Return a string for the rcode.
+ */
+const char *
+p_rcode(int rcode) {
+	return (sym_ntos(__p_rcode_syms, rcode, (int *)0));
+}
+
+#ifndef MOZILLA_NECKO_EXCLUDE_CODE
+/*
+ * Return a string for a res_sockaddr_union.
+ */
+const char *
+p_sockun(union res_sockaddr_union u, char *buf, size_t size) {
+	char ret[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:123.123.123.123"];
+
+	switch (u.sin.sin_family) {
+	case AF_INET:
+		inet_ntop(AF_INET, &u.sin.sin_addr, ret, sizeof ret);
+		break;
+#ifdef HAS_INET6_STRUCTS
+	case AF_INET6:
+		inet_ntop(AF_INET6, &u.sin6.sin6_addr, ret, sizeof ret);
+		break;
+#endif
+	default:
+		sprintf(ret, "[af%d]", u.sin.sin_family);
+		break;
+	}
+	if (size > 0U) {
+		strncpy(buf, ret, size - 1);
+		buf[size - 1] = '0';
+	}
+	return (buf);
+}
+#endif
+
+/*
+ * routines to convert between on-the-wire RR format and zone file format.
+ * Does not contain conversion to/from decimal degrees; divide or multiply
+ * by 60*60*1000 for that.
+ */
+
+static const unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
+				      1000000,10000000,100000000,1000000000};
+
+/* takes an XeY precision/size value, returns a string representation. */
+static const char *
+precsize_ntoa(prec)
+	u_int32_t prec;
+{
+	static char retbuf[sizeof "90000000.00"];	/* XXX nonreentrant */
+	unsigned long val;
+	int mantissa, exponent;
+
+	mantissa = (int)((prec >> 4) & 0x0f) % 10;
+	exponent = (int)((prec >> 0) & 0x0f) % 10;
+
+	val = mantissa * poweroften[exponent];
+
+	(void) sprintf(retbuf, "%lu.%.2lu", val/100, val%100);
+	return (retbuf);
+}
+
+#ifndef MOZILLA_NECKO_EXCLUDE_CODE
+/* converts ascii size/precision X * 10**Y(cm) to 0xXY.  moves pointer. */
+static u_int8_t
+precsize_aton(const char **strptr) {
+	unsigned int mval = 0, cmval = 0;
+	u_int8_t retval = 0;
+	const char *cp;
+	int exponent;
+	int mantissa;
+
+	cp = *strptr;
+
+	while (isdigit((unsigned char)*cp))
+		mval = mval * 10 + (*cp++ - '0');
+
+	if (*cp == '.') {		/* centimeters */
+		cp++;
+		if (isdigit((unsigned char)*cp)) {
+			cmval = (*cp++ - '0') * 10;
+			if (isdigit((unsigned char)*cp)) {
+				cmval += (*cp++ - '0');
+			}
+		}
+	}
+	cmval = (mval * 100) + cmval;
+
+	for (exponent = 0; exponent < 9; exponent++)
+		if (cmval < poweroften[exponent+1])
+			break;
+
+	mantissa = cmval / poweroften[exponent];
+	if (mantissa > 9)
+		mantissa = 9;
+
+	retval = (mantissa << 4) | exponent;
+
+	*strptr = cp;
+
+	return (retval);
+}
+
+/* converts ascii lat/lon to unsigned encoded 32-bit number.  moves pointer. */
+static u_int32_t
+latlon2ul(const char **latlonstrptr, int *which) {
+	const char *cp;
+	u_int32_t retval;
+	int deg = 0, min = 0, secs = 0, secsfrac = 0;
+
+	cp = *latlonstrptr;
+
+	while (isdigit((unsigned char)*cp))
+		deg = deg * 10 + (*cp++ - '0');
+
+	while (isspace((unsigned char)*cp))
+		cp++;
+
+	if (!(isdigit((unsigned char)*cp)))
+		goto fndhemi;
+
+	while (isdigit((unsigned char)*cp))
+		min = min * 10 + (*cp++ - '0');
+
+	while (isspace((unsigned char)*cp))
+		cp++;
+
+	if (!(isdigit((unsigned char)*cp)))
+		goto fndhemi;
+
+	while (isdigit((unsigned char)*cp))
+		secs = secs * 10 + (*cp++ - '0');
+
+	if (*cp == '.') {		/* decimal seconds */
+		cp++;
+		if (isdigit((unsigned char)*cp)) {
+			secsfrac = (*cp++ - '0') * 100;
+			if (isdigit((unsigned char)*cp)) {
+				secsfrac += (*cp++ - '0') * 10;
+				if (isdigit((unsigned char)*cp)) {
+					secsfrac += (*cp++ - '0');
+				}
+			}
+		}
+	}
+
+	while (!isspace((unsigned char)*cp))	/* if any trailing garbage */
+		cp++;
+
+	while (isspace((unsigned char)*cp))
+		cp++;
+
+ fndhemi:
+	switch (*cp) {
+	case 'N': case 'n':
+	case 'E': case 'e':
+		retval = ((unsigned)1<<31)
+			+ (((((deg * 60) + min) * 60) + secs) * 1000)
+			+ secsfrac;
+		break;
+	case 'S': case 's':
+	case 'W': case 'w':
+		retval = ((unsigned)1<<31)
+			- (((((deg * 60) + min) * 60) + secs) * 1000)
+			- secsfrac;
+		break;
+	default:
+		retval = 0;	/* invalid value -- indicates error */
+		break;
+	}
+
+	switch (*cp) {
+	case 'N': case 'n':
+	case 'S': case 's':
+		*which = 1;	/* latitude */
+		break;
+	case 'E': case 'e':
+	case 'W': case 'w':
+		*which = 2;	/* longitude */
+		break;
+	default:
+		*which = 0;	/* error */
+		break;
+	}
+
+	cp++;			/* skip the hemisphere */
+
+	while (!isspace((unsigned char)*cp))	/* if any trailing garbage */
+		cp++;
+
+	while (isspace((unsigned char)*cp))	/* move to next field */
+		cp++;
+
+	*latlonstrptr = cp;
+
+	return (retval);
+}
+
+/* converts a zone file representation in a string to an RDATA on-the-wire
+ * representation. */
+int
+loc_aton(ascii, binary)
+	const char *ascii;
+	u_char *binary;
+{
+	const char *cp, *maxcp;
+	u_char *bcp;
+
+	u_int32_t latit = 0, longit = 0, alt = 0;
+	u_int32_t lltemp1 = 0, lltemp2 = 0;
+	int altmeters = 0, altfrac = 0, altsign = 1;
+	u_int8_t hp = 0x16;	/* default = 1e6 cm = 10000.00m = 10km */
+	u_int8_t vp = 0x13;	/* default = 1e3 cm = 10.00m */
+	u_int8_t siz = 0x12;	/* default = 1e2 cm = 1.00m */
+	int which1 = 0, which2 = 0;
+
+	cp = ascii;
+	maxcp = cp + strlen(ascii);
+
+	lltemp1 = latlon2ul(&cp, &which1);
+
+	lltemp2 = latlon2ul(&cp, &which2);
+
+	switch (which1 + which2) {
+	case 3:			/* 1 + 2, the only valid combination */
+		if ((which1 == 1) && (which2 == 2)) { /* normal case */
+			latit = lltemp1;
+			longit = lltemp2;
+		} else if ((which1 == 2) && (which2 == 1)) { /* reversed */
+			longit = lltemp1;
+			latit = lltemp2;
+		} else {	/* some kind of brokenness */
+			return (0);
+		}
+		break;
+	default:		/* we didn't get one of each */
+		return (0);
+	}
+
+	/* altitude */
+	if (*cp == '-') {
+		altsign = -1;
+		cp++;
+	}
+
+	if (*cp == '+')
+		cp++;
+
+	while (isdigit((unsigned char)*cp))
+		altmeters = altmeters * 10 + (*cp++ - '0');
+
+	if (*cp == '.') {		/* decimal meters */
+		cp++;
+		if (isdigit((unsigned char)*cp)) {
+			altfrac = (*cp++ - '0') * 10;
+			if (isdigit((unsigned char)*cp)) {
+				altfrac += (*cp++ - '0');
+			}
+		}
+	}
+
+	alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
+
+	while (!isspace((unsigned char)*cp) && (cp < maxcp)) /* if trailing garbage or m */
+		cp++;
+
+	while (isspace((unsigned char)*cp) && (cp < maxcp))
+		cp++;
+
+	if (cp >= maxcp)
+		goto defaults;
+
+	siz = precsize_aton(&cp);
+
+	while (!isspace((unsigned char)*cp) && (cp < maxcp))	/* if trailing garbage or m */
+		cp++;
+
+	while (isspace((unsigned char)*cp) && (cp < maxcp))
+		cp++;
+
+	if (cp >= maxcp)
+		goto defaults;
+
+	hp = precsize_aton(&cp);
+
+	while (!isspace((unsigned char)*cp) && (cp < maxcp))	/* if trailing garbage or m */
+		cp++;
+
+	while (isspace((unsigned char)*cp) && (cp < maxcp))
+		cp++;
+
+	if (cp >= maxcp)
+		goto defaults;
+
+	vp = precsize_aton(&cp);
+
+ defaults:
+
+	bcp = binary;
+	*bcp++ = (u_int8_t) 0;	/* version byte */
+	*bcp++ = siz;
+	*bcp++ = hp;
+	*bcp++ = vp;
+	PUTLONG(latit,bcp);
+	PUTLONG(longit,bcp);
+	PUTLONG(alt,bcp);
+
+	return (16);		/* size of RR in octets */
+}
+#endif
+
+/* takes an on-the-wire LOC RR and formats it in a human readable format. */
+const char *
+loc_ntoa(binary, ascii)
+	const u_char *binary;
+	char *ascii;
+{
+	static const char *error = "?";
+	static char tmpbuf[sizeof
+"1000 60 60.000 N 1000 60 60.000 W -12345678.00m 90000000.00m 90000000.00m 90000000.00m"];
+	const u_char *cp = binary;
+
+	int latdeg, latmin, latsec, latsecfrac;
+	int longdeg, longmin, longsec, longsecfrac;
+	char northsouth, eastwest;
+	const char *altsign;
+	int altmeters, altfrac;
+
+	const u_int32_t referencealt = 100000 * 100;
+
+	int32_t latval, longval, altval;
+	u_int32_t templ;
+	u_int8_t sizeval, hpval, vpval, versionval;
+
+	char *sizestr, *hpstr, *vpstr;
+
+	versionval = *cp++;
+
+	if (ascii == NULL)
+		ascii = tmpbuf;
+
+	if (versionval) {
+		(void) sprintf(ascii, "; error: unknown LOC RR version");
+		return (ascii);
+	}
+
+	sizeval = *cp++;
+
+	hpval = *cp++;
+	vpval = *cp++;
+
+	GETLONG(templ, cp);
+	latval = (templ - ((unsigned)1<<31));
+
+	GETLONG(templ, cp);
+	longval = (templ - ((unsigned)1<<31));
+
+	GETLONG(templ, cp);
+	if (templ < referencealt) { /* below WGS 84 spheroid */
+		altval = referencealt - templ;
+		altsign = "-";
+	} else {
+		altval = templ - referencealt;
+		altsign = "";
+	}
+
+	if (latval < 0) {
+		northsouth = 'S';
+		latval = -latval;
+	} else
+		northsouth = 'N';
+
+	latsecfrac = latval % 1000;
+	latval = latval / 1000;
+	latsec = latval % 60;
+	latval = latval / 60;
+	latmin = latval % 60;
+	latval = latval / 60;
+	latdeg = latval;
+
+	if (longval < 0) {
+		eastwest = 'W';
+		longval = -longval;
+	} else
+		eastwest = 'E';
+
+	longsecfrac = longval % 1000;
+	longval = longval / 1000;
+	longsec = longval % 60;
+	longval = longval / 60;
+	longmin = longval % 60;
+	longval = longval / 60;
+	longdeg = longval;
+
+	altfrac = altval % 100;
+	altmeters = (altval / 100);
+
+	sizestr = strdup(precsize_ntoa((u_int32_t)sizeval));
+	hpstr = strdup(precsize_ntoa((u_int32_t)hpval));
+	vpstr = strdup(precsize_ntoa((u_int32_t)vpval));
+
+	sprintf(ascii,
+	    "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %s%d.%.2dm %sm %sm %sm",
+		latdeg, latmin, latsec, latsecfrac, northsouth,
+		longdeg, longmin, longsec, longsecfrac, eastwest,
+		altsign, altmeters, altfrac,
+		(sizestr != NULL) ? sizestr : error,
+		(hpstr != NULL) ? hpstr : error,
+		(vpstr != NULL) ? vpstr : error);
+
+	if (sizestr != NULL)
+		free(sizestr);
+	if (hpstr != NULL)
+		free(hpstr);
+	if (vpstr != NULL)
+		free(vpstr);
+
+	return (ascii);
+}
+
+
+/* Return the number of DNS hierarchy levels in the name. */
+int
+dn_count_labels(const char *name) {
+	int i, len, count;
+
+	len = strlen(name);
+	for (i = 0, count = 0; i < len; i++) {
+		/* XXX need to check for \. or use named's nlabels(). */
+		if (name[i] == '.')
+			count++;
+	}
+
+	/* don't count initial wildcard */
+	if (name[0] == '*')
+		if (count)
+			count--;
+
+	/* don't count the null label for root. */
+	/* if terminating '.' not found, must adjust */
+	/* count to include last label */
+	if (len > 0 && name[len-1] != '.')
+		count++;
+	return (count);
+}
+
+
+/*
+ * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
+ * SIG records are required to be printed like this, by the Secure DNS RFC.
+ */
+char *
+p_secstodate (u_long secs) {
+	/* XXX nonreentrant */
+	static char output[15];		/* YYYYMMDDHHMMSS and null */
+	time_t myclock = secs;
+	struct tm *mytime;
+#ifdef HAVE_TIME_R
+	struct tm res;
+
+	mytime = gmtime_r(&myclock, &res);
+#else
+	mytime = gmtime(&myclock);
+#endif
+	mytime->tm_year += 1900;
+	mytime->tm_mon += 1;
+	sprintf(output, "%04d%02d%02d%02d%02d%02d",
+		mytime->tm_year, mytime->tm_mon, mytime->tm_mday,
+		mytime->tm_hour, mytime->tm_min, mytime->tm_sec);
+	return (output);
+}
+
+#ifndef MOZILLA_NECKO_EXCLUDE_CODE
+u_int16_t
+res_nametoclass(const char *buf, int *successp) {
+	unsigned long result;
+	char *endptr;
+	int success;
+
+	result = sym_ston(__p_class_syms, buf, &success);
+	if (success)
+		goto done;
+
+	if (strncasecmp(buf, "CLASS", 5) != 0 ||
+	    !isdigit((unsigned char)buf[5]))
+		goto done;
+	errno = 0;
+	result = strtoul(buf + 5, &endptr, 10);
+	if (errno == 0 && *endptr == '\0' && result <= 0xffffU)
+		success = 1;
+ done:
+	if (successp)
+		*successp = success;
+	return (u_int16_t)(result);
+}
+
+u_int16_t
+res_nametotype(const char *buf, int *successp) {
+	unsigned long result;
+	char *endptr;
+	int success;
+
+	result = sym_ston(__p_type_syms, buf, &success);
+	if (success)
+		goto done;
+
+	if (strncasecmp(buf, "type", 4) != 0 ||
+	    !isdigit((unsigned char)buf[4]))
+		goto done;
+	errno = 0;
+	result = strtoul(buf + 4, &endptr, 10);
+	if (errno == 0 && *endptr == '\0' && result <= 0xffffU)
+		success = 1;
+ done:
+	if (successp)
+		*successp = success;
+	return (u_int16_t)(result);
+}
+#endif
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/res_debug.h
@@ -0,0 +1,46 @@
+/*	$NetBSD: res_debug.h,v 1.1.1.1 2004/05/20 17:18:55 christos Exp $	*/
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#ifndef _RES_DEBUG_H_
+#define _RES_DEBUG_H_
+
+#ifndef DEBUG
+#   define Dprint(cond, args) /*empty*/
+#   define DprintQ(cond, args, query, size) /*empty*/
+#   define Aerror(statp, file, string, error, address) /*empty*/
+#   define Perror(statp, file, string, error) /*empty*/
+#else
+#   define Dprint(cond, args) if (cond) {fprintf args;} else {}
+#   define DprintQ(cond, args, query, size) if (cond) {\
+			fprintf args;\
+			res_pquery(statp, query, size, stdout);\
+		} else {}
+#endif
+
+#endif /* _RES_DEBUG_H_ */ 
new file mode 100644
--- /dev/null
+++ b/other-licenses/android/res_init.c
@@ -0,0 +1,915 @@
+/*	$NetBSD: res_init.c,v 1.8 2006/03/19 03:10:08 christos Exp $	*/
+
+/*
+ * Copyright (c) 1985, 1989, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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 DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This version of this file is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers.  It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
+ * and Steve Workman <sjhworkman@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+
+#define ANDROID_CHANGES 1
+#define MOZILLE_NECKO_EXCLUDE_CODE 1
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#ifdef notdef
+static const char sccsid[] = "@(#)res_init.c	8.1 (Berkeley) 6/7/93";
+static const char rcsid[] = "Id: res_init.c,v 1.9.2.5.4.2 2004/03/16 12:34:18 marka Exp";
+#else
+__RCSID("$NetBSD: res_init.c,v 1.8 2006/03/19 03:10:08 christos Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include "arpa_nameser.h"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+
+#ifdef ANDROID_CHANGES
+#include <sys/system_properties.h>
+#endif /* ANDROID_CHANGES */
+
+#ifndef MIN
+#define	MIN(x,y)	((x)<(y)?(x):(y))
+#endif
+
+/* ensure that sockaddr_in6 and IN6ADDR_ANY_INIT are declared / defined */
+#ifdef ANDROID_CHANGES
+#include "resolv_private.h"
+#define MAX_DNS_PROPERTIES 8
+#define DNS_PROP_NAME_PREFIX "net.dns"
+#define DNS_CHANGE_PROP_NAME "net.dnschange"
+#define DNS_SEARCH_PROP_NAME "net.dns.search"
+const prop_info *dns_change_prop;
+int dns_last_change_counter;
+static int _get_dns_change_count();
+#else
+#include <resolv.h>
+#endif
+
+#include "res_private.h"
+
+/* Options.  Should all be left alone. */
+#ifndef DEBUG
+#define DEBUG
+#endif
+
+static void res_setoptions __P((res_state, const char *, const char *));
+
+static const char sort_mask[] = "/&";
+#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
+static u_int32_t net_mask __P((struct in_addr));
+
+#if !defined(isascii)	/* XXX - could be a function */
+# define isascii(c) (!(c & 0200))
+#endif
+
+/*
+ * Resolver state default settings.
+ */
+
+/*
+ * Set up default settings.  If the configuration file exist, the values
+ * there will have precedence.  Otherwise, the server address is set to
+ * INADDR_ANY and the default domain name comes from the gethostname().
+ *
+ * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
+ * rather than INADDR_ANY ("0.0.0.0") as the default name server address
+ * since it was noted that INADDR_ANY actually meant ``the first interface
+ * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
+ * it had to be "up" in order for you to reach your own name server.  It
+ * was later decided that since the recommended practice is to always
+ * install local static routes through 127.0.0.1 for all your network
+ * interfaces, that we could solve this problem without a code change.
+ *
+ * The configuration file should always be used, since it is the only way
+ * to specify a default domain.  If you are running a server on your local
+ * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
+ * in the configuration file.
+ *
+ * Return 0 if completes successfully, -1 on error
+ */
+int
+res_ninit(res_state statp) {
+	extern int __res_vinit(res_state, int);
+
+	return (__res_vinit(statp, 0));
+}
+
+#ifdef ANDROID_CHANGES
+int load_domain_search_list(res_state statp) {
+	char propvalue[PROP_VALUE_MAX];
+	register char *cp, **pp;
+
+	if(__system_property_get(DNS_SEARCH_PROP_NAME, propvalue) >= 1) {
+		strlcpy(statp->defdname, propvalue, sizeof(statp->defdname));
+		if ((cp = strchr(statp->defdname, '\n')) != NULL)
+			*cp = '\0';
+		cp = statp->defdname;
+		pp = statp->dnsrch;
+		while ( pp < statp->dnsrch + MAXDNSRCH ) {
+			while (*cp == ' ' || *cp == '\t') /* skip leading white space */
+				cp++;
+			if (*cp == '\0')  /* stop if nothing more */
+				break;
+			*pp++ = cp;  /* record this search domain */
+			while (*cp) { /* zero-terminate it */
+				if (*cp == ' ' || *cp == '\t') {
+					*cp++ = '\0';
+					break;
+				}
+				cp++;
+			}
+		}
+		*pp = NULL; /* statp->dnsrch has MAXDNSRCH+1 items */
+		if (pp > statp->dnsrch)
+			return 1;
+	}
+	statp->defdname[0] = '\0';  /* no default domain name on Android */
+	statp->dnsrch[0] = NULL;
+	return 0;
+}
+#endif
+
+/* This function has to be reachable by res_data.c but not publicly. */
+int
+__res_vinit(res_state statp, int preinit) {
+	register FILE *fp;
+	register char *cp, **pp;
+	register int n;
+	char buf[BUFSIZ];
+	int nserv = 0;    /* number of nameserver records read from file */
+	int haveenv = 0;
+	int havesearch = 0;
+	int nsort = 0;
+	char *net;
+	int dots;
+	union res_sockaddr_union u[2];
+#ifdef ANDROID_CHANGES
+        pid_t mypid = getpid();
+        int use_proc_props = 0;
+        int found_prop;
+	char dnsProperty[PROP_VALUE_MAX];
+#endif
+
+	if (!preinit) {
+		statp->retrans = RES_TIMEOUT;
+		statp->retry = RES_DFLRETRY;
+		statp->options = RES_DEFAULT;
+		statp->id = res_randomid();
+	}
+
+  if ((statp->options & RES_INIT) != 0U)
+       res_ndestroy(statp);
+
+	memset(u, 0, sizeof(u));
+#ifdef USELOOPBACK
+	u[nserv].sin.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
+#else
+	u[nserv].sin.sin_addr.s_addr = INADDR_ANY;
+#endif
+	u[nserv].sin.sin_family = AF_INET;
+	u[nserv].sin.sin_port = htons(NAMESERVER_PORT);
+#ifdef HAVE_SA_LEN
+	u[nserv].sin.sin_len = sizeof(struct sockaddr_in);
+#endif
+	nserv++;
+#ifdef HAS_INET6_STRUCTS
+#ifdef USELOOPBACK
+	u[nserv].sin6.sin6_addr = in6addr_loopback;
+#else
+	u[nserv].sin6.sin6_addr = in6addr_any;
+#endif
+	u[nserv].sin6.sin6_family = AF_INET6;
+	u[nserv].sin6.sin6_port = htons(NAMESERVER_PORT);
+#ifdef HAVE_SA_LEN
+	u[nserv].sin6.sin6_len = sizeof(struct sockaddr_in6);
+#endif
+	nserv++;
+#endif
+	statp->nscount = 0;
+	statp->ndots = 1;
+	statp->pfcode = 0;
+	statp->_vcsock = -1;
+	statp->_flags = 0;
+	statp->qhook = NULL;
+	statp->rhook = NULL;
+	statp->_u._ext.nscount = 0;
+	statp->_u._ext.ext = malloc(sizeof(*statp->_u._ext.ext));
+	if (statp->_u._ext.ext != NULL) {
+	        memset(statp->_u._ext.ext, 0, sizeof(*statp->_u._ext.ext));
+		statp->_u._ext.ext->nsaddrs[0].sin = statp->nsaddr;
+		strcpy(statp->_u._ext.ext->nsuffix, "ip6.arpa");
+		strcpy(statp->_u._ext.ext->nsuffix2, "ip6.int");
+	}
+	statp->nsort = 0;
+	res_setservers(statp, u, nserv);
+
+#if 0 /* IGNORE THE ENVIRONMENT */
+	/* Allow user to override the local domain definition */
+	if ((cp = getenv("LOCALDOMAIN")) != NULL) {
+		(void)strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
+		statp->defdname[sizeof(statp->defdname) - 1] = '\0';
+		haveenv++;
+
+		/*
+		 * Set search list to be blank-separated strings
+		 * from rest of env value.  Permits users of LOCALDOMAIN
+		 * to still have a search list, and anyone to set the
+		 * one that they want to use as an individual (even more
+		 * important now that the rfc1535 stuff restricts searches)
+		 */
+		cp = statp->defdname;
+		pp = statp->dnsrch;
+		*pp++ = cp;
+		for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) {
+			if (*cp == '\n')	/* silly backwards compat */
+				break;
+			else if (*cp == ' ' || *cp == '\t') {
+				*cp = 0;
+				n = 1;
+			} else if (n) {
+				*pp++ = cp;
+				n = 0;
+				havesearch = 1;
+			}
+		}
+		/* null terminate last domain if there are excess */
+		while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n')
+			cp++;
+		*cp = '\0';
+		*pp++ = 0;
+	}
+	if (nserv > 0)
+		statp->nscount = nserv;
+#endif
+#ifdef ANDROID_CHANGES /* READ FROM SYSTEM PROPERTIES */
+	dns_last_change_counter = _get_dns_change_count();
+
+	nserv = 0;
+	for(n = 1; n <= MAX_DNS_PROPERTIES && nserv < MAXNS; n++) {
+		char propname[PROP_NAME_MAX];
+		char propvalue[PROP_VALUE_MAX];
+
+		struct addrinfo hints, *ai;
+		char sbuf[NI_MAXSERV];
+		const size_t minsiz = sizeof(statp->_u._ext.ext->nsaddrs[0]);
+
+		/*
+		 * Check first for process-specific properties, and if those don't
+		 * exist, try the generic properties.
+		 */
+		found_prop = 0;
+		if (n == 1 || use_proc_props) {
+			snprintf(propname, sizeof(propname), "%s%d.%d", DNS_PROP_NAME_PREFIX, n, mypid);
+			if(__system_property_get(propname, propvalue) < 1) {
+				if (use_proc_props) {
+					break;
+				}
+			} else {
+				found_prop = 1;
+				use_proc_props = 1;
+			}
+		}
+		if (!found_prop) {
+			snprintf(propname, sizeof(propname), "%s%d", DNS_PROP_NAME_PREFIX, n);
+			if(__system_property_get(propname, propvalue) < 1) {
+				break;
+			}
+		}
+
+		cp = propvalue;
+
+		while (*cp == ' ' || *cp == '\t')
+			cp++;
+		cp[strcspn(cp, ";# \t\n")] = '\0';
+		if ((*cp != '\0') && (*cp != '\n')) {
+			memset(&hints, 0, sizeof(hints));
+			hints.ai_family = PF_UNSPEC;
+			hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
+			hints.ai_flags = AI_NUMERICHOST;
+			sprintf(sbuf, "%u", NAMESERVER_PORT);
+			if (getaddrinfo(cp, sbuf, &hints, &ai) == 0 &&
+			    (size_t)ai->ai_addrlen <= minsiz) {
+				if (statp->_u._ext.ext != NULL) {
+					memcpy(&statp->_u._ext.ext->nsaddrs[nserv],
+					       ai->ai_addr, ai->ai_addrlen);
+				}
+				if ((size_t)ai->ai_addrlen <=
+				    sizeof(statp->nsaddr_list[nserv])) {
+					memcpy(&statp->nsaddr_list[nserv],
+					       ai->ai_addr, ai->ai_addrlen);
+				} else {
+					statp->nsaddr_list[nserv].sin_family = 0;
+				}
+				freeaddrinfo(ai);
+				nserv++;
+			}
+		}
+	}
+
+	/* Add the domain search list */
+	havesearch = load_domain_search_list(statp);
+#else /* !ANDROID_CHANGES - IGNORE resolv.conf in Android */
+#define	MATCH(line, name) \
+	(!strncmp(line, name, sizeof(name) - 1) && \
+	(line[sizeof(name) - 1] == ' ' || \
+	 line[sizeof(name) - 1] == '\t'))
+
+	nserv = 0;
+	if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
+	    /* read the config file */
+	    while (fgets(buf, sizeof(buf), fp) != NULL) {
+		/* skip comments */
+		if (*buf == ';' || *buf == '#')
+			continue;
+		/* read default domain name */
+		if (MATCH(buf, "domain")) {
+		    if (haveenv)	/* skip if have from environ */
+			    continue;
+		    cp = buf + sizeof("domain") - 1;
+		    while (*cp == ' ' || *cp == '\t')
+			    cp++;
+		    if ((*cp == '\0') || (*cp == '\n'))
+			    continue;
+		    strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
+		    statp->defdname[sizeof(statp->defdname) - 1] = '\0';
+		    if ((cp = strpbrk(statp->defdname, " \t\n")) != NULL)
+			    *cp = '\0';
+		    havesearch = 0;
+		    continue;
+		}
+		/* set search list */
+		if (MATCH(buf, "search")) {
+		    if (haveenv)	/* skip if have from environ */
+			    continue;
+		    cp = buf + sizeof("search") - 1;
+		    while (*cp == ' ' || *cp == '\t')
+			    cp++;
+		    if ((*cp == '\0') || (*cp == '\n'))
+			    continue;
+		    strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
+		    statp->defdname[sizeof(statp->defdname) - 1] = '\0';
+		    if ((cp = strchr(statp->defdname, '\n')) != NULL)
+			    *cp = '\0';
+		    /*
+		     * Set search list to be blank-separated strings
+		     * on rest of line.
+		     */
+		    cp = statp->defdname;
+		    pp = statp->dnsrch;
+		    *pp++ = cp;
+		    for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) {
+			    if (*cp == ' ' || *cp == '\t') {
+				    *cp = 0;
+				    n = 1;
+			    } else if (n) {
+				    *pp++ = cp;
+				    n = 0;
+			    }
+		    }
+		    /* null terminate last domain if there are excess */
+		    while (*cp != '\0' && *cp != ' ' && *cp != '\t')
+			    cp++;
+		    *cp = '\0';
+		    *pp++ = 0;
+		    havesearch = 1;
+		    continue;
+		}
+		/* read nameservers to query */
+		if (MATCH(buf, "nameserver") && nserv < MAXNS) {
+		    struct addrinfo hints, *ai;
+		    char sbuf[NI_MAXSERV];
+		    const size_t minsiz =
+		        sizeof(statp->_u._ext.ext->nsaddrs[0]);
+
+		    cp = buf + sizeof("nameserver") - 1;
+		    while (*cp == ' ' || *cp == '\t')
+			cp++;
+		    cp[strcspn(cp, ";# \t\n")] = '\0';
+		    if ((*cp != '\0') && (*cp != '\n')) {
+			memset(&hints, 0, sizeof(hints));
+			hints.ai_family = PF_UNSPEC;
+			hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
+			hints.ai_flags = AI_NUMERICHOST;
+			sprintf(sbuf, "%u", NAMESERVER_PORT);
+			if (getaddrinfo(cp, sbuf, &hints, &ai) == 0 &&
+			    ai->ai_addrlen <= minsiz) {
+			    if (statp->_u._ext.ext != NULL) {
+				memcpy(&statp->_u._ext.ext->nsaddrs[nserv],
+				    ai->ai_addr, ai->ai_addrlen);
+			    }
+			    if (ai->ai_addrlen <=
+			        sizeof(statp->nsaddr_list[nserv])) {
+				memcpy(&statp->nsaddr_list[nserv],
+				    ai->ai_addr, ai->ai_addrlen);
+			    } else
+				statp->nsaddr_list[nserv].sin_family = 0;
+			    freeaddrinfo(ai);
+			    nserv++;
+			}
+		    }
+		    continue;
+		}
+		if (MATCH(buf, "sortlist")) {
+		    struct in_addr a;
+