Merge "Flesh out <arpa/inet.h>."
diff --git a/libc/Android.mk b/libc/Android.mk
index 6d1bcf8..cf3d48c 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -110,6 +110,7 @@
     bionic/clock.cpp \
     bionic/clone.cpp \
     bionic/cmsg_nxthdr.cpp \
+    bionic/connect.cpp \
     bionic/dirent.cpp \
     bionic/dup2.cpp \
     bionic/epoll_create.cpp \
@@ -141,6 +142,7 @@
     bionic/mkfifo.cpp \
     bionic/mknod.cpp \
     bionic/mntent.cpp \
+    bionic/NetdClientDispatch.cpp \
     bionic/open.cpp \
     bionic/pause.cpp \
     bionic/pipe.cpp \
@@ -889,6 +891,7 @@
     bionic/debug_stacktrace.cpp \
     bionic/pthread_debug.cpp \
     bionic/libc_init_dynamic.cpp \
+    bionic/NetdClient.cpp \
 
 LOCAL_MODULE := libc
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 93ed85c..e9fb575 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -234,7 +234,7 @@
 int           socket(int, int, int)              arm,arm64,mips,mips64,x86_64
 int           socketpair(int, int, int, int*)    arm,arm64,mips,mips64,x86_64
 int           bind(int, struct sockaddr*, int)  arm,arm64,mips,mips64,x86_64
-int           connect(int, struct sockaddr*, socklen_t)   arm,arm64,mips,mips64,x86_64
+int           __connect:connect(int, struct sockaddr*, socklen_t)   arm,arm64,mips,mips64,x86_64
 int           listen(int, int)                   arm,arm64,mips,mips64,x86_64
 int           accept(int, struct sockaddr*, socklen_t*)  arm,arm64,mips,mips64,x86_64
 int           accept4(int, struct sockaddr*, socklen_t*, int)  arm,arm64,mips,mips64,x86_64
@@ -253,7 +253,7 @@
 # sockets for x86. These are done as an "indexed" call to socketcall syscall.
 int           socket:socketcall:1(int, int, int) x86
 int           bind:socketcall:2(int, struct sockaddr*, int)  x86
-int           connect:socketcall:3(int, struct sockaddr*, socklen_t)   x86
+int           __connect:socketcall:3(int, struct sockaddr*, socklen_t)   x86
 int           listen:socketcall:4(int, int)                   x86
 int           accept:socketcall:5(int, struct sockaddr*, socklen_t*)  x86
 int           getsockname:socketcall:6(int, struct sockaddr*, socklen_t*)  x86
diff --git a/libc/arch-arm/syscalls/connect.S b/libc/arch-arm/syscalls/__connect.S
similarity index 88%
rename from libc/arch-arm/syscalls/connect.S
rename to libc/arch-arm/syscalls/__connect.S
index f7a5188..8cb026c 100644
--- a/libc/arch-arm/syscalls/connect.S
+++ b/libc/arch-arm/syscalls/__connect.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(connect)
+ENTRY(__connect)
     mov     ip, r7
     ldr     r7, =__NR_connect
     swi     #0
@@ -11,4 +11,4 @@
     bxls    lr
     neg     r0, r0
     b       __set_errno
-END(connect)
+END(__connect)
diff --git a/libc/arch-arm64/syscalls/connect.S b/libc/arch-arm64/syscalls/__connect.S
similarity index 88%
rename from libc/arch-arm64/syscalls/connect.S
rename to libc/arch-arm64/syscalls/__connect.S
index d3cd43d..c46f418 100644
--- a/libc/arch-arm64/syscalls/connect.S
+++ b/libc/arch-arm64/syscalls/__connect.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(connect)
+ENTRY(__connect)
     stp     x29, x30, [sp, #-16]!
     mov     x29,  sp
     str     x8,       [sp, #-16]!
@@ -18,4 +18,5 @@
     b.hi    __set_errno
 
     ret
-END(connect)
+END(__connect)
+.hidden __connect
diff --git a/libc/arch-mips/syscalls/connect.S b/libc/arch-mips/syscalls/__connect.S
similarity index 89%
rename from libc/arch-mips/syscalls/connect.S
rename to libc/arch-mips/syscalls/__connect.S
index 6f10652..f7ac916 100644
--- a/libc/arch-mips/syscalls/connect.S
+++ b/libc/arch-mips/syscalls/__connect.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(connect)
+ENTRY(__connect)
     .set noreorder
     .cpload t9
     li v0, __NR_connect
@@ -16,4 +16,4 @@
     j t9
     nop
     .set reorder
-END(connect)
+END(__connect)
diff --git a/libc/arch-mips64/syscalls/connect.S b/libc/arch-mips64/syscalls/__connect.S
similarity index 87%
rename from libc/arch-mips64/syscalls/connect.S
rename to libc/arch-mips64/syscalls/__connect.S
index 8fe2d56..b1475fb 100644
--- a/libc/arch-mips64/syscalls/connect.S
+++ b/libc/arch-mips64/syscalls/__connect.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(connect)
+ENTRY(__connect)
     .set push
     .set noreorder
     li v0, __NR_connect
@@ -22,4 +22,5 @@
     j t9
     move ra, t0
     .set pop
-END(connect)
+END(__connect)
+.hidden __connect
diff --git a/libc/arch-x86/syscalls/connect.S b/libc/arch-x86/syscalls/__connect.S
similarity index 94%
rename from libc/arch-x86/syscalls/connect.S
rename to libc/arch-x86/syscalls/__connect.S
index c0d73ca..2f53b33 100644
--- a/libc/arch-x86/syscalls/connect.S
+++ b/libc/arch-x86/syscalls/__connect.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(connect)
+ENTRY(__connect)
     pushl   %ebx
     pushl   %ecx
     .cfi_def_cfa_offset 8
@@ -24,4 +24,4 @@
     popl    %ecx
     popl    %ebx
     ret
-END(connect)
+END(__connect)
diff --git a/libc/arch-x86_64/syscalls/connect.S b/libc/arch-x86_64/syscalls/__connect.S
similarity index 84%
rename from libc/arch-x86_64/syscalls/connect.S
rename to libc/arch-x86_64/syscalls/__connect.S
index 23cdbae..288484e 100644
--- a/libc/arch-x86_64/syscalls/connect.S
+++ b/libc/arch-x86_64/syscalls/__connect.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(connect)
+ENTRY(__connect)
     movl    $__NR_connect, %eax
     syscall
     cmpq    $-MAX_ERRNO, %rax
@@ -13,4 +13,5 @@
     orq     $-1, %rax
 1:
     ret
-END(connect)
+END(__connect)
+.hidden __connect
diff --git a/libc/bionic/NetdClient.cpp b/libc/bionic/NetdClient.cpp
new file mode 100644
index 0000000..6826ee8
--- /dev/null
+++ b/libc/bionic/NetdClient.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef LIBC_STATIC
+#error NetdClient.cpp should NOT be included in static libc builds.
+#endif
+
+#include <private/NetdClient.h>
+#include <private/libc_logging.h>
+#include <pthread.h>
+
+#include <dlfcn.h>
+
+template <typename FunctionType>
+static void netdClientInitFunction(void* handle, const char* symbol, FunctionType* function) {
+    typedef void (*InitFunctionType)(FunctionType*);
+    InitFunctionType initFunction = reinterpret_cast<InitFunctionType>(dlsym(handle, symbol));
+    if (initFunction != NULL) {
+        initFunction(function);
+    }
+}
+
+static void netdClientInitImpl() {
+    void* netdClientHandle = dlopen("libnetd_client.so", RTLD_LAZY);
+    if (netdClientHandle == NULL) {
+        // If the library is not available, it's not an error. We'll just use
+        // default implementations of functions that it would've overridden.
+        return;
+    }
+    netdClientInitFunction(netdClientHandle, "netdClientInitConnect",
+                           &__netdClientDispatch.connect);
+}
+
+static pthread_once_t netdClientInitOnce = PTHREAD_ONCE_INIT;
+
+extern "C" __LIBC_HIDDEN__ void netdClientInit() {
+    if (pthread_once(&netdClientInitOnce, netdClientInitImpl)) {
+        __libc_format_log(ANDROID_LOG_ERROR, "netdClient",
+                          "Unable to initialize netd_client component.");
+    }
+}
diff --git a/libc/bionic/NetdClientDispatch.cpp b/libc/bionic/NetdClientDispatch.cpp
new file mode 100644
index 0000000..31728d2
--- /dev/null
+++ b/libc/bionic/NetdClientDispatch.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <private/NetdClient.h>
+
+#ifdef __i386__
+#define __socketcall __attribute__((__cdecl__))
+#else
+#define __socketcall
+#endif
+
+extern "C" __socketcall int __connect(int, const sockaddr*, socklen_t);
+
+NetdClientDispatch __netdClientDispatch __attribute__((aligned(32))) = {
+    __connect
+};
diff --git a/libc/bionic/connect.cpp b/libc/bionic/connect.cpp
new file mode 100644
index 0000000..c5db46b
--- /dev/null
+++ b/libc/bionic/connect.cpp
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <private/NetdClient.h>
+#include <sys/socket.h>
+
+int connect(int sockfd, const sockaddr* addr, socklen_t addrlen) {
+    return __netdClientDispatch.connect(sockfd, addr, addrlen);
+}
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 61fb887..3d98861 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -58,6 +58,7 @@
   extern void pthread_debug_init(void);
   extern void malloc_debug_init(void);
   extern void malloc_debug_fini(void);
+  extern void netdClientInit(void);
 };
 
 // We flag the __libc_preinit function as a constructor to ensure
@@ -79,6 +80,9 @@
   // Hooks for the debug malloc and pthread libraries to let them know that we're starting up.
   pthread_debug_init();
   malloc_debug_init();
+
+  // Hook for the netd client library to let it know that we're starting up.
+  netdClientInit();
 }
 
 __LIBC_HIDDEN__ void __libc_postfini() {
diff --git a/libc/include/nsswitch.h b/libc/include/nsswitch.h
deleted file mode 100644
index d19d055..0000000
--- a/libc/include/nsswitch.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/*	$NetBSD: nsswitch.h,v 1.18 2005/11/29 03:12:58 christos Exp $	*/
-
-/*-
- * Copyright (c) 1997, 1998, 1999, 2004 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Luke Mewburn.
- *
- * 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 NetBSD
- *        Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
- */
-
-#ifndef _NSSWITCH_H
-#define _NSSWITCH_H	1
-
-#include <sys/types.h>
-#include <stdarg.h>
-
-#define	NSS_MODULE_INTERFACE_VERSION	0
-
-#ifndef _PATH_NS_CONF
-#define _PATH_NS_CONF	"/etc/nsswitch.conf"
-#endif
-
-#define	NS_CONTINUE	0
-#define	NS_RETURN	1
-
-/*
- * Layout of:
- *	uint32_t ns_src.flags
- */ 
-	/* nsswitch.conf status codes and nsdispatch(3) return values */
-#define	NS_SUCCESS	(1<<0)		/* entry was found */
-#define	NS_UNAVAIL	(1<<1)		/* source not responding, or corrupt */
-#define	NS_NOTFOUND	(1<<2)		/* source responded 'no such entry' */
-#define	NS_TRYAGAIN	(1<<3)		/* source busy, may respond to retrys */
-#define	NS_STATUSMASK	0x000000ff	/* bitmask to get the status flags */
-
-	/* internal nsdispatch(3) flags; not settable in nsswitch.conf(5)  */
-#define	NS_FORCEALL	(1<<8)		/* force all methods to be invoked; */
-
-/*
- * Currently implemented sources.
- */
-#define NSSRC_FILES	"files"		/* local files */
-#define	NSSRC_DNS	"dns"		/* DNS; IN for hosts, HS for others */
-#define	NSSRC_NIS	"nis"		/* YP/NIS */
-#define	NSSRC_COMPAT	"compat"	/* passwd,group in YP compat mode */
-
-/*
- * Currently implemented databases.
- */
-#define NSDB_HOSTS		"hosts"
-#define NSDB_GROUP		"group"
-#define NSDB_GROUP_COMPAT	"group_compat"
-#define NSDB_NETGROUP		"netgroup"
-#define NSDB_NETWORKS		"networks"
-#define NSDB_PASSWD		"passwd"
-#define NSDB_PASSWD_COMPAT	"passwd_compat"
-#define NSDB_SHELLS		"shells"
-
-/*
- * Suggested databases to implement.
- */
-#define NSDB_ALIASES		"aliases"
-#define NSDB_AUTH		"auth"
-#define NSDB_AUTOMOUNT		"automount"
-#define NSDB_BOOTPARAMS		"bootparams"
-#define NSDB_ETHERS		"ethers"
-#define NSDB_EXPORTS		"exports"
-#define NSDB_NETMASKS		"netmasks"
-#define NSDB_PHONES		"phones"
-#define NSDB_PRINTCAP		"printcap"
-#define NSDB_PROTOCOLS		"protocols"
-#define NSDB_REMOTE		"remote"
-#define NSDB_RPC		"rpc"
-#define NSDB_SENDMAILVARS	"sendmailvars"
-#define NSDB_SERVICES		"services"
-#define NSDB_TERMCAP		"termcap"
-#define NSDB_TTYS		"ttys"
-
-/*
- * ns_dtab `callback' function signature.
- */
-typedef	int (*nss_method)(void *, void *, va_list);
-
-/*
- * ns_dtab - `nsswitch dispatch table'
- * Contains an entry for each source and the appropriate function to call.
- */
-typedef struct {
-	const char	 *src;
-	nss_method	 callback;
-	void		 *cb_data;
-} ns_dtab;
-
-/*
- * Macros to help build an ns_dtab[]
- */
-#define NS_FILES_CB(F,C)	{ NSSRC_FILES,	F,	__UNCONST(C) },
-#define NS_COMPAT_CB(F,C)	{ NSSRC_COMPAT,	F,	__UNCONST(C) },
- 
-#ifdef HESIOD
-#   define NS_DNS_CB(F,C)	{ NSSRC_DNS,	F,	__UNCONST(C) },
-#else
-#   define NS_DNS_CB(F,C)
-#endif
-
-#ifdef YP
-#   define NS_NIS_CB(F,C)	{ NSSRC_NIS,	F,	__UNCONST(C) },
-#else
-#   define NS_NIS_CB(F,C)
-#endif
-
-/*
- * ns_src - `nsswitch source'
- * Used by the nsparser routines to store a mapping between a source
- * and its dispatch control flags for a given database.
- */
-typedef struct {
-	const char	*name;
-	uint32_t	 flags;
-} ns_src;
-
-
-/*
- * Default sourcelists (if nsswitch.conf is missing, corrupt,
- * or the requested database doesn't have an entry)
- */
-extern const ns_src __nsdefaultsrc[];
-extern const ns_src __nsdefaultcompat[];
-extern const ns_src __nsdefaultcompat_forceall[];
-extern const ns_src __nsdefaultfiles[];
-extern const ns_src __nsdefaultfiles_forceall[];
-extern const ns_src __nsdefaultnis[];
-extern const ns_src __nsdefaultnis_forceall[];
-
-
-/*
- * ns_mtab - `nsswitch method table'
- * An nsswitch module provides a mapping from (database name, method name)
- * tuples to the nss_method and associated callback data.  Effectively,
- * ns_dtab, but used for dynamically loaded modules.
- */
-typedef struct {
-	const char	*database;
-	const char	*name;
-	nss_method	 method;
-	void		*mdata;
-} ns_mtab;
-
-/*
- * nss_module_register_fn - module registration function
- *	called at module load
- * nss_module_unregister_fn - module un-registration function
- *	called at module unload
- */
-typedef	void (*nss_module_unregister_fn)(ns_mtab *, u_int);
-typedef	ns_mtab *(*nss_module_register_fn)(const char *, u_int *,
-					   nss_module_unregister_fn *);
-
-#ifdef _NS_PRIVATE
-
-/*
- * Private data structures for back-end nsswitch implementation.
- */
-
-/*
- * ns_dbt - `nsswitch database thang'
- * For each database in /etc/nsswitch.conf there is a ns_dbt, with its
- * name and a list of ns_src's containing the source information.
- */
-typedef struct {
-	const char	*name;		/* name of database */
-	ns_src		*srclist;	/* list of sources */
-	u_int		 srclistsize;	/* size of srclist */
-} ns_dbt;
-
-/*
- * ns_mod - `nsswitch module'
- */
-typedef struct {
-	const char	*name;		/* module name */
-	void		*handle;	/* handle from dlopen() */
-	ns_mtab		*mtab;		/* method table */
-	u_int		 mtabsize;	/* size of mtab */
-					/* called to unload module */
-	nss_module_unregister_fn unregister;
-} ns_mod;
-
-#endif /* _NS_PRIVATE */
-
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-int	nsdispatch(void *, const ns_dtab [], const char *,
-			const char *, const ns_src [], ...);
-
-#ifdef _NS_PRIVATE
-int		 _nsdbtaddsrc(ns_dbt *, const ns_src *);
-void		 _nsdbtdump(const ns_dbt *);
-int		 _nsdbtput(const ns_dbt *);
-void		 _nsyyerror(const char *);
-int		 _nsyylex(void);
-#endif /* _NS_PRIVATE */
-
-__END_DECLS
-
-#endif /* !_NSSWITCH_H */
diff --git a/libc/private/NetdClient.h b/libc/private/NetdClient.h
new file mode 100644
index 0000000..48c05cb
--- /dev/null
+++ b/libc/private/NetdClient.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PRIVATE_NETD_CLIENT_H
+#define PRIVATE_NETD_CLIENT_H
+
+#include <sys/socket.h>
+
+struct NetdClientDispatch {
+    int (*connect)(int, const sockaddr*, socklen_t);
+};
+
+extern NetdClientDispatch __netdClientDispatch;
+
+#endif  // PRIVATE_NETD_CLIENT_H