auto import from //depot/cupcake/@135843
diff --git a/libs/utils/InetAddress.cpp b/libs/utils/InetAddress.cpp
new file mode 100644
index 0000000..39a0a68
--- /dev/null
+++ b/libs/utils/InetAddress.cpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+//
+// Internet address class.
+//
+#ifdef HAVE_WINSOCK
+# include <winsock2.h>
+#else
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+//# include <arpa/inet.h>
+# include <netdb.h>
+#endif
+
+#include <utils/inet_address.h>
+#include <utils/threads.h>
+#include <utils/Log.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+using namespace android;
+
+
+/*
+ * ===========================================================================
+ * InetAddress
+ * ===========================================================================
+ */
+
+// lock for the next couple of functions; could tuck into InetAddress
+static Mutex* gGHBNLock;
+
+/*
+ * Lock/unlock access to the hostent struct returned by gethostbyname().
+ */
+static inline void lock_gethostbyname(void)
+{
+ if (gGHBNLock == NULL)
+ gGHBNLock = new Mutex;
+ gGHBNLock->lock();
+}
+static inline void unlock_gethostbyname(void)
+{
+ assert(gGHBNLock != NULL);
+ gGHBNLock->unlock();
+}
+
+
+/*
+ * Constructor -- just init members. This is private so that callers
+ * are required to use getByName().
+ */
+InetAddress::InetAddress(void)
+ : mAddress(NULL), mLength(-1), mName(NULL)
+{
+}
+
+/*
+ * Destructor -- free address storage.
+ */
+InetAddress::~InetAddress(void)
+{
+ delete[] (char*) mAddress;
+ delete[] mName;
+}
+
+/*
+ * Copy constructor.
+ */
+InetAddress::InetAddress(const InetAddress& orig)
+{
+ *this = orig; // use assignment code
+}
+
+/*
+ * Assignment operator.
+ */
+InetAddress& InetAddress::operator=(const InetAddress& addr)
+{
+ // handle self-assignment
+ if (this == &addr)
+ return *this;
+ // copy mLength and mAddress
+ mLength = addr.mLength;
+ if (mLength > 0) {
+ mAddress = new char[mLength];
+ memcpy(mAddress, addr.mAddress, mLength);
+ LOG(LOG_DEBUG, "socket",
+ "HEY: copied %d bytes in assignment operator\n", mLength);
+ } else {
+ mAddress = NULL;
+ }
+ // copy mName
+ mName = new char[strlen(addr.mName)+1];
+ strcpy(mName, addr.mName);
+
+ return *this;
+}
+
+/*
+ * Create a new object from a name or a dotted-number IP notation.
+ *
+ * Returns NULL on failure.
+ */
+InetAddress*
+InetAddress::getByName(const char* host)
+{
+ InetAddress* newAddr = NULL;
+ struct sockaddr_in addr;
+ struct hostent* he;
+ DurationTimer hostTimer, lockTimer;
+
+ // gethostbyname() isn't reentrant, so we need to lock things until
+ // we can copy the data out.
+ lockTimer.start();
+ lock_gethostbyname();
+ hostTimer.start();
+
+ he = gethostbyname(host);
+ if (he == NULL) {
+ LOG(LOG_WARN, "socket", "WARNING: cannot resolve host %s\n", host);
+ unlock_gethostbyname();
+ return NULL;
+ }
+
+ memcpy(&addr.sin_addr, he->h_addr, he->h_length);
+ addr.sin_family = he->h_addrtype;
+ addr.sin_port = 0;
+
+ // got it, unlock us
+ hostTimer.stop();
+ he = NULL;
+ unlock_gethostbyname();
+
+ lockTimer.stop();
+ if ((long) lockTimer.durationUsecs() > 100000) {
+ long lockTime = (long) lockTimer.durationUsecs();
+ long hostTime = (long) hostTimer.durationUsecs();
+ LOG(LOG_DEBUG, "socket",
+ "Lookup of %s took %.3fs (gethostbyname=%.3fs lock=%.3fs)\n",
+ host, lockTime / 1000000.0, hostTime / 1000000.0,
+ (lockTime - hostTime) / 1000000.0);
+ }
+
+ // Alloc storage and copy it over.
+ newAddr = new InetAddress();
+ if (newAddr == NULL)
+ return NULL;
+
+ newAddr->mLength = sizeof(struct sockaddr_in);
+ newAddr->mAddress = new char[sizeof(struct sockaddr_in)];
+ if (newAddr->mAddress == NULL) {
+ delete newAddr;
+ return NULL;
+ }
+ memcpy(newAddr->mAddress, &addr, newAddr->mLength);
+
+ // Keep this for debug messages.
+ newAddr->mName = new char[strlen(host)+1];
+ if (newAddr->mName == NULL) {
+ delete newAddr;
+ return NULL;
+ }
+ strcpy(newAddr->mName, host);
+
+ return newAddr;
+}
+
+
+/*
+ * ===========================================================================
+ * InetSocketAddress
+ * ===========================================================================
+ */
+
+/*
+ * Create an address with the host wildcard (INADDR_ANY).
+ */
+bool InetSocketAddress::create(int port)
+{
+ assert(mAddress == NULL);
+
+ mAddress = InetAddress::getByName("0.0.0.0");
+ if (mAddress == NULL)
+ return false;
+ mPort = port;
+ return true;
+}
+
+/*
+ * Create address with host and port specified.
+ */
+bool InetSocketAddress::create(const InetAddress* addr, int port)
+{
+ assert(mAddress == NULL);
+
+ mAddress = new InetAddress(*addr); // make a copy
+ if (mAddress == NULL)
+ return false;
+ mPort = port;
+ return true;
+}
+
+/*
+ * Create address with host and port specified.
+ */
+bool InetSocketAddress::create(const char* host, int port)
+{
+ assert(mAddress == NULL);
+
+ mAddress = InetAddress::getByName(host);
+ if (mAddress == NULL)
+ return false;
+ mPort = port;
+ return true;
+}
+