Merge "[MIPS] Benchmark test for MIPS memset16/memset32"
diff --git a/adb/Android.mk b/adb/Android.mk
index bc8315e..32dd95a 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -16,7 +16,7 @@
 ifeq ($(HOST_OS),linux)
   USB_SRCS := usb_linux.c
   EXTRA_SRCS := get_my_path_linux.c
-  LOCAL_LDLIBS += -lrt -lncurses -lpthread
+  LOCAL_LDLIBS += -lrt -ldl -lpthread
 endif
 
 ifeq ($(HOST_OS),darwin)
@@ -139,7 +139,7 @@
 ifneq ($(SDK_ONLY),true)
 include $(CLEAR_VARS)
 
-LOCAL_LDLIBS := -lrt -lncurses -lpthread
+LOCAL_LDLIBS := -lrt -ldl -lpthread
 
 LOCAL_SRC_FILES := \
 	adb.c \
diff --git a/adb/adb.c b/adb/adb.c
index b3283de..92436da 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <time.h>
 #include <sys/time.h>
+#include <stdint.h>
 
 #include "sysdeps.h"
 #include "adb.h"
@@ -46,6 +47,7 @@
 #endif
 
 int HOST = 0;
+int gListenAll = 0;
 
 static int auth_enabled = 0;
 
@@ -701,7 +703,13 @@
     if(!strncmp("tcp:", name, 4)){
         int  ret;
         port = atoi(name + 4);
-        ret = socket_loopback_server(port, SOCK_STREAM);
+
+        if (gListenAll > 0) {
+            ret = socket_inaddr_any_server(port, SOCK_STREAM);
+        } else {
+            ret = socket_loopback_server(port, SOCK_STREAM);
+        }
+
         return ret;
     }
 #ifndef HAVE_WIN32_IPC  /* no Unix-domain sockets on Win32 */
@@ -984,6 +992,7 @@
     /* message since the pipe handles must be inheritable, we use a     */
     /* security attribute                                               */
     HANDLE                pipe_read, pipe_write;
+    HANDLE                stdout_handle, stderr_handle;
     SECURITY_ATTRIBUTES   sa;
     STARTUPINFO           startup;
     PROCESS_INFORMATION   pinfo;
@@ -1003,6 +1012,26 @@
 
     SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );
 
+    /* Some programs want to launch an adb command and collect its output by
+     * calling CreateProcess with inheritable stdout/stderr handles, then
+     * using read() to get its output. When this happens, the stdout/stderr
+     * handles passed to the adb client process will also be inheritable.
+     * When starting the adb server here, care must be taken to reset them
+     * to non-inheritable.
+     * Otherwise, something bad happens: even if the adb command completes,
+     * the calling process is stuck while read()-ing from the stdout/stderr
+     * descriptors, because they're connected to corresponding handles in the
+     * adb server process (even if the latter never uses/writes to them).
+     */
+    stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE );
+    stderr_handle = GetStdHandle( STD_ERROR_HANDLE );
+    if (stdout_handle != INVALID_HANDLE_VALUE) {
+        SetHandleInformation( stdout_handle, HANDLE_FLAG_INHERIT, 0 );
+    }
+    if (stderr_handle != INVALID_HANDLE_VALUE) {
+        SetHandleInformation( stderr_handle, HANDLE_FLAG_INHERIT, 0 );
+    }
+
     ZeroMemory( &startup, sizeof(startup) );
     startup.cb = sizeof(startup);
     startup.hStdInput  = GetStdHandle( STD_INPUT_HANDLE );
@@ -1079,8 +1108,10 @@
         dup2(fd[1], STDERR_FILENO);
         adb_close(fd[1]);
 
+        char str_port[30];
+        snprintf(str_port, sizeof(str_port), "%d",  server_port);
         // child process
-        int result = execl(path, "adb", "fork-server", "server", NULL);
+        int result = execl(path, "adb", "-P", str_port, "fork-server", "server", NULL);
         // this should not return
         fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
     } else  {
diff --git a/adb/adb_client.c b/adb/adb_client.c
index 9a812f0..8340738 100644
--- a/adb/adb_client.c
+++ b/adb/adb_client.c
@@ -17,6 +17,7 @@
 static const char* __adb_serial = NULL;
 
 static int __adb_server_port = DEFAULT_ADB_PORT;
+static const char* __adb_server_name = NULL;
 
 void adb_set_transport(transport_type type, const char* serial)
 {
@@ -29,6 +30,11 @@
     __adb_server_port = server_port;
 }
 
+void adb_set_tcp_name(const char* hostname)
+{
+    __adb_server_name = hostname;
+}
+
 int  adb_get_emulator_console_port(void)
 {
     const char*   serial = __adb_serial;
@@ -181,7 +187,11 @@
     }
     snprintf(tmp, sizeof tmp, "%04x", len);
 
-    fd = socket_loopback_client(__adb_server_port, SOCK_STREAM);
+    if (__adb_server_name)
+        fd = socket_network_client(__adb_server_name, __adb_server_port, SOCK_STREAM);
+    else
+        fd = socket_loopback_client(__adb_server_port, SOCK_STREAM);
+
     if(fd < 0) {
         strcpy(__adb_error, "cannot connect to daemon");
         return -2;
@@ -212,7 +222,10 @@
     int fd = _adb_connect("host:version");
 
     D("adb_connect: service %s\n", service);
-    if(fd == -2) {
+    if(fd == -2 && __adb_server_name) {
+        fprintf(stderr,"** Cannot start server on remote host\n");
+        return fd;
+    } else if(fd == -2) {
         fprintf(stdout,"* daemon not running. starting it now on port %d *\n",
                 __adb_server_port);
     start_server:
@@ -266,7 +279,7 @@
 
     fd = _adb_connect(service);
     if(fd == -2) {
-        fprintf(stderr,"** daemon still not running");
+        fprintf(stderr,"** daemon still not running\n");
     }
     D("adb_connect: return fd %d\n", fd);
 
diff --git a/adb/adb_client.h b/adb/adb_client.h
index 40ab189..0ec47ca 100644
--- a/adb/adb_client.h
+++ b/adb/adb_client.h
@@ -29,6 +29,10 @@
 */
 void adb_set_tcp_specifics(int server_port);
 
+/* Set TCP Hostname of the transport to use
+*/
+void adb_set_tcp_name(const char* hostname);
+
 /* Return the console port of the currently connected emulator (if any)
  * of -1 if there is no emulator, and -2 if there is more than one.
  * assumes adb_set_transport() was alled previously...
diff --git a/adb/commandline.c b/adb/commandline.c
index a4c2f40..cbe4616 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -46,6 +46,7 @@
 int uninstall_app(transport_type transport, char* serial, int argc, char** argv);
 
 static const char *gProductOutPath = NULL;
+extern int gListenAll;
 
 static char *product_file(const char *extra)
 {
@@ -80,6 +81,7 @@
 
     fprintf(stderr,
         "\n"
+        " -a                            - directs adb to listen on all interfaces for a connection\n"
         " -d                            - directs command to the only connected USB device\n"
         "                                 returns an error if more than one USB device is present.\n"
         " -e                            - directs command to the only running emulator.\n"
@@ -93,6 +95,8 @@
         "                                 If -p is not specified, the ANDROID_PRODUCT_OUT\n"
         "                                 environment variable is used, which must\n"
         "                                 be an absolute path.\n"
+        " -H                            - Name of adb server host (default: localhost)\n"
+        " -P                            - Port of adb server (default: 5037)\n"
         " devices [-l]                  - list all connected devices\n"
         "                                 ('-l' will also list device qualifiers)\n"
         " connect <host>[:<port>]       - connect to a device via TCP/IP\n"
@@ -946,9 +950,9 @@
     int server_port = DEFAULT_ADB_PORT;
     if (server_port_str && strlen(server_port_str) > 0) {
         server_port = (int) strtol(server_port_str, NULL, 0);
-        if (server_port <= 0) {
+        if (server_port <= 0 || server_port > 65535) {
             fprintf(stderr,
-                    "adb: Env var ANDROID_ADB_SERVER_PORT must be a positive number. Got \"%s\"\n",
+                    "adb: Env var ANDROID_ADB_SERVER_PORT must be a positive number less than 65535. Got \"%s\"\n",
                     server_port_str);
             return usage();
         }
@@ -994,6 +998,42 @@
             ttype = kTransportUsb;
         } else if (!strcmp(argv[0],"-e")) {
             ttype = kTransportLocal;
+        } else if (!strcmp(argv[0],"-a")) {
+            gListenAll = 1;
+        } else if(!strncmp(argv[0], "-H", 2)) {
+            const char *hostname = NULL;
+            if (argv[0][2] == '\0') {
+                if (argc < 2) return usage();
+                hostname = argv[1];
+                argc--;
+                argv++;
+            } else {
+                hostname = argv[0] + 2;
+            }
+            adb_set_tcp_name(hostname);
+
+        } else if(!strncmp(argv[0], "-P", 2)) {
+            if (argv[0][2] == '\0') {
+                if (argc < 2) return usage();
+                server_port_str = argv[1];
+                argc--;
+                argv++;
+            } else {
+                server_port_str = argv[0] + 2;
+            }
+            if (strlen(server_port_str) > 0) {
+                server_port = (int) strtol(server_port_str, NULL, 0);
+                if (server_port <= 0 || server_port > 65535) {
+                    fprintf(stderr,
+                            "adb: port number must be a positive number less than 65536. Got \"%s\"\n",
+                            server_port_str);
+                    return usage();
+                }
+            } else {
+                fprintf(stderr,
+                "adb: port number must be a positive number less than 65536. Got empty string.\n");
+                return usage();
+            }
         } else {
                 /* out of recognized modifiers and flags */
             break;
diff --git a/adb/sysdeps_win32.c b/adb/sysdeps_win32.c
index d41c42c..2105b16 100644
--- a/adb/sysdeps_win32.c
+++ b/adb/sysdeps_win32.c
@@ -781,7 +781,7 @@
 void  disable_tcp_nagle(int fd)
 {
     FH   fh = _fh_from_int(fd);
-    int  on;
+    int  on = 1;
 
     if ( !fh || fh->clazz != &_fh_socket_class )
         return;
diff --git a/debuggerd/tombstone.c b/debuggerd/tombstone.c
index 98016c3..e8b3e24 100644
--- a/debuggerd/tombstone.c
+++ b/debuggerd/tombstone.c
@@ -350,6 +350,18 @@
     }
 }
 
+static void dump_map(log_t* log, map_info_t* m, const char* what) {
+    if (m != NULL) {
+        _LOG(log, false, "    %08x-%08x %c%c%c %s\n", m->start, m->end,
+             m->is_readable ? 'r' : '-',
+             m->is_writable ? 'w' : '-',
+             m->is_executable ? 'x' : '-',
+             m->name);
+    } else {
+        _LOG(log, false, "    (no %s)\n", what);
+    }
+}
+
 static void dump_nearby_maps(const ptrace_context_t* context, log_t* log, pid_t tid) {
     siginfo_t si;
     memset(&si, 0, sizeof(si));
@@ -396,21 +408,9 @@
      * Show "next" then "match" then "prev" so that the addresses appear in
      * ascending order (like /proc/pid/maps).
      */
-    if (next != NULL) {
-        _LOG(log, false, "    %08x-%08x %s\n", next->start, next->end, next->name);
-    } else {
-        _LOG(log, false, "    (no map below)\n");
-    }
-    if (map != NULL) {
-        _LOG(log, false, "    %08x-%08x %s\n", map->start, map->end, map->name);
-    } else {
-        _LOG(log, false, "    (no map for address)\n");
-    }
-    if (prev != NULL) {
-        _LOG(log, false, "    %08x-%08x %s\n", prev->start, prev->end, prev->name);
-    } else {
-        _LOG(log, false, "    (no map above)\n");
-    }
+    dump_map(log, next, "map below");
+    dump_map(log, map, "map for address");
+    dump_map(log, prev, "map above");
 }
 
 static void dump_thread(const ptrace_context_t* context, log_t* log, pid_t tid, bool at_fault,
diff --git a/fastboot/engine.c b/fastboot/engine.c
index 7a55260..8d46991 100644
--- a/fastboot/engine.c
+++ b/fastboot/engine.c
@@ -29,6 +29,7 @@
 #include "fastboot.h"
 #include "make_ext4fs.h"
 
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -45,8 +46,6 @@
 #include <sys/mman.h>
 #endif
 
-extern struct fs_info info;
-
 #define ARRAY_SIZE(x)           (sizeof(x)/sizeof(x[0]))
 
 double now()
@@ -302,10 +301,7 @@
 #else
     fd = fileno(tmpfile());
 #endif
-    /* reset ext4fs info so we can be called multiple times */
-    reset_ext4fs_info();
-    info.len = image->partition_size;
-    make_ext4fs_internal(fd, NULL, NULL, NULL, 0, 1, 0, 0, 0, NULL);
+    make_ext4fs_sparse_fd(fd, image->partition_size, NULL, NULL);
 
     fstat(fd, &st);
     image->image_size = st.st_size;
diff --git a/include/corkscrew/map_info.h b/include/corkscrew/map_info.h
index ea1d35f..c9b241d 100644
--- a/include/corkscrew/map_info.h
+++ b/include/corkscrew/map_info.h
@@ -32,6 +32,7 @@
     uintptr_t start;
     uintptr_t end;
     bool is_readable;
+    bool is_writable;
     bool is_executable;
     void* data; // arbitrary data associated with the map by the user, initially NULL
     char name[];
@@ -46,9 +47,10 @@
 /* Finds the memory map that contains the specified address. */
 const map_info_t* find_map_info(const map_info_t* milist, uintptr_t addr);
 
-/* Returns true if the addr is in an readable map. */
+/* Returns true if the addr is in a readable map. */
 bool is_readable_map(const map_info_t* milist, uintptr_t addr);
-
+/* Returns true if the addr is in a writable map. */
+bool is_writable_map(const map_info_t* milist, uintptr_t addr);
 /* Returns true if the addr is in an executable map. */
 bool is_executable_map(const map_info_t* milist, uintptr_t addr);
 
diff --git a/include/cutils/atomic-arm.h b/include/cutils/atomic-arm.h
index 795afd3..172a0cd 100644
--- a/include/cutils/atomic-arm.h
+++ b/include/cutils/atomic-arm.h
@@ -18,55 +18,33 @@
 #define ANDROID_CUTILS_ATOMIC_ARM_H
 
 #include <stdint.h>
-#include <machine/cpu-features.h>
 
 #ifndef ANDROID_ATOMIC_INLINE
 #define ANDROID_ATOMIC_INLINE inline __attribute__((always_inline))
 #endif
 
-extern ANDROID_ATOMIC_INLINE void android_compiler_barrier(void)
+extern ANDROID_ATOMIC_INLINE void android_compiler_barrier()
 {
     __asm__ __volatile__ ("" : : : "memory");
 }
 
+extern ANDROID_ATOMIC_INLINE void android_memory_barrier()
+{
 #if ANDROID_SMP == 0
-extern ANDROID_ATOMIC_INLINE void android_memory_barrier(void)
-{
     android_compiler_barrier();
-}
-extern ANDROID_ATOMIC_INLINE void android_memory_store_barrier(void)
-{
-    android_compiler_barrier();
-}
-#elif defined(__ARM_HAVE_DMB)
-extern ANDROID_ATOMIC_INLINE void android_memory_barrier(void)
-{
-    __asm__ __volatile__ ("dmb" : : : "memory");
-}
-extern ANDROID_ATOMIC_INLINE void android_memory_store_barrier(void)
-{
-    __asm__ __volatile__ ("dmb st" : : : "memory");
-}
-#elif defined(__ARM_HAVE_LDREX_STREX)
-extern ANDROID_ATOMIC_INLINE void android_memory_barrier(void)
-{
-    __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory");
-}
-extern ANDROID_ATOMIC_INLINE void android_memory_store_barrier(void)
-{
-    android_memory_barrier();
-}
 #else
-extern ANDROID_ATOMIC_INLINE void android_memory_barrier(void)
-{
-    typedef void (kuser_memory_barrier)(void);
-    (*(kuser_memory_barrier *)0xffff0fa0)();
-}
-extern ANDROID_ATOMIC_INLINE void android_memory_store_barrier(void)
-{
-    android_memory_barrier();
-}
+    __asm__ __volatile__ ("dmb" : : : "memory");
 #endif
+}
+
+extern ANDROID_ATOMIC_INLINE void android_memory_store_barrier()
+{
+#if ANDROID_SMP == 0
+    android_compiler_barrier();
+#else
+    __asm__ __volatile__ ("dmb st" : : : "memory");
+#endif
+}
 
 extern ANDROID_ATOMIC_INLINE
 int32_t android_atomic_acquire_load(volatile const int32_t *ptr)
@@ -83,32 +61,32 @@
     return *ptr;
 }
 
-extern ANDROID_ATOMIC_INLINE void
-android_atomic_acquire_store(int32_t value, volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE
+void android_atomic_acquire_store(int32_t value, volatile int32_t *ptr)
 {
     *ptr = value;
     android_memory_barrier();
 }
 
-extern ANDROID_ATOMIC_INLINE void
-android_atomic_release_store(int32_t value, volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE
+void android_atomic_release_store(int32_t value, volatile int32_t *ptr)
 {
     android_memory_barrier();
     *ptr = value;
 }
 
-#if defined(__thumb__)
-extern int android_atomic_cas(int32_t old_value, int32_t new_value,
-                              volatile int32_t *ptr);
-#elif defined(__ARM_HAVE_LDREX_STREX)
-extern ANDROID_ATOMIC_INLINE int
-android_atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE
+int android_atomic_cas(int32_t old_value, int32_t new_value,
+                       volatile int32_t *ptr)
 {
     int32_t prev, status;
     do {
         __asm__ __volatile__ ("ldrex %0, [%3]\n"
                               "mov %1, #0\n"
                               "teq %0, %4\n"
+#ifdef __thumb2__
+                              "it eq\n"
+#endif
                               "strexeq %1, %5, [%3]"
                               : "=&r" (prev), "=&r" (status), "+m"(*ptr)
                               : "r" (ptr), "Ir" (old_value), "r" (new_value)
@@ -116,49 +94,26 @@
     } while (__builtin_expect(status != 0, 0));
     return prev != old_value;
 }
-#else
-extern ANDROID_ATOMIC_INLINE int
-android_atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t *ptr)
-{
-    typedef int (kuser_cmpxchg)(int32_t, int32_t, volatile int32_t *);
-    int32_t prev, status;
-    prev = *ptr;
-    do {
-        status = (*(kuser_cmpxchg *)0xffff0fc0)(old_value, new_value, ptr);
-        if (__builtin_expect(status == 0, 1))
-            return 0;
-        prev = *ptr;
-    } while (prev == old_value);
-    return 1;
-}
-#endif
 
-extern ANDROID_ATOMIC_INLINE int
-android_atomic_acquire_cas(int32_t old_value,
-                           int32_t new_value,
-                           volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE
+int android_atomic_acquire_cas(int32_t old_value, int32_t new_value,
+                               volatile int32_t *ptr)
 {
     int status = android_atomic_cas(old_value, new_value, ptr);
     android_memory_barrier();
     return status;
 }
 
-extern ANDROID_ATOMIC_INLINE int
-android_atomic_release_cas(int32_t old_value,
-                           int32_t new_value,
-                           volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE
+int android_atomic_release_cas(int32_t old_value, int32_t new_value,
+                               volatile int32_t *ptr)
 {
     android_memory_barrier();
     return android_atomic_cas(old_value, new_value, ptr);
 }
 
-
-#if defined(__thumb__)
-extern int32_t android_atomic_add(int32_t increment,
-                                  volatile int32_t *ptr);
-#elif defined(__ARM_HAVE_LDREX_STREX)
-extern ANDROID_ATOMIC_INLINE int32_t
-android_atomic_add(int32_t increment, volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE
+int32_t android_atomic_add(int32_t increment, volatile int32_t *ptr)
 {
     int32_t prev, tmp, status;
     android_memory_barrier();
@@ -173,19 +128,6 @@
     } while (__builtin_expect(status != 0, 0));
     return prev;
 }
-#else
-extern ANDROID_ATOMIC_INLINE int32_t
-android_atomic_add(int32_t increment, volatile int32_t *ptr)
-{
-    int32_t prev, status;
-    android_memory_barrier();
-    do {
-        prev = *ptr;
-        status = android_atomic_cas(prev, prev + increment, ptr);
-    } while (__builtin_expect(status != 0, 0));
-    return prev;
-}
-#endif
 
 extern ANDROID_ATOMIC_INLINE int32_t android_atomic_inc(volatile int32_t *addr)
 {
@@ -197,11 +139,8 @@
     return android_atomic_add(-1, addr);
 }
 
-#if defined(__thumb__)
-extern int32_t android_atomic_and(int32_t value, volatile int32_t *ptr);
-#elif defined(__ARM_HAVE_LDREX_STREX)
-extern ANDROID_ATOMIC_INLINE int32_t
-android_atomic_and(int32_t value, volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE
+int32_t android_atomic_and(int32_t value, volatile int32_t *ptr)
 {
     int32_t prev, tmp, status;
     android_memory_barrier();
@@ -216,25 +155,9 @@
     } while (__builtin_expect(status != 0, 0));
     return prev;
 }
-#else
-extern ANDROID_ATOMIC_INLINE int32_t
-android_atomic_and(int32_t value, volatile int32_t *ptr)
-{
-    int32_t prev, status;
-    android_memory_barrier();
-    do {
-        prev = *ptr;
-        status = android_atomic_cas(prev, prev & value, ptr);
-    } while (__builtin_expect(status != 0, 0));
-    return prev;
-}
-#endif
 
-#if defined(__thumb__)
-extern int32_t android_atomic_or(int32_t value, volatile int32_t *ptr);
-#elif defined(__ARM_HAVE_LDREX_STREX)
-extern ANDROID_ATOMIC_INLINE int32_t
-android_atomic_or(int32_t value, volatile int32_t *ptr)
+extern ANDROID_ATOMIC_INLINE
+int32_t android_atomic_or(int32_t value, volatile int32_t *ptr)
 {
     int32_t prev, tmp, status;
     android_memory_barrier();
@@ -249,18 +172,5 @@
     } while (__builtin_expect(status != 0, 0));
     return prev;
 }
-#else
-extern ANDROID_ATOMIC_INLINE int32_t
-android_atomic_or(int32_t value, volatile int32_t *ptr)
-{
-    int32_t prev, status;
-    android_memory_barrier();
-    do {
-        prev = *ptr;
-        status = android_atomic_cas(prev, prev | value, ptr);
-    } while (__builtin_expect(status != 0, 0));
-    return prev;
-}
-#endif
 
 #endif /* ANDROID_CUTILS_ATOMIC_ARM_H */
diff --git a/include/cutils/tztime.h b/include/cutils/tztime.h
index 36ac25d..dbdbd60 100644
--- a/include/cutils/tztime.h
+++ b/include/cutils/tztime.h
@@ -17,45 +17,8 @@
 #ifndef _CUTILS_TZTIME_H
 #define _CUTILS_TZTIME_H
 
-#include <time.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-time_t mktime_tz(struct tm * const tmp, char const * tz);
-void localtime_tz(const time_t * const timep, struct tm * tmp, const char* tz);
-
-#ifdef HAVE_ANDROID_OS
-
-/* the following is defined in the Bionic C library on Android, but the
- * declarations are only available through a platform-private header
- */
+// TODO: fix both callers to just include <bionic_time.h> themselves.
 #include <bionic_time.h>
 
-#else /* !HAVE_ANDROID_OS */
-
-struct strftime_locale {
-    const char *mon[12];    /* short names */
-    const char *month[12];  /* long names */
-    const char *standalone_month[12];  /* long standalone names */
-    const char *wday[7];    /* short names */
-    const char *weekday[7]; /* long names */
-    const char *X_fmt;
-    const char *x_fmt;
-    const char *c_fmt;
-    const char *am;
-    const char *pm;
-    const char *date_fmt;
-};
-
-size_t strftime_tz(char *s, size_t max, const char *format, const struct tm *tm, const struct strftime_locale *locale);
-
-#endif /* !HAVE_ANDROID_OS */
-
-#ifdef __cplusplus
-}
-#endif
-
 #endif /* __CUTILS_TZTIME_H */ 
 
diff --git a/init/devices.c b/init/devices.c
index dd875d6..b07a1a6 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -881,8 +881,8 @@
         sehandle = selinux_android_file_context_handle();
     }
 
-    /* is 64K enough? udev uses 16MB! */
-    device_fd = uevent_open_socket(64*1024, true);
+    /* is 256K enough? udev uses 16MB! */
+    device_fd = uevent_open_socket(256*1024, true);
     if(device_fd < 0)
         return;
 
diff --git a/init/init.c b/init/init.c
index b20b434..48d8559 100755
--- a/init/init.c
+++ b/init/init.c
@@ -198,28 +198,36 @@
     }
 
     if (is_selinux_enabled() > 0) {
-        char *mycon = NULL, *fcon = NULL;
+        if (svc->seclabel) {
+            scon = strdup(svc->seclabel);
+            if (!scon) {
+                ERROR("Out of memory while starting '%s'\n", svc->name);
+                return;
+            }
+        } else {
+            char *mycon = NULL, *fcon = NULL;
 
-        INFO("computing context for service '%s'\n", svc->args[0]);
-        rc = getcon(&mycon);
-        if (rc < 0) {
-            ERROR("could not get context while starting '%s'\n", svc->name);
-            return;
-        }
+            INFO("computing context for service '%s'\n", svc->args[0]);
+            rc = getcon(&mycon);
+            if (rc < 0) {
+                ERROR("could not get context while starting '%s'\n", svc->name);
+                return;
+            }
 
-        rc = getfilecon(svc->args[0], &fcon);
-        if (rc < 0) {
-            ERROR("could not get context while starting '%s'\n", svc->name);
+            rc = getfilecon(svc->args[0], &fcon);
+            if (rc < 0) {
+                ERROR("could not get context while starting '%s'\n", svc->name);
+                freecon(mycon);
+                return;
+            }
+
+            rc = security_compute_create(mycon, fcon, string_to_security_class("process"), &scon);
             freecon(mycon);
-            return;
-        }
-
-        rc = security_compute_create(mycon, fcon, string_to_security_class("process"), &scon);
-        freecon(mycon);
-        freecon(fcon);
-        if (rc < 0) {
-            ERROR("could not get context while starting '%s'\n", svc->name);
-            return;
+            freecon(fcon);
+            if (rc < 0) {
+                ERROR("could not get context while starting '%s'\n", svc->name);
+                return;
+            }
         }
     }
 
diff --git a/libcorkscrew/arch-mips/backtrace-mips.c b/libcorkscrew/arch-mips/backtrace-mips.c
index 07d4a24..1abdd83 100644
--- a/libcorkscrew/arch-mips/backtrace-mips.c
+++ b/libcorkscrew/arch-mips/backtrace-mips.c
@@ -90,7 +90,8 @@
         if (frame)
             frame->stack_top = state->sp;
 
-        ALOGV("#%d: frame=%p pc=%08x sp=%08x\n", index, frame, frame->absolute_pc, frame->stack_top);
+        ALOGV("#%d: frame=%p pc=%08x sp=%08x\n",
+              index, frame, frame->absolute_pc, frame->stack_top);
 
         for (addr = state->pc; maxcheck-- > 0 && !found_start; addr -= 4) {
             uint32_t op;
@@ -115,7 +116,7 @@
                 ALOGV("@0x%08x: found ra offset=%d\n", addr, ra_offset);
                 break;
             case 0x3c1c0000: // lui gp
-                    ALOGV("@0x%08x: found function boundary\n", addr);
+                ALOGV("@0x%08x: found function boundary\n", addr);
                 found_start = true;
                 break;
             default:
@@ -162,7 +163,8 @@
     state.pc = uc->pc;
     state.ra = uc->ra;
 
-    ALOGV("unwind_backtrace_signal_arch: ignore_depth=%d max_depth=%d pc=0x%08x sp=0x%08x ra=0x%08x\n",
+    ALOGV("unwind_backtrace_signal_arch: "
+          "ignore_depth=%d max_depth=%d pc=0x%08x sp=0x%08x ra=0x%08x\n",
           ignore_depth, max_depth, state.pc, state.sp, state.ra);
 
     memory_t memory;
@@ -184,7 +186,8 @@
     state.ra = regs.regs[31];
     state.pc = regs.epc;
 
-    ALOGV("unwind_backtrace_ptrace_arch: ignore_depth=%d max_depth=%d pc=0x%08x sp=0x%08x ra=0x%08x\n",
+    ALOGV("unwind_backtrace_ptrace_arch: "
+          "ignore_depth=%d max_depth=%d pc=0x%08x sp=0x%08x ra=0x%08x\n",
           ignore_depth, max_depth, state.pc, state.sp, state.ra);
 
     memory_t memory;
diff --git a/libcorkscrew/backtrace.c b/libcorkscrew/backtrace.c
index 3697d18..03dbd53 100644
--- a/libcorkscrew/backtrace.c
+++ b/libcorkscrew/backtrace.c
@@ -35,10 +35,8 @@
 #include <cutils/atomic.h>
 #include <elf.h>
 
-#if HAVE_DLADDR
 #define __USE_GNU // For dladdr(3) in glibc.
 #include <dlfcn.h>
-#endif
 
 #if defined(__BIONIC__)
 
@@ -256,7 +254,6 @@
             if (mi->name[0]) {
                 symbol->map_name = strdup(mi->name);
             }
-#if HAVE_DLADDR
             Dl_info info;
             if (dladdr((const void*)frame->absolute_pc, &info) && info.dli_sname) {
                 symbol->relative_symbol_addr = (uintptr_t)info.dli_saddr
@@ -264,7 +261,6 @@
                 symbol->symbol_name = strdup(info.dli_sname);
                 symbol->demangled_name = demangle_symbol_name(symbol->symbol_name);
             }
-#endif
         }
     }
     release_my_map_info_list(milist);
diff --git a/libcorkscrew/map_info.c b/libcorkscrew/map_info.c
index 3c52854..6a27664 100644
--- a/libcorkscrew/map_info.c
+++ b/libcorkscrew/map_info.c
@@ -57,13 +57,15 @@
         mi->start = start;
         mi->end = end;
         mi->is_readable = strlen(permissions) == 4 && permissions[0] == 'r';
+        mi->is_writable = strlen(permissions) == 4 && permissions[1] == 'w';
         mi->is_executable = strlen(permissions) == 4 && permissions[2] == 'x';
         mi->data = NULL;
         memcpy(mi->name, name, name_len);
         mi->name[name_len] = '\0';
         ALOGV("Parsed map: start=0x%08x, end=0x%08x, "
-                "is_readable=%d, is_executable=%d, name=%s",
-                mi->start, mi->end, mi->is_readable, mi->is_executable, mi->name);
+                "is_readable=%d, is_writable=%d, is_executable=%d, name=%s",
+                mi->start, mi->end,
+                mi->is_readable, mi->is_writable, mi->is_executable, mi->name);
     }
     return mi;
 }
@@ -110,6 +112,11 @@
     return mi && mi->is_readable;
 }
 
+bool is_writable_map(const map_info_t* milist, uintptr_t addr) {
+    const map_info_t* mi = find_map_info(milist, addr);
+    return mi && mi->is_writable;
+}
+
 bool is_executable_map(const map_info_t* milist, uintptr_t addr) {
     const map_info_t* mi = find_map_info(milist, addr);
     return mi && mi->is_executable;
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index fbec131..3485392 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -77,12 +77,8 @@
         abort_socket.c \
         fs.c \
         selector.c \
-        tztime.c \
         multiuser.c \
         zygote.c
-
-    commonHostSources += \
-        tzstrftime.c
 endif
 
 
diff --git a/libcutils/private.h b/libcutils/private.h
deleted file mode 100644
index 2837b70..0000000
--- a/libcutils/private.h
+++ /dev/null
@@ -1,368 +0,0 @@
-#ifndef PRIVATE_H
-
-#define PRIVATE_H
-
-/*
-** This file is in the public domain, so clarified as of
-** 1996-06-05 by Arthur David Olson.
-*/
-
-/*
-** This header is for use ONLY with the time conversion code.
-** There is no guarantee that it will remain unchanged,
-** or that it will remain at all.
-** Do NOT copy it to any system include directory.
-** Thank you!
-*/
-
-/*
-** ID
-*/
-
-#ifndef lint
-#ifndef NOID
-static char	privatehid[] = "@(#)private.h	8.2";
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-#define GRANDPARENTED	"Local time zone must be set--see zic manual page"
-
-/*
-** Defaults for preprocessor symbols.
-** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'.
-*/
-
-#ifndef HAVE_ADJTIME
-#define HAVE_ADJTIME		1
-#endif /* !defined HAVE_ADJTIME */
-
-#ifndef HAVE_GETTEXT
-#define HAVE_GETTEXT		0
-#endif /* !defined HAVE_GETTEXT */
-
-#ifndef HAVE_INCOMPATIBLE_CTIME_R
-#define HAVE_INCOMPATIBLE_CTIME_R	0
-#endif /* !defined INCOMPATIBLE_CTIME_R */
-
-#ifndef HAVE_SETTIMEOFDAY
-#define HAVE_SETTIMEOFDAY	3
-#endif /* !defined HAVE_SETTIMEOFDAY */
-
-#ifndef HAVE_STRERROR
-#define HAVE_STRERROR		1
-#endif /* !defined HAVE_STRERROR */
-
-#ifndef HAVE_SYMLINK
-#define HAVE_SYMLINK		1
-#endif /* !defined HAVE_SYMLINK */
-
-#ifndef HAVE_SYS_STAT_H
-#define HAVE_SYS_STAT_H		1
-#endif /* !defined HAVE_SYS_STAT_H */
-
-#ifndef HAVE_SYS_WAIT_H
-#define HAVE_SYS_WAIT_H		1
-#endif /* !defined HAVE_SYS_WAIT_H */
-
-#ifndef HAVE_UNISTD_H
-#define HAVE_UNISTD_H		1
-#endif /* !defined HAVE_UNISTD_H */
-
-#ifndef HAVE_UTMPX_H
-#define HAVE_UTMPX_H		0
-#endif /* !defined HAVE_UTMPX_H */
-
-#ifndef LOCALE_HOME
-#define LOCALE_HOME		"/usr/lib/locale"
-#endif /* !defined LOCALE_HOME */
-
-#if HAVE_INCOMPATIBLE_CTIME_R
-#define asctime_r _incompatible_asctime_r
-#define ctime_r _incompatible_ctime_r
-#endif /* HAVE_INCOMPATIBLE_CTIME_R */
-
-/*
-** Nested includes
-*/
-
-#include "sys/types.h"	/* for time_t */
-#include "stdio.h"
-#include "errno.h"
-#include "string.h"
-#include "limits.h"	/* for CHAR_BIT et al. */
-#include "time.h"
-#include "stdlib.h"
-
-#if HAVE_GETTEXT
-#include "libintl.h"
-#endif /* HAVE_GETTEXT */
-
-#if HAVE_SYS_WAIT_H
-#include <sys/wait.h>	/* for WIFEXITED and WEXITSTATUS */
-#endif /* HAVE_SYS_WAIT_H */
-
-#ifndef WIFEXITED
-#define WIFEXITED(status)	(((status) & 0xff) == 0)
-#endif /* !defined WIFEXITED */
-#ifndef WEXITSTATUS
-#define WEXITSTATUS(status)	(((status) >> 8) & 0xff)
-#endif /* !defined WEXITSTATUS */
-
-#if HAVE_UNISTD_H
-#include "unistd.h"	/* for F_OK and R_OK */
-#endif /* HAVE_UNISTD_H */
-
-#if !HAVE_UNISTD_H
-#ifndef F_OK
-#define F_OK	0
-#endif /* !defined F_OK */
-#ifndef R_OK
-#define R_OK	4
-#endif /* !defined R_OK */
-#endif /* !HAVE_UNISTD_H */
-
-/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
-#define is_digit(c) ((unsigned)(c) - '0' <= 9)
-
-/*
-** Define HAVE_STDINT_H's default value here, rather than at the
-** start, since __GLIBC__'s value depends on previously-included
-** files.
-** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.)
-*/
-#ifndef HAVE_STDINT_H
-#define HAVE_STDINT_H \
-	(199901 <= __STDC_VERSION__ || \
-	2 < (__GLIBC__ + (0 < __GLIBC_MINOR__)))
-#endif /* !defined HAVE_STDINT_H */
-
-#if HAVE_STDINT_H
-#include "stdint.h"
-#endif /* !HAVE_STDINT_H */
-
-#ifndef INT_FAST64_MAX
-/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX.  */
-#if defined LLONG_MAX || defined __LONG_LONG_MAX__
-typedef long long	int_fast64_t;
-#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
-#if (LONG_MAX >> 31) < 0xffffffff
-Please use a compiler that supports a 64-bit integer type (or wider);
-you may need to compile with "-DHAVE_STDINT_H".
-#endif /* (LONG_MAX >> 31) < 0xffffffff */
-typedef long		int_fast64_t;
-#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
-#endif /* !defined INT_FAST64_MAX */
-
-#ifndef INT32_MAX
-#define INT32_MAX 0x7fffffff
-#endif /* !defined INT32_MAX */
-#ifndef INT32_MIN
-#define INT32_MIN (-1 - INT32_MAX)
-#endif /* !defined INT32_MIN */
-
-/*
-** Workarounds for compilers/systems.
-*/
-
-/*
-** If your compiler lacks prototypes, "#define P(x) ()".
-*/
-
-#ifndef P
-#define P(x)	x
-#endif /* !defined P */
-
-/*
-** SunOS 4.1.1 headers lack EXIT_SUCCESS.
-*/
-
-#ifndef EXIT_SUCCESS
-#define EXIT_SUCCESS	0
-#endif /* !defined EXIT_SUCCESS */
-
-/*
-** SunOS 4.1.1 headers lack EXIT_FAILURE.
-*/
-
-#ifndef EXIT_FAILURE
-#define EXIT_FAILURE	1
-#endif /* !defined EXIT_FAILURE */
-
-/*
-** SunOS 4.1.1 headers lack FILENAME_MAX.
-*/
-
-#ifndef FILENAME_MAX
-
-#ifndef MAXPATHLEN
-#ifdef unix
-#include "sys/param.h"
-#endif /* defined unix */
-#endif /* !defined MAXPATHLEN */
-
-#ifdef MAXPATHLEN
-#define FILENAME_MAX	MAXPATHLEN
-#endif /* defined MAXPATHLEN */
-#ifndef MAXPATHLEN
-#define FILENAME_MAX	1024		/* Pure guesswork */
-#endif /* !defined MAXPATHLEN */
-
-#endif /* !defined FILENAME_MAX */
-
-/*
-** SunOS 4.1.1 libraries lack remove.
-*/
-
-#ifndef remove
-extern int	unlink P((const char * filename));
-#define remove	unlink
-#endif /* !defined remove */
-
-/*
-** Some ancient errno.h implementations don't declare errno.
-** But some newer errno.h implementations define it as a macro.
-** Fix the former without affecting the latter.
-*/
-
-#ifndef errno
-extern int errno;
-#endif /* !defined errno */
-
-/*
-** Some time.h implementations don't declare asctime_r.
-** Others might define it as a macro.
-** Fix the former without affecting the latter.
-*/
-
-#ifndef asctime_r
-extern char *	asctime_r();
-#endif
-
-/*
-** Private function declarations.
-*/
-
-char *		icalloc P((int nelem, int elsize));
-char *		icatalloc P((char * old, const char * new));
-char *		icpyalloc P((const char * string));
-char *		imalloc P((int n));
-void *		irealloc P((void * pointer, int size));
-void		icfree P((char * pointer));
-void		ifree P((char * pointer));
-const char *	scheck P((const char * string, const char * format));
-
-/*
-** Finally, some convenience items.
-*/
-
-#ifndef TRUE
-#define TRUE	1
-#endif /* !defined TRUE */
-
-#ifndef FALSE
-#define FALSE	0
-#endif /* !defined FALSE */
-
-#ifndef TYPE_BIT
-#define TYPE_BIT(type)	(sizeof (type) * CHAR_BIT)
-#endif /* !defined TYPE_BIT */
-
-#ifndef TYPE_SIGNED
-#define TYPE_SIGNED(type) (((type) -1) < 0)
-#endif /* !defined TYPE_SIGNED */
-
-/*
-** Since the definition of TYPE_INTEGRAL contains floating point numbers,
-** it cannot be used in preprocessor directives.
-*/
-
-#ifndef TYPE_INTEGRAL
-#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5)
-#endif /* !defined TYPE_INTEGRAL */
-
-#ifndef INT_STRLEN_MAXIMUM
-/*
-** 302 / 1000 is log10(2.0) rounded up.
-** Subtract one for the sign bit if the type is signed;
-** add one for integer division truncation;
-** add one more for a minus sign if the type is signed.
-*/
-#define INT_STRLEN_MAXIMUM(type) \
-	((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
-	1 + TYPE_SIGNED(type))
-#endif /* !defined INT_STRLEN_MAXIMUM */
-
-/*
-** INITIALIZE(x)
-*/
-
-#ifndef GNUC_or_lint
-#ifdef lint
-#define GNUC_or_lint
-#endif /* defined lint */
-#ifndef lint
-#ifdef __GNUC__
-#define GNUC_or_lint
-#endif /* defined __GNUC__ */
-#endif /* !defined lint */
-#endif /* !defined GNUC_or_lint */
-
-#ifndef INITIALIZE
-#ifdef GNUC_or_lint
-#define INITIALIZE(x)	((x) = 0)
-#endif /* defined GNUC_or_lint */
-#ifndef GNUC_or_lint
-#define INITIALIZE(x)
-#endif /* !defined GNUC_or_lint */
-#endif /* !defined INITIALIZE */
-
-/*
-** For the benefit of GNU folk...
-** `_(MSGID)' uses the current locale's message library string for MSGID.
-** The default is to use gettext if available, and use MSGID otherwise.
-*/
-
-#ifndef _
-#if HAVE_GETTEXT
-#define _(msgid) gettext(msgid)
-#else /* !HAVE_GETTEXT */
-#define _(msgid) msgid
-#endif /* !HAVE_GETTEXT */
-#endif /* !defined _ */
-
-#ifndef TZ_DOMAIN
-#define TZ_DOMAIN "tz"
-#endif /* !defined TZ_DOMAIN */
-
-#if HAVE_INCOMPATIBLE_CTIME_R
-#undef asctime_r
-#undef ctime_r
-char *asctime_r P((struct tm const *, char *));
-char *ctime_r P((time_t const *, char *));
-#endif /* HAVE_INCOMPATIBLE_CTIME_R */
-
-#ifndef YEARSPERREPEAT
-#define YEARSPERREPEAT		400	/* years before a Gregorian repeat */
-#endif /* !defined YEARSPERREPEAT */
-
-/*
-** The Gregorian year averages 365.2425 days, which is 31556952 seconds.
-*/
-
-#ifndef AVGSECSPERYEAR
-#define AVGSECSPERYEAR		31556952L
-#endif /* !defined AVGSECSPERYEAR */
-
-#ifndef SECSPERREPEAT
-#define SECSPERREPEAT		((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
-#endif /* !defined SECSPERREPEAT */
- 
-#ifndef SECSPERREPEAT_BITS
-#define SECSPERREPEAT_BITS	34	/* ceil(log2(SECSPERREPEAT)) */
-#endif /* !defined SECSPERREPEAT_BITS */
-
-/*
-** UNIX was a registered trademark of The Open Group in 2003.
-*/
-
-#endif /* !defined PRIVATE_H */
diff --git a/libcutils/tzfile.h b/libcutils/tzfile.h
deleted file mode 100644
index 8c70375..0000000
--- a/libcutils/tzfile.h
+++ /dev/null
@@ -1,180 +0,0 @@
-#ifndef TZFILE_H
-
-#define TZFILE_H
-
-/*
-** This file is in the public domain, so clarified as of
-** 1996-06-05 by Arthur David Olson.
-*/
-
-/*
-** This header is for use ONLY with the time conversion code.
-** There is no guarantee that it will remain unchanged,
-** or that it will remain at all.
-** Do NOT copy it to any system include directory.
-** Thank you!
-*/
-
-/*
-** ID
-*/
-
-#ifndef lint
-#ifndef NOID
-static char	tzfilehid[] = "@(#)tzfile.h	8.1";
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-/*
-** Information about time zone files.
-*/
-
-#ifndef TZDIR
-#define TZDIR "/usr/share/zoneinfo" /* "/android/usr/share/zoneinfo" */ /* Time zone object file directory */
-#endif /* !defined TZDIR */
-
-#ifndef TZDEFAULT
-#define TZDEFAULT	"localtime"
-#endif /* !defined TZDEFAULT */
-
-#ifndef TZDEFRULES
-#define TZDEFRULES	"posixrules"
-#endif /* !defined TZDEFRULES */
-
-/*
-** Each file begins with. . .
-*/
-
-#define	TZ_MAGIC	"TZif"
-
-struct tzhead {
-	char	tzh_magic[4];		/* TZ_MAGIC */
-	char	tzh_version[1];		/* '\0' or '2' as of 2005 */
-	char	tzh_reserved[15];	/* reserved--must be zero */
-	char	tzh_ttisgmtcnt[4];	/* coded number of trans. time flags */
-	char	tzh_ttisstdcnt[4];	/* coded number of trans. time flags */
-	char	tzh_leapcnt[4];		/* coded number of leap seconds */
-	char	tzh_timecnt[4];		/* coded number of transition times */
-	char	tzh_typecnt[4];		/* coded number of local time types */
-	char	tzh_charcnt[4];		/* coded number of abbr. chars */
-};
-
-/*
-** . . .followed by. . .
-**
-**	tzh_timecnt (char [4])s		coded transition times a la time(2)
-**	tzh_timecnt (unsigned char)s	types of local time starting at above
-**	tzh_typecnt repetitions of
-**		one (char [4])		coded UTC offset in seconds
-**		one (unsigned char)	used to set tm_isdst
-**		one (unsigned char)	that's an abbreviation list index
-**	tzh_charcnt (char)s		'\0'-terminated zone abbreviations
-**	tzh_leapcnt repetitions of
-**		one (char [4])		coded leap second transition times
-**		one (char [4])		total correction after above
-**	tzh_ttisstdcnt (char)s		indexed by type; if TRUE, transition
-**					time is standard time, if FALSE,
-**					transition time is wall clock time
-**					if absent, transition times are
-**					assumed to be wall clock time
-**	tzh_ttisgmtcnt (char)s		indexed by type; if TRUE, transition
-**					time is UTC, if FALSE,
-**					transition time is local time
-**					if absent, transition times are
-**					assumed to be local time
-*/
-
-/*
-** If tzh_version is '2' or greater, the above is followed by a second instance
-** of tzhead and a second instance of the data in which each coded transition
-** time uses 8 rather than 4 chars,
-** then a POSIX-TZ-environment-variable-style string for use in handling
-** instants after the last transition time stored in the file
-** (with nothing between the newlines if there is no POSIX representation for
-** such instants).
-*/
-
-/*
-** In the current implementation, "tzset()" refuses to deal with files that
-** exceed any of the limits below.
-*/
-
-#ifndef TZ_MAX_TIMES
-#define TZ_MAX_TIMES	1200
-#endif /* !defined TZ_MAX_TIMES */
-
-#ifndef TZ_MAX_TYPES
-#ifndef NOSOLAR
-#define TZ_MAX_TYPES	256 /* Limited by what (unsigned char)'s can hold */
-#endif /* !defined NOSOLAR */
-#ifdef NOSOLAR
-/*
-** Must be at least 14 for Europe/Riga as of Jan 12 1995,
-** as noted by Earl Chew.
-*/
-#define TZ_MAX_TYPES	20	/* Maximum number of local time types */
-#endif /* !defined NOSOLAR */
-#endif /* !defined TZ_MAX_TYPES */
-
-#ifndef TZ_MAX_CHARS
-#define TZ_MAX_CHARS	50	/* Maximum number of abbreviation characters */
-				/* (limited by what unsigned chars can hold) */
-#endif /* !defined TZ_MAX_CHARS */
-
-#ifndef TZ_MAX_LEAPS
-#define TZ_MAX_LEAPS	50	/* Maximum number of leap second corrections */
-#endif /* !defined TZ_MAX_LEAPS */
-
-#define SECSPERMIN	60
-#define MINSPERHOUR	60
-#define HOURSPERDAY	24
-#define DAYSPERWEEK	7
-#define DAYSPERNYEAR	365
-#define DAYSPERLYEAR	366
-#define SECSPERHOUR	(SECSPERMIN * MINSPERHOUR)
-#define SECSPERDAY	((long) SECSPERHOUR * HOURSPERDAY)
-#define MONSPERYEAR	12
-
-#define TM_SUNDAY	0
-#define TM_MONDAY	1
-#define TM_TUESDAY	2
-#define TM_WEDNESDAY	3
-#define TM_THURSDAY	4
-#define TM_FRIDAY	5
-#define TM_SATURDAY	6
-
-#define TM_JANUARY	0
-#define TM_FEBRUARY	1
-#define TM_MARCH	2
-#define TM_APRIL	3
-#define TM_MAY		4
-#define TM_JUNE		5
-#define TM_JULY		6
-#define TM_AUGUST	7
-#define TM_SEPTEMBER	8
-#define TM_OCTOBER	9
-#define TM_NOVEMBER	10
-#define TM_DECEMBER	11
-
-#define TM_YEAR_BASE	1900
-
-#define EPOCH_YEAR	1970
-#define EPOCH_WDAY	TM_THURSDAY
-
-#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
-
-/*
-** Since everything in isleap is modulo 400 (or a factor of 400), we know that
-**	isleap(y) == isleap(y % 400)
-** and so
-**	isleap(a + b) == isleap((a + b) % 400)
-** or
-**	isleap(a + b) == isleap(a % 400 + b % 400)
-** This is true even if % means modulo rather than Fortran remainder
-** (which is allowed by C89 but not C99).
-** We use this to avoid addition overflow problems.
-*/
-
-#define isleap_sum(a, b)	isleap((a) % 400 + (b) % 400)
-
-#endif /* !defined TZFILE_H */
diff --git a/libcutils/tzstrftime.c b/libcutils/tzstrftime.c
deleted file mode 100644
index e4f54df..0000000
--- a/libcutils/tzstrftime.c
+++ /dev/null
@@ -1,842 +0,0 @@
-#ifndef lint
-#ifndef NOID
-static char	elsieid[] = "@(#)strftime.c	8.1";
-/*
-** Based on the UCB version with the ID appearing below.
-** This is ANSIish only when "multibyte character == plain character".
-*/
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-#include <stdio.h>
-#include <time.h>
-#include <tzfile.h>
-#include <limits.h>
-#include <cutils/tztime.h>
-
-/*
-** Copyright (c) 1989 The Regents of the University of California.
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms are permitted
-** provided that the above copyright notice and this paragraph are
-** duplicated in all such forms and that any documentation,
-** advertising materials, and other materials related to such
-** distribution and use acknowledge that the software was developed
-** by the University of California, Berkeley. The name of the
-** University may not be used to endorse or promote products derived
-** from this software without specific prior written permission.
-** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
-** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-*/
-
-#ifndef LIBC_SCCS
-#ifndef lint
-static const char	sccsid[] = "@(#)strftime.c	5.4 (Berkeley) 3/14/89";
-#endif /* !defined lint */
-#endif /* !defined LIBC_SCCS */
-
-#include <ctype.h>
-
-#define P(x) x
-
-static char *	_add P((const char *, char *, const char *, int));
-static char *	_conv P((int, const char *, char *, const char *));
-static char *	_fmt P((const char *, const struct tm *, char *, const char *,
-			int *, const struct strftime_locale *Locale));
-static char *	_yconv P((int, int, int, int, char *, const char *, int));
-static char *	getformat P((int, char *, char *, char *, char *));
-
-extern char *	tzname[];
-
-
-
-
-
-/* from private.h */
-
-#ifndef TYPE_BIT
-#define TYPE_BIT(type)  (sizeof (type) * CHAR_BIT)
-#endif /* !defined TYPE_BIT */
-
-#ifndef TYPE_SIGNED
-#define TYPE_SIGNED(type) (((type) -1) < 0)
-#endif /* !defined TYPE_SIGNED */
-
-#ifndef INT_STRLEN_MAXIMUM
-/*
- * ** 302 / 1000 is log10(2.0) rounded up.
- * ** Subtract one for the sign bit if the type is signed;
- * ** add one for integer division truncation;
- * ** add one more for a minus sign if the type is signed.
- * */
-#define INT_STRLEN_MAXIMUM(type) \
-    ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
-    1 + TYPE_SIGNED(type))
-#endif /* !defined INT_STRLEN_MAXIMUM */
-
-/* end of part from private.h */
-
-
-
-
-#ifndef YEAR_2000_NAME
-#define YEAR_2000_NAME	"CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
-#endif /* !defined YEAR_2000_NAME */
-
-#define IN_NONE	0
-#define IN_SOME	1
-#define IN_THIS	2
-#define IN_ALL	3
-
-#define FORCE_LOWER_CASE 0x100
-
-size_t
-strftime_tz(s, maxsize, format, t, Locale)
-char * const		s;
-const size_t		maxsize;
-const char * const	format;
-const struct tm * const	t;
-const struct strftime_locale *Locale;
-{
-	char *	p;
-	int	warn;
-
-	warn = IN_NONE;
-	p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn, Locale);
-#if 0
-	if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) {
-		(void) fprintf(stderr, "\n");
-		if (format == NULL)
-			(void) fprintf(stderr, "NULL strftime format ");
-		else	(void) fprintf(stderr, "strftime format \"%s\" ",
-				format);
-		(void) fprintf(stderr, "yields only two digits of years in ");
-		if (warn == IN_SOME)
-			(void) fprintf(stderr, "some locales");
-		else if (warn == IN_THIS)
-			(void) fprintf(stderr, "the current locale");
-		else	(void) fprintf(stderr, "all locales");
-		(void) fprintf(stderr, "\n");
-	}
-#endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */
-	if (p == s + maxsize)
-		return 0;
-	*p = '\0';
-	return p - s;
-}
-
-static char *getformat(int modifier, char *normal, char *underscore,
-                       char *dash, char *zero) {
-    switch (modifier) {
-    case '_':
-        return underscore;
-
-    case '-':
-        return dash;
-
-    case '0':
-        return zero;
-    }
-
-    return normal;
-}
-
-static char *
-_fmt(format, t, pt, ptlim, warnp, Locale)
-const char *		format;
-const struct tm * const	t;
-char *			pt;
-const char * const	ptlim;
-int *			warnp;
-const struct strftime_locale *Locale;
-{
-	for ( ; *format; ++format) {
-		if (*format == '%') {
-            int modifier = 0;
-label:
-			switch (*++format) {
-			case '\0':
-				--format;
-				break;
-			case 'A':
-				pt = _add((t->tm_wday < 0 ||
-					t->tm_wday >= DAYSPERWEEK) ?
-					"?" : Locale->weekday[t->tm_wday],
-					pt, ptlim, modifier);
-				continue;
-			case 'a':
-				pt = _add((t->tm_wday < 0 ||
-					t->tm_wday >= DAYSPERWEEK) ?
-					"?" : Locale->wday[t->tm_wday],
-					pt, ptlim, modifier);
-				continue;
-			case 'B':
-				if (modifier == '-') {
-					pt = _add((t->tm_mon < 0 ||
-						t->tm_mon >= MONSPERYEAR) ?
-						"?" : Locale->standalone_month[t->tm_mon],
-						pt, ptlim, modifier);
-				} else {
-					pt = _add((t->tm_mon < 0 ||
-						t->tm_mon >= MONSPERYEAR) ?
-						"?" : Locale->month[t->tm_mon],
-						pt, ptlim, modifier);
-				}
-				continue;
-			case 'b':
-			case 'h':
-				pt = _add((t->tm_mon < 0 ||
-					t->tm_mon >= MONSPERYEAR) ?
-					"?" : Locale->mon[t->tm_mon],
-					pt, ptlim, modifier);
-				continue;
-			case 'C':
-				/*
-				** %C used to do a...
-				**	_fmt("%a %b %e %X %Y", t);
-				** ...whereas now POSIX 1003.2 calls for
-				** something completely different.
-				** (ado, 1993-05-24)
-				*/
-				pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0,
-					pt, ptlim, modifier);
-				continue;
-			case 'c':
-				{
-				int warn2 = IN_SOME;
-
-				pt = _fmt(Locale->c_fmt, t, pt, ptlim, warnp, Locale);
-				if (warn2 == IN_ALL)
-					warn2 = IN_THIS;
-				if (warn2 > *warnp)
-					*warnp = warn2;
-				}
-				continue;
-			case 'D':
-                                pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp, Locale);
-				continue;
-			case 'd':
-                                pt = _conv(t->tm_mday,
-                                           getformat(modifier, "%02d",
-                                                     "%2d", "%d", "%02d"),
-                                           pt, ptlim);
-				continue;
-			case 'E':
-			case 'O':
-				/*
-				** C99 locale modifiers.
-				** The sequences
-				**	%Ec %EC %Ex %EX %Ey %EY
-				**	%Od %oe %OH %OI %Om %OM
-				**	%OS %Ou %OU %OV %Ow %OW %Oy
-				** are supposed to provide alternate
-				** representations.
-				*/
-				goto label;
-            case '_':
-            case '-':
-            case '0':
-            case '^':
-            case '#':
-                modifier = *format;
-                goto label;
-			case 'e':
-				pt = _conv(t->tm_mday,
-                                           getformat(modifier, "%2d",
-                                                     "%2d", "%d", "%02d"),
-                                           pt, ptlim);
-				continue;
-			case 'F':
-				pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp, Locale);
-				continue;
-			case 'H':
-				pt = _conv(t->tm_hour,
-                                           getformat(modifier, "%02d",
-                                                     "%2d", "%d", "%02d"),
-                                           pt, ptlim);
-				continue;
-			case 'I':
-				pt = _conv((t->tm_hour % 12) ?
-					(t->tm_hour % 12) : 12,
-					getformat(modifier, "%02d",
-                                                  "%2d", "%d", "%02d"),
-                                        pt, ptlim);
-				continue;
-			case 'j':
-				pt = _conv(t->tm_yday + 1,
-                           getformat(modifier, "%03d", "%3d", "%d", "%03d"),
-                           pt, ptlim);
-				continue;
-			case 'k':
-				/*
-				** This used to be...
-				**	_conv(t->tm_hour % 12 ?
-				**		t->tm_hour % 12 : 12, 2, ' ');
-				** ...and has been changed to the below to
-				** match SunOS 4.1.1 and Arnold Robbins'
-				** strftime version 3.0. That is, "%k" and
-				** "%l" have been swapped.
-				** (ado, 1993-05-24)
-				*/
-				pt = _conv(t->tm_hour,
-                                           getformat(modifier, "%2d",
-                                                     "%2d", "%d", "%02d"),
-                                           pt, ptlim);
-				continue;
-#ifdef KITCHEN_SINK
-			case 'K':
-				/*
-				** After all this time, still unclaimed!
-				*/
-				pt = _add("kitchen sink", pt, ptlim, modifier);
-				continue;
-#endif /* defined KITCHEN_SINK */
-			case 'l':
-				/*
-				** This used to be...
-				**	_conv(t->tm_hour, 2, ' ');
-				** ...and has been changed to the below to
-				** match SunOS 4.1.1 and Arnold Robbin's
-				** strftime version 3.0. That is, "%k" and
-				** "%l" have been swapped.
-				** (ado, 1993-05-24)
-				*/
-				pt = _conv((t->tm_hour % 12) ?
-					(t->tm_hour % 12) : 12,
-					getformat(modifier, "%2d",
-                                                  "%2d", "%d", "%02d"),
-                                        pt, ptlim);
-				continue;
-			case 'M':
-				pt = _conv(t->tm_min,
-                                           getformat(modifier, "%02d",
-                                                     "%2d", "%d", "%02d"),
-                                           pt, ptlim);
-				continue;
-			case 'm':
-				pt = _conv(t->tm_mon + 1,
-                                           getformat(modifier, "%02d",
-                                                     "%2d", "%d", "%02d"),
-                                           pt, ptlim);
-				continue;
-			case 'n':
-				pt = _add("\n", pt, ptlim, modifier);
-				continue;
-			case 'p':
-				pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
-					Locale->pm :
-					Locale->am,
-					pt, ptlim, modifier);
-				continue;
-			case 'P':
-				pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
-					Locale->pm :
-					Locale->am,
-					pt, ptlim, FORCE_LOWER_CASE);
-				continue;
-			case 'R':
-				pt = _fmt("%H:%M", t, pt, ptlim, warnp, Locale);
-				continue;
-			case 'r':
-				pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp, Locale);
-				continue;
-			case 'S':
-				pt = _conv(t->tm_sec,
-                                           getformat(modifier, "%02d",
-                                                     "%2d", "%d", "%02d"),
-                                           pt, ptlim);
-				continue;
-			case 's':
-				{
-					struct tm	tm;
-					char		buf[INT_STRLEN_MAXIMUM(
-								time_t) + 1];
-					time_t		mkt;
-
-					tm = *t;
-					mkt = mktime(&tm);
-					if (TYPE_SIGNED(time_t))
-						(void) sprintf(buf, "%ld",
-							(long) mkt);
-					else	(void) sprintf(buf, "%lu",
-							(unsigned long) mkt);
-					pt = _add(buf, pt, ptlim, modifier);
-				}
-				continue;
-			case 'T':
-				pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp, Locale);
-				continue;
-			case 't':
-				pt = _add("\t", pt, ptlim, modifier);
-				continue;
-			case 'U':
-				pt = _conv((t->tm_yday + DAYSPERWEEK -
-					t->tm_wday) / DAYSPERWEEK,
-					getformat(modifier, "%02d",
-                                                  "%2d", "%d", "%02d"),
-                                        pt, ptlim);
-				continue;
-			case 'u':
-				/*
-				** From Arnold Robbins' strftime version 3.0:
-				** "ISO 8601: Weekday as a decimal number
-				** [1 (Monday) - 7]"
-				** (ado, 1993-05-24)
-				*/
-				pt = _conv((t->tm_wday == 0) ?
-					DAYSPERWEEK : t->tm_wday, "%d", pt, ptlim);
-				continue;
-			case 'V':	/* ISO 8601 week number */
-			case 'G':	/* ISO 8601 year (four digits) */
-			case 'g':	/* ISO 8601 year (two digits) */
-/*
-** From Arnold Robbins' strftime version 3.0: "the week number of the
-** year (the first Monday as the first day of week 1) as a decimal number
-** (01-53)."
-** (ado, 1993-05-24)
-**
-** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn:
-** "Week 01 of a year is per definition the first week which has the
-** Thursday in this year, which is equivalent to the week which contains
-** the fourth day of January. In other words, the first week of a new year
-** is the week which has the majority of its days in the new year. Week 01
-** might also contain days from the previous year and the week before week
-** 01 of a year is the last week (52 or 53) of the previous year even if
-** it contains days from the new year. A week starts with Monday (day 1)
-** and ends with Sunday (day 7). For example, the first week of the year
-** 1997 lasts from 1996-12-30 to 1997-01-05..."
-** (ado, 1996-01-02)
-*/
-				{
-					int	year;
-					int	base;
-					int	yday;
-					int	wday;
-					int	w;
-
-					year = t->tm_year;
-					base = TM_YEAR_BASE;
-					yday = t->tm_yday;
-					wday = t->tm_wday;
-					for ( ; ; ) {
-						int	len;
-						int	bot;
-						int	top;
-
-						len = isleap_sum(year, base) ?
-							DAYSPERLYEAR :
-							DAYSPERNYEAR;
-						/*
-						** What yday (-3 ... 3) does
-						** the ISO year begin on?
-						*/
-						bot = ((yday + 11 - wday) %
-							DAYSPERWEEK) - 3;
-						/*
-						** What yday does the NEXT
-						** ISO year begin on?
-						*/
-						top = bot -
-							(len % DAYSPERWEEK);
-						if (top < -3)
-							top += DAYSPERWEEK;
-						top += len;
-						if (yday >= top) {
-							++base;
-							w = 1;
-							break;
-						}
-						if (yday >= bot) {
-							w = 1 + ((yday - bot) /
-								DAYSPERWEEK);
-							break;
-						}
-						--base;
-						yday += isleap_sum(year, base) ?
-							DAYSPERLYEAR :
-							DAYSPERNYEAR;
-					}
-#ifdef XPG4_1994_04_09
-					if ((w == 52 &&
-						t->tm_mon == TM_JANUARY) ||
-						(w == 1 &&
-						t->tm_mon == TM_DECEMBER))
-							w = 53;
-#endif /* defined XPG4_1994_04_09 */
-					if (*format == 'V')
-						pt = _conv(w,
-                                                           getformat(modifier,
-                                                                     "%02d",
-                                                                     "%2d",
-                                                                     "%d",
-                                                                     "%02d"),
-							   pt, ptlim);
-					else if (*format == 'g') {
-						*warnp = IN_ALL;
-						pt = _yconv(year, base, 0, 1,
-							pt, ptlim, modifier);
-					} else	pt = _yconv(year, base, 1, 1,
-							pt, ptlim, modifier);
-				}
-				continue;
-			case 'v':
-				/*
-				** From Arnold Robbins' strftime version 3.0:
-				** "date as dd-bbb-YYYY"
-				** (ado, 1993-05-24)
-				*/
-				pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp, Locale);
-				continue;
-			case 'W':
-				pt = _conv((t->tm_yday + DAYSPERWEEK -
-					(t->tm_wday ?
-					(t->tm_wday - 1) :
-					(DAYSPERWEEK - 1))) / DAYSPERWEEK,
-					getformat(modifier, "%02d",
-                                                  "%2d", "%d", "%02d"),
-                                        pt, ptlim);
-				continue;
-			case 'w':
-				pt = _conv(t->tm_wday, "%d", pt, ptlim);
-				continue;
-			case 'X':
-				pt = _fmt(Locale->X_fmt, t, pt, ptlim, warnp, Locale);
-				continue;
-			case 'x':
-				{
-				int	warn2 = IN_SOME;
-
-				pt = _fmt(Locale->x_fmt, t, pt, ptlim, &warn2, Locale);
-				if (warn2 == IN_ALL)
-					warn2 = IN_THIS;
-				if (warn2 > *warnp)
-					*warnp = warn2;
-				}
-				continue;
-			case 'y':
-				*warnp = IN_ALL;
-				pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1,
-					pt, ptlim, modifier);
-				continue;
-			case 'Y':
-				pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1,
-					pt, ptlim, modifier);
-				continue;
-			case 'Z':
-#ifdef TM_ZONE
-				if (t->TM_ZONE != NULL)
-					pt = _add(t->TM_ZONE, pt, ptlim,
-                                                  modifier);
-				else
-#endif /* defined TM_ZONE */
-				if (t->tm_isdst >= 0)
-					pt = _add(tzname[t->tm_isdst != 0],
-						pt, ptlim, modifier);
-				/*
-				** C99 says that %Z must be replaced by the
-				** empty string if the time zone is not
-				** determinable.
-				*/
-				continue;
-			case 'z':
-				{
-				int		diff;
-				char const *	sign;
-
-				if (t->tm_isdst < 0)
-					continue;
-#ifdef TM_GMTOFF
-				diff = t->TM_GMTOFF;
-#else /* !defined TM_GMTOFF */
-				/*
-				** C99 says that the UTC offset must
-				** be computed by looking only at
-				** tm_isdst. This requirement is
-				** incorrect, since it means the code
-				** must rely on magic (in this case
-				** altzone and timezone), and the
-				** magic might not have the correct
-				** offset. Doing things correctly is
-				** tricky and requires disobeying C99;
-				** see GNU C strftime for details.
-				** For now, punt and conform to the
-				** standard, even though it's incorrect.
-				**
-				** C99 says that %z must be replaced by the
-				** empty string if the time zone is not
-				** determinable, so output nothing if the
-				** appropriate variables are not available.
-				*/
-				if (t->tm_isdst == 0)
-#ifdef USG_COMPAT
-					diff = -timezone;
-#else /* !defined USG_COMPAT */
-					continue;
-#endif /* !defined USG_COMPAT */
-				else
-#ifdef ALTZONE
-					diff = -altzone;
-#else /* !defined ALTZONE */
-					continue;
-#endif /* !defined ALTZONE */
-#endif /* !defined TM_GMTOFF */
-				if (diff < 0) {
-					sign = "-";
-					diff = -diff;
-				} else	sign = "+";
-				pt = _add(sign, pt, ptlim, modifier);
-				diff /= SECSPERMIN;
-				diff = (diff / MINSPERHOUR) * 100 +
-					(diff % MINSPERHOUR);
-				pt = _conv(diff,
-                                           getformat(modifier, "%04d",
-                                                     "%4d", "%d", "%04d"),
-                                           pt, ptlim);
-				}
-				continue;
-			case '+':
-				pt = _fmt(Locale->date_fmt, t, pt, ptlim,
-					warnp, Locale);
-				continue;
-			case '%':
-			/*
-			** X311J/88-090 (4.12.3.5): if conversion char is
-			** undefined, behavior is undefined. Print out the
-			** character itself as printf(3) also does.
-			*/
-			default:
-				break;
-			}
-		}
-		if (pt == ptlim)
-			break;
-		*pt++ = *format;
-	}
-	return pt;
-}
-
-static char *
-_conv(n, format, pt, ptlim)
-const int		n;
-const char * const	format;
-char * const		pt;
-const char * const	ptlim;
-{
-	char	buf[INT_STRLEN_MAXIMUM(int) + 1];
-
-	(void) sprintf(buf, format, n);
-	return _add(buf, pt, ptlim, 0);
-}
-
-static char *
-_add(str, pt, ptlim, modifier)
-const char *		str;
-char *			pt;
-const char * const	ptlim;
-int                     modifier;
-{
-        int c;
-
-        switch (modifier) {
-        case FORCE_LOWER_CASE:
-                while (pt < ptlim && (*pt = tolower(*str++)) != '\0') {
-                        ++pt;
-                }
-                break;
-
-        case '^':
-                while (pt < ptlim && (*pt = toupper(*str++)) != '\0') {
-                        ++pt;
-                }
-                break;
-
-        case '#':
-                while (pt < ptlim && (c = *str++) != '\0') {
-                        if (isupper(c)) {
-                                c = tolower(c);
-                        } else if (islower(c)) {
-                                c = toupper(c);
-                        }
-                        *pt = c;
-                        ++pt;
-                }
-
-                break;
-
-        default:
-                while (pt < ptlim && (*pt = *str++) != '\0') {
-                        ++pt;
-                }
-        }
-
-	return pt;
-}
-
-/*
-** POSIX and the C Standard are unclear or inconsistent about
-** what %C and %y do if the year is negative or exceeds 9999.
-** Use the convention that %C concatenated with %y yields the
-** same output as %Y, and that %Y contains at least 4 bytes,
-** with more only if necessary.
-*/
-
-static char *
-_yconv(a, b, convert_top, convert_yy, pt, ptlim, modifier)
-const int		a;
-const int		b;
-const int		convert_top;
-const int		convert_yy;
-char *			pt;
-const char * const	ptlim;
-int                     modifier;
-{
-	register int	lead;
-	register int	trail;
-
-#define DIVISOR	100
-	trail = a % DIVISOR + b % DIVISOR;
-	lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR;
-	trail %= DIVISOR;
-	if (trail < 0 && lead > 0) {
-		trail += DIVISOR;
-		--lead;
-	} else if (lead < 0 && trail > 0) {
-		trail -= DIVISOR;
-		++lead;
-	}
-	if (convert_top) {
-		if (lead == 0 && trail < 0)
-			pt = _add("-0", pt, ptlim, modifier);
-		else	pt = _conv(lead, getformat(modifier, "%02d",
-                                                   "%2d", "%d", "%02d"),
-                                   pt, ptlim);
-	}
-	if (convert_yy)
-		pt = _conv(((trail < 0) ? -trail : trail),
-                           getformat(modifier, "%02d", "%2d", "%d", "%02d"),
-                           pt, ptlim);
-	return pt;
-}
-
-#ifdef LOCALE_HOME
-static struct lc_time_T *
-_loc P((void))
-{
-	static const char	locale_home[] = LOCALE_HOME;
-	static const char	lc_time[] = "LC_TIME";
-	static char *		locale_buf;
-
-	int			fd;
-	int			oldsun;	/* "...ain't got nothin' to do..." */
-	char *			lbuf;
-	char *			name;
-	char *			p;
-	const char **		ap;
-	const char *		plim;
-	char			filename[FILENAME_MAX];
-	struct stat		st;
-	size_t			namesize;
-	size_t			bufsize;
-
-	/*
-	** Use localebuf.mon[0] to signal whether locale is already set up.
-	*/
-	if (localebuf.mon[0])
-		return &localebuf;
-	name = setlocale(LC_TIME, (char *) NULL);
-	if (name == NULL || *name == '\0')
-		goto no_locale;
-	/*
-	** If the locale name is the same as our cache, use the cache.
-	*/
-	lbuf = locale_buf;
-	if (lbuf != NULL && strcmp(name, lbuf) == 0) {
-		p = lbuf;
-		for (ap = (const char **) &localebuf;
-			ap < (const char **) (&localebuf + 1);
-				++ap)
-					*ap = p += strlen(p) + 1;
-		return &localebuf;
-	}
-	/*
-	** Slurp the locale file into the cache.
-	*/
-	namesize = strlen(name) + 1;
-	if (sizeof filename <
-		((sizeof locale_home) + namesize + (sizeof lc_time)))
-			goto no_locale;
-	oldsun = 0;
-	(void) sprintf(filename, "%s/%s/%s", locale_home, name, lc_time);
-	fd = open(filename, O_RDONLY);
-	if (fd < 0) {
-		/*
-		** Old Sun systems have a different naming and data convention.
-		*/
-		oldsun = 1;
-		(void) sprintf(filename, "%s/%s/%s", locale_home,
-			lc_time, name);
-		fd = open(filename, O_RDONLY);
-		if (fd < 0)
-			goto no_locale;
-	}
-	if (fstat(fd, &st) != 0)
-		goto bad_locale;
-	if (st.st_size <= 0)
-		goto bad_locale;
-	bufsize = namesize + st.st_size;
-	locale_buf = NULL;
-	lbuf = (lbuf == NULL) ? malloc(bufsize) : realloc(lbuf, bufsize);
-	if (lbuf == NULL)
-		goto bad_locale;
-	(void) strcpy(lbuf, name);
-	p = lbuf + namesize;
-	plim = p + st.st_size;
-	if (read(fd, p, (size_t) st.st_size) != st.st_size)
-		goto bad_lbuf;
-	if (close(fd) != 0)
-		goto bad_lbuf;
-	/*
-	** Parse the locale file into localebuf.
-	*/
-	if (plim[-1] != '\n')
-		goto bad_lbuf;
-	for (ap = (const char **) &localebuf;
-		ap < (const char **) (&localebuf + 1);
-			++ap) {
-				if (p == plim)
-					goto bad_lbuf;
-				*ap = p;
-				while (*p != '\n')
-					++p;
-				*p++ = '\0';
-	}
-	if (oldsun) {
-		/*
-		** SunOS 4 used an obsolescent format; see localdtconv(3).
-		** c_fmt had the ``short format for dates and times together''
-		** (SunOS 4 date, "%a %b %e %T %Z %Y" in the C locale);
-		** date_fmt had the ``long format for dates''
-		** (SunOS 4 strftime %C, "%A, %B %e, %Y" in the C locale).
-		** Discard the latter in favor of the former.
-		*/
-		localebuf.date_fmt = localebuf.c_fmt;
-	}
-	/*
-	** Record the successful parse in the cache.
-	*/
-	locale_buf = lbuf;
-
-	return &localebuf;
-
-bad_lbuf:
-	free(lbuf);
-bad_locale:
-	(void) close(fd);
-no_locale:
-	localebuf = C_time_locale;
-	locale_buf = NULL;
-	return &localebuf;
-}
-#endif /* defined LOCALE_HOME */
diff --git a/libcutils/tztime.c b/libcutils/tztime.c
deleted file mode 100644
index d6448a1..0000000
--- a/libcutils/tztime.c
+++ /dev/null
@@ -1,1950 +0,0 @@
-/*
-** This file is in the public domain, so clarified as of
-** 1996-06-05 by Arthur David Olson.
-*/
-
-#include <stdio.h>
-
-#ifndef lint
-#ifndef NOID
-static char	elsieid[] = "@(#)localtime.c	8.3";
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-/*
-** Leap second handling from Bradley White.
-** POSIX-style TZ environment variable handling from Guy Harris.
-*/
-
-/*LINTLIBRARY*/
-
-#include "private.h"
-#include "tzfile.h"
-#include "fcntl.h"
-#include "float.h"	/* for FLT_MAX and DBL_MAX */
-
-#ifndef TZ_ABBR_MAX_LEN
-#define TZ_ABBR_MAX_LEN	16
-#endif /* !defined TZ_ABBR_MAX_LEN */
-
-#ifndef TZ_ABBR_CHAR_SET
-#define TZ_ABBR_CHAR_SET \
-	"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
-#endif /* !defined TZ_ABBR_CHAR_SET */
-
-#ifndef TZ_ABBR_ERR_CHAR
-#define TZ_ABBR_ERR_CHAR	'_'
-#endif /* !defined TZ_ABBR_ERR_CHAR */
-
-#define INDEXFILE "/system/usr/share/zoneinfo/zoneinfo.idx"
-#define DATAFILE "/system/usr/share/zoneinfo/zoneinfo.dat"
-#define NAMELEN 40
-#define INTLEN 4
-#define READLEN (NAMELEN + 3 * INTLEN)
-
-/*
-** SunOS 4.1.1 headers lack O_BINARY.
-*/
-
-#ifdef O_BINARY
-#define OPEN_MODE	(O_RDONLY | O_BINARY)
-#endif /* defined O_BINARY */
-#ifndef O_BINARY
-#define OPEN_MODE	O_RDONLY
-#endif /* !defined O_BINARY */
-
-/* Complex computations to determine the min/max of time_t depending
- * on TYPE_BIT / TYPE_SIGNED / TYPE_INTEGRAL.
- * These macros cannot be used in pre-processor directives, so we
- * let the C compiler do the work, which makes things a bit funky.
- */
-static const time_t TIME_T_MAX =
-    TYPE_INTEGRAL(time_t) ?
-        ( TYPE_SIGNED(time_t) ?
-            ~((time_t)1 << (TYPE_BIT(time_t)-1))
-        :
-            ~(time_t)0
-        )
-    : /* if time_t is a floating point number */
-        ( sizeof(time_t) > sizeof(float) ? (time_t)DBL_MAX : (time_t)FLT_MAX );
-
-static const time_t TIME_T_MIN =
-    TYPE_INTEGRAL(time_t) ?
-        ( TYPE_SIGNED(time_t) ?
-            ((time_t)1 << (TYPE_BIT(time_t)-1))
-        :
-            0
-        )
-    :
-        ( sizeof(time_t) > sizeof(float) ? (time_t)DBL_MIN : (time_t)FLT_MIN );
-
-#ifndef WILDABBR
-/*
-** Someone might make incorrect use of a time zone abbreviation:
-**	1.	They might reference tzname[0] before calling tzset (explicitly
-**		or implicitly).
-**	2.	They might reference tzname[1] before calling tzset (explicitly
-**		or implicitly).
-**	3.	They might reference tzname[1] after setting to a time zone
-**		in which Daylight Saving Time is never observed.
-**	4.	They might reference tzname[0] after setting to a time zone
-**		in which Standard Time is never observed.
-**	5.	They might reference tm.TM_ZONE after calling offtime.
-** What's best to do in the above cases is open to debate;
-** for now, we just set things up so that in any of the five cases
-** WILDABBR is used. Another possibility: initialize tzname[0] to the
-** string "tzname[0] used before set", and similarly for the other cases.
-** And another: initialize tzname[0] to "ERA", with an explanation in the
-** manual page of what this "time zone abbreviation" means (doing this so
-** that tzname[0] has the "normal" length of three characters).
-*/
-#define WILDABBR	"   "
-#endif /* !defined WILDABBR */
-
-static char		wildabbr[] = WILDABBR;
-
-static const char	gmt[] = "GMT";
-
-/*
-** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
-** We default to US rules as of 1999-08-17.
-** POSIX 1003.1 section 8.1.1 says that the default DST rules are
-** implementation dependent; for historical reasons, US rules are a
-** common default.
-*/
-#ifndef TZDEFRULESTRING
-#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
-#endif /* !defined TZDEFDST */
-
-struct ttinfo {				/* time type information */
-	long		tt_gmtoff;	/* UTC offset in seconds */
-	int		tt_isdst;	/* used to set tm_isdst */
-	int		tt_abbrind;	/* abbreviation list index */
-	int		tt_ttisstd;	/* TRUE if transition is std time */
-	int		tt_ttisgmt;	/* TRUE if transition is UTC */
-};
-
-struct lsinfo {				/* leap second information */
-	time_t		ls_trans;	/* transition time */
-	long		ls_corr;	/* correction to apply */
-};
-
-#define BIGGEST(a, b)	(((a) > (b)) ? (a) : (b))
-
-#ifdef TZNAME_MAX
-#define MY_TZNAME_MAX	TZNAME_MAX
-#endif /* defined TZNAME_MAX */
-#ifndef TZNAME_MAX
-#define MY_TZNAME_MAX	255
-#endif /* !defined TZNAME_MAX */
-
-struct state {
-	int		leapcnt;
-	int		timecnt;
-	int		typecnt;
-	int		charcnt;
-	int		goback;
-	int		goahead;
-	time_t		ats[TZ_MAX_TIMES];
-	unsigned char	types[TZ_MAX_TIMES];
-	struct ttinfo	ttis[TZ_MAX_TYPES];
-	char		chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
-				(2 * (MY_TZNAME_MAX + 1)))];
-	struct lsinfo	lsis[TZ_MAX_LEAPS];
-};
-
-struct rule {
-	int		r_type;		/* type of rule--see below */
-	int		r_day;		/* day number of rule */
-	int		r_week;		/* week number of rule */
-	int		r_mon;		/* month number of rule */
-	long		r_time;		/* transition time of rule */
-};
-
-#define JULIAN_DAY		0	/* Jn - Julian day */
-#define DAY_OF_YEAR		1	/* n - day of year */
-#define MONTH_NTH_DAY_OF_WEEK	2	/* Mm.n.d - month, week, day of week */
-
-/*
-** Prototypes for static functions.
-*/
-
-static long		detzcode P((const char * codep));
-static time_t		detzcode64 P((const char * codep));
-static int		differ_by_repeat P((time_t t1, time_t t0));
-static const char *	getzname P((const char * strp));
-static const char *	getqzname P((const char * strp, const int delim));
-static const char *	getnum P((const char * strp, int * nump, int min,
-				int max));
-static const char *	getsecs P((const char * strp, long * secsp));
-static const char *	getoffset P((const char * strp, long * offsetp));
-static const char *	getrule P((const char * strp, struct rule * rulep));
-static void		gmtload P((struct state * sp));
-static struct tm *	gmtsub P((const time_t * timep, long offset,
-				struct tm * tmp));
-static struct tm *	localsub P((const time_t * timep, long offset,
-				struct tm * tmp, const struct state *sp));
-static int		increment_overflow P((int * number, int delta));
-static int		leaps_thru_end_of P((int y));
-static int		long_increment_overflow P((long * number, int delta));
-static int		long_normalize_overflow P((long * tensptr,
-				int * unitsptr, int base));
-static int		normalize_overflow P((int * tensptr, int * unitsptr,
-				int base));
-static void		settzname P((void));
-static time_t		time1 P((struct tm * tmp,
-				struct tm * (*funcp) P((const time_t *,
-				long, struct tm *, const struct state* sp)),
-				long offset, const struct state *	sp));
-static time_t		time2 P((struct tm *tmp,
-				struct tm * (*funcp) P((const time_t *,
-				long, struct tm*, const struct state* sp)),
-				long offset, int * okayp, const struct state *	sp));
-static time_t		time2sub P((struct tm *tmp,
-				struct tm * (*funcp) P((const time_t*, long, struct tm*,const struct state *sp)),
-				long offset, int * okayp, int do_norm_secs,
-                const struct state *sp));
-static struct tm *	timesub P((const time_t * timep, long offset,
-				const struct state * sp, struct tm * tmp));
-static int		tmcomp P((const struct tm * atmp,
-				const struct tm * btmp));
-static time_t		transtime P((time_t janfirst, int year,
-				const struct rule * rulep, long offset));
-static int		tzload P((const char * name, struct state * sp,
-				int doextend));
-static int		tzload_uncached P((const char * name, struct state * sp,
-				int doextend));
-static int		tzparse P((const char * name, struct state * sp,
-				int lastditch));
-
-#ifdef ALL_STATE
-static struct state *	gmtptr;
-#endif /* defined ALL_STATE */
-
-#ifndef ALL_STATE
-static struct state	gmtmem;
-#define gmtptr		(&gmtmem)
-#endif /* State Farm */
-
-#define CACHE_COUNT 4
-static char * g_cacheNames[CACHE_COUNT] = {0,0};
-static struct state	g_cacheStates[CACHE_COUNT];
-static int g_lastCache = 0;
-static struct state g_utc;
-unsigned char g_utcSet = 0;
-
-
-#ifndef TZ_STRLEN_MAX
-#define TZ_STRLEN_MAX 255
-#endif /* !defined TZ_STRLEN_MAX */
-
-static char		lcl_TZname[TZ_STRLEN_MAX + 1];
-static int		lcl_is_set;
-static int		gmt_is_set;
-
-char *			tzname[2] = {
-	wildabbr,
-	wildabbr
-};
-
-/*
-** Section 4.12.3 of X3.159-1989 requires that
-**	Except for the strftime function, these functions [asctime,
-**	ctime, gmtime, localtime] return values in one of two static
-**	objects: a broken-down time structure and an array of char.
-** Thanks to Paul Eggert for noting this.
-*/
-
-static struct tm	tm;
-
-#ifdef USG_COMPAT
-time_t			timezone = 0;
-int			daylight = 0;
-#endif /* defined USG_COMPAT */
-
-#ifdef ALTZONE
-time_t			altzone = 0;
-#endif /* defined ALTZONE */
-
-static long
-detzcode(codep)
-const char * const	codep;
-{
-	register long	result;
-	register int	i;
-
-	result = (codep[0] & 0x80) ? ~0L : 0;
-	for (i = 0; i < 4; ++i)
-		result = (result << 8) | (codep[i] & 0xff);
-	return result;
-}
-
-static time_t
-detzcode64(codep)
-const char * const	codep;
-{
-	register time_t	result;
-	register int	i;
-
-	result = (codep[0] & 0x80) ?  (~(int_fast64_t) 0) : 0;
-	for (i = 0; i < 8; ++i)
-		result = result * 256 + (codep[i] & 0xff);
-	return result;
-}
-
-static int
-differ_by_repeat(t1, t0)
-const time_t	t1;
-const time_t	t0;
-{
-	if (TYPE_INTEGRAL(time_t) &&
-		TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
-			return 0;
-	return t1 - t0 == SECSPERREPEAT;
-}
-
-static int toint(unsigned char *s) {
-    return (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
-}
-
-static int
-tzload(const char *name, struct state * const sp, const int doextend)
-{
-    if (name) {
-        int i, err;
-        if (0 == strcmp(name, "UTC")) {
-            if (!g_utcSet) {
-                tzload_uncached(name, &g_utc, 1);
-                g_utcSet = 1;
-            }
-            //printf("tzload: utc\n");
-            *sp = g_utc;
-            return 0;
-        }
-        for (i=0; i<CACHE_COUNT; i++) {
-            if (g_cacheNames[i] && 0 == strcmp(name, g_cacheNames[i])) {
-                *sp = g_cacheStates[i];
-                //printf("tzload: hit: %s\n", name);
-                return 0;
-            }
-        }
-        //printf("tzload: miss: %s\n", name);
-        g_lastCache++;
-        if (g_lastCache >= CACHE_COUNT) {
-            g_lastCache = 0;
-        }
-        i = g_lastCache;
-        if (g_cacheNames[i]) {
-            free(g_cacheNames[i]);
-        }
-        err = tzload_uncached(name, &(g_cacheStates[i]), 1);
-        if (err == 0) {
-            g_cacheNames[i] = strdup(name);
-            *sp = g_cacheStates[i];
-            return 0;
-        } else {
-            g_cacheNames[i] = NULL;
-            return err;
-        }
-    }
-    return tzload_uncached(name, sp, doextend);
-}
-
-static int
-tzload_uncached(name, sp, doextend)
-register const char *		name;
-register struct state * const	sp;
-register const int		doextend;
-{
-	register const char *		p;
-	register int			i;
-	register int			fid;
-	register int			stored;
-	register int			nread;
-	union {
-		struct tzhead	tzhead;
-		char		buf[2 * sizeof(struct tzhead) +
-					2 * sizeof *sp +
-					4 * TZ_MAX_TIMES];
-	} u;
-    int                     toread = sizeof u.buf;
-
-	if (name == NULL && (name = TZDEFAULT) == NULL)
-		return -1;
-	{
-		register int	doaccess;
-		/*
-		** Section 4.9.1 of the C standard says that
-		** "FILENAME_MAX expands to an integral constant expression
-		** that is the size needed for an array of char large enough
-		** to hold the longest file name string that the implementation
-		** guarantees can be opened."
-		*/
-		char		fullname[FILENAME_MAX + 1];
-		const char	*origname = name;
-
-		if (name[0] == ':')
-			++name;
-		doaccess = name[0] == '/';
-		if (!doaccess) {
-			if ((p = TZDIR) == NULL)
-				return -1;
-			if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)
-				return -1;
-			(void) strcpy(fullname, p);
-			(void) strcat(fullname, "/");
-			(void) strcat(fullname, name);
-			/*
-			** Set doaccess if '.' (as in "../") shows up in name.
-			*/
-			if (strchr(name, '.') != NULL)
-				doaccess = TRUE;
-			name = fullname;
-		}
-		if (doaccess && access(name, R_OK) != 0)
-			return -1;
-		if ((fid = open(name, OPEN_MODE)) == -1) {
-            char buf[READLEN];
-            char name[NAMELEN + 1];
-            int fidix = open(INDEXFILE, OPEN_MODE);
-            int off = -1;
-
-            if (fidix < 0) {
-                return -1;
-            }
-
-            while (read(fidix, buf, sizeof(buf)) == sizeof(buf)) {
-                memcpy(name, buf, NAMELEN);
-                name[NAMELEN] = '\0';
-
-                if (strcmp(name, origname) == 0) {
-                    off = toint((unsigned char *) buf + NAMELEN);
-                    toread = toint((unsigned char *) buf + NAMELEN + INTLEN);
-                    break;
-                }
-            }
-
-            close(fidix);
-
-            if (off < 0)
-                return -1;
-
-            fid = open(DATAFILE, OPEN_MODE);
-
-            if (fid < 0) {
-                return -1;
-            }
-
-            if (lseek(fid, off, SEEK_SET) < 0) {
-                return -1;
-            }
-        }
-	}
-	nread = read(fid, u.buf, toread);
-	if (close(fid) < 0 || nread <= 0)
-		return -1;
-	for (stored = 4; stored <= 8; stored *= 2) {
-		int		ttisstdcnt;
-		int		ttisgmtcnt;
-
-		ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt);
-		ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt);
-		sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt);
-		sp->timecnt = (int) detzcode(u.tzhead.tzh_timecnt);
-		sp->typecnt = (int) detzcode(u.tzhead.tzh_typecnt);
-		sp->charcnt = (int) detzcode(u.tzhead.tzh_charcnt);
-		p = u.tzhead.tzh_charcnt + sizeof u.tzhead.tzh_charcnt;
-		if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
-			sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
-			sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
-			sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
-			(ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
-			(ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
-				return -1;
-		if (nread - (p - u.buf) <
-			sp->timecnt * stored +		/* ats */
-			sp->timecnt +			/* types */
-			sp->typecnt * 6 +		/* ttinfos */
-			sp->charcnt +			/* chars */
-			sp->leapcnt * (stored + 4) +	/* lsinfos */
-			ttisstdcnt +			/* ttisstds */
-			ttisgmtcnt)			/* ttisgmts */
-				return -1;
-		for (i = 0; i < sp->timecnt; ++i) {
-			sp->ats[i] = (stored == 4) ?
-				detzcode(p) : detzcode64(p);
-			p += stored;
-		}
-		for (i = 0; i < sp->timecnt; ++i) {
-			sp->types[i] = (unsigned char) *p++;
-			if (sp->types[i] >= sp->typecnt)
-				return -1;
-		}
-		for (i = 0; i < sp->typecnt; ++i) {
-			register struct ttinfo *	ttisp;
-
-			ttisp = &sp->ttis[i];
-			ttisp->tt_gmtoff = detzcode(p);
-			p += 4;
-			ttisp->tt_isdst = (unsigned char) *p++;
-			if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
-				return -1;
-			ttisp->tt_abbrind = (unsigned char) *p++;
-			if (ttisp->tt_abbrind < 0 ||
-				ttisp->tt_abbrind > sp->charcnt)
-					return -1;
-		}
-		for (i = 0; i < sp->charcnt; ++i)
-			sp->chars[i] = *p++;
-		sp->chars[i] = '\0';	/* ensure '\0' at end */
-		for (i = 0; i < sp->leapcnt; ++i) {
-			register struct lsinfo *	lsisp;
-
-			lsisp = &sp->lsis[i];
-			lsisp->ls_trans = (stored == 4) ?
-				detzcode(p) : detzcode64(p);
-			p += stored;
-			lsisp->ls_corr = detzcode(p);
-			p += 4;
-		}
-		for (i = 0; i < sp->typecnt; ++i) {
-			register struct ttinfo *	ttisp;
-
-			ttisp = &sp->ttis[i];
-			if (ttisstdcnt == 0)
-				ttisp->tt_ttisstd = FALSE;
-			else {
-				ttisp->tt_ttisstd = *p++;
-				if (ttisp->tt_ttisstd != TRUE &&
-					ttisp->tt_ttisstd != FALSE)
-						return -1;
-			}
-		}
-		for (i = 0; i < sp->typecnt; ++i) {
-			register struct ttinfo *	ttisp;
-
-			ttisp = &sp->ttis[i];
-			if (ttisgmtcnt == 0)
-				ttisp->tt_ttisgmt = FALSE;
-			else {
-				ttisp->tt_ttisgmt = *p++;
-				if (ttisp->tt_ttisgmt != TRUE &&
-					ttisp->tt_ttisgmt != FALSE)
-						return -1;
-			}
-		}
-		/*
-		** Out-of-sort ats should mean we're running on a
-		** signed time_t system but using a data file with
-		** unsigned values (or vice versa).
-		*/
-		for (i = 0; i < sp->timecnt - 2; ++i)
-			if (sp->ats[i] > sp->ats[i + 1]) {
-				++i;
-				if (TYPE_SIGNED(time_t)) {
-					/*
-					** Ignore the end (easy).
-					*/
-					sp->timecnt = i;
-				} else {
-					/*
-					** Ignore the beginning (harder).
-					*/
-					register int	j;
-
-					for (j = 0; j + i < sp->timecnt; ++j) {
-						sp->ats[j] = sp->ats[j + i];
-						sp->types[j] = sp->types[j + i];
-					}
-					sp->timecnt = j;
-				}
-				break;
-			}
-		/*
-		** If this is an old file, we're done.
-		*/
-		if (u.tzhead.tzh_version[0] == '\0')
-			break;
-		nread -= p - u.buf;
-		for (i = 0; i < nread; ++i)
-			u.buf[i] = p[i];
-		/*
-		** If this is a narrow integer time_t system, we're done.
-		*/
-		if (stored >= (int) sizeof(time_t) && TYPE_INTEGRAL(time_t))
-			break;
-	}
-	if (doextend && nread > 2 &&
-		u.buf[0] == '\n' && u.buf[nread - 1] == '\n' &&
-		sp->typecnt + 2 <= TZ_MAX_TYPES) {
-			struct state	ts;
-			register int	result;
-
-			u.buf[nread - 1] = '\0';
-			result = tzparse(&u.buf[1], &ts, FALSE);
-			if (result == 0 && ts.typecnt == 2 &&
-				sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) {
-					for (i = 0; i < 2; ++i)
-						ts.ttis[i].tt_abbrind +=
-							sp->charcnt;
-					for (i = 0; i < ts.charcnt; ++i)
-						sp->chars[sp->charcnt++] =
-							ts.chars[i];
-					i = 0;
-					while (i < ts.timecnt &&
-						ts.ats[i] <=
-						sp->ats[sp->timecnt - 1])
-							++i;
-					while (i < ts.timecnt &&
-					    sp->timecnt < TZ_MAX_TIMES) {
-						sp->ats[sp->timecnt] =
-							ts.ats[i];
-						sp->types[sp->timecnt] =
-							sp->typecnt +
-							ts.types[i];
-						++sp->timecnt;
-						++i;
-					}
-					sp->ttis[sp->typecnt++] = ts.ttis[0];
-					sp->ttis[sp->typecnt++] = ts.ttis[1];
-			}
-	}
-	i = 2 * YEARSPERREPEAT;
-	sp->goback = sp->goahead = sp->timecnt > i;
-	sp->goback &= sp->types[i] == sp->types[0] &&
-		differ_by_repeat(sp->ats[i], sp->ats[0]);
-	sp->goahead &=
-		sp->types[sp->timecnt - 1] == sp->types[sp->timecnt - 1 - i] &&
-		differ_by_repeat(sp->ats[sp->timecnt - 1],
-			 sp->ats[sp->timecnt - 1 - i]);
-	return 0;
-}
-
-static const int	mon_lengths[2][MONSPERYEAR] = {
-	{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
-	{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
-};
-
-static const int	year_lengths[2] = {
-	DAYSPERNYEAR, DAYSPERLYEAR
-};
-
-/*
-** Given a pointer into a time zone string, scan until a character that is not
-** a valid character in a zone name is found. Return a pointer to that
-** character.
-*/
-
-static const char *
-getzname(strp)
-register const char *	strp;
-{
-	register char	c;
-
-	while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
-		c != '+')
-			++strp;
-	return strp;
-}
-
-/*
-** Given a pointer into an extended time zone string, scan until the ending
-** delimiter of the zone name is located. Return a pointer to the delimiter.
-**
-** As with getzname above, the legal character set is actually quite
-** restricted, with other characters producing undefined results.
-** We don't do any checking here; checking is done later in common-case code.
-*/
-
-static const char *
-getqzname(register const char *strp, const int delim)
-{
-	register int	c;
-
-	while ((c = *strp) != '\0' && c != delim)
-		++strp;
-	return strp;
-}
-
-/*
-** Given a pointer into a time zone string, extract a number from that string.
-** Check that the number is within a specified range; if it is not, return
-** NULL.
-** Otherwise, return a pointer to the first character not part of the number.
-*/
-
-static const char *
-getnum(strp, nump, min, max)
-register const char *	strp;
-int * const		nump;
-const int		min;
-const int		max;
-{
-	register char	c;
-	register int	num;
-
-	if (strp == NULL || !is_digit(c = *strp))
-		return NULL;
-	num = 0;
-	do {
-		num = num * 10 + (c - '0');
-		if (num > max)
-			return NULL;	/* illegal value */
-		c = *++strp;
-	} while (is_digit(c));
-	if (num < min)
-		return NULL;		/* illegal value */
-	*nump = num;
-	return strp;
-}
-
-/*
-** Given a pointer into a time zone string, extract a number of seconds,
-** in hh[:mm[:ss]] form, from the string.
-** If any error occurs, return NULL.
-** Otherwise, return a pointer to the first character not part of the number
-** of seconds.
-*/
-
-static const char *
-getsecs(strp, secsp)
-register const char *	strp;
-long * const		secsp;
-{
-	int	num;
-
-	/*
-	** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
-	** "M10.4.6/26", which does not conform to Posix,
-	** but which specifies the equivalent of
-	** ``02:00 on the first Sunday on or after 23 Oct''.
-	*/
-	strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
-	if (strp == NULL)
-		return NULL;
-	*secsp = num * (long) SECSPERHOUR;
-	if (*strp == ':') {
-		++strp;
-		strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
-		if (strp == NULL)
-			return NULL;
-		*secsp += num * SECSPERMIN;
-		if (*strp == ':') {
-			++strp;
-			/* `SECSPERMIN' allows for leap seconds. */
-			strp = getnum(strp, &num, 0, SECSPERMIN);
-			if (strp == NULL)
-				return NULL;
-			*secsp += num;
-		}
-	}
-	return strp;
-}
-
-/*
-** Given a pointer into a time zone string, extract an offset, in
-** [+-]hh[:mm[:ss]] form, from the string.
-** If any error occurs, return NULL.
-** Otherwise, return a pointer to the first character not part of the time.
-*/
-
-static const char *
-getoffset(strp, offsetp)
-register const char *	strp;
-long * const		offsetp;
-{
-	register int	neg = 0;
-
-	if (*strp == '-') {
-		neg = 1;
-		++strp;
-	} else if (*strp == '+')
-		++strp;
-	strp = getsecs(strp, offsetp);
-	if (strp == NULL)
-		return NULL;		/* illegal time */
-	if (neg)
-		*offsetp = -*offsetp;
-	return strp;
-}
-
-/*
-** Given a pointer into a time zone string, extract a rule in the form
-** date[/time]. See POSIX section 8 for the format of "date" and "time".
-** If a valid rule is not found, return NULL.
-** Otherwise, return a pointer to the first character not part of the rule.
-*/
-
-static const char *
-getrule(strp, rulep)
-const char *			strp;
-register struct rule * const	rulep;
-{
-	if (*strp == 'J') {
-		/*
-		** Julian day.
-		*/
-		rulep->r_type = JULIAN_DAY;
-		++strp;
-		strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
-	} else if (*strp == 'M') {
-		/*
-		** Month, week, day.
-		*/
-		rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
-		++strp;
-		strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
-		if (strp == NULL)
-			return NULL;
-		if (*strp++ != '.')
-			return NULL;
-		strp = getnum(strp, &rulep->r_week, 1, 5);
-		if (strp == NULL)
-			return NULL;
-		if (*strp++ != '.')
-			return NULL;
-		strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
-	} else if (is_digit(*strp)) {
-		/*
-		** Day of year.
-		*/
-		rulep->r_type = DAY_OF_YEAR;
-		strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
-	} else	return NULL;		/* invalid format */
-	if (strp == NULL)
-		return NULL;
-	if (*strp == '/') {
-		/*
-		** Time specified.
-		*/
-		++strp;
-		strp = getsecs(strp, &rulep->r_time);
-	} else	rulep->r_time = 2 * SECSPERHOUR;	/* default = 2:00:00 */
-	return strp;
-}
-
-/*
-** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the
-** year, a rule, and the offset from UTC at the time that rule takes effect,
-** calculate the Epoch-relative time that rule takes effect.
-*/
-
-static time_t
-transtime(janfirst, year, rulep, offset)
-const time_t				janfirst;
-const int				year;
-register const struct rule * const	rulep;
-const long				offset;
-{
-	register int	leapyear;
-	register time_t	value;
-	register int	i;
-	int		d, m1, yy0, yy1, yy2, dow;
-
-	INITIALIZE(value);
-	leapyear = isleap(year);
-	switch (rulep->r_type) {
-
-	case JULIAN_DAY:
-		/*
-		** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
-		** years.
-		** In non-leap years, or if the day number is 59 or less, just
-		** add SECSPERDAY times the day number-1 to the time of
-		** January 1, midnight, to get the day.
-		*/
-		value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
-		if (leapyear && rulep->r_day >= 60)
-			value += SECSPERDAY;
-		break;
-
-	case DAY_OF_YEAR:
-		/*
-		** n - day of year.
-		** Just add SECSPERDAY times the day number to the time of
-		** January 1, midnight, to get the day.
-		*/
-		value = janfirst + rulep->r_day * SECSPERDAY;
-		break;
-
-	case MONTH_NTH_DAY_OF_WEEK:
-		/*
-		** Mm.n.d - nth "dth day" of month m.
-		*/
-		value = janfirst;
-		for (i = 0; i < rulep->r_mon - 1; ++i)
-			value += mon_lengths[leapyear][i] * SECSPERDAY;
-
-		/*
-		** Use Zeller's Congruence to get day-of-week of first day of
-		** month.
-		*/
-		m1 = (rulep->r_mon + 9) % 12 + 1;
-		yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
-		yy1 = yy0 / 100;
-		yy2 = yy0 % 100;
-		dow = ((26 * m1 - 2) / 10 +
-			1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
-		if (dow < 0)
-			dow += DAYSPERWEEK;
-
-		/*
-		** "dow" is the day-of-week of the first day of the month. Get
-		** the day-of-month (zero-origin) of the first "dow" day of the
-		** month.
-		*/
-		d = rulep->r_day - dow;
-		if (d < 0)
-			d += DAYSPERWEEK;
-		for (i = 1; i < rulep->r_week; ++i) {
-			if (d + DAYSPERWEEK >=
-				mon_lengths[leapyear][rulep->r_mon - 1])
-					break;
-			d += DAYSPERWEEK;
-		}
-
-		/*
-		** "d" is the day-of-month (zero-origin) of the day we want.
-		*/
-		value += d * SECSPERDAY;
-		break;
-	}
-
-	/*
-	** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
-	** question. To get the Epoch-relative time of the specified local
-	** time on that day, add the transition time and the current offset
-	** from UTC.
-	*/
-	return value + rulep->r_time + offset;
-}
-
-/*
-** Given a POSIX section 8-style TZ string, fill in the rule tables as
-** appropriate.
-*/
-
-static int
-tzparse(name, sp, lastditch)
-const char *			name;
-register struct state * const	sp;
-const int			lastditch;
-{
-	const char *			stdname;
-	const char *			dstname;
-	size_t				stdlen;
-	size_t				dstlen;
-	long				stdoffset;
-	long				dstoffset;
-	register time_t *		atp;
-	register unsigned char *	typep;
-	register char *			cp;
-	register int			load_result;
-
-	INITIALIZE(dstname);
-	stdname = name;
-	if (lastditch) {
-		stdlen = strlen(name);	/* length of standard zone name */
-		name += stdlen;
-		if (stdlen >= sizeof sp->chars)
-			stdlen = (sizeof sp->chars) - 1;
-		stdoffset = 0;
-	} else {
-		if (*name == '<') {
-			name++;
-			stdname = name;
-			name = getqzname(name, '>');
-			if (*name != '>')
-				return (-1);
-			stdlen = name - stdname;
-			name++;
-		} else {
-			name = getzname(name);
-			stdlen = name - stdname;
-		}
-		if (*name == '\0')
-			return -1;
-		name = getoffset(name, &stdoffset);
-		if (name == NULL)
-			return -1;
-	}
-	load_result = tzload(TZDEFRULES, sp, FALSE);
-	if (load_result != 0)
-		sp->leapcnt = 0;		/* so, we're off a little */
-	sp->timecnt = 0;
-	if (*name != '\0') {
-		if (*name == '<') {
-			dstname = ++name;
-			name = getqzname(name, '>');
-			if (*name != '>')
-				return -1;
-			dstlen = name - dstname;
-			name++;
-		} else {
-			dstname = name;
-			name = getzname(name);
-			dstlen = name - dstname; /* length of DST zone name */
-		}
-		if (*name != '\0' && *name != ',' && *name != ';') {
-			name = getoffset(name, &dstoffset);
-			if (name == NULL)
-				return -1;
-		} else	dstoffset = stdoffset - SECSPERHOUR;
-		if (*name == '\0' && load_result != 0)
-			name = TZDEFRULESTRING;
-		if (*name == ',' || *name == ';') {
-			struct rule	start;
-			struct rule	end;
-			register int	year;
-			register time_t	janfirst;
-			time_t		starttime;
-			time_t		endtime;
-
-			++name;
-			if ((name = getrule(name, &start)) == NULL)
-				return -1;
-			if (*name++ != ',')
-				return -1;
-			if ((name = getrule(name, &end)) == NULL)
-				return -1;
-			if (*name != '\0')
-				return -1;
-			sp->typecnt = 2;	/* standard time and DST */
-			/*
-			** Two transitions per year, from EPOCH_YEAR forward.
-			*/
-			sp->ttis[0].tt_gmtoff = -dstoffset;
-			sp->ttis[0].tt_isdst = 1;
-			sp->ttis[0].tt_abbrind = stdlen + 1;
-			sp->ttis[1].tt_gmtoff = -stdoffset;
-			sp->ttis[1].tt_isdst = 0;
-			sp->ttis[1].tt_abbrind = 0;
-			atp = sp->ats;
-			typep = sp->types;
-			janfirst = 0;
-			for (year = EPOCH_YEAR;
-			    sp->timecnt + 2 <= TZ_MAX_TIMES;
-			    ++year) {
-			    	time_t	newfirst;
-
-				starttime = transtime(janfirst, year, &start,
-					stdoffset);
-				endtime = transtime(janfirst, year, &end,
-					dstoffset);
-				if (starttime > endtime) {
-					*atp++ = endtime;
-					*typep++ = 1;	/* DST ends */
-					*atp++ = starttime;
-					*typep++ = 0;	/* DST begins */
-				} else {
-					*atp++ = starttime;
-					*typep++ = 0;	/* DST begins */
-					*atp++ = endtime;
-					*typep++ = 1;	/* DST ends */
-				}
-				sp->timecnt += 2;
-				newfirst = janfirst;
-				newfirst += year_lengths[isleap(year)] *
-					SECSPERDAY;
-				if (newfirst <= janfirst)
-					break;
-				janfirst = newfirst;
-			}
-		} else {
-			register long	theirstdoffset;
-			register long	theirdstoffset;
-			register long	theiroffset;
-			register int	isdst;
-			register int	i;
-			register int	j;
-
-			if (*name != '\0')
-				return -1;
-			/*
-			** Initial values of theirstdoffset and theirdstoffset.
-			*/
-			theirstdoffset = 0;
-			for (i = 0; i < sp->timecnt; ++i) {
-				j = sp->types[i];
-				if (!sp->ttis[j].tt_isdst) {
-					theirstdoffset =
-						-sp->ttis[j].tt_gmtoff;
-					break;
-				}
-			}
-			theirdstoffset = 0;
-			for (i = 0; i < sp->timecnt; ++i) {
-				j = sp->types[i];
-				if (sp->ttis[j].tt_isdst) {
-					theirdstoffset =
-						-sp->ttis[j].tt_gmtoff;
-					break;
-				}
-			}
-			/*
-			** Initially we're assumed to be in standard time.
-			*/
-			isdst = FALSE;
-			theiroffset = theirstdoffset;
-			/*
-			** Now juggle transition times and types
-			** tracking offsets as you do.
-			*/
-			for (i = 0; i < sp->timecnt; ++i) {
-				j = sp->types[i];
-				sp->types[i] = sp->ttis[j].tt_isdst;
-				if (sp->ttis[j].tt_ttisgmt) {
-					/* No adjustment to transition time */
-				} else {
-					/*
-					** If summer time is in effect, and the
-					** transition time was not specified as
-					** standard time, add the summer time
-					** offset to the transition time;
-					** otherwise, add the standard time
-					** offset to the transition time.
-					*/
-					/*
-					** Transitions from DST to DDST
-					** will effectively disappear since
-					** POSIX provides for only one DST
-					** offset.
-					*/
-					if (isdst && !sp->ttis[j].tt_ttisstd) {
-						sp->ats[i] += dstoffset -
-							theirdstoffset;
-					} else {
-						sp->ats[i] += stdoffset -
-							theirstdoffset;
-					}
-				}
-				theiroffset = -sp->ttis[j].tt_gmtoff;
-				if (sp->ttis[j].tt_isdst)
-					theirdstoffset = theiroffset;
-				else	theirstdoffset = theiroffset;
-			}
-			/*
-			** Finally, fill in ttis.
-			** ttisstd and ttisgmt need not be handled.
-			*/
-			sp->ttis[0].tt_gmtoff = -stdoffset;
-			sp->ttis[0].tt_isdst = FALSE;
-			sp->ttis[0].tt_abbrind = 0;
-			sp->ttis[1].tt_gmtoff = -dstoffset;
-			sp->ttis[1].tt_isdst = TRUE;
-			sp->ttis[1].tt_abbrind = stdlen + 1;
-			sp->typecnt = 2;
-		}
-	} else {
-		dstlen = 0;
-		sp->typecnt = 1;		/* only standard time */
-		sp->timecnt = 0;
-		sp->ttis[0].tt_gmtoff = -stdoffset;
-		sp->ttis[0].tt_isdst = 0;
-		sp->ttis[0].tt_abbrind = 0;
-	}
-	sp->charcnt = stdlen + 1;
-	if (dstlen != 0)
-		sp->charcnt += dstlen + 1;
-	if ((size_t) sp->charcnt > sizeof sp->chars)
-		return -1;
-	cp = sp->chars;
-	(void) strncpy(cp, stdname, stdlen);
-	cp += stdlen;
-	*cp++ = '\0';
-	if (dstlen != 0) {
-		(void) strncpy(cp, dstname, dstlen);
-		*(cp + dstlen) = '\0';
-	}
-	return 0;
-}
-
-static void
-gmtload(sp)
-struct state * const	sp;
-{
-	if (tzload(gmt, sp, TRUE) != 0)
-		(void) tzparse(gmt, sp, TRUE);
-}
-
-/*
-** The easy way to behave "as if no library function calls" localtime
-** is to not call it--so we drop its guts into "localsub", which can be
-** freely called. (And no, the PANS doesn't require the above behavior--
-** but it *is* desirable.)
-**
-** The unused offset argument is for the benefit of mktime variants.
-*/
-
-/*ARGSUSED*/
-static struct tm *
-localsub(timep, offset, tmp, sp)
-const time_t * const	timep;
-const long		offset;
-struct tm * const	tmp;
-const struct state *		sp;
-{
-	register const struct ttinfo *	ttisp;
-	register int			i;
-	register struct tm *		result;
-	const time_t			t = *timep;
-
-#ifdef ALL_STATE
-	if (sp == NULL)
-		return gmtsub(timep, offset, tmp);
-#endif /* defined ALL_STATE */
-	if ((sp->goback && t < sp->ats[0]) ||
-		(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
-			time_t			newt = t;
-			register time_t		seconds;
-			register time_t		tcycles;
-			register int_fast64_t	icycles;
-
-			if (t < sp->ats[0])
-				seconds = sp->ats[0] - t;
-			else	seconds = t - sp->ats[sp->timecnt - 1];
-			--seconds;
-			tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
-			++tcycles;
-			icycles = tcycles;
-			if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
-				return NULL;
-			seconds = icycles;
-			seconds *= YEARSPERREPEAT;
-			seconds *= AVGSECSPERYEAR;
-			if (t < sp->ats[0])
-				newt += seconds;
-			else	newt -= seconds;
-			if (newt < sp->ats[0] ||
-				newt > sp->ats[sp->timecnt - 1])
-					return NULL;	/* "cannot happen" */
-			result = localsub(&newt, offset, tmp, sp);
-			if (result == tmp) {
-				register time_t	newy;
-
-				newy = tmp->tm_year;
-				if (t < sp->ats[0])
-					newy -= icycles * YEARSPERREPEAT;
-				else	newy += icycles * YEARSPERREPEAT;
-				tmp->tm_year = newy;
-				if (tmp->tm_year != newy)
-					return NULL;
-			}
-			return result;
-	}
-	if (sp->timecnt == 0 || t < sp->ats[0]) {
-		i = 0;
-		while (sp->ttis[i].tt_isdst)
-			if (++i >= sp->typecnt) {
-				i = 0;
-				break;
-			}
-	} else {
-		register int	lo = 1;
-		register int	hi = sp->timecnt;
-
-		while (lo < hi) {
-			register int	mid = (lo + hi) >> 1;
-
-			if (t < sp->ats[mid])
-				hi = mid;
-			else	lo = mid + 1;
-		}
-		i = (int) sp->types[lo - 1];
-	}
-	ttisp = &sp->ttis[i];
-	/*
-	** To get (wrong) behavior that's compatible with System V Release 2.0
-	** you'd replace the statement below with
-	**	t += ttisp->tt_gmtoff;
-	**	timesub(&t, 0L, sp, tmp);
-	*/
-	result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
-	tmp->tm_isdst = ttisp->tt_isdst;
-#ifdef HAVE_TM_GMTOFF
-	tmp->tm_gmtoff = ttisp->tt_gmtoff;
-#endif
-	tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
-#ifdef TM_ZONE
-	tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
-#endif /* defined TM_ZONE */
-	return result;
-}
-
-
-// ============================================================================
-#if 0
-struct tm *
-localtime(timep)
-const time_t * const	timep;
-{
-	tzset();
-	return localsub(timep, 0L, &tm);
-}
-#endif
-
-/*
-** Re-entrant version of localtime.
-*/
-
-// ============================================================================
-void
-localtime_tz(const time_t * const timep, struct tm * tmp, const char* tz)
-{
-    struct state st;
-    if (tzload(tz, &st, TRUE) != 0) {
-        // not sure what's best here, but for now, we fall back to gmt
-        gmtload(&st);
-    }
-
-	localsub(timep, 0L, tmp, &st);
-}
-
-/*
-** gmtsub is to gmtime as localsub is to localtime.
-*/
-
-static struct tm *
-gmtsub(timep, offset, tmp)
-const time_t * const	timep;
-const long		offset;
-struct tm * const	tmp;
-{
-	register struct tm *	result;
-
-	if (!gmt_is_set) {
-		gmt_is_set = TRUE;
-#ifdef ALL_STATE
-		gmtptr = (struct state *) malloc(sizeof *gmtptr);
-		if (gmtptr != NULL)
-#endif /* defined ALL_STATE */
-			gmtload(gmtptr);
-	}
-	result = timesub(timep, offset, gmtptr, tmp);
-#ifdef TM_ZONE
-	/*
-	** Could get fancy here and deliver something such as
-	** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero,
-	** but this is no time for a treasure hunt.
-	*/
-	if (offset != 0)
-		tmp->TM_ZONE = wildabbr;
-	else {
-#ifdef ALL_STATE
-		if (gmtptr == NULL)
-			tmp->TM_ZONE = gmt;
-		else	tmp->TM_ZONE = gmtptr->chars;
-#endif /* defined ALL_STATE */
-#ifndef ALL_STATE
-		tmp->TM_ZONE = gmtptr->chars;
-#endif /* State Farm */
-	}
-#endif /* defined TM_ZONE */
-	return result;
-}
-
-// ============================================================================
-#if 0
-struct tm *
-gmtime(timep)
-const time_t * const	timep;
-{
-	return gmtsub(timep, 0L, &tm);
-}
-#endif
-
-/*
-* Re-entrant version of gmtime.
-*/
-
-// ============================================================================
-#if 0
-struct tm *
-gmtime_r(timep, tmp)
-const time_t * const	timep;
-struct tm *		tmp;
-{
-	return gmtsub(timep, 0L, tmp);
-}
-#endif
-
-#ifdef STD_INSPIRED
-
-// ============================================================================
-#if 0
-struct tm *
-offtime(timep, offset)
-const time_t * const	timep;
-const long		offset;
-{
-	return gmtsub(timep, offset, &tm);
-}
-#endif
-
-#endif /* defined STD_INSPIRED */
-
-/*
-** Return the number of leap years through the end of the given year
-** where, to make the math easy, the answer for year zero is defined as zero.
-*/
-
-static int
-leaps_thru_end_of(y)
-register const int	y;
-{
-	return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
-		-(leaps_thru_end_of(-(y + 1)) + 1);
-}
-
-static struct tm *
-timesub(timep, offset, sp, tmp)
-const time_t * const			timep;
-const long				offset;
-register const struct state * const	sp;
-register struct tm * const		tmp;
-{
-	register const struct lsinfo *	lp;
-	register time_t			tdays;
-	register int			idays;	/* unsigned would be so 2003 */
-	register long			rem;
-	int				y;
-	register const int *		ip;
-	register long			corr;
-	register int			hit;
-	register int			i;
-
-	corr = 0;
-	hit = 0;
-#ifdef ALL_STATE
-	i = (sp == NULL) ? 0 : sp->leapcnt;
-#endif /* defined ALL_STATE */
-#ifndef ALL_STATE
-	i = sp->leapcnt;
-#endif /* State Farm */
-	while (--i >= 0) {
-		lp = &sp->lsis[i];
-		if (*timep >= lp->ls_trans) {
-			if (*timep == lp->ls_trans) {
-				hit = ((i == 0 && lp->ls_corr > 0) ||
-					lp->ls_corr > sp->lsis[i - 1].ls_corr);
-				if (hit)
-					while (i > 0 &&
-						sp->lsis[i].ls_trans ==
-						sp->lsis[i - 1].ls_trans + 1 &&
-						sp->lsis[i].ls_corr ==
-						sp->lsis[i - 1].ls_corr + 1) {
-							++hit;
-							--i;
-					}
-			}
-			corr = lp->ls_corr;
-			break;
-		}
-	}
-	y = EPOCH_YEAR;
-	tdays = *timep / SECSPERDAY;
-	rem = *timep - tdays * SECSPERDAY;
-	while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
-		int		newy;
-		register time_t	tdelta;
-		register int	idelta;
-		register int	leapdays;
-
-		tdelta = tdays / DAYSPERLYEAR;
-		idelta = tdelta;
-		if (tdelta - idelta >= 1 || idelta - tdelta >= 1)
-			return NULL;
-		if (idelta == 0)
-			idelta = (tdays < 0) ? -1 : 1;
-		newy = y;
-		if (increment_overflow(&newy, idelta))
-			return NULL;
-		leapdays = leaps_thru_end_of(newy - 1) -
-			leaps_thru_end_of(y - 1);
-		tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
-		tdays -= leapdays;
-		y = newy;
-	}
-	{
-		register long	seconds;
-
-		seconds = tdays * SECSPERDAY + 0.5;
-		tdays = seconds / SECSPERDAY;
-		rem += seconds - tdays * SECSPERDAY;
-	}
-	/*
-	** Given the range, we can now fearlessly cast...
-	*/
-	idays = tdays;
-	rem += offset - corr;
-	while (rem < 0) {
-		rem += SECSPERDAY;
-		--idays;
-	}
-	while (rem >= SECSPERDAY) {
-		rem -= SECSPERDAY;
-		++idays;
-	}
-	while (idays < 0) {
-		if (increment_overflow(&y, -1))
-			return NULL;
-		idays += year_lengths[isleap(y)];
-	}
-	while (idays >= year_lengths[isleap(y)]) {
-		idays -= year_lengths[isleap(y)];
-		if (increment_overflow(&y, 1))
-			return NULL;
-	}
-	tmp->tm_year = y;
-	if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
-		return NULL;
-	tmp->tm_yday = idays;
-	/*
-	** The "extra" mods below avoid overflow problems.
-	*/
-	tmp->tm_wday = EPOCH_WDAY +
-		((y - EPOCH_YEAR) % DAYSPERWEEK) *
-		(DAYSPERNYEAR % DAYSPERWEEK) +
-		leaps_thru_end_of(y - 1) -
-		leaps_thru_end_of(EPOCH_YEAR - 1) +
-		idays;
-	tmp->tm_wday %= DAYSPERWEEK;
-	if (tmp->tm_wday < 0)
-		tmp->tm_wday += DAYSPERWEEK;
-	tmp->tm_hour = (int) (rem / SECSPERHOUR);
-	rem %= SECSPERHOUR;
-	tmp->tm_min = (int) (rem / SECSPERMIN);
-	/*
-	** A positive leap second requires a special
-	** representation. This uses "... ??:59:60" et seq.
-	*/
-	tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
-	ip = mon_lengths[isleap(y)];
-	for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
-		idays -= ip[tmp->tm_mon];
-	tmp->tm_mday = (int) (idays + 1);
-	tmp->tm_isdst = 0;
-#ifdef TM_GMTOFF
-	tmp->TM_GMTOFF = offset;
-#endif /* defined TM_GMTOFF */
-	return tmp;
-}
-
-// ============================================================================
-#if 0
-char *
-ctime(timep)
-const time_t * const	timep;
-{
-/*
-** Section 4.12.3.2 of X3.159-1989 requires that
-**	The ctime function converts the calendar time pointed to by timer
-**	to local time in the form of a string. It is equivalent to
-**		asctime(localtime(timer))
-*/
-	return asctime(localtime(timep));
-}
-#endif
-
-// ============================================================================
-#if 0
-char *
-ctime_r(timep, buf)
-const time_t * const	timep;
-char *			buf;
-{
-	struct tm	mytm;
-
-	return asctime_r(localtime_r(timep, &mytm), buf);
-}
-#endif
-
-/*
-** Adapted from code provided by Robert Elz, who writes:
-**	The "best" way to do mktime I think is based on an idea of Bob
-**	Kridle's (so its said...) from a long time ago.
-**	It does a binary search of the time_t space. Since time_t's are
-**	just 32 bits, its a max of 32 iterations (even at 64 bits it
-**	would still be very reasonable).
-*/
-
-#ifndef WRONG
-#define WRONG	(-1)
-#endif /* !defined WRONG */
-
-/*
-** Simplified normalize logic courtesy Paul Eggert.
-*/
-
-static int
-increment_overflow(number, delta)
-int *   number;
-int delta;
-{
-    unsigned  number0 = (unsigned)*number;
-    unsigned  number1 = (unsigned)(number0 + delta);
-
-    *number = (int)number1;
-
-    if (delta >= 0) {
-        return ((int)number1 < (int)number0);
-    } else {
-        return ((int)number1 > (int)number0);
-    }
-}
-
-static int
-long_increment_overflow(number, delta)
-long *  number;
-int delta;
-{
-    unsigned long  number0 = (unsigned long)*number;
-    unsigned long  number1 = (unsigned long)(number0 + delta);
-
-    *number = (long)number1;
-
-    if (delta >= 0) {
-        return ((long)number1 < (long)number0);
-    } else {
-        return ((long)number1 > (long)number0);
-    }
-}
-
-static int
-normalize_overflow(tensptr, unitsptr, base)
-int * const	tensptr;
-int * const	unitsptr;
-const int	base;
-{
-	register int	tensdelta;
-
-	tensdelta = (*unitsptr >= 0) ?
-		(*unitsptr / base) :
-		(-1 - (-1 - *unitsptr) / base);
-	*unitsptr -= tensdelta * base;
-	return increment_overflow(tensptr, tensdelta);
-}
-
-static int
-long_normalize_overflow(tensptr, unitsptr, base)
-long * const	tensptr;
-int * const	unitsptr;
-const int	base;
-{
-	register int	tensdelta;
-
-	tensdelta = (*unitsptr >= 0) ?
-		(*unitsptr / base) :
-		(-1 - (-1 - *unitsptr) / base);
-	*unitsptr -= tensdelta * base;
-	return long_increment_overflow(tensptr, tensdelta);
-}
-
-static int
-tmcomp(atmp, btmp)
-register const struct tm * const atmp;
-register const struct tm * const btmp;
-{
-	register int	result;
-
-	if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
-		(result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
-		(result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
-		(result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
-		(result = (atmp->tm_min - btmp->tm_min)) == 0)
-			result = atmp->tm_sec - btmp->tm_sec;
-	return result;
-}
-
-static time_t
-time2sub(tmp, funcp, offset, okayp, do_norm_secs, sp)
-struct tm * const	tmp;
-struct tm * (* const	funcp) P((const time_t*, long, struct tm*,const struct state *sp));
-const long		offset;
-int * const		okayp;
-const int		do_norm_secs;
-const struct state *	sp;
-{
-	register int			dir;
-	register int			i, j;
-	register int			saved_seconds;
-	register long			li;
-	register time_t			lo;
-	register time_t			hi;
-	long				y;
-	time_t				newt;
-	time_t				t;
-	struct tm			yourtm, mytm;
-
-	*okayp = FALSE;
-	yourtm = *tmp;
-	if (do_norm_secs) {
-		if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
-			SECSPERMIN))
-				return WRONG;
-	}
-	if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
-		return WRONG;
-	if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
-		return WRONG;
-	y = yourtm.tm_year;
-	if (long_normalize_overflow(&y, &yourtm.tm_mon, MONSPERYEAR))
-		return WRONG;
-	/*
-	** Turn y into an actual year number for now.
-	** It is converted back to an offset from TM_YEAR_BASE later.
-	*/
-	if (long_increment_overflow(&y, TM_YEAR_BASE))
-		return WRONG;
-	while (yourtm.tm_mday <= 0) {
-		if (long_increment_overflow(&y, -1))
-			return WRONG;
-		li = y + (1 < yourtm.tm_mon);
-		yourtm.tm_mday += year_lengths[isleap(li)];
-	}
-	while (yourtm.tm_mday > DAYSPERLYEAR) {
-		li = y + (1 < yourtm.tm_mon);
-		yourtm.tm_mday -= year_lengths[isleap(li)];
-		if (long_increment_overflow(&y, 1))
-			return WRONG;
-	}
-	for ( ; ; ) {
-		i = mon_lengths[isleap(y)][yourtm.tm_mon];
-		if (yourtm.tm_mday <= i)
-			break;
-		yourtm.tm_mday -= i;
-		if (++yourtm.tm_mon >= MONSPERYEAR) {
-			yourtm.tm_mon = 0;
-			if (long_increment_overflow(&y, 1))
-				return WRONG;
-		}
-	}
-	if (long_increment_overflow(&y, -TM_YEAR_BASE))
-		return WRONG;
-	yourtm.tm_year = y;
-	if (yourtm.tm_year != y)
-		return WRONG;
-	if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
-		saved_seconds = 0;
-	else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
-		/*
-		** We can't set tm_sec to 0, because that might push the
-		** time below the minimum representable time.
-		** Set tm_sec to 59 instead.
-		** This assumes that the minimum representable time is
-		** not in the same minute that a leap second was deleted from,
-		** which is a safer assumption than using 58 would be.
-		*/
-		if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
-			return WRONG;
-		saved_seconds = yourtm.tm_sec;
-		yourtm.tm_sec = SECSPERMIN - 1;
-	} else {
-		saved_seconds = yourtm.tm_sec;
-		yourtm.tm_sec = 0;
-	}
-	/*
-	** Do a binary search (this works whatever time_t's type is).
-	*/
-	if (!TYPE_SIGNED(time_t)) {
-		lo = 0;
-		hi = lo - 1;
-	} else if (!TYPE_INTEGRAL(time_t)) {
-		if (sizeof(time_t) > sizeof(float))
-			hi = (time_t) DBL_MAX;
-		else	hi = (time_t) FLT_MAX;
-		lo = -hi;
-	} else {
-		lo = 1;
-		for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i)
-			lo *= 2;
-		hi = -(lo + 1);
-	}
-	for ( ; ; ) {
-		t = lo / 2 + hi / 2;
-		if (t < lo)
-			t = lo;
-		else if (t > hi)
-			t = hi;
-		if ((*funcp)(&t, offset, &mytm, sp) == NULL) {
-			/*
-			** Assume that t is too extreme to be represented in
-			** a struct tm; arrange things so that it is less
-			** extreme on the next pass.
-			*/
-			dir = (t > 0) ? 1 : -1;
-		} else	dir = tmcomp(&mytm, &yourtm);
-		if (dir != 0) {
-			if (t == lo) {
-			        if (t == TIME_T_MAX)
-			             return WRONG;
-				++t;
-				++lo;
-			} else if (t == hi) {
-			        if (t == TIME_T_MIN)
-			             return WRONG;
-				--t;
-				--hi;
-			}
-			if (lo > hi)
-				return WRONG;
-			if (dir > 0)
-				hi = t;
-			else	lo = t;
-			continue;
-		}
-		if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
-			break;
-		/*
-		** Right time, wrong type.
-		** Hunt for right time, right type.
-		** It's okay to guess wrong since the guess
-		** gets checked.
-		*/
-		/*
-		** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
-		*/
-#ifdef ALL_STATE
-		if (sp == NULL)
-			return WRONG;
-#endif /* defined ALL_STATE */
-		for (i = sp->typecnt - 1; i >= 0; --i) {
-			if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
-				continue;
-			for (j = sp->typecnt - 1; j >= 0; --j) {
-				if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
-					continue;
-				newt = t + sp->ttis[j].tt_gmtoff -
-					sp->ttis[i].tt_gmtoff;
-				if ((*funcp)(&newt, offset, &mytm, sp) == NULL)
-					continue;
-				if (tmcomp(&mytm, &yourtm) != 0)
-					continue;
-				if (mytm.tm_isdst != yourtm.tm_isdst)
-					continue;
-				/*
-				** We have a match.
-				*/
-				t = newt;
-				goto label;
-			}
-		}
-		return WRONG;
-	}
-label:
-	newt = t + saved_seconds;
-	if ((newt < t) != (saved_seconds < 0))
-		return WRONG;
-	t = newt;
-	if ((*funcp)(&t, offset, tmp, sp))
-		*okayp = TRUE;
-	return t;
-}
-
-static time_t
-time2(tmp, funcp, offset, okayp, sp)
-struct tm * const	tmp;
-struct tm * (* const	funcp) P((const time_t*, long, struct tm*,
-            const struct state* sp));
-const long		offset;
-int * const		okayp;
-const struct state *	sp;
-{
-	time_t	t;
-
-	/*
-	** First try without normalization of seconds
-	** (in case tm_sec contains a value associated with a leap second).
-	** If that fails, try with normalization of seconds.
-	*/
-	t = time2sub(tmp, funcp, offset, okayp, FALSE, sp);
-	return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE, sp);
-}
-
-static time_t
-time1(tmp, funcp, offset, sp)
-struct tm * const	tmp;
-struct tm * (* const	funcp) P((const time_t *, long, struct tm *, const struct state* sp));
-const long		offset;
-const struct state *	sp;
-{
-	register time_t			t;
-	register int			samei, otheri;
-	register int			sameind, otherind;
-	register int			i;
-	register int			nseen;
-	int				seen[TZ_MAX_TYPES];
-	int				types[TZ_MAX_TYPES];
-	int				okay;
-
-	if (tmp->tm_isdst > 1)
-		tmp->tm_isdst = 1;
-	t = time2(tmp, funcp, offset, &okay, sp);
-#define PCTS 1
-#ifdef PCTS
-	/*
-	** PCTS code courtesy Grant Sullivan.
-	*/
-	if (okay)
-		return t;
-	if (tmp->tm_isdst < 0)
-		tmp->tm_isdst = 0;	/* reset to std and try again */
-#endif /* defined PCTS */
-#ifndef PCTS
-	if (okay || tmp->tm_isdst < 0)
-		return t;
-#endif /* !defined PCTS */
-	/*
-	** We're supposed to assume that somebody took a time of one type
-	** and did some math on it that yielded a "struct tm" that's bad.
-	** We try to divine the type they started from and adjust to the
-	** type they need.
-	*/
-	/*
-	** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
-	*/
-#ifdef ALL_STATE
-	if (sp == NULL)
-		return WRONG;
-#endif /* defined ALL_STATE */
-	for (i = 0; i < sp->typecnt; ++i)
-		seen[i] = FALSE;
-	nseen = 0;
-	for (i = sp->timecnt - 1; i >= 0; --i)
-		if (!seen[sp->types[i]]) {
-			seen[sp->types[i]] = TRUE;
-			types[nseen++] = sp->types[i];
-		}
-	for (sameind = 0; sameind < nseen; ++sameind) {
-		samei = types[sameind];
-		if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
-			continue;
-		for (otherind = 0; otherind < nseen; ++otherind) {
-			otheri = types[otherind];
-			if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
-				continue;
-			tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
-					sp->ttis[samei].tt_gmtoff;
-			tmp->tm_isdst = !tmp->tm_isdst;
-			t = time2(tmp, funcp, offset, &okay, sp);
-			if (okay)
-				return t;
-			tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
-					sp->ttis[samei].tt_gmtoff;
-			tmp->tm_isdst = !tmp->tm_isdst;
-		}
-	}
-	return WRONG;
-}
-
-// ============================================================================
-time_t
-mktime_tz(struct tm * const	tmp, char const * tz)
-{
-    struct state st;
-    if (tzload(tz, &st, TRUE) != 0) {
-        // not sure what's best here, but for now, we fall back to gmt
-        gmtload(&st);
-    }
-	return time1(tmp, localsub, 0L, &st);
-}
diff --git a/libnetutils/dhcp_utils.c b/libnetutils/dhcp_utils.c
index d0ca90a..b4caaf9 100644
--- a/libnetutils/dhcp_utils.c
+++ b/libnetutils/dhcp_utils.c
@@ -211,7 +211,7 @@
                  p2p_interface, DHCP_CONFIG_PATH, prop_value, interface);
     else
         snprintf(daemon_cmd, sizeof(daemon_cmd), "%s_%s:-f %s %s", DAEMON_NAME,
-                 DHCP_CONFIG_PATH, p2p_interface, interface);
+                 p2p_interface, DHCP_CONFIG_PATH, interface);
     memset(prop_value, '\0', PROPERTY_VALUE_MAX);
     property_set(ctrl_prop, daemon_cmd);
     if (wait_for_property(daemon_prop_name, desired_status, 10) < 0) {
diff --git a/rootdir/init.rc b/rootdir/init.rc
index a76602c..5205200 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -120,6 +120,12 @@
     write /dev/cpuctl/apps/bg_non_interactive/cpu.rt_runtime_us 700000
     write /dev/cpuctl/apps/bg_non_interactive/cpu.rt_period_us 1000000
 
+# qtaguid will limit access to specific data based on group memberships.
+#   net_bw_acct grants impersonation of socket owners.
+#   net_bw_stats grants access to other apps' detailed tagged-socket stats.
+    chown root net_bw_acct /proc/net/xt_qtaguid/ctrl
+    chown root net_bw_stats /proc/net/xt_qtaguid/stats
+
 # Allow everybody to read the xt_qtaguid resource tracking misc dev.
 # This is needed by any process that uses socket tagging.
     chmod 0644 /dev/xt_qtaguid