eclair snapshot
diff --git a/libc/Android.mk b/libc/Android.mk
index 59a4c6b..5718d18 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -288,6 +288,7 @@
 	arch-arm/bionic/clone.S \
 	arch-arm/bionic/ffs.S \
 	arch-arm/bionic/kill.S \
+	arch-arm/bionic/libgcc_compat.c \
 	arch-arm/bionic/tkill.S \
 	arch-arm/bionic/memcmp.S \
 	arch-arm/bionic/memcmp16.S \
@@ -366,6 +367,16 @@
 ifeq ($(TARGET_ARCH),arm)
   libc_common_cflags += -fstrict-aliasing
   libc_crt_target_cflags := -mthumb-interwork
+  #
+  # Define HAVE_ARM_TLS_REGISTER macro to indicate to the C library
+  # that it should access the hardware TLS register directly in
+  # private/bionic_tls.h
+  #
+  # The value must match your kernel configuration
+  #
+  ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true)
+    libc_common_cflags += -DHAVE_ARM_TLS_REGISTER
+  endif
 else # !arm
   ifeq ($(TARGET_ARCH),x86)
     libc_crt_target_cflags := -m32
diff --git a/libc/arch-arm/bionic/atomics_arm.S b/libc/arch-arm/bionic/atomics_arm.S
index b2da09f..f8b23e6 100644
--- a/libc/arch-arm/bionic/atomics_arm.S
+++ b/libc/arch-arm/bionic/atomics_arm.S
@@ -41,6 +41,8 @@
    .equ     kernel_cmpxchg, 0xFFFF0FC0
    .equ     kernel_atomic_base, 0xFFFF0FFF
 __atomic_dec:
+    .fnstart
+    .save {r4, lr}
     stmdb   sp!, {r4, lr}
     mov     r2, r0
 1: @ atomic_dec
@@ -53,8 +55,11 @@
     add     r0, r1, #1
     ldmia   sp!, {r4, lr}
     bx      lr
+    .fnend
 
 __atomic_inc:
+    .fnstart
+    .save {r4, lr}
     stmdb   sp!, {r4, lr}
     mov     r2, r0
 1: @ atomic_inc
@@ -67,9 +72,12 @@
     sub     r0, r1, #1
     ldmia   sp!, {r4, lr}
     bx      lr
+    .fnend
 
 /* r0(old) r1(new) r2(addr) -> r0(zero_if_succeeded) */
 __atomic_cmpxchg:
+    .fnstart
+    .save {r4, lr}
     stmdb   sp!, {r4, lr}
     mov     r4, r0          /* r4 = save oldvalue */
 1: @ atomic_cmpxchg
@@ -84,6 +92,7 @@
 2: @ atomic_cmpxchg
     ldmia   sp!, {r4, lr}
     bx      lr
+    .fnend
 #else
 #define KUSER_CMPXCHG 0xffffffc0
 
diff --git a/libc/arch-arm/bionic/libgcc_compat.c b/libc/arch-arm/bionic/libgcc_compat.c
new file mode 100644
index 0000000..886d025
--- /dev/null
+++ b/libc/arch-arm/bionic/libgcc_compat.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* This file contains dummy references to libgcc.a functions to force the
+ * dynamic linker to copy their definition into the final libc.so binary.
+ *
+ * They are required to ensure backwards binary compatibility with
+ * Android 1.5 and Android 1.6 system images. Some applications built
+ * using the NDK require them to be here.
+ *
+ * Now, for a more elaborate description of the issue:
+ *
+ * libgcc.a is a compiler-specific library containing various helper
+ * functions used to implement certain operations that are not necessarily
+ * supported by the target CPU. For example, integer division doesn't have a
+ * corresponding CPU instruction on ARMv5, and is instead implemented in the
+ * compiler-generated machine code as a call to an __idiv helper function.
+ *
+ * Normally, one has to place libgcc.a in the link command used to generate
+ * target binaries (shared libraries and executables) after all objects and
+ * static libraries, but before dependent shared libraries, i.e. something
+ * like:
+ *         gcc <options> -o libfoo.so  foo.a libgcc.a -lc -lm
+ *
+ * This ensures that any helper function needed by the code in foo.a is copied
+ * into the final libfoo.so. Unfortunately, the Android build system has been
+ * using this instead:
+ *
+ *         gcc <options> -o libfoo.so foo.a -lc -lm libgcc.a
+ *
+ * The problem with this is that if one helper function needed by foo.a has
+ * already been copied into libc.so or libm.so, then nothing will be copied
+ * into libfoo.so. Instead, a symbol import definition will be added to it
+ * so libfoo.so can directly call the one in libc.so at runtime.
+ *
+ * When changing toolchains for 2.0, the set of helper functions copied to
+ * libc.so changed, which resulted in some native shared libraries generated
+ * with the NDK to fail to load properly.
+ *
+ * The NDK has been fixed after 1.6_r1 to use the correct link command, so
+ * any native shared library generated with it should now be safe from that
+ * problem. On the other hand, existing shared libraries distributed with
+ * applications that were generated with a previous version of the NDK
+ * still need all 1.5/1.6 helper functions in libc.so and libn.so
+ *
+ * Final note: some of the functions below should really be in libm.so to
+ *             completely reflect the state of 1.5/1.6 system images. However,
+ *             since libm.so depends on libc.so, it's easier to put all of
+ *             these in libc.so instead, since the dynamic linker will always
+ *             search in libc.so before libm.so for dependencies.
+ */
+
+#define   COMPAT_FUNCTIONS_LIST \
+    XX(__adddf3)             \
+    XX(__addsf3)             \
+    XX(__aeabi_cdcmpeq)      \
+    XX(__aeabi_cdcmple)      \
+    XX(__aeabi_cdrcmple)     \
+    XX(__aeabi_d2f)          \
+    XX(__aeabi_d2iz)         \
+    XX(__aeabi_dadd)         \
+    XX(__aeabi_dcmpeq)       \
+    XX(__aeabi_dcmpge)       \
+    XX(__aeabi_dcmpgt)       \
+    XX(__aeabi_dcmple)       \
+    XX(__aeabi_dcmplt)       \
+    XX(__aeabi_dcmpun)       \
+    XX(__aeabi_ddiv)         \
+    XX(__aeabi_dmul)         \
+    XX(__aeabi_drsub)        \
+    XX(__aeabi_dsub)         \
+    XX(__aeabi_f2d)          \
+    XX(__aeabi_f2iz)         \
+    XX(__aeabi_fadd)         \
+    XX(__aeabi_fcmpun)       \
+    XX(__aeabi_fdiv)         \
+    XX(__aeabi_fmul)         \
+    XX(__aeabi_frsub)        \
+    XX(__aeabi_fsub)         \
+    XX(__aeabi_i2d)          \
+    XX(__aeabi_i2f)          \
+    XX(__aeabi_l2d)          \
+    XX(__aeabi_l2f)          \
+    XX(__aeabi_lmul)         \
+    XX(__aeabi_ui2d)         \
+    XX(__aeabi_ui2f)         \
+    XX(__aeabi_ul2d)         \
+    XX(__aeabi_ul2f)         \
+    XX(__cmpdf2)             \
+    XX(__divdf3)             \
+    XX(__divsf3)             \
+    XX(__eqdf2)             \
+    XX(__extendsfdf2)        \
+    XX(__fixdfsi)            \
+    XX(__fixsfsi)            \
+    XX(__floatdidf)          \
+    XX(__floatdisf)          \
+    XX(__floatsidf)          \
+    XX(__floatsisf)          \
+    XX(__floatundidf)        \
+    XX(__floatundisf)        \
+    XX(__floatunsidf)        \
+    XX(__floatunsisf)        \
+    XX(__gedf2)              \
+    XX(__gtdf2)              \
+    XX(__ledf2)              \
+    XX(__ltdf2)              \
+    XX(__muldf3)             \
+    XX(__muldi3)             \
+    XX(__mulsf3)             \
+    XX(__nedf2)              \
+    XX(__subdf3)             \
+    XX(__subsf3)             \
+    XX(__truncdfsf2)         \
+    XX(__unorddf2)           \
+    XX(__unordsf2)           \
+
+#define  XX(f)    extern void f(void);
+COMPAT_FUNCTIONS_LIST
+#undef XX
+
+void  __bionic_libgcc_compat_hooks(void)
+{
+#define XX(f)    f();
+COMPAT_FUNCTIONS_LIST
+#undef XX
+}
diff --git a/libc/arch-arm/bionic/memcmp.S b/libc/arch-arm/bionic/memcmp.S
index f45b56b..67dcddc 100644
--- a/libc/arch-arm/bionic/memcmp.S
+++ b/libc/arch-arm/bionic/memcmp.S
@@ -44,6 +44,7 @@
  */
 
 memcmp:
+        .fnstart
         PLD         (r0, #0)
         PLD         (r1, #0)
 
@@ -53,6 +54,7 @@
         moveq       r0, #0
         bxeq        lr
 
+        .save {r4, lr}
         /* save registers */
         stmfd       sp!, {r4, lr}
         
@@ -174,6 +176,7 @@
 9:      /* restore registers and return */
         ldmfd       sp!, {r4, lr}
         bx          lr
+        .fnend
 
 
 
diff --git a/libc/arch-arm/bionic/memcmp16.S b/libc/arch-arm/bionic/memcmp16.S
index 38d8b62..f398588 100644
--- a/libc/arch-arm/bionic/memcmp16.S
+++ b/libc/arch-arm/bionic/memcmp16.S
@@ -44,6 +44,7 @@
  */
 
 __memcmp16:
+        .fnstart
         PLD         (r0, #0)
         PLD         (r1, #0)
 
@@ -79,6 +80,7 @@
         bx          lr
 
 
+        .save {r4, lr}
         /* save registers */
 0:      stmfd       sp!, {r4, lr}
         
@@ -93,6 +95,7 @@
         /* restore registers and return */
         ldmnefd     sp!, {r4, lr}
         bxne        lr
+        .fnend
 
 
 
diff --git a/libc/arch-arm/bionic/memcpy.S b/libc/arch-arm/bionic/memcpy.S
index fcb58cd..024d885 100644
--- a/libc/arch-arm/bionic/memcpy.S
+++ b/libc/arch-arm/bionic/memcpy.S
@@ -28,6 +28,127 @@
 
 #include <machine/cpu-features.h>
 
+#if __ARM_ARCH__ == 7 || defined(__ARM_NEON__)
+
+        .text
+        .fpu    neon
+
+        .global memcpy
+        .type memcpy, %function
+        .align 4
+
+/* a prefetch distance of 4 cache-lines works best experimentally */
+#define CACHE_LINE_SIZE     64
+#define PREFETCH_DISTANCE   (CACHE_LINE_SIZE*4)
+
+memcpy:
+        .fnstart
+        .save       {r0, lr}
+        stmfd       sp!, {r0, lr}
+
+        /* start preloading as early as possible */
+        pld         [r1, #(CACHE_LINE_SIZE*0)]
+        pld         [r1, #(CACHE_LINE_SIZE*1)]
+
+        /* do we have at least 16-bytes to copy (needed for alignment below) */
+        cmp         r2, #16
+        blo         5f
+
+        /* align destination to half cache-line for the write-buffer */
+        rsb         r3, r0, #0
+        ands        r3, r3, #0xF
+        beq         0f
+
+        /* copy up to 15-bytes (count in r3) */
+        sub         r2, r2, r3
+        movs        ip, r3, lsl #31
+        ldrmib      lr, [r1], #1
+        strmib      lr, [r0], #1
+        ldrcsb      ip, [r1], #1
+        ldrcsb      lr, [r1], #1
+        strcsb      ip, [r0], #1
+        strcsb      lr, [r0], #1
+        movs        ip, r3, lsl #29
+        bge         1f
+        // copies 4 bytes, destination 32-bits aligned
+        vld4.8      {d0[0], d1[0], d2[0], d3[0]}, [r1]!
+        vst4.8      {d0[0], d1[0], d2[0], d3[0]}, [r0, :32]!
+1:      bcc         2f
+        // copies 8 bytes, destination 64-bits aligned
+        vld1.8      {d0}, [r1]!
+        vst1.8      {d0}, [r0, :64]!
+2:
+
+0:      /* preload immediately the next cache line, which we may need */
+        pld         [r1, #(CACHE_LINE_SIZE*0)]
+        pld         [r1, #(CACHE_LINE_SIZE*1)]
+
+        /* make sure we have at least 64 bytes to copy */
+        subs        r2, r2, #64
+        blo         2f
+
+        /* preload all the cache lines we need.
+         * NOTE: the number of pld below depends on PREFETCH_DISTANCE,
+         * ideally would would increase the distance in the main loop to
+         * avoid the goofy code below. In practice this doesn't seem to make
+         * a big difference.
+         */
+        pld         [r1, #(CACHE_LINE_SIZE*2)]
+        pld         [r1, #(CACHE_LINE_SIZE*3)]
+        pld         [r1, #(PREFETCH_DISTANCE)]
+
+1:      /* The main loop copies 64 bytes at a time */
+        vld1.8      {d0  - d3},   [r1]!
+        vld1.8      {d4  - d7},   [r1]!
+        pld         [r1, #(PREFETCH_DISTANCE)]
+        subs        r2, r2, #64
+        vst1.8      {d0  - d3},   [r0, :128]!
+        vst1.8      {d4  - d7},   [r0, :128]!
+        bhs         1b
+
+2:      /* fix-up the remaining count and make sure we have >= 32 bytes left */
+        add         r2, r2, #64
+        subs        r2, r2, #32
+        blo         4f
+
+3:      /* 32 bytes at a time. These cache lines were already preloaded */
+        vld1.8      {d0 - d3},  [r1]!
+        subs        r2, r2, #32
+        vst1.8      {d0 - d3},  [r0, :128]!
+        bhs         3b
+
+4:      /* less than 32 left */
+        add         r2, r2, #32
+        tst         r2, #0x10
+        beq         5f
+        // copies 16 bytes, 128-bits aligned
+        vld1.8      {d0, d1}, [r1]!
+        vst1.8      {d0, d1}, [r0, :128]!
+
+5:      /* copy up to 15-bytes (count in r2) */
+        movs        ip, r2, lsl #29
+        bcc         1f
+        vld1.8      {d0}, [r1]!
+        vst1.8      {d0}, [r0]!
+1:      bge         2f
+        vld4.8      {d0[0], d1[0], d2[0], d3[0]}, [r1]!
+        vst4.8      {d0[0], d1[0], d2[0], d3[0]}, [r0]!
+2:      movs        ip, r2, lsl #31
+        ldrmib      r3, [r1], #1
+        ldrcsb      ip, [r1], #1
+        ldrcsb      lr, [r1], #1
+        strmib      r3, [r0], #1
+        strcsb      ip, [r0], #1
+        strcsb      lr, [r0], #1
+
+        ldmfd       sp!, {r0, lr}
+        bx          lr
+        .fnend
+
+
+#else   /* __ARM_ARCH__ < 7 */
+
+
 	.text
 
     .global memcpy
@@ -40,9 +161,9 @@
 		 * note that memcpy() always returns the destination pointer,
 		 * so we have to preserve R0.
 		 */
-	
-memcpy:	
-		/* The stack must always be 64-bits aligned to be compliant with the 
+
+memcpy:
+		/* The stack must always be 64-bits aligned to be compliant with the
 		 * ARM ABI. Since we have to save R0, we might as well save R4
 		 * which we can use for better pipelining of the reads below
 		 */
@@ -82,10 +203,10 @@
         strmib		r3, [r0], #1
 		strcsb		r4, [r0], #1
 		strcsb		r12,[r0], #1
-		
+
 src_aligned:
 
-		/* see if src and dst are aligned together (congruent) */	
+		/* see if src and dst are aligned together (congruent) */
 		eor			r12, r0, r1
 		tst			r12, #3
 		bne			non_congruent
@@ -103,7 +224,7 @@
 		andhi		r3, r2, #0x1C
 
 		/* conditionnaly copies 0 to 7 words (length in r3) */
-		movs		r12, r3, lsl #28 
+		movs		r12, r3, lsl #28
 		ldmcsia		r1!, {r4, r5, r6, r7}	/* 16 bytes */
 		ldmmiia		r1!, {r8, r9}			/*  8 bytes */
 		stmcsia		r0!, {r4, r5, r6, r7}
@@ -124,7 +245,7 @@
 
         /*
          * We preload a cache-line up to 64 bytes ahead. On the 926, this will
-         * stall only until the requested world is fetched, but the linefill 
+         * stall only until the requested world is fetched, but the linefill
          * continues in the the background.
          * While the linefill is going, we write our previous cache-line
          * into the write-buffer (which should have some free space).
@@ -150,19 +271,19 @@
 
         // NOTE: if r12 is more than 64 ahead of r1, the following ldrhi
         // for ARM9 preload will not be safely guarded by the preceding subs.
-        // When it is safely guarded the only possibility to have SIGSEGV here 
+        // When it is safely guarded the only possibility to have SIGSEGV here
         // is because the caller overstates the length.
         ldrhi       r3, [r12], #32      /* cheap ARM9 preload */
         stmia       r0!, { r4-r11 }
 		bhs         1b
-		
+
         add         r2, r2, #32
 
 
 
 
 less_than_32_left:
-		/* 
+		/*
 		 * less than 32 bytes left at this point (length in r2)
 		 */
 
@@ -174,7 +295,7 @@
 		beq			1f
 
 		/* conditionnaly copies 0 to 31 bytes */
-		movs		r12, r2, lsl #28 
+		movs		r12, r2, lsl #28
 		ldmcsia		r1!, {r4, r5, r6, r7}	/* 16 bytes */
 		ldmmiia		r1!, {r8, r9}			/*  8 bytes */
 		stmcsia		r0!, {r4, r5, r6, r7}
@@ -182,7 +303,7 @@
 		movs		r12, r2, lsl #30
 		ldrcs		r3, [r1], #4			/*  4 bytes */
 		ldrmih		r4, [r1], #2			/*  2 bytes */
-		strcs		r3, [r0], #4		
+		strcs		r3, [r0], #4
 		strmih		r4, [r0], #2
 		tst         r2, #0x1
 		ldrneb		r3, [r1]				/*  last byte  */
@@ -200,34 +321,34 @@
 		 * here source is aligned to 4 bytes
 		 * but destination is not.
 		 *
-		 * in the code below r2 is the number of bytes read 
+		 * in the code below r2 is the number of bytes read
 		 * (the number of bytes written is always smaller, because we have
 		 * partial words in the shift queue)
 		 */
 		cmp			r2, #4
 		blo			copy_last_3_and_return
-		
+
         /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
          * frame. Don't update sp.
          */
         stmea		sp, {r5-r11}
-		
+
 		/* compute shifts needed to align src to dest */
 		rsb			r5, r0, #0
 		and			r5, r5, #3			/* r5 = # bytes in partial words */
-		mov			r12, r5, lsl #3		/* r12 = right */ 
+		mov			r12, r5, lsl #3		/* r12 = right */
 		rsb			lr, r12, #32		/* lr = left  */
-		
+
 		/* read the first word */
 		ldr			r3, [r1], #4
 		sub			r2, r2, #4
-		
+
 		/* write a partial word (0 to 3 bytes), such that destination
 		 * becomes aligned to 32 bits (r5 = nb of words to copy for alignment)
 		 */
 		movs		r5, r5, lsl #31
 		strmib		r3, [r0], #1
-		movmi		r3, r3, lsr #8		
+		movmi		r3, r3, lsr #8
 		strcsb		r3, [r0], #1
 		movcs		r3, r3, lsr #8
 		strcsb		r3, [r0], #1
@@ -235,7 +356,7 @@
 
 		cmp			r2, #4
 		blo			partial_word_tail
-		
+
 		/* Align destination to 32 bytes (cache line boundary) */
 1:		tst			r0, #0x1c
 		beq			2f
@@ -366,7 +487,7 @@
 		strcsb		r3, [r0], #1
 		movcs		r3, r3, lsr #8
 		strcsb		r3, [r0], #1
-		
+
 		/* Refill spilled registers from the stack. Don't update sp. */
 		ldmfd		sp, {r5-r11}
 
@@ -385,3 +506,5 @@
 		bx			lr
         .fnend
 
+
+#endif    /* __ARM_ARCH__ < 7 */
diff --git a/libc/arch-arm/bionic/memset.S b/libc/arch-arm/bionic/memset.S
index d52d622..93abe15 100644
--- a/libc/arch-arm/bionic/memset.S
+++ b/libc/arch-arm/bionic/memset.S
@@ -80,7 +80,7 @@
         
 		rsb         r3, r0, #0
 		ands		r3, r3, #0x1C
-		beq         aligned32
+		beq         3f
 		cmp         r3, r2
 		andhi		r3, r2, #0x1C
 		sub         r2, r2, r3
@@ -93,7 +93,7 @@
 		movs		r3, r3, lsl #2
         strcs       r1, [r0], #4
 
-aligned32:
+3:
         subs        r2, r2, #32
         mov         r3, r1
         bmi         2f
diff --git a/libc/arch-arm/include/machine/cpu-features.h b/libc/arch-arm/include/machine/cpu-features.h
index f836006..925067e 100644
--- a/libc/arch-arm/include/machine/cpu-features.h
+++ b/libc/arch-arm/include/machine/cpu-features.h
@@ -149,7 +149,6 @@
 #  define __ARM_HAVE_PC_INTERWORK
 #endif
 
-
 /* Assembly-only macros */
 
 /* define a handy PLD(address) macro since the cache preload
diff --git a/libc/bionic/dlmalloc.c b/libc/bionic/dlmalloc.c
index 78f20c0..f6f878e 100644
--- a/libc/bionic/dlmalloc.c
+++ b/libc/bionic/dlmalloc.c
@@ -1154,6 +1154,23 @@
 */
 void* mspace_realloc(mspace msp, void* mem, size_t newsize);
 
+#if ANDROID /* Added for Android, not part of dlmalloc as released */
+/*
+  mspace_merge_objects will merge allocated memory mema and memb
+  together, provided memb immediately follows mema.  It is roughly as
+  if memb has been freed and mema has been realloced to a larger size.
+  On successfully merging, mema will be returned. If either argument
+  is null or memb does not immediately follow mema, null will be
+  returned.
+
+  Both mema and memb should have been previously allocated using
+  malloc or a related routine such as realloc. If either mema or memb
+  was not malloced or was previously freed, the result is undefined,
+  but like mspace_free, the default is to abort the program.
+*/
+void* mspace_merge_objects(mspace msp, void* mema, void* memb);
+#endif
+
 /*
   mspace_calloc behaves as calloc, but operates within
   the given space.
@@ -4872,6 +4889,62 @@
   }
 }
 
+#if ANDROID
+void* mspace_merge_objects(mspace msp, void* mema, void* memb)
+{
+  /* PREACTION/POSTACTION aren't necessary because we are only
+     modifying fields of inuse chunks owned by the current thread, in
+     which case no other malloc operations can touch them.
+   */
+  if (mema == NULL || memb == NULL) {
+    return NULL;
+  }
+  mchunkptr pa = mem2chunk(mema);
+  mchunkptr pb = mem2chunk(memb);
+
+#if FOOTERS
+  mstate fm = get_mstate_for(pa);
+#else /* FOOTERS */
+  mstate fm = (mstate)msp;
+#endif /* FOOTERS */
+  if (!ok_magic(fm)) {
+    USAGE_ERROR_ACTION(fm, pa);
+    return NULL;
+  }
+  check_inuse_chunk(fm, pa);
+  if (RTCHECK(ok_address(fm, pa) && ok_cinuse(pa))) {
+    if (next_chunk(pa) != pb) {
+      /* Since pb may not be in fm, we can't check ok_address(fm, pb);
+         since ok_cinuse(pb) would be unsafe before an address check,
+         return NULL rather than invoke USAGE_ERROR_ACTION if pb is not
+         in use or is a bogus address.
+       */
+      return NULL;
+    }
+    /* Since b follows a, they share the mspace. */
+#if FOOTERS
+    assert(fm == get_mstate_for(pb));
+#endif /* FOOTERS */
+    check_inuse_chunk(fm, pb);
+    if (RTCHECK(ok_address(fm, pb) && ok_cinuse(pb))) {
+      size_t sz = chunksize(pb);
+      pa->head += sz;
+      /* Make sure pa still passes. */
+      check_inuse_chunk(fm, pa);
+      return mema;
+    }
+    else {
+      USAGE_ERROR_ACTION(fm, pb);
+      return NULL;
+    }
+  }
+  else {
+    USAGE_ERROR_ACTION(fm, pa);
+    return NULL;
+  }
+}
+#endif /* ANDROID */
+
 void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) {
   mstate ms = (mstate)msp;
   if (!ok_magic(ms)) {
diff --git a/libc/bionic/dlmalloc.h b/libc/bionic/dlmalloc.h
index 75b5e1f..e5f7d4a 100644
--- a/libc/bionic/dlmalloc.h
+++ b/libc/bionic/dlmalloc.h
@@ -547,6 +547,21 @@
 void* mspace_realloc(mspace msp, void* mem, size_t newsize);
 
 /*
+  mspace_merge_objects will merge allocated memory mema and memb
+  together, provided memb immediately follows mema.  It is roughly as
+  if memb has been freed and mema has been realloced to a larger size.
+  On successfully merging, mema will be returned. If either argument
+  is null or memb does not immediately follow mema, null will be
+  returned.
+
+  Both mema and memb should have been previously allocated using
+  malloc or a related routine such as realloc. If either mema or memb
+  was not malloced or was previously freed, the result is undefined,
+  but like mspace_free, the default is to abort the program.
+*/
+void* mspace_merge_objects(mspace msp, void* mema, void* memb);
+
+/*
   mspace_calloc behaves as calloc, but operates within
   the given space.
 */
diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c
index ec3c459..42f5f4c 100644
--- a/libc/bionic/pthread.c
+++ b/libc/bionic/pthread.c
@@ -441,7 +441,7 @@
 
 int pthread_attr_getstackaddr(pthread_attr_t const * attr, void ** stack_addr)
 {
-    *stack_addr = attr->stack_base + attr->stack_size;
+    *stack_addr = (char*)attr->stack_base + attr->stack_size;
     return 0;
 }
 
@@ -789,7 +789,18 @@
     if (!attr)
         return EINVAL;
 
-    return (pshared == PTHREAD_PROCESS_PRIVATE) ? 0 : ENOTSUP;
+    switch (pshared) {
+    case PTHREAD_PROCESS_PRIVATE:
+    case PTHREAD_PROCESS_SHARED:
+        /* our current implementation of pthread actually supports shared
+         * mutexes but won't cleanup if a process dies with the mutex held.
+         * Nevertheless, it's better than nothing. Shared mutexes are used
+         * by surfaceflinger and audioflinger.
+         */
+        return 0;
+    }
+
+    return ENOTSUP;
 }
 
 int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared)
@@ -1114,6 +1125,135 @@
 }
 
 
+/* initialize 'ts' with the difference between 'abstime' and the current time
+ * according to 'clock'. Returns -1 if abstime already expired, or 0 otherwise.
+ */
+static int
+__timespec_to_absolute(struct timespec*  ts, const struct timespec*  abstime, clockid_t  clock)
+{
+    clock_gettime(clock, ts);
+    ts->tv_sec  = abstime->tv_sec - ts->tv_sec;
+    ts->tv_nsec = abstime->tv_nsec - ts->tv_nsec;
+    if (ts->tv_nsec < 0) {
+        ts->tv_sec--;
+        ts->tv_nsec += 1000000000;
+    }
+    if ((ts->tv_nsec < 0) || (ts->tv_sec < 0))
+        return -1;
+
+    return 0;
+}
+
+/* initialize 'abstime' to the current time according to 'clock' plus 'msecs'
+ * milliseconds.
+ */
+static void
+__timespec_to_relative_msec(struct timespec*  abstime, unsigned  msecs, clockid_t  clock)
+{
+    clock_gettime(clock, abstime);
+    abstime->tv_sec  += msecs/1000;
+    abstime->tv_nsec += (msecs%1000)*1000000;
+    if (abstime->tv_nsec >= 1000000000) {
+        abstime->tv_sec++;
+        abstime->tv_nsec -= 1000000000;
+    }
+}
+
+int pthread_mutex_lock_timeout_np(pthread_mutex_t *mutex, unsigned msecs)
+{
+    clockid_t        clock = CLOCK_MONOTONIC;
+    struct timespec  abstime;
+    struct timespec  ts;
+
+    /* compute absolute expiration time */
+    __timespec_to_relative_msec(&abstime, msecs, clock);
+
+    if (__likely(mutex != NULL))
+    {
+        int  mtype = (mutex->value & MUTEX_TYPE_MASK);
+
+        if ( __likely(mtype == MUTEX_TYPE_NORMAL) )
+        {
+            /* fast path for unconteded lock */
+            if (__atomic_cmpxchg(0, 1, &mutex->value) == 0)
+                return 0;
+
+            /* loop while needed */
+            while (__atomic_swap(2, &mutex->value) != 0) {
+                if (__timespec_to_absolute(&ts, &abstime, clock) < 0)
+                    return EBUSY;
+
+                __futex_wait(&mutex->value, 2, &ts);
+            }
+            return 0;
+        }
+        else
+        {
+            int  tid = __get_thread()->kernel_id;
+            int  oldv;
+
+            if ( tid == MUTEX_OWNER(mutex) )
+            {
+                int  oldv, counter;
+
+                if (mtype == MUTEX_TYPE_ERRORCHECK) {
+                    /* already locked by ourselves */
+                    return EDEADLK;
+                }
+
+                _recursive_lock();
+                oldv = mutex->value;
+                counter = (oldv + (1 << MUTEX_COUNTER_SHIFT)) & MUTEX_COUNTER_MASK;
+                mutex->value = (oldv & ~MUTEX_COUNTER_MASK) | counter;
+                _recursive_unlock();
+                return 0;
+            }
+            else
+            {
+                /*
+                 * If the new lock is available immediately, we grab it in
+                 * the "uncontended" state.
+                 */
+                int new_lock_type = 1;
+
+                for (;;) {
+                    int  oldv;
+                    struct timespec  ts;
+
+                    _recursive_lock();
+                    oldv = mutex->value;
+                    if (oldv == mtype) { /* uncontended released lock => 1 or 2 */
+                        mutex->value = ((tid << 16) | mtype | new_lock_type);
+                    } else if ((oldv & 3) == 1) { /* locked state 1 => state 2 */
+                        oldv ^= 3;
+                        mutex->value = oldv;
+                    }
+                    _recursive_unlock();
+
+                    if (oldv == mtype)
+                        break;
+
+                    /*
+                     * The lock was held, possibly contended by others.  From
+                     * now on, if we manage to acquire the lock, we have to
+                     * assume that others are still contending for it so that
+                     * we'll wake them when we unlock it.
+                     */
+                    new_lock_type = 2;
+
+                    if (__timespec_to_absolute(&ts, &abstime, clock) < 0)
+                        return EBUSY;
+
+                    __futex_wait( &mutex->value, oldv, &ts );
+                }
+                return 0;
+            }
+        }
+    }
+    return EINVAL;
+}
+
+
 /* XXX *technically* there is a race condition that could allow
  * XXX a signal to be missed.  If thread A is preempted in _wait()
  * XXX after unlocking the mutex and before waiting, and if other
@@ -1178,16 +1318,8 @@
     struct timespec * tsp;
 
     if (abstime != NULL) {
-        clock_gettime(clock, &ts);
-        ts.tv_sec = abstime->tv_sec - ts.tv_sec;
-        ts.tv_nsec = abstime->tv_nsec - ts.tv_nsec;
-        if (ts.tv_nsec < 0) {
-            ts.tv_sec--;
-            ts.tv_nsec += 1000000000;
-        }
-        if((ts.tv_nsec < 0) || (ts.tv_sec < 0)) {
+        if (__timespec_to_absolute(&ts, abstime, clock) < 0)
             return ETIMEDOUT;
-        }
         tsp = &ts;
     } else {
         tsp = NULL;
@@ -1204,6 +1336,7 @@
 }
 
 
+/* this one exists only for backward binary compatibility */
 int pthread_cond_timedwait_monotonic(pthread_cond_t *cond,
                                      pthread_mutex_t * mutex,
                                      const struct timespec *abstime)
@@ -1211,6 +1344,20 @@
     return __pthread_cond_timedwait(cond, mutex, abstime, CLOCK_MONOTONIC);
 }
 
+int pthread_cond_timedwait_monotonic_np(pthread_cond_t *cond,
+                                     pthread_mutex_t * mutex,
+                                     const struct timespec *abstime)
+{
+    return __pthread_cond_timedwait(cond, mutex, abstime, CLOCK_MONOTONIC);
+}
+
+int pthread_cond_timedwait_relative_np(pthread_cond_t *cond,
+                                      pthread_mutex_t * mutex,
+                                      const struct timespec *reltime)
+{
+    return __pthread_cond_timedwait_relative(cond, mutex, reltime);
+}
+
 int pthread_cond_timeout_np(pthread_cond_t *cond,
                             pthread_mutex_t * mutex,
                             unsigned msecs)
diff --git a/libc/docs/OVERVIEW.TXT b/libc/docs/OVERVIEW.TXT
index 4c153b1..753e48a 100644
--- a/libc/docs/OVERVIEW.TXT
+++ b/libc/docs/OVERVIEW.TXT
@@ -63,6 +63,18 @@
   Instead, Bionic provides a <time64.h> header that defines a time64_t type,
   and related functions like mktime64(), localtime64(), etc...
 
+  strftime() uses time64_t internally, so the '%s' format (seconds since the
+  epoch) is supported for dates >= 2038.
+
+
+strftime_tz():
+
+  Bionic also provides the non-standard strftime_tz() function, a variant
+  of strftime() which also accepts a time locale descriptor as defined
+  by "struct strftime_locale" in <time.h>.
+
+  This function is used by the low-level framework code in Android.
+
 
 Timezone management:
 
diff --git a/libc/include/arpa/inet.h b/libc/include/arpa/inet.h
index 3ebb872..e78e7c5 100644
--- a/libc/include/arpa/inet.h
+++ b/libc/include/arpa/inet.h
@@ -31,7 +31,6 @@
 #include <stdint.h>
 #include <sys/types.h>
 #include <netinet/in.h>
-#include <netinet/in6.h>
 
 __BEGIN_DECLS
 
diff --git a/libc/include/netinet/in.h b/libc/include/netinet/in.h
index 77ae506..0ebd926 100644
--- a/libc/include/netinet/in.h
+++ b/libc/include/netinet/in.h
@@ -32,6 +32,7 @@
 #include <linux/socket.h>
 #include <linux/in.h>
 #include <linux/in6.h>
+#include <netinet/in6.h>
 
 __BEGIN_DECLS
 
@@ -39,6 +40,9 @@
 
 extern int bindresvport (int sd, struct sockaddr_in *sin);
 
+static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
+static const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
+
 __END_DECLS
 
 #endif /* _NETINET_IN_H_ */
diff --git a/libc/include/netinet/in6.h b/libc/include/netinet/in6.h
index e645c48..2f5fee1 100644
--- a/libc/include/netinet/in6.h
+++ b/libc/include/netinet/in6.h
@@ -90,4 +90,12 @@
 
 #define INET6_ADDRSTRLEN 46
 
+#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
+#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
+
+#define IN6ADDR_ANY_INIT {{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}
+
+#define ipv6mr_interface ipv6mr_ifindex
+
+
 #endif /* _NETINET_IN6_H */
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index e3afdae..6603b3f 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -179,14 +179,41 @@
  *         to the CLOCK_MONOTONIC clock instead, to avoid any problems when
  *         the wall-clock time is changed brutally
  */
+int pthread_cond_timedwait_monotonic_np(pthread_cond_t         *cond,
+                                        pthread_mutex_t        *mutex,
+                                        const struct timespec  *abstime);
+
+/* BIONIC: DEPRECATED. same as pthread_cond_timedwait_monotonic_np()
+ * unfortunately pthread_cond_timedwait_monotonic has shipped already
+ */
 int pthread_cond_timedwait_monotonic(pthread_cond_t         *cond,
                                      pthread_mutex_t        *mutex,
                                      const struct timespec  *abstime);
 
+#define HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC 1
+
+/* BIONIC: same as pthread_cond_timedwait, except the 'reltime' given refers
+ *         is relative to the current time.
+ */
+int pthread_cond_timedwait_relative_np(pthread_cond_t         *cond,
+                                     pthread_mutex_t        *mutex,
+                                     const struct timespec  *reltime);
+
+#define HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE 1
+
+
+
 int pthread_cond_timeout_np(pthread_cond_t *cond,
                             pthread_mutex_t * mutex,
                             unsigned msecs);
 
+/* same as pthread_mutex_lock(), but will wait up to 'msecs' milli-seconds
+ * before returning. same return values than pthread_mutex_trylock though, i.e.
+ * returns EBUSY if the lock could not be acquired after the timeout
+ * expired.
+ */
+int pthread_mutex_lock_timeout_np(pthread_mutex_t *mutex, unsigned msecs);
+
 int pthread_key_create(pthread_key_t *key, void (*destructor_function)(void *));
 int pthread_key_delete (pthread_key_t);
 int pthread_setspecific(pthread_key_t key, const void *value);
diff --git a/libc/include/time.h b/libc/include/time.h
index 35c2358..5d1a0e2 100644
--- a/libc/include/time.h
+++ b/libc/include/time.h
@@ -79,9 +79,29 @@
 extern char*       strptime(const char *buf, const char *fmt, struct tm *tm);
 extern size_t      strftime(char *s, size_t max, const char *format, const struct tm *tm);
 
+/* ANDROID-BEGIN */
+struct strftime_locale {
+    const char *  mon[12];
+    const char *  month[12];
+    const char *  standalone_month[12];
+    const char *  wday[7];
+    const char *  weekday[7];
+    const char *  X_fmt;
+    const char *  x_fmt;
+    const char *  c_fmt;
+    const char *  am;
+    const char *  pm;
+    const char *  date_fmt;
+};
+
+extern size_t      strftime_tz(char *s, size_t max, const char *format, const struct tm *tm, const struct strftime_locale*  lc);
+/* ANDROID-END */
+
 extern char *ctime(const time_t *timep);
 extern char *ctime_r(const time_t *timep, char *buf);
 
+extern void  tzset(void);
+
 /* global includes */
 extern char*     tzname[];
 extern int       daylight;
@@ -89,7 +109,7 @@
 
 #define CLOCKS_PER_SEC     1000000
 
-extern clock_t   clock();
+extern clock_t   clock(void);
 
 /* BIONIC: extra linux clock goodies */
 extern int clock_getres(int, struct timespec *);
diff --git a/libc/kernel/common/linux/akm8973.h b/libc/kernel/common/linux/akm8973.h
new file mode 100644
index 0000000..2892f72
--- /dev/null
+++ b/libc/kernel/common/linux/akm8973.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef AKM8973_H
+#define AKM8973_H
+
+#include <linux/ioctl.h>
+
+#define AKMIO 0xA1
+
+#define ECS_IOCTL_WRITE _IOW(AKMIO, 0x01, char[5])
+#define ECS_IOCTL_READ _IOWR(AKMIO, 0x02, char[5])
+#define ECS_IOCTL_RESET _IO(AKMIO, 0x03)
+#define ECS_IOCTL_SET_MODE _IOW(AKMIO, 0x04, short)
+#define ECS_IOCTL_GETDATA _IOR(AKMIO, 0x05, char[RBUFF_SIZE+1])
+#define ECS_IOCTL_SET_YPR _IOW(AKMIO, 0x06, short[12])
+#define ECS_IOCTL_GET_OPEN_STATUS _IOR(AKMIO, 0x07, int)
+#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(AKMIO, 0x08, int)
+#define ECS_IOCTL_GET_DELAY _IOR(AKMIO, 0x30, short)
+
+#define ECS_IOCTL_APP_SET_MODE _IOW(AKMIO, 0x10, short)
+#define ECS_IOCTL_APP_SET_MFLAG _IOW(AKMIO, 0x11, short)
+#define ECS_IOCTL_APP_GET_MFLAG _IOW(AKMIO, 0x12, short)
+#define ECS_IOCTL_APP_SET_AFLAG _IOW(AKMIO, 0x13, short)
+#define ECS_IOCTL_APP_GET_AFLAG _IOR(AKMIO, 0x14, short)
+#define ECS_IOCTL_APP_SET_TFLAG _IOR(AKMIO, 0x15, short)
+#define ECS_IOCTL_APP_GET_TFLAG _IOR(AKMIO, 0x16, short)
+#define ECS_IOCTL_APP_RESET_PEDOMETER _IO(AKMIO, 0x17)
+#define ECS_IOCTL_APP_SET_DELAY _IOW(AKMIO, 0x18, short)
+#define ECS_IOCTL_APP_GET_DELAY ECS_IOCTL_GET_DELAY
+#define ECS_IOCTL_APP_SET_MVFLAG _IOW(AKMIO, 0x19, short)
+#define ECS_IOCTL_APP_GET_MVFLAG _IOR(AKMIO, 0x1A, short)
+
+#define ECS_IOCTL_SET_STEP_CNT _IOW(AKMIO, 0x20, short)
+#endif
+
+
diff --git a/libc/kernel/common/linux/android_pmem.h b/libc/kernel/common/linux/android_pmem.h
index 858857e..bdf3aba 100644
--- a/libc/kernel/common/linux/android_pmem.h
+++ b/libc/kernel/common/linux/android_pmem.h
@@ -12,40 +12,36 @@
 #ifndef _ANDROID_PMEM_H_
 #define _ANDROID_PMEM_H_
 
-#include <stdint.h>
-
-#ifndef __user
-#define __user
-#endif
-
-struct pmem_region {
- unsigned long offset;
- unsigned long len;
-};
-
 #define PMEM_IOCTL_MAGIC 'p'
-#define PMEM_GET_PHYS _IOW(PMEM_IOCTL_MAGIC, 1, struct pmem_region *)
-#define PMEM_MAP _IOW(PMEM_IOCTL_MAGIC, 2, struct pmem_region *)
-#define PMEM_GET_SIZE _IOW(PMEM_IOCTL_MAGIC, 3, struct pmem_region *)
-#define PMEM_UNMAP _IOW(PMEM_IOCTL_MAGIC, 4, struct pmem_region *)
+#define PMEM_GET_PHYS _IOW(PMEM_IOCTL_MAGIC, 1, unsigned int)
+#define PMEM_MAP _IOW(PMEM_IOCTL_MAGIC, 2, unsigned int)
+#define PMEM_GET_SIZE _IOW(PMEM_IOCTL_MAGIC, 3, unsigned int)
+#define PMEM_UNMAP _IOW(PMEM_IOCTL_MAGIC, 4, unsigned int)
 
 #define PMEM_ALLOCATE _IOW(PMEM_IOCTL_MAGIC, 5, unsigned int)
 
 #define PMEM_CONNECT _IOW(PMEM_IOCTL_MAGIC, 6, unsigned int)
 
-#define PMEM_GET_TOTAL_SIZE _IOW(PMEM_IOCTL_MAGIC, 7, struct pmem_region *)
+#define PMEM_GET_TOTAL_SIZE _IOW(PMEM_IOCTL_MAGIC, 7, unsigned int)
 
-#define HW3D_REVOKE_GPU _IOW(PMEM_IOCTL_MAGIC, 8, unsigned int)
-#define HW3D_GRANT_GPU _IOW(PMEM_IOCTL_MAGIC, 9, unsigned int)
-#define HW3D_WAIT_IRQ _IOW(PMEM_IOCTL_MAGIC,10, unsigned int)
+struct android_pmem_platform_data
+{
+ const char* name;
 
-struct android_pmem_platform_data;
-struct pmem_file_operations {
- int (*mmap) (struct file *, struct vm_area_struct *);
- int (*open) (struct inode *, struct file *);
- ssize_t (*read) (struct file *, char __user *, size_t, long long *);
- int (*release) (struct inode *, struct file *);
- long (*ioctl) (struct file *, unsigned int, unsigned long);
+ unsigned long start;
+
+ unsigned long size;
+
+ unsigned no_allocator;
+
+ unsigned cached;
+
+ unsigned buffered;
+};
+
+struct pmem_region {
+ unsigned long offset;
+ unsigned long len;
 };
 
 #endif
diff --git a/libc/kernel/common/linux/capella_cm3602.h b/libc/kernel/common/linux/capella_cm3602.h
new file mode 100644
index 0000000..6391e8a
--- /dev/null
+++ b/libc/kernel/common/linux/capella_cm3602.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_CAPELLA_CM3602_H
+#define __LINUX_CAPELLA_CM3602_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define CAPELLA_CM3602_IOCTL_MAGIC 'c'
+#define CAPELLA_CM3602_IOCTL_GET_ENABLED   _IOR(CAPELLA_CM3602_IOCTL_MAGIC, 1, int *)
+#define CAPELLA_CM3602_IOCTL_ENABLE   _IOW(CAPELLA_CM3602_IOCTL_MAGIC, 2, int *)
+
+#endif
+
diff --git a/libc/kernel/common/linux/ethtool.h b/libc/kernel/common/linux/ethtool.h
new file mode 100644
index 0000000..7a5b3cd
--- /dev/null
+++ b/libc/kernel/common/linux/ethtool.h
@@ -0,0 +1,321 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ETHTOOL_H
+#define _LINUX_ETHTOOL_H
+
+#include <linux/types.h>
+
+struct ethtool_cmd {
+ __u32 cmd;
+ __u32 supported;
+ __u32 advertising;
+ __u16 speed;
+ __u8 duplex;
+ __u8 port;
+ __u8 phy_address;
+ __u8 transceiver;
+ __u8 autoneg;
+ __u32 maxtxpkt;
+ __u32 maxrxpkt;
+ __u16 speed_hi;
+ __u16 reserved2;
+ __u32 reserved[3];
+};
+
+#define ETHTOOL_BUSINFO_LEN 32
+struct ethtool_drvinfo {
+ __u32 cmd;
+ char driver[32];
+ char version[32];
+ char fw_version[32];
+ char bus_info[ETHTOOL_BUSINFO_LEN];
+ char reserved1[32];
+ char reserved2[12];
+ __u32 n_priv_flags;
+ __u32 n_stats;
+ __u32 testinfo_len;
+ __u32 eedump_len;
+ __u32 regdump_len;
+};
+																
+#define SOPASS_MAX 6
+
+struct ethtool_wolinfo {
+ __u32 cmd;
+ __u32 supported;
+ __u32 wolopts;
+ __u8 sopass[SOPASS_MAX];
+};
+
+struct ethtool_value {
+ __u32 cmd;
+ __u32 data;
+};
+
+struct ethtool_regs {
+ __u32 cmd;
+ __u32 version;
+ __u32 len;
+ __u8 data[0];
+};
+
+struct ethtool_eeprom {
+ __u32 cmd;
+ __u32 magic;
+ __u32 offset;
+ __u32 len;
+ __u8 data[0];
+};
+
+struct ethtool_coalesce {
+ __u32 cmd;
+
+ __u32 rx_coalesce_usecs;
+
+ __u32 rx_max_coalesced_frames;
+
+ __u32 rx_coalesce_usecs_irq;
+ __u32 rx_max_coalesced_frames_irq;
+
+ __u32 tx_coalesce_usecs;
+
+ __u32 tx_max_coalesced_frames;
+
+ __u32 tx_coalesce_usecs_irq;
+ __u32 tx_max_coalesced_frames_irq;
+
+ __u32 stats_block_coalesce_usecs;
+
+ __u32 use_adaptive_rx_coalesce;
+ __u32 use_adaptive_tx_coalesce;
+
+ __u32 pkt_rate_low;
+ __u32 rx_coalesce_usecs_low;
+ __u32 rx_max_coalesced_frames_low;
+ __u32 tx_coalesce_usecs_low;
+ __u32 tx_max_coalesced_frames_low;
+
+ __u32 pkt_rate_high;
+ __u32 rx_coalesce_usecs_high;
+ __u32 rx_max_coalesced_frames_high;
+ __u32 tx_coalesce_usecs_high;
+ __u32 tx_max_coalesced_frames_high;
+
+ __u32 rate_sample_interval;
+};
+
+struct ethtool_ringparam {
+ __u32 cmd;
+
+ __u32 rx_max_pending;
+ __u32 rx_mini_max_pending;
+ __u32 rx_jumbo_max_pending;
+ __u32 tx_max_pending;
+
+ __u32 rx_pending;
+ __u32 rx_mini_pending;
+ __u32 rx_jumbo_pending;
+ __u32 tx_pending;
+};
+
+struct ethtool_pauseparam {
+ __u32 cmd;
+
+ __u32 autoneg;
+ __u32 rx_pause;
+ __u32 tx_pause;
+};
+
+#define ETH_GSTRING_LEN 32
+enum ethtool_stringset {
+ ETH_SS_TEST = 0,
+ ETH_SS_STATS,
+ ETH_SS_PRIV_FLAGS,
+};
+
+struct ethtool_gstrings {
+ __u32 cmd;
+ __u32 string_set;
+ __u32 len;
+ __u8 data[0];
+};
+
+enum ethtool_test_flags {
+ ETH_TEST_FL_OFFLINE = (1 << 0),
+ ETH_TEST_FL_FAILED = (1 << 1),
+};
+
+struct ethtool_test {
+ __u32 cmd;
+ __u32 flags;
+ __u32 reserved;
+ __u32 len;
+ __u64 data[0];
+};
+
+struct ethtool_stats {
+ __u32 cmd;
+ __u32 n_stats;
+ __u64 data[0];
+};
+
+struct ethtool_perm_addr {
+ __u32 cmd;
+ __u32 size;
+ __u8 data[0];
+};
+
+enum ethtool_flags {
+ ETH_FLAG_LRO = (1 << 15),
+};
+
+struct ethtool_rxnfc {
+ __u32 cmd;
+ __u32 flow_type;
+ __u64 data;
+};
+
+#define ETHTOOL_GSET 0x00000001  
+#define ETHTOOL_SSET 0x00000002  
+#define ETHTOOL_GDRVINFO 0x00000003  
+#define ETHTOOL_GREGS 0x00000004  
+#define ETHTOOL_GWOL 0x00000005  
+#define ETHTOOL_SWOL 0x00000006  
+#define ETHTOOL_GMSGLVL 0x00000007  
+#define ETHTOOL_SMSGLVL 0x00000008  
+#define ETHTOOL_NWAY_RST 0x00000009  
+#define ETHTOOL_GLINK 0x0000000a  
+#define ETHTOOL_GEEPROM 0x0000000b  
+#define ETHTOOL_SEEPROM 0x0000000c  
+#define ETHTOOL_GCOALESCE 0x0000000e  
+#define ETHTOOL_SCOALESCE 0x0000000f  
+#define ETHTOOL_GRINGPARAM 0x00000010  
+#define ETHTOOL_SRINGPARAM 0x00000011  
+#define ETHTOOL_GPAUSEPARAM 0x00000012  
+#define ETHTOOL_SPAUSEPARAM 0x00000013  
+#define ETHTOOL_GRXCSUM 0x00000014  
+#define ETHTOOL_SRXCSUM 0x00000015  
+#define ETHTOOL_GTXCSUM 0x00000016  
+#define ETHTOOL_STXCSUM 0x00000017  
+#define ETHTOOL_GSG 0x00000018  
+#define ETHTOOL_SSG 0x00000019  
+#define ETHTOOL_TEST 0x0000001a  
+#define ETHTOOL_GSTRINGS 0x0000001b  
+#define ETHTOOL_PHYS_ID 0x0000001c  
+#define ETHTOOL_GSTATS 0x0000001d  
+#define ETHTOOL_GTSO 0x0000001e  
+#define ETHTOOL_STSO 0x0000001f  
+#define ETHTOOL_GPERMADDR 0x00000020  
+#define ETHTOOL_GUFO 0x00000021  
+#define ETHTOOL_SUFO 0x00000022  
+#define ETHTOOL_GGSO 0x00000023  
+#define ETHTOOL_SGSO 0x00000024  
+#define ETHTOOL_GFLAGS 0x00000025  
+#define ETHTOOL_SFLAGS 0x00000026  
+#define ETHTOOL_GPFLAGS 0x00000027  
+#define ETHTOOL_SPFLAGS 0x00000028  
+
+#define ETHTOOL_GRXFH 0x00000029  
+#define ETHTOOL_SRXFH 0x0000002a  
+#define ETHTOOL_GGRO 0x0000002b  
+#define ETHTOOL_SGRO 0x0000002c  
+
+#define SPARC_ETH_GSET ETHTOOL_GSET
+#define SPARC_ETH_SSET ETHTOOL_SSET
+
+#define SUPPORTED_10baseT_Half (1 << 0)
+#define SUPPORTED_10baseT_Full (1 << 1)
+#define SUPPORTED_100baseT_Half (1 << 2)
+#define SUPPORTED_100baseT_Full (1 << 3)
+#define SUPPORTED_1000baseT_Half (1 << 4)
+#define SUPPORTED_1000baseT_Full (1 << 5)
+#define SUPPORTED_Autoneg (1 << 6)
+#define SUPPORTED_TP (1 << 7)
+#define SUPPORTED_AUI (1 << 8)
+#define SUPPORTED_MII (1 << 9)
+#define SUPPORTED_FIBRE (1 << 10)
+#define SUPPORTED_BNC (1 << 11)
+#define SUPPORTED_10000baseT_Full (1 << 12)
+#define SUPPORTED_Pause (1 << 13)
+#define SUPPORTED_Asym_Pause (1 << 14)
+#define SUPPORTED_2500baseX_Full (1 << 15)
+
+#define ADVERTISED_10baseT_Half (1 << 0)
+#define ADVERTISED_10baseT_Full (1 << 1)
+#define ADVERTISED_100baseT_Half (1 << 2)
+#define ADVERTISED_100baseT_Full (1 << 3)
+#define ADVERTISED_1000baseT_Half (1 << 4)
+#define ADVERTISED_1000baseT_Full (1 << 5)
+#define ADVERTISED_Autoneg (1 << 6)
+#define ADVERTISED_TP (1 << 7)
+#define ADVERTISED_AUI (1 << 8)
+#define ADVERTISED_MII (1 << 9)
+#define ADVERTISED_FIBRE (1 << 10)
+#define ADVERTISED_BNC (1 << 11)
+#define ADVERTISED_10000baseT_Full (1 << 12)
+#define ADVERTISED_Pause (1 << 13)
+#define ADVERTISED_Asym_Pause (1 << 14)
+#define ADVERTISED_2500baseX_Full (1 << 15)
+
+#define SPEED_10 10
+#define SPEED_100 100
+#define SPEED_1000 1000
+#define SPEED_2500 2500
+#define SPEED_10000 10000
+
+#define DUPLEX_HALF 0x00
+#define DUPLEX_FULL 0x01
+
+#define PORT_TP 0x00
+#define PORT_AUI 0x01
+#define PORT_MII 0x02
+#define PORT_FIBRE 0x03
+#define PORT_BNC 0x04
+
+#define XCVR_INTERNAL 0x00
+#define XCVR_EXTERNAL 0x01
+#define XCVR_DUMMY1 0x02
+#define XCVR_DUMMY2 0x03
+#define XCVR_DUMMY3 0x04
+
+#define AUTONEG_DISABLE 0x00
+#define AUTONEG_ENABLE 0x01
+
+#define WAKE_PHY (1 << 0)
+#define WAKE_UCAST (1 << 1)
+#define WAKE_MCAST (1 << 2)
+#define WAKE_BCAST (1 << 3)
+#define WAKE_ARP (1 << 4)
+#define WAKE_MAGIC (1 << 5)
+#define WAKE_MAGICSECURE (1 << 6)  
+
+#define TCP_V4_FLOW 0x01
+#define UDP_V4_FLOW 0x02
+#define SCTP_V4_FLOW 0x03
+#define AH_ESP_V4_FLOW 0x04
+#define TCP_V6_FLOW 0x05
+#define UDP_V6_FLOW 0x06
+#define SCTP_V6_FLOW 0x07
+#define AH_ESP_V6_FLOW 0x08
+
+#define RXH_DEV_PORT (1 << 0)
+#define RXH_L2DA (1 << 1)
+#define RXH_VLAN (1 << 2)
+#define RXH_L3_PROTO (1 << 3)
+#define RXH_IP_SRC (1 << 4)
+#define RXH_IP_DST (1 << 5)
+#define RXH_L4_B_0_1 (1 << 6)  
+#define RXH_L4_B_2_3 (1 << 7)  
+#define RXH_DISCARD (1 << 31)
+
+#endif
+
diff --git a/libc/kernel/common/linux/lightsensor.h b/libc/kernel/common/linux/lightsensor.h
new file mode 100644
index 0000000..70257ed
--- /dev/null
+++ b/libc/kernel/common/linux/lightsensor.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_LIGHTSENSOR_H
+#define __LINUX_LIGHTSENSOR_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define LIGHTSENSOR_IOCTL_MAGIC 'l'
+
+#define LIGHTSENSOR_IOCTL_GET_ENABLED _IOR(LIGHTSENSOR_IOCTL_MAGIC, 1, int *)
+#define LIGHTSENSOR_IOCTL_ENABLE _IOW(LIGHTSENSOR_IOCTL_MAGIC, 2, int *)
+
+#endif
+
diff --git a/libc/kernel/common/linux/lis331dlh.h b/libc/kernel/common/linux/lis331dlh.h
new file mode 100644
index 0000000..49d1b12
--- /dev/null
+++ b/libc/kernel/common/linux/lis331dlh.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LIS331DLH_H__
+#define __LIS331DLH_H__
+
+#include <linux/ioctl.h>  
+
+#define LIS331DLH_IOCTL_BASE 77
+
+#define LIS331DLH_IOCTL_SET_DELAY _IOW(LIS331DLH_IOCTL_BASE, 0, int)
+#define LIS331DLH_IOCTL_GET_DELAY _IOR(LIS331DLH_IOCTL_BASE, 1, int)
+#define LIS331DLH_IOCTL_SET_ENABLE _IOW(LIS331DLH_IOCTL_BASE, 2, int)
+#define LIS331DLH_IOCTL_GET_ENABLE _IOR(LIS331DLH_IOCTL_BASE, 3, int)
+#define LIS331DLH_IOCTL_SET_G_RANGE _IOW(LIS331DLH_IOCTL_BASE, 4, int)
+
+#define LIS331DLH_G_2G 0x00
+#define LIS331DLH_G_4G 0x10
+#define LIS331DLH_G_8G 0x30
+
+#endif
+
diff --git a/libc/kernel/common/linux/msm_hw3d.h b/libc/kernel/common/linux/msm_hw3d.h
new file mode 100644
index 0000000..3d05106
--- /dev/null
+++ b/libc/kernel/common/linux/msm_hw3d.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _MSM_HW3D_H_
+#define _MSM_HW3D_H_
+
+#include <linux/fs.h>
+#include <linux/ioctl.h>
+
+struct hw3d_region;
+
+#define HW3D_IOCTL_MAGIC 'h'
+#define HW3D_WAIT_FOR_REVOKE _IO(HW3D_IOCTL_MAGIC, 0x80)
+#define HW3D_WAIT_FOR_INTERRUPT _IO(HW3D_IOCTL_MAGIC, 0x81)
+#define HW3D_GET_REGIONS   _IOR(HW3D_IOCTL_MAGIC, 0x82, struct hw3d_region *)
+
+#define HW3D_REGION_OFFSET(id) ((((uint32_t)(id)) & 0xf) << 28)
+#define HW3D_REGION_ID(addr) (((uint32_t)(addr) >> 28) & 0xf)
+#define HW3D_OFFSET_IN_REGION(addr) ((uint32_t)(addr) & ~(0xfUL << 28))
+
+enum {
+ HW3D_EBI = 0,
+ HW3D_SMI = 1,
+ HW3D_REGS = 2,
+
+ HW3D_NUM_REGIONS = HW3D_REGS + 1,
+};
+
+struct hw3d_region {
+ unsigned long phys;
+ unsigned long map_offset;
+ unsigned long len;
+};
+
+#endif
+
diff --git a/libc/kernel/common/linux/msm_kgsl.h b/libc/kernel/common/linux/msm_kgsl.h
new file mode 100644
index 0000000..d717e57
--- /dev/null
+++ b/libc/kernel/common/linux/msm_kgsl.h
@@ -0,0 +1,192 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _MSM_KGSL_H
+#define _MSM_KGSL_H
+
+#define KGSL_CONTEXT_SAVE_GMEM 1
+#define KGSL_CONTEXT_NO_GMEM_ALLOC 2
+
+#define KGSL_FLAGS_NORMALMODE 0x00000000
+#define KGSL_FLAGS_SAFEMODE 0x00000001
+#define KGSL_FLAGS_INITIALIZED0 0x00000002
+#define KGSL_FLAGS_INITIALIZED 0x00000004
+#define KGSL_FLAGS_STARTED 0x00000008
+#define KGSL_FLAGS_ACTIVE 0x00000010
+#define KGSL_FLAGS_RESERVED0 0x00000020
+#define KGSL_FLAGS_RESERVED1 0x00000040
+#define KGSL_FLAGS_RESERVED2 0x00000080
+
+enum kgsl_deviceid {
+ KGSL_DEVICE_ANY = 0x00000000,
+ KGSL_DEVICE_YAMATO = 0x00000001,
+ KGSL_DEVICE_G12 = 0x00000002,
+ KGSL_DEVICE_MAX = 0x00000002
+};
+
+struct kgsl_devinfo {
+
+ unsigned int device_id;
+
+ unsigned int chip_id;
+ unsigned int mmu_enabled;
+ unsigned int gmem_gpubaseaddr;
+
+ unsigned int gmem_hostbaseaddr;
+ unsigned int gmem_sizebytes;
+};
+
+struct kgsl_devmemstore {
+ volatile unsigned int soptimestamp;
+ unsigned int sbz;
+ volatile unsigned int eoptimestamp;
+ unsigned int sbz2;
+};
+
+#define KGSL_DEVICE_MEMSTORE_OFFSET(field)   offsetof(struct kgsl_devmemstore, field)
+
+enum kgsl_timestamp_type {
+ KGSL_TIMESTAMP_CONSUMED = 0x00000001,
+ KGSL_TIMESTAMP_RETIRED = 0x00000002,
+ KGSL_TIMESTAMP_MAX = 0x00000002,
+};
+
+enum kgsl_property_type {
+ KGSL_PROP_DEVICE_INFO = 0x00000001,
+ KGSL_PROP_DEVICE_SHADOW = 0x00000002,
+ KGSL_PROP_DEVICE_POWER = 0x00000003,
+ KGSL_PROP_SHMEM = 0x00000004,
+ KGSL_PROP_SHMEM_APERTURES = 0x00000005,
+ KGSL_PROP_MMU_ENABLE = 0x00000006
+};
+
+struct kgsl_shadowprop {
+ unsigned int gpuaddr;
+ unsigned int size;
+ unsigned int flags;
+};
+
+#define KGSL_IOC_TYPE 0x09
+
+struct kgsl_device_getproperty {
+ unsigned int type;
+ void *value;
+ unsigned int sizebytes;
+};
+
+#define IOCTL_KGSL_DEVICE_GETPROPERTY   _IOWR(KGSL_IOC_TYPE, 0x2, struct kgsl_device_getproperty)
+
+struct kgsl_device_regread {
+ unsigned int offsetwords;
+ unsigned int value;
+};
+
+#define IOCTL_KGSL_DEVICE_REGREAD   _IOWR(KGSL_IOC_TYPE, 0x3, struct kgsl_device_regread)
+
+struct kgsl_device_waittimestamp {
+ unsigned int timestamp;
+ unsigned int timeout;
+};
+
+#define IOCTL_KGSL_DEVICE_WAITTIMESTAMP   _IOW(KGSL_IOC_TYPE, 0x6, struct kgsl_device_waittimestamp)
+
+struct kgsl_ringbuffer_issueibcmds {
+ unsigned int drawctxt_id;
+ unsigned int ibaddr;
+ unsigned int sizedwords;
+ unsigned int timestamp;
+ unsigned int flags;
+};
+
+#define IOCTL_KGSL_RINGBUFFER_ISSUEIBCMDS   _IOWR(KGSL_IOC_TYPE, 0x10, struct kgsl_ringbuffer_issueibcmds)
+
+struct kgsl_cmdstream_readtimestamp {
+ unsigned int type;
+ unsigned int timestamp;
+};
+
+#define IOCTL_KGSL_CMDSTREAM_READTIMESTAMP   _IOR(KGSL_IOC_TYPE, 0x11, struct kgsl_cmdstream_readtimestamp)
+
+struct kgsl_cmdstream_freememontimestamp {
+ unsigned int gpuaddr;
+ unsigned int type;
+ unsigned int timestamp;
+};
+
+#define IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP   _IOR(KGSL_IOC_TYPE, 0x12, struct kgsl_cmdstream_freememontimestamp)
+
+struct kgsl_drawctxt_create {
+ unsigned int flags;
+ unsigned int drawctxt_id;
+};
+
+#define IOCTL_KGSL_DRAWCTXT_CREATE   _IOWR(KGSL_IOC_TYPE, 0x13, struct kgsl_drawctxt_create)
+
+struct kgsl_drawctxt_destroy {
+ unsigned int drawctxt_id;
+};
+
+#define IOCTL_KGSL_DRAWCTXT_DESTROY   _IOW(KGSL_IOC_TYPE, 0x14, struct kgsl_drawctxt_destroy)
+
+struct kgsl_sharedmem_from_pmem {
+ int pmem_fd;
+ unsigned int gpuaddr;
+};
+
+#define IOCTL_KGSL_SHAREDMEM_FROM_PMEM   _IOWR(KGSL_IOC_TYPE, 0x20, struct kgsl_sharedmem_from_pmem)
+
+struct kgsl_sharedmem_free {
+ unsigned int gpuaddr;
+};
+
+#define IOCTL_KGSL_SHAREDMEM_FREE   _IOW(KGSL_IOC_TYPE, 0x21, struct kgsl_sharedmem_free)
+
+struct kgsl_gmem_desc {
+ unsigned int x;
+ unsigned int y;
+ unsigned int width;
+ unsigned int height;
+ unsigned int pitch;
+};
+
+struct kgsl_buffer_desc {
+ void *hostptr;
+ unsigned int gpuaddr;
+ int size;
+ unsigned int format;
+ unsigned int pitch;
+ unsigned int enabled;
+};
+
+struct kgsl_bind_gmem_shadow {
+ unsigned int drawctxt_id;
+ struct kgsl_gmem_desc gmem_desc;
+ unsigned int shadow_x;
+ unsigned int shadow_y;
+ struct kgsl_buffer_desc shadow_buffer;
+ unsigned int buffer_id;
+};
+
+#define IOCTL_KGSL_DRAWCTXT_BIND_GMEM_SHADOW   _IOW(KGSL_IOC_TYPE, 0x22, struct kgsl_bind_gmem_shadow)
+
+struct kgsl_sharedmem_from_vmalloc {
+ unsigned int gpuaddr;
+ unsigned int hostptr;
+
+ int force_no_low_watermark;
+};
+
+#define IOCTL_KGSL_SHAREDMEM_FROM_VMALLOC   _IOWR(KGSL_IOC_TYPE, 0x23, struct kgsl_sharedmem_from_vmalloc)
+
+#define IOCTL_KGSL_SHAREDMEM_FLUSH_CACHE   _IOW(KGSL_IOC_TYPE, 0x24, struct kgsl_sharedmem_free)
+
+#endif
+
diff --git a/libc/kernel/common/linux/msm_mdp.h b/libc/kernel/common/linux/msm_mdp.h
index 43fdac3..c355218 100644
--- a/libc/kernel/common/linux/msm_mdp.h
+++ b/libc/kernel/common/linux/msm_mdp.h
@@ -30,6 +30,7 @@
  MDP_Y_CBCR_H2V1,
  MDP_RGBA_8888,
  MDP_BGRA_8888,
+ MDP_RGBX_8888,
  MDP_IMGTYPE_LIMIT
 };
 
@@ -46,6 +47,7 @@
 #define MDP_ROT_270 (MDP_ROT_90|MDP_FLIP_UD|MDP_FLIP_LR)
 #define MDP_DITHER 0x8
 #define MDP_BLUR 0x10
+#define MDP_BLEND_FG_PREMULT 0x20000
 
 #define MDP_TRANSP_NOP 0xffffffff
 #define MDP_ALPHA_NOP 0xff
@@ -81,3 +83,4 @@
 };
 
 #endif
+
diff --git a/libc/kernel/common/linux/msm_q6vdec.h b/libc/kernel/common/linux/msm_q6vdec.h
new file mode 100644
index 0000000..0182bfb
--- /dev/null
+++ b/libc/kernel/common/linux/msm_q6vdec.h
@@ -0,0 +1,212 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _MSM_VDEC_H_
+#define _MSM_VDEC_H_
+
+#include <linux/types.h>
+
+#define VDEC_IOCTL_MAGIC 'v'
+
+#define VDEC_IOCTL_INITIALIZE _IOWR(VDEC_IOCTL_MAGIC, 1, struct vdec_init)
+#define VDEC_IOCTL_SETBUFFERS _IOW(VDEC_IOCTL_MAGIC, 2, struct vdec_buffer)
+#define VDEC_IOCTL_QUEUE _IOWR(VDEC_IOCTL_MAGIC, 3,   struct vdec_input_buf)
+#define VDEC_IOCTL_REUSEFRAMEBUFFER _IOW(VDEC_IOCTL_MAGIC, 4, unsigned int)
+#define VDEC_IOCTL_FLUSH _IOW(VDEC_IOCTL_MAGIC, 5, unsigned int)
+#define VDEC_IOCTL_EOS _IO(VDEC_IOCTL_MAGIC, 6)
+#define VDEC_IOCTL_GETMSG _IOR(VDEC_IOCTL_MAGIC, 7, struct vdec_msg)
+#define VDEC_IOCTL_CLOSE _IO(VDEC_IOCTL_MAGIC, 8)
+#define VDEC_IOCTL_FREEBUFFERS _IOW(VDEC_IOCTL_MAGIC, 9, struct vdec_buf_info)
+#define VDEC_IOCTL_GETDECATTRIBUTES _IOR(VDEC_IOCTL_MAGIC, 10,   struct vdec_dec_attributes)
+
+enum {
+ VDEC_FRAME_DECODE_OK,
+ VDEC_FRAME_DECODE_ERR,
+ VDEC_FATAL_ERR,
+ VDEC_FLUSH_FINISH,
+ VDEC_EOS,
+ VDEC_FRAME_FLUSH,
+ VDEC_STREAM_SWITCH,
+ VDEC_SUSPEND_FINISH,
+ VDEC_BUFFER_CONSUMED
+};
+
+enum {
+ VDEC_FLUSH_INPUT,
+ VDEC_FLUSH_OUTPUT,
+ VDEC_FLUSH_ALL
+};
+
+enum {
+ VDEC_BUFFER_TYPE_INPUT,
+ VDEC_BUFFER_TYPE_OUTPUT,
+ VDEC_BUFFER_TYPE_INTERNAL1,
+ VDEC_BUFFER_TYPE_INTERNAL2,
+};
+
+enum {
+ VDEC_QUEUE_SUCCESS,
+ VDEC_QUEUE_FAILED,
+ VDEC_QUEUE_BADSTATE,
+};
+
+struct vdec_input_buf_info {
+ u32 offset;
+ u32 data;
+ u32 size;
+ int timestamp_lo;
+ int timestamp_hi;
+ int avsync_state;
+ u32 flags;
+};
+
+struct vdec_buf_desc {
+ u32 bufsize;
+ u32 num_min_buffers;
+ u32 num_max_buffers;
+};
+
+struct vdec_buf_req {
+ u32 max_input_queue_size;
+ struct vdec_buf_desc input;
+ struct vdec_buf_desc output;
+ struct vdec_buf_desc dec_req1;
+ struct vdec_buf_desc dec_req2;
+};
+
+struct vdec_region_info {
+ u32 src_id;
+ u32 offset;
+ u32 size;
+};
+
+struct vdec_config {
+ u32 fourcc;
+ u32 width;
+ u32 height;
+ u32 order;
+ u32 notify_enable;
+ u32 vc1_rowbase;
+ u32 h264_startcode_detect;
+ u32 h264_nal_len_size;
+ u32 postproc_flag;
+ u32 fruc_enable;
+ u32 reserved;
+};
+
+struct vdec_vc1_panscan_regions {
+ int num;
+ int width[4];
+ int height[4];
+ int xoffset[4];
+ int yoffset[4];
+};
+
+struct vdec_cropping_window {
+ u32 x1;
+ u32 y1;
+ u32 x2;
+ u32 y2;
+};
+
+struct vdec_frame_info {
+ u32 status;
+ u32 offset;
+ u32 data1;
+ u32 data2;
+ int timestamp_lo;
+ int timestamp_hi;
+ int cal_timestamp_lo;
+ int cal_timestamp_hi;
+ u32 dec_width;
+ u32 dec_height;
+ struct vdec_cropping_window cwin;
+ u32 picture_type[2];
+ u32 picture_format;
+ u32 vc1_rangeY;
+ u32 vc1_rangeUV;
+ u32 picture_resolution;
+ u32 frame_disp_repeat;
+ u32 repeat_first_field;
+ u32 top_field_first;
+ u32 interframe_interp;
+ struct vdec_vc1_panscan_regions panscan;
+ u32 concealed_macblk_num;
+ u32 flags;
+ u32 performance_stats;
+ u32 data3;
+};
+
+struct vdec_buf_info {
+ u32 buf_type;
+ struct vdec_region_info region;
+ u32 num_buf;
+ u32 islast;
+};
+
+struct vdec_buffer {
+ u32 pmem_id;
+ struct vdec_buf_info buf;
+};
+
+struct vdec_sequence {
+ u8 *header;
+ u32 len;
+};
+
+struct vdec_config_sps {
+ struct vdec_config cfg;
+ struct vdec_sequence seq;
+};
+
+#define VDEC_MSG_REUSEINPUTBUFFER 1
+#define VDEC_MSG_FRAMEDONE 2
+
+struct vdec_msg {
+ u32 id;
+
+ union {
+
+ u32 buf_id;
+
+ struct vdec_frame_info vfr_info;
+ };
+};
+
+struct vdec_init {
+ struct vdec_config_sps sps_cfg;
+ struct vdec_buf_req *buf_req;
+};
+
+struct vdec_input_buf {
+ u32 pmem_id;
+ struct vdec_input_buf_info buffer;
+ struct vdec_queue_status *queue_status;
+};
+
+struct vdec_queue_status {
+ u32 status;
+};
+
+struct vdec_dec_attributes {
+ u32 fourcc;
+ u32 profile;
+ u32 level;
+ u32 dec_pic_width;
+ u32 dec_pic_height;
+ struct vdec_buf_desc input;
+ struct vdec_buf_desc output;
+ struct vdec_buf_desc dec_req1;
+ struct vdec_buf_desc dec_req2;
+};
+
+#endif
+
diff --git a/libc/kernel/common/linux/msm_q6venc.h b/libc/kernel/common/linux/msm_q6venc.h
new file mode 100755
index 0000000..5b63680
--- /dev/null
+++ b/libc/kernel/common/linux/msm_q6venc.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _MSM_VENC_H_
+#define _MSM_VENC_H_
+
+#include <linux/types.h>
+
+struct venc_buf {
+ unsigned int src_id;
+ int fd;
+ unsigned long offset;
+ unsigned long size;
+};
+
+struct q6_init_config {
+ unsigned short venc_standard;
+ unsigned short partial_run_length_flag;
+ unsigned short h263_annex_ispt;
+ unsigned short h263_annex_jspt;
+ unsigned short h263_annex_tspt;
+ unsigned short rc_flag;
+ unsigned short one_mv_flag;
+ unsigned short acdc_pred_enable;
+ unsigned short rounding_bit_ctrl;
+ unsigned short rotation_flag;
+ unsigned short max_mvx;
+ unsigned short max_mvy;
+ unsigned short enc_frame_height_inmb;
+ unsigned short enc_frame_width_inmb;
+ unsigned short dvs_frame_height;
+ unsigned short dvs_frame_width;
+
+ unsigned int ref_frame_buf1_phy;
+ unsigned int ref_frame_buf2_phy;
+ unsigned int rlc_buf1_phy;
+ unsigned int rlc_buf2_phy;
+ unsigned int rlc_buf_length;
+};
+
+struct init_config {
+ struct venc_buf ref_frame_buf1;
+ struct venc_buf ref_frame_buf2;
+ struct venc_buf rlc_buf1;
+ struct venc_buf rlc_buf2;
+ struct q6_init_config q6_init_config;
+};
+
+struct q6_encode_param {
+ unsigned int luma_addr;
+ unsigned int chroma_addr;
+ unsigned int x_offset;
+ unsigned int y_offset;
+ unsigned int frame_rho_budget;
+ unsigned int frame_type;
+ unsigned int qp;
+};
+
+struct encode_param {
+ struct venc_buf y_addr;
+ unsigned long uv_offset;
+ struct q6_encode_param q6_encode_param;
+};
+
+struct intra_refresh {
+ unsigned int intra_refresh_enable;
+ unsigned int intra_mb_num;
+};
+
+struct rc_config {
+ unsigned short max_frame_qp_up_delta;
+ unsigned short max_frame_qp_down_delta;
+ unsigned short min_frame_qp;
+ unsigned short max_frame_qp;
+};
+
+struct q6_frame_type {
+ unsigned int frame_type;
+ unsigned int frame_len;
+ unsigned int frame_addr;
+ unsigned int map_table;
+};
+
+struct frame_type {
+ struct venc_buf frame_addr;
+ struct q6_frame_type q6_frame_type;
+};
+
+#define VENC_IOCTL_MAGIC 'V'
+
+#define VENC_IOCTL_INITIALIZE _IOW(VENC_IOCTL_MAGIC, 1, struct init_config)
+#define VENC_IOCTL_ENCODE _IOW(VENC_IOCTL_MAGIC, 2, struct encode_param)
+#define VENC_IOCTL_INTRA_REFRESH _IOW(VENC_IOCTL_MAGIC, 3, struct intra_refresh)
+#define VENC_IOCTL_RC_CONFIG _IOW(VENC_IOCTL_MAGIC, 4, struct rc_config)
+#define VENC_IOCTL_ENCODE_CONFIG _IOW(VENC_IOCTL_MAGIC, 5, struct init_config)
+#define VENC_IOCTL_STOP _IO(VENC_IOCTL_MAGIC, 6)
+#define VENC_IOCTL_WAIT_FOR_ENCODE _IOR(VENC_IOCTL_MAGIC, 7, struct frame_type)
+#define VENC_IOCTL_STOP_ENCODE _IO(VENC_IOCTL_MAGIC, 8)
+
+#endif
+
diff --git a/libc/kernel/common/linux/sfh7743.h b/libc/kernel/common/linux/sfh7743.h
new file mode 100644
index 0000000..b6c363d
--- /dev/null
+++ b/libc/kernel/common/linux/sfh7743.h
@@ -0,0 +1,22 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SFH7743_H_
+#define _LINUX_SFH7743_H_
+
+#include <linux/ioctl.h>
+
+#define SFH7743_IO 0xA2
+
+#define SFH7743_IOCTL_GET_ENABLE _IOR(SFH7743_IO, 0x00, char)
+#define SFH7743_IOCTL_SET_ENABLE _IOW(SFH7743_IO, 0x01, char)
+
+#endif
diff --git a/libc/kernel/common/linux/videodev.h b/libc/kernel/common/linux/videodev.h
index 1f37fde..5a95f82 100644
--- a/libc/kernel/common/linux/videodev.h
+++ b/libc/kernel/common/linux/videodev.h
@@ -12,8 +12,25 @@
 #ifndef __LINUX_VIDEODEV_H
 #define __LINUX_VIDEODEV_H
 
+#include <linux/types.h>
+#include <linux/ioctl.h>
 #include <linux/videodev2.h>
 
+#define VID_TYPE_CAPTURE 1  
+#define VID_TYPE_TUNER 2  
+#define VID_TYPE_TELETEXT 4  
+#define VID_TYPE_OVERLAY 8  
+#define VID_TYPE_CHROMAKEY 16  
+#define VID_TYPE_CLIPPING 32  
+#define VID_TYPE_FRAMERAM 64  
+#define VID_TYPE_SCALES 128  
+#define VID_TYPE_MONOCHROME 256  
+#define VID_TYPE_SUBCAPTURE 512  
+#define VID_TYPE_MPEG_DECODER 1024  
+#define VID_TYPE_MPEG_ENCODER 2048  
+#define VID_TYPE_MJPEG_DECODER 4096  
+#define VID_TYPE_MJPEG_ENCODER 8192  
+
 struct video_capability
 {
  char name[32];
@@ -283,45 +300,6 @@
 #define VID_PLAY_RESET 13
 #define VID_PLAY_END_MARK 14
 
-#define VID_HARDWARE_BT848 1
-#define VID_HARDWARE_QCAM_BW 2
-#define VID_HARDWARE_PMS 3
-#define VID_HARDWARE_QCAM_C 4
-#define VID_HARDWARE_PSEUDO 5
-#define VID_HARDWARE_SAA5249 6
-#define VID_HARDWARE_AZTECH 7
-#define VID_HARDWARE_SF16MI 8
-#define VID_HARDWARE_RTRACK 9
-#define VID_HARDWARE_ZOLTRIX 10
-#define VID_HARDWARE_SAA7146 11
-#define VID_HARDWARE_VIDEUM 12  
-#define VID_HARDWARE_RTRACK2 13
-#define VID_HARDWARE_PERMEDIA2 14  
-#define VID_HARDWARE_RIVA128 15  
-#define VID_HARDWARE_PLANB 16  
-#define VID_HARDWARE_BROADWAY 17  
-#define VID_HARDWARE_GEMTEK 18
-#define VID_HARDWARE_TYPHOON 19
-#define VID_HARDWARE_VINO 20  
-#define VID_HARDWARE_CADET 21  
-#define VID_HARDWARE_TRUST 22  
-#define VID_HARDWARE_TERRATEC 23  
-#define VID_HARDWARE_CPIA 24
-#define VID_HARDWARE_ZR36120 25  
-#define VID_HARDWARE_ZR36067 26  
-#define VID_HARDWARE_OV511 27
-#define VID_HARDWARE_ZR356700 28  
-#define VID_HARDWARE_W9966 29
-#define VID_HARDWARE_SE401 30  
-#define VID_HARDWARE_PWC 31  
-#define VID_HARDWARE_MEYE 32  
-#define VID_HARDWARE_CPIA2 33
-#define VID_HARDWARE_VICAM 34
-#define VID_HARDWARE_SF16FMR2 35
-#define VID_HARDWARE_W9968CF 36
-#define VID_HARDWARE_SAA7114H 37
-#define VID_HARDWARE_SN9C102 38
-#define VID_HARDWARE_ARV 39
-
 #endif
 
+
diff --git a/libc/kernel/common/linux/videodev2.h b/libc/kernel/common/linux/videodev2.h
index dae4e93..3a91510 100644
--- a/libc/kernel/common/linux/videodev2.h
+++ b/libc/kernel/common/linux/videodev2.h
@@ -11,7 +11,10 @@
  ****************************************************************************/
 #ifndef __LINUX_VIDEODEV2_H
 #define __LINUX_VIDEODEV2_H
-#define __user
+
+#include <sys/time.h>
+#include <linux/compiler.h>
+#include <linux/ioctl.h>
 #include <linux/types.h>
 
 #define VIDEO_MAX_FRAME 32
@@ -31,7 +34,7 @@
 #define VID_TYPE_MJPEG_DECODER 4096  
 #define VID_TYPE_MJPEG_ENCODER 8192  
 
-#define v4l2_fourcc(a,b,c,d)  (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
+#define v4l2_fourcc(a, b, c, d)  ((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) | ((__u32)(d) << 24))
 
 enum v4l2_field {
  V4L2_FIELD_ANY = 0,
@@ -42,10 +45,12 @@
  V4L2_FIELD_SEQ_TB = 5,
  V4L2_FIELD_SEQ_BT = 6,
  V4L2_FIELD_ALTERNATE = 7,
+ V4L2_FIELD_INTERLACED_TB = 8,
+ V4L2_FIELD_INTERLACED_BT = 9,
 };
-#define V4L2_FIELD_HAS_TOP(field)   ((field) == V4L2_FIELD_TOP ||  (field) == V4L2_FIELD_INTERLACED ||  (field) == V4L2_FIELD_SEQ_TB ||  (field) == V4L2_FIELD_SEQ_BT)
-#define V4L2_FIELD_HAS_BOTTOM(field)   ((field) == V4L2_FIELD_BOTTOM ||  (field) == V4L2_FIELD_INTERLACED ||  (field) == V4L2_FIELD_SEQ_TB ||  (field) == V4L2_FIELD_SEQ_BT)
-#define V4L2_FIELD_HAS_BOTH(field)   ((field) == V4L2_FIELD_INTERLACED ||  (field) == V4L2_FIELD_SEQ_TB ||  (field) == V4L2_FIELD_SEQ_BT)
+#define V4L2_FIELD_HAS_TOP(field)   ((field) == V4L2_FIELD_TOP ||  (field) == V4L2_FIELD_INTERLACED ||  (field) == V4L2_FIELD_INTERLACED_TB ||  (field) == V4L2_FIELD_INTERLACED_BT ||  (field) == V4L2_FIELD_SEQ_TB ||  (field) == V4L2_FIELD_SEQ_BT)
+#define V4L2_FIELD_HAS_BOTTOM(field)   ((field) == V4L2_FIELD_BOTTOM ||  (field) == V4L2_FIELD_INTERLACED ||  (field) == V4L2_FIELD_INTERLACED_TB ||  (field) == V4L2_FIELD_INTERLACED_BT ||  (field) == V4L2_FIELD_SEQ_TB ||  (field) == V4L2_FIELD_SEQ_BT)
+#define V4L2_FIELD_HAS_BOTH(field)   ((field) == V4L2_FIELD_INTERLACED ||  (field) == V4L2_FIELD_INTERLACED_TB ||  (field) == V4L2_FIELD_INTERLACED_BT ||  (field) == V4L2_FIELD_SEQ_TB ||  (field) == V4L2_FIELD_SEQ_BT)
 
 enum v4l2_buf_type {
  V4L2_BUF_TYPE_VIDEO_CAPTURE = 1,
@@ -53,9 +58,10 @@
  V4L2_BUF_TYPE_VIDEO_OVERLAY = 3,
  V4L2_BUF_TYPE_VBI_CAPTURE = 4,
  V4L2_BUF_TYPE_VBI_OUTPUT = 5,
-
  V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6,
  V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7,
+
+ V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,
  V4L2_BUF_TYPE_PRIVATE = 0x80,
 };
 
@@ -118,8 +124,7 @@
  __u32 denominator;
 };
 
-struct v4l2_capability
-{
+struct v4l2_capability {
  __u8 driver[16];
  __u8 card[32];
  __u8 bus_info[32];
@@ -136,6 +141,8 @@
 #define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040  
 #define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080  
 #define V4L2_CAP_RDS_CAPTURE 0x00000100  
+#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200  
+#define V4L2_CAP_HW_FREQ_SEEK 0x00000400  
 
 #define V4L2_CAP_TUNER 0x00010000  
 #define V4L2_CAP_AUDIO 0x00020000  
@@ -145,8 +152,7 @@
 #define V4L2_CAP_ASYNCIO 0x02000000  
 #define V4L2_CAP_STREAMING 0x04000000  
 
-struct v4l2_pix_format
-{
+struct v4l2_pix_format {
  __u32 width;
  __u32 height;
  __u32 pixelformat;
@@ -157,48 +163,71 @@
  __u32 priv;
 };
 
-#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R','G','B','1')  
-#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R','G','B','O')  
-#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R','G','B','P')  
-#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R','G','B','Q')  
-#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R','G','B','R')  
-#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B','G','R','3')  
-#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R','G','B','3')  
-#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B','G','R','4')  
-#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R','G','B','4')  
-#define V4L2_PIX_FMT_GREY v4l2_fourcc('G','R','E','Y')  
-#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y','V','U','9')  
-#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y','V','1','2')  
-#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y','U','Y','V')  
-#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U','Y','V','Y')  
-#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4','2','2','P')  
-#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4','1','1','P')  
-#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y','4','1','P')  
+#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1')  
+#define V4L2_PIX_FMT_RGB444 v4l2_fourcc('R', '4', '4', '4')  
+#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R', 'G', 'B', 'O')  
+#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R', 'G', 'B', 'P')  
+#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q')  
+#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R', 'G', 'B', 'R')  
+#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B', 'G', 'R', '3')  
+#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R', 'G', 'B', '3')  
+#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4')  
+#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4')  
+#define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y')  
+#define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ')  
+#define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8')  
+#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y', 'V', 'U', '9')  
+#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2')  
+#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V')  
+#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y')  
+#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y')  
+#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P')  
+#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P')  
+#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P')  
+#define V4L2_PIX_FMT_YUV444 v4l2_fourcc('Y', '4', '4', '4')  
+#define V4L2_PIX_FMT_YUV555 v4l2_fourcc('Y', 'U', 'V', 'O')  
+#define V4L2_PIX_FMT_YUV565 v4l2_fourcc('Y', 'U', 'V', 'P')  
+#define V4L2_PIX_FMT_YUV32 v4l2_fourcc('Y', 'U', 'V', '4')  
 
-#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N','V','1','2')  
-#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N','V','2','1')  
+#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2')  
+#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1')  
+#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6')  
+#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1')  
 
-#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y','U','V','9')  
-#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y','U','1','2')  
-#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y','Y','U','V')  
-#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H','I','2','4')  
-#define V4L2_PIX_FMT_HM12 v4l2_fourcc('H','M','1','2')  
+#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9')  
+#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2')  
+#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y', 'Y', 'U', 'V')  
+#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4')  
+#define V4L2_PIX_FMT_HM12 v4l2_fourcc('H', 'M', '1', '2')  
 
-#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B','A','8','1')  
+#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1')  
+#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G')  
 
-#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M','J','P','G')  
-#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J','P','E','G')  
-#define V4L2_PIX_FMT_DV v4l2_fourcc('d','v','s','d')  
-#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M','P','E','G')  
+#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0')
 
-#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W','N','V','A')  
-#define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S','9','1','0')  
-#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P','W','C','1')  
-#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P','W','C','2')  
-#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E','6','2','5')  
+#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0')
+#define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2')  
+#define V4L2_PIX_FMT_W1S_PATT v4l2_fourcc('P', 'A', 'T', '1')  
 
-struct v4l2_fmtdesc
-{
+#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G')  
+#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J', 'P', 'E', 'G')  
+#define V4L2_PIX_FMT_DV v4l2_fourcc('d', 'v', 's', 'd')  
+#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M', 'P', 'E', 'G')  
+
+#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A')  
+#define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0')  
+#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P', 'W', 'C', '1')  
+#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2')  
+#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5')  
+#define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S', '5', '0', '1')  
+#define V4L2_PIX_FMT_SPCA505 v4l2_fourcc('S', '5', '0', '5')  
+#define V4L2_PIX_FMT_SPCA508 v4l2_fourcc('S', '5', '0', '8')  
+#define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1')  
+#define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P', '2', '0', '7')  
+#define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G')  
+#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U')  
+
+struct v4l2_fmtdesc {
  __u32 index;
  enum v4l2_buf_type type;
  __u32 flags;
@@ -209,8 +238,67 @@
 
 #define V4L2_FMT_FLAG_COMPRESSED 0x0001
 
-struct v4l2_timecode
-{
+enum v4l2_frmsizetypes {
+ V4L2_FRMSIZE_TYPE_DISCRETE = 1,
+ V4L2_FRMSIZE_TYPE_CONTINUOUS = 2,
+ V4L2_FRMSIZE_TYPE_STEPWISE = 3,
+};
+
+struct v4l2_frmsize_discrete {
+ __u32 width;
+ __u32 height;
+};
+
+struct v4l2_frmsize_stepwise {
+ __u32 min_width;
+ __u32 max_width;
+ __u32 step_width;
+ __u32 min_height;
+ __u32 max_height;
+ __u32 step_height;
+};
+
+struct v4l2_frmsizeenum {
+ __u32 index;
+ __u32 pixel_format;
+ __u32 type;
+
+ union {
+ struct v4l2_frmsize_discrete discrete;
+ struct v4l2_frmsize_stepwise stepwise;
+ };
+
+ __u32 reserved[2];
+};
+
+enum v4l2_frmivaltypes {
+ V4L2_FRMIVAL_TYPE_DISCRETE = 1,
+ V4L2_FRMIVAL_TYPE_CONTINUOUS = 2,
+ V4L2_FRMIVAL_TYPE_STEPWISE = 3,
+};
+
+struct v4l2_frmival_stepwise {
+ struct v4l2_fract min;
+ struct v4l2_fract max;
+ struct v4l2_fract step;
+};
+
+struct v4l2_frmivalenum {
+ __u32 index;
+ __u32 pixel_format;
+ __u32 width;
+ __u32 height;
+ __u32 type;
+
+ union {
+ struct v4l2_fract discrete;
+ struct v4l2_frmival_stepwise stepwise;
+ };
+
+ __u32 reserved[2];
+};
+
+struct v4l2_timecode {
  __u32 type;
  __u32 flags;
  __u8 frames;
@@ -232,8 +320,7 @@
 #define V4L2_TC_USERBITS_USERDEFINED 0x0000
 #define V4L2_TC_USERBITS_8BITCHARS 0x0008
 
-struct v4l2_jpegcompression
-{
+struct v4l2_jpegcompression {
  int quality;
 
  int APPn;
@@ -252,16 +339,14 @@
 #define V4L2_JPEG_MARKER_APP (1<<7)  
 };
 
-struct v4l2_requestbuffers
-{
+struct v4l2_requestbuffers {
  __u32 count;
  enum v4l2_buf_type type;
  enum v4l2_memory memory;
  __u32 reserved[2];
 };
 
-struct v4l2_buffer
-{
+struct v4l2_buffer {
  __u32 index;
  enum v4l2_buf_type type;
  __u32 bytesused;
@@ -290,12 +375,11 @@
 #define V4L2_BUF_FLAG_TIMECODE 0x0100  
 #define V4L2_BUF_FLAG_INPUT 0x0200  
 
-struct v4l2_framebuffer
-{
+struct v4l2_framebuffer {
  __u32 capability;
  __u32 flags;
 
- void* base;
+ void *base;
  struct v4l2_pix_format fmt;
 };
 
@@ -303,29 +387,35 @@
 #define V4L2_FBUF_CAP_CHROMAKEY 0x0002
 #define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004
 #define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008
+#define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010
+#define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020
+#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040
+#define V4L2_FBUF_CAP_SRC_CHROMAKEY 0x0080
 
 #define V4L2_FBUF_FLAG_PRIMARY 0x0001
 #define V4L2_FBUF_FLAG_OVERLAY 0x0002
 #define V4L2_FBUF_FLAG_CHROMAKEY 0x0004
+#define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008
+#define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010
+#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020
+#define V4L2_FBUF_FLAG_SRC_CHROMAKEY 0x0040
 
-struct v4l2_clip
-{
+struct v4l2_clip {
  struct v4l2_rect c;
  struct v4l2_clip __user *next;
 };
 
-struct v4l2_window
-{
+struct v4l2_window {
  struct v4l2_rect w;
  enum v4l2_field field;
  __u32 chromakey;
  struct v4l2_clip __user *clips;
  __u32 clipcount;
  void __user *bitmap;
+ __u8 global_alpha;
 };
 
-struct v4l2_captureparm
-{
+struct v4l2_captureparm {
  __u32 capability;
  __u32 capturemode;
  struct v4l2_fract timeperframe;
@@ -337,8 +427,7 @@
 #define V4L2_MODE_HIGHQUALITY 0x0001  
 #define V4L2_CAP_TIMEPERFRAME 0x1000  
 
-struct v4l2_outputparm
-{
+struct v4l2_outputparm {
  __u32 capability;
  __u32 outputmode;
  struct v4l2_fract timeperframe;
@@ -411,8 +500,7 @@
 #define V4L2_STD_UNKNOWN 0
 #define V4L2_STD_ALL (V4L2_STD_525_60 |  V4L2_STD_625_50)
 
-struct v4l2_standard
-{
+struct v4l2_standard {
  __u32 index;
  v4l2_std_id id;
  __u8 name[24];
@@ -421,8 +509,7 @@
  __u32 reserved[4];
 };
 
-struct v4l2_input
-{
+struct v4l2_input {
  __u32 index;
  __u8 name[32];
  __u32 type;
@@ -451,8 +538,7 @@
 #define V4L2_IN_ST_NO_ACCESS 0x02000000  
 #define V4L2_IN_ST_VTR 0x04000000  
 
-struct v4l2_output
-{
+struct v4l2_output {
  __u32 index;
  __u8 name[32];
  __u32 type;
@@ -466,14 +552,12 @@
 #define V4L2_OUTPUT_TYPE_ANALOG 2
 #define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3
 
-struct v4l2_control
-{
+struct v4l2_control {
  __u32 id;
  __s32 value;
 };
 
-struct v4l2_ext_control
-{
+struct v4l2_ext_control {
  __u32 id;
  __u32 reserved2[2];
  union {
@@ -483,8 +567,7 @@
  };
 } __attribute__ ((packed));
 
-struct v4l2_ext_controls
-{
+struct v4l2_ext_controls {
  __u32 ctrl_class;
  __u32 count;
  __u32 error_idx;
@@ -494,13 +577,13 @@
 
 #define V4L2_CTRL_CLASS_USER 0x00980000  
 #define V4L2_CTRL_CLASS_MPEG 0x00990000  
+#define V4L2_CTRL_CLASS_CAMERA 0x009a0000  
 
 #define V4L2_CTRL_ID_MASK (0x0fffffff)
 #define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL)
 #define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000)
 
-struct v4l2_queryctrl
-{
+struct v4l2_queryctrl {
  __u32 id;
  enum v4l2_ctrl_type type;
  __u8 name[32];
@@ -512,8 +595,7 @@
  __u32 reserved[2];
 };
 
-struct v4l2_querymenu
-{
+struct v4l2_querymenu {
  __u32 id;
  __u32 index;
  __u8 name[32];
@@ -545,7 +627,7 @@
 #define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8)
 #define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9)
 #define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10)
-#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11)
+#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11)  
 #define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12)
 #define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13)
 #define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14)
@@ -557,9 +639,31 @@
 #define V4L2_CID_GAIN (V4L2_CID_BASE+19)
 #define V4L2_CID_HFLIP (V4L2_CID_BASE+20)
 #define V4L2_CID_VFLIP (V4L2_CID_BASE+21)
+
 #define V4L2_CID_HCENTER (V4L2_CID_BASE+22)
 #define V4L2_CID_VCENTER (V4L2_CID_BASE+23)
-#define V4L2_CID_LASTP1 (V4L2_CID_BASE+24)  
+
+#define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24)
+enum v4l2_power_line_frequency {
+ V4L2_CID_POWER_LINE_FREQUENCY_DISABLED = 0,
+ V4L2_CID_POWER_LINE_FREQUENCY_50HZ = 1,
+ V4L2_CID_POWER_LINE_FREQUENCY_60HZ = 2,
+};
+#define V4L2_CID_HUE_AUTO (V4L2_CID_BASE+25)
+#define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE+26)
+#define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27)
+#define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28)
+#define V4L2_CID_CHROMA_AGC (V4L2_CID_BASE+29)
+#define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30)
+#define V4L2_CID_COLORFX (V4L2_CID_BASE+31)
+#define V4L2_CID_ROTATE (V4L2_CID_BASE+32)
+#define V4L2_CID_BG_COLOR (V4L2_CID_BASE+33)
+#define V4L2_CID_LASTP1 (V4L2_CID_BASE+34)
+enum v4l2_colorfx {
+ V4L2_COLORFX_NONE = 0,
+ V4L2_COLORFX_BW = 1,
+ V4L2_COLORFX_SEPIA = 2,
+};
 
 #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
 #define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1)
@@ -596,6 +700,8 @@
  V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0,
  V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1,
  V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2,
+ V4L2_MPEG_AUDIO_ENCODING_AAC = 3,
+ V4L2_MPEG_AUDIO_ENCODING_AC3 = 4,
 };
 #define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102)
 enum v4l2_mpeg_audio_l1_bitrate {
@@ -673,11 +779,36 @@
  V4L2_MPEG_AUDIO_CRC_NONE = 0,
  V4L2_MPEG_AUDIO_CRC_CRC16 = 1,
 };
+#define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109)
+#define V4L2_CID_MPEG_AUDIO_AAC_BITRATE (V4L2_CID_MPEG_BASE+110)
+#define V4L2_CID_MPEG_AUDIO_AC3_BITRATE (V4L2_CID_MPEG_BASE+111)
+enum v4l2_mpeg_audio_ac3_bitrate {
+ V4L2_MPEG_AUDIO_AC3_BITRATE_32K = 0,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_40K = 1,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_48K = 2,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_56K = 3,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_64K = 4,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_80K = 5,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_96K = 6,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_112K = 7,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_128K = 8,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_160K = 9,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_192K = 10,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_224K = 11,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_256K = 12,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_320K = 13,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_384K = 14,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_448K = 15,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_512K = 16,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_576K = 17,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18,
+};
 
 #define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200)
 enum v4l2_mpeg_video_encoding {
  V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0,
  V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC = 2,
 };
 #define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201)
 enum v4l2_mpeg_video_aspect {
@@ -698,6 +829,8 @@
 #define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207)
 #define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208)
 #define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209)
+#define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210)
+#define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211)
 
 #define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000)
 #define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0)
@@ -737,9 +870,40 @@
 #define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8)
 #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9)
 #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10)
+#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11)
 
-struct v4l2_tuner
-{
+#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900)
+#define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1)
+
+#define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE+1)
+enum v4l2_exposure_auto_type {
+ V4L2_EXPOSURE_AUTO = 0,
+ V4L2_EXPOSURE_MANUAL = 1,
+ V4L2_EXPOSURE_SHUTTER_PRIORITY = 2,
+ V4L2_EXPOSURE_APERTURE_PRIORITY = 3
+};
+#define V4L2_CID_EXPOSURE_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+2)
+#define V4L2_CID_EXPOSURE_AUTO_PRIORITY (V4L2_CID_CAMERA_CLASS_BASE+3)
+
+#define V4L2_CID_PAN_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+4)
+#define V4L2_CID_TILT_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+5)
+#define V4L2_CID_PAN_RESET (V4L2_CID_CAMERA_CLASS_BASE+6)
+#define V4L2_CID_TILT_RESET (V4L2_CID_CAMERA_CLASS_BASE+7)
+
+#define V4L2_CID_PAN_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+8)
+#define V4L2_CID_TILT_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+9)
+
+#define V4L2_CID_FOCUS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+10)
+#define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11)
+#define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12)
+
+#define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+13)
+#define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14)
+#define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15)
+
+#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16)
+
+struct v4l2_tuner {
  __u32 index;
  __u8 name[32];
  enum v4l2_tuner_type type;
@@ -753,8 +917,7 @@
  __u32 reserved[4];
 };
 
-struct v4l2_modulator
-{
+struct v4l2_modulator {
  __u32 index;
  __u8 name[32];
  __u32 capability;
@@ -784,16 +947,22 @@
 #define V4L2_TUNER_MODE_LANG1 0x0003
 #define V4L2_TUNER_MODE_LANG1_LANG2 0x0004
 
-struct v4l2_frequency
-{
+struct v4l2_frequency {
  __u32 tuner;
  enum v4l2_tuner_type type;
  __u32 frequency;
  __u32 reserved[8];
 };
 
-struct v4l2_audio
-{
+struct v4l2_hw_freq_seek {
+ __u32 tuner;
+ enum v4l2_tuner_type type;
+ __u32 seek_upward;
+ __u32 wrap_around;
+ __u32 reserved[8];
+};
+
+struct v4l2_audio {
  __u32 index;
  __u8 name[32];
  __u32 capability;
@@ -806,8 +975,7 @@
 
 #define V4L2_AUDMODE_AVL 0x00001
 
-struct v4l2_audioout
-{
+struct v4l2_audioout {
  __u32 index;
  __u8 name[32];
  __u32 capability;
@@ -815,8 +983,45 @@
  __u32 reserved[2];
 };
 
-struct v4l2_vbi_format
-{
+#define V4L2_ENC_IDX_FRAME_I (0)
+#define V4L2_ENC_IDX_FRAME_P (1)
+#define V4L2_ENC_IDX_FRAME_B (2)
+#define V4L2_ENC_IDX_FRAME_MASK (0xf)
+
+struct v4l2_enc_idx_entry {
+ __u64 offset;
+ __u64 pts;
+ __u32 length;
+ __u32 flags;
+ __u32 reserved[2];
+};
+
+#define V4L2_ENC_IDX_ENTRIES (64)
+struct v4l2_enc_idx {
+ __u32 entries;
+ __u32 entries_cap;
+ __u32 reserved[4];
+ struct v4l2_enc_idx_entry entry[V4L2_ENC_IDX_ENTRIES];
+};
+
+#define V4L2_ENC_CMD_START (0)
+#define V4L2_ENC_CMD_STOP (1)
+#define V4L2_ENC_CMD_PAUSE (2)
+#define V4L2_ENC_CMD_RESUME (3)
+
+#define V4L2_ENC_CMD_STOP_AT_GOP_END (1 << 0)
+
+struct v4l2_encoder_cmd {
+ __u32 cmd;
+ __u32 flags;
+ union {
+ struct {
+ __u32 data[8];
+ } raw;
+ };
+};
+
+struct v4l2_vbi_format {
  __u32 sampling_rate;
  __u32 offset;
  __u32 samples_per_line;
@@ -827,11 +1032,10 @@
  __u32 reserved[2];
 };
 
-#define V4L2_VBI_UNSYNC (1<< 0)
-#define V4L2_VBI_INTERLACED (1<< 1)
+#define V4L2_VBI_UNSYNC (1 << 0)
+#define V4L2_VBI_INTERLACED (1 << 1)
 
-struct v4l2_sliced_vbi_format
-{
+struct v4l2_sliced_vbi_format {
  __u16 service_set;
 
  __u16 service_lines[2][24];
@@ -850,16 +1054,15 @@
 #define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525)
 #define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625)
 
-struct v4l2_sliced_vbi_cap
-{
+struct v4l2_sliced_vbi_cap {
  __u16 service_set;
 
  __u16 service_lines[2][24];
- __u32 reserved[4];
+ enum v4l2_buf_type type;
+ __u32 reserved[3];
 };
 
-struct v4l2_sliced_vbi_data
-{
+struct v4l2_sliced_vbi_data {
  __u32 id;
  __u32 field;
  __u32 line;
@@ -867,11 +1070,9 @@
  __u8 data[48];
 };
 
-struct v4l2_format
-{
+struct v4l2_format {
  enum v4l2_buf_type type;
- union
- {
+ union {
  struct v4l2_pix_format pix;
  struct v4l2_window win;
  struct v4l2_vbi_format vbi;
@@ -880,81 +1081,126 @@
  } fmt;
 };
 
-struct v4l2_streamparm
-{
+struct v4l2_streamparm {
  enum v4l2_buf_type type;
- union
- {
+ union {
  struct v4l2_captureparm capture;
  struct v4l2_outputparm output;
  __u8 raw_data[200];
  } parm;
 };
 
-#define VIDIOC_QUERYCAP _IOR ('V', 0, struct v4l2_capability)
-#define VIDIOC_RESERVED _IO ('V', 1)
-#define VIDIOC_ENUM_FMT _IOWR ('V', 2, struct v4l2_fmtdesc)
-#define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format)
-#define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format)
-#define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers)
-#define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer)
-#define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer)
-#define VIDIOC_S_FBUF _IOW ('V', 11, struct v4l2_framebuffer)
-#define VIDIOC_OVERLAY _IOW ('V', 14, int)
-#define VIDIOC_QBUF _IOWR ('V', 15, struct v4l2_buffer)
-#define VIDIOC_DQBUF _IOWR ('V', 17, struct v4l2_buffer)
-#define VIDIOC_STREAMON _IOW ('V', 18, int)
-#define VIDIOC_STREAMOFF _IOW ('V', 19, int)
-#define VIDIOC_G_PARM _IOWR ('V', 21, struct v4l2_streamparm)
-#define VIDIOC_S_PARM _IOWR ('V', 22, struct v4l2_streamparm)
-#define VIDIOC_G_STD _IOR ('V', 23, v4l2_std_id)
-#define VIDIOC_S_STD _IOW ('V', 24, v4l2_std_id)
-#define VIDIOC_ENUMSTD _IOWR ('V', 25, struct v4l2_standard)
-#define VIDIOC_ENUMINPUT _IOWR ('V', 26, struct v4l2_input)
-#define VIDIOC_G_CTRL _IOWR ('V', 27, struct v4l2_control)
-#define VIDIOC_S_CTRL _IOWR ('V', 28, struct v4l2_control)
-#define VIDIOC_G_TUNER _IOWR ('V', 29, struct v4l2_tuner)
-#define VIDIOC_S_TUNER _IOW ('V', 30, struct v4l2_tuner)
-#define VIDIOC_G_AUDIO _IOR ('V', 33, struct v4l2_audio)
-#define VIDIOC_S_AUDIO _IOW ('V', 34, struct v4l2_audio)
-#define VIDIOC_QUERYCTRL _IOWR ('V', 36, struct v4l2_queryctrl)
-#define VIDIOC_QUERYMENU _IOWR ('V', 37, struct v4l2_querymenu)
-#define VIDIOC_G_INPUT _IOR ('V', 38, int)
-#define VIDIOC_S_INPUT _IOWR ('V', 39, int)
-#define VIDIOC_G_OUTPUT _IOR ('V', 46, int)
-#define VIDIOC_S_OUTPUT _IOWR ('V', 47, int)
-#define VIDIOC_ENUMOUTPUT _IOWR ('V', 48, struct v4l2_output)
-#define VIDIOC_G_AUDOUT _IOR ('V', 49, struct v4l2_audioout)
-#define VIDIOC_S_AUDOUT _IOW ('V', 50, struct v4l2_audioout)
-#define VIDIOC_G_MODULATOR _IOWR ('V', 54, struct v4l2_modulator)
-#define VIDIOC_S_MODULATOR _IOW ('V', 55, struct v4l2_modulator)
-#define VIDIOC_G_FREQUENCY _IOWR ('V', 56, struct v4l2_frequency)
-#define VIDIOC_S_FREQUENCY _IOW ('V', 57, struct v4l2_frequency)
-#define VIDIOC_CROPCAP _IOWR ('V', 58, struct v4l2_cropcap)
-#define VIDIOC_G_CROP _IOWR ('V', 59, struct v4l2_crop)
-#define VIDIOC_S_CROP _IOW ('V', 60, struct v4l2_crop)
-#define VIDIOC_G_JPEGCOMP _IOR ('V', 61, struct v4l2_jpegcompression)
-#define VIDIOC_S_JPEGCOMP _IOW ('V', 62, struct v4l2_jpegcompression)
-#define VIDIOC_QUERYSTD _IOR ('V', 63, v4l2_std_id)
-#define VIDIOC_TRY_FMT _IOWR ('V', 64, struct v4l2_format)
-#define VIDIOC_ENUMAUDIO _IOWR ('V', 65, struct v4l2_audio)
-#define VIDIOC_ENUMAUDOUT _IOWR ('V', 66, struct v4l2_audioout)
-#define VIDIOC_G_PRIORITY _IOR ('V', 67, enum v4l2_priority)
-#define VIDIOC_S_PRIORITY _IOW ('V', 68, enum v4l2_priority)
-#define VIDIOC_G_SLICED_VBI_CAP _IOR ('V', 69, struct v4l2_sliced_vbi_cap)
-#define VIDIOC_LOG_STATUS _IO ('V', 70)
-#define VIDIOC_G_EXT_CTRLS _IOWR ('V', 71, struct v4l2_ext_controls)
-#define VIDIOC_S_EXT_CTRLS _IOWR ('V', 72, struct v4l2_ext_controls)
-#define VIDIOC_TRY_EXT_CTRLS _IOWR ('V', 73, struct v4l2_ext_controls)
+#define V4L2_CHIP_MATCH_HOST 0  
+#define V4L2_CHIP_MATCH_I2C_DRIVER 1  
+#define V4L2_CHIP_MATCH_I2C_ADDR 2  
+#define V4L2_CHIP_MATCH_AC97 3  
+
+struct v4l2_dbg_match {
+ __u32 type;
+ union {
+ __u32 addr;
+ char name[32];
+ };
+} __attribute__ ((packed));
+
+struct v4l2_dbg_register {
+ struct v4l2_dbg_match match;
+ __u32 size;
+ __u64 reg;
+ __u64 val;
+} __attribute__ ((packed));
+
+struct v4l2_dbg_chip_ident {
+ struct v4l2_dbg_match match;
+ __u32 ident;
+ __u32 revision;
+} __attribute__ ((packed));
+
+struct v4l2_chip_ident_old {
+ __u32 match_type;
+ __u32 match_chip;
+ __u32 ident;
+ __u32 revision;
+};
+
+#define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability)
+#define VIDIOC_RESERVED _IO('V', 1)
+#define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc)
+#define VIDIOC_G_FMT _IOWR('V', 4, struct v4l2_format)
+#define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format)
+#define VIDIOC_REQBUFS _IOWR('V', 8, struct v4l2_requestbuffers)
+#define VIDIOC_QUERYBUF _IOWR('V', 9, struct v4l2_buffer)
+#define VIDIOC_G_FBUF _IOR('V', 10, struct v4l2_framebuffer)
+#define VIDIOC_S_FBUF _IOW('V', 11, struct v4l2_framebuffer)
+#define VIDIOC_OVERLAY _IOW('V', 14, int)
+#define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer)
+#define VIDIOC_DQBUF _IOWR('V', 17, struct v4l2_buffer)
+#define VIDIOC_STREAMON _IOW('V', 18, int)
+#define VIDIOC_STREAMOFF _IOW('V', 19, int)
+#define VIDIOC_G_PARM _IOWR('V', 21, struct v4l2_streamparm)
+#define VIDIOC_S_PARM _IOWR('V', 22, struct v4l2_streamparm)
+#define VIDIOC_G_STD _IOR('V', 23, v4l2_std_id)
+#define VIDIOC_S_STD _IOW('V', 24, v4l2_std_id)
+#define VIDIOC_ENUMSTD _IOWR('V', 25, struct v4l2_standard)
+#define VIDIOC_ENUMINPUT _IOWR('V', 26, struct v4l2_input)
+#define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control)
+#define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control)
+#define VIDIOC_G_TUNER _IOWR('V', 29, struct v4l2_tuner)
+#define VIDIOC_S_TUNER _IOW('V', 30, struct v4l2_tuner)
+#define VIDIOC_G_AUDIO _IOR('V', 33, struct v4l2_audio)
+#define VIDIOC_S_AUDIO _IOW('V', 34, struct v4l2_audio)
+#define VIDIOC_QUERYCTRL _IOWR('V', 36, struct v4l2_queryctrl)
+#define VIDIOC_QUERYMENU _IOWR('V', 37, struct v4l2_querymenu)
+#define VIDIOC_G_INPUT _IOR('V', 38, int)
+#define VIDIOC_S_INPUT _IOWR('V', 39, int)
+#define VIDIOC_G_OUTPUT _IOR('V', 46, int)
+#define VIDIOC_S_OUTPUT _IOWR('V', 47, int)
+#define VIDIOC_ENUMOUTPUT _IOWR('V', 48, struct v4l2_output)
+#define VIDIOC_G_AUDOUT _IOR('V', 49, struct v4l2_audioout)
+#define VIDIOC_S_AUDOUT _IOW('V', 50, struct v4l2_audioout)
+#define VIDIOC_G_MODULATOR _IOWR('V', 54, struct v4l2_modulator)
+#define VIDIOC_S_MODULATOR _IOW('V', 55, struct v4l2_modulator)
+#define VIDIOC_G_FREQUENCY _IOWR('V', 56, struct v4l2_frequency)
+#define VIDIOC_S_FREQUENCY _IOW('V', 57, struct v4l2_frequency)
+#define VIDIOC_CROPCAP _IOWR('V', 58, struct v4l2_cropcap)
+#define VIDIOC_G_CROP _IOWR('V', 59, struct v4l2_crop)
+#define VIDIOC_S_CROP _IOW('V', 60, struct v4l2_crop)
+#define VIDIOC_G_JPEGCOMP _IOR('V', 61, struct v4l2_jpegcompression)
+#define VIDIOC_S_JPEGCOMP _IOW('V', 62, struct v4l2_jpegcompression)
+#define VIDIOC_QUERYSTD _IOR('V', 63, v4l2_std_id)
+#define VIDIOC_TRY_FMT _IOWR('V', 64, struct v4l2_format)
+#define VIDIOC_ENUMAUDIO _IOWR('V', 65, struct v4l2_audio)
+#define VIDIOC_ENUMAUDOUT _IOWR('V', 66, struct v4l2_audioout)
+#define VIDIOC_G_PRIORITY _IOR('V', 67, enum v4l2_priority)
+#define VIDIOC_S_PRIORITY _IOW('V', 68, enum v4l2_priority)
+#define VIDIOC_G_SLICED_VBI_CAP _IOWR('V', 69, struct v4l2_sliced_vbi_cap)
+#define VIDIOC_LOG_STATUS _IO('V', 70)
+#define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct v4l2_ext_controls)
+#define VIDIOC_S_EXT_CTRLS _IOWR('V', 72, struct v4l2_ext_controls)
+#define VIDIOC_TRY_EXT_CTRLS _IOWR('V', 73, struct v4l2_ext_controls)
+#define VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct v4l2_frmsizeenum)
+#define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct v4l2_frmivalenum)
+#define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct v4l2_enc_idx)
+#define VIDIOC_ENCODER_CMD _IOWR('V', 77, struct v4l2_encoder_cmd)
+#define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct v4l2_encoder_cmd)
+
+#define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register)
+#define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register)
+
+#define VIDIOC_DBG_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_dbg_chip_ident)
+
+#define VIDIOC_G_CHIP_IDENT_OLD _IOWR('V', 81, struct v4l2_chip_ident_old)
+
+#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek)
 
 #ifdef __OLD_VIDIOC_
 
-#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int)
-#define VIDIOC_S_PARM_OLD _IOW ('V', 22, struct v4l2_streamparm)
-#define VIDIOC_S_CTRL_OLD _IOW ('V', 28, struct v4l2_control)
-#define VIDIOC_G_AUDIO_OLD _IOWR ('V', 33, struct v4l2_audio)
-#define VIDIOC_G_AUDOUT_OLD _IOWR ('V', 49, struct v4l2_audioout)
-#define VIDIOC_CROPCAP_OLD _IOR ('V', 58, struct v4l2_cropcap)
+#define VIDIOC_OVERLAY_OLD _IOWR('V', 14, int)
+#define VIDIOC_S_PARM_OLD _IOW('V', 22, struct v4l2_streamparm)
+#define VIDIOC_S_CTRL_OLD _IOW('V', 28, struct v4l2_control)
+#define VIDIOC_G_AUDIO_OLD _IOWR('V', 33, struct v4l2_audio)
+#define VIDIOC_G_AUDOUT_OLD _IOWR('V', 49, struct v4l2_audioout)
+#define VIDIOC_CROPCAP_OLD _IOR('V', 58, struct v4l2_cropcap)
 #endif
 
 #define BASE_VIDIOC_PRIVATE 192  
diff --git a/libc/kernel/common/media/msm_camera.h b/libc/kernel/common/media/msm_camera.h
index 6596d6b..a0b4a24 100644
--- a/libc/kernel/common/media/msm_camera.h
+++ b/libc/kernel/common/media/msm_camera.h
@@ -54,9 +54,9 @@
 
 #define MSM_CAM_IOCTL_SET_CROP   _IOW(MSM_CAM_IOCTL_MAGIC, 18, struct crop_info *)
 
-#define MSM_CAM_IOCTL_PICT_PP   _IOW(MSM_CAM_IOCTL_MAGIC, 19, uint8_t *)
+#define MSM_CAM_IOCTL_PP   _IOW(MSM_CAM_IOCTL_MAGIC, 19, uint8_t *)
 
-#define MSM_CAM_IOCTL_PICT_PP_DONE   _IOW(MSM_CAM_IOCTL_MAGIC, 20, struct msm_snapshot_pp_status *)
+#define MSM_CAM_IOCTL_PP_DONE   _IOW(MSM_CAM_IOCTL_MAGIC, 20, struct msm_snapshot_pp_status *)
 
 #define MSM_CAM_IOCTL_SENSOR_IO_CFG   _IOW(MSM_CAM_IOCTL_MAGIC, 21, struct sensor_cfg_data *)
 
@@ -73,6 +73,11 @@
 #define MAX_SENSOR_NUM 3
 #define MAX_SENSOR_NAME 32
 
+#define PP_SNAP 1
+#define PP_RAW_SNAP (1<<1)
+#define PP_PREV (1<<2)
+#define PP_MASK (PP_SNAP|PP_RAW_SNAP|PP_PREV)
+
 #define MSM_CAM_CTRL_CMD_DONE 0
 #define MSM_CAM_SENSOR_VFE_CMD 1
 
@@ -130,11 +135,12 @@
 #define CMD_SNAP_BUF_RELEASE 11
 #define CMD_SNAP_BUF_CFG 12
 #define CMD_STATS_DISABLE 13
-#define CMD_STATS_ENABLE 14
+#define CMD_STATS_AEC_AWB_ENABLE 14
 #define CMD_STATS_AF_ENABLE 15
 #define CMD_STATS_BUF_RELEASE 16
 #define CMD_STATS_AF_BUF_RELEASE 17
-#define UPDATE_STATS_INVALID 18
+#define CMD_STATS_ENABLE 18
+#define UPDATE_STATS_INVALID 19
 
 struct msm_vfe_cfg_cmd {
  int cmd_type;
@@ -150,7 +156,7 @@
 #define MSM_PMEM_OUTPUT1 0
 #define MSM_PMEM_OUTPUT2 1
 #define MSM_PMEM_OUTPUT1_OUTPUT2 2
-#define MSM_PMEM_THUMBAIL 3
+#define MSM_PMEM_THUMBNAIL 3
 #define MSM_PMEM_MAINIMG 4
 #define MSM_PMEM_RAW_MAINIMG 5
 #define MSM_PMEM_AEC_AWB 6
diff --git a/libc/kernel/tools/clean_header.py b/libc/kernel/tools/clean_header.py
index de4bf85..28cb05e 100755
--- a/libc/kernel/tools/clean_header.py
+++ b/libc/kernel/tools/clean_header.py
@@ -96,7 +96,7 @@
         sys.exit(1)
 
     try:
-        optlist, args = getopt.getopt( sys.argv[1:], 'uv' )
+        optlist, args = getopt.getopt( sys.argv[1:], 'uvk:' )
     except:
         # unrecognized option
         sys.stderr.write( "error: unrecognized option\n" )
@@ -108,6 +108,8 @@
         elif opt == '-v':
             verbose = 1
             D_setlevel(1)
+        elif opt == '-k':
+            kernel_original_path = arg
 
     if len(args) == 0:
         usage()
diff --git a/libc/netbsd/net/getaddrinfo.c b/libc/netbsd/net/getaddrinfo.c
index f2189fb..1233cb8 100644
--- a/libc/netbsd/net/getaddrinfo.c
+++ b/libc/netbsd/net/getaddrinfo.c
@@ -335,6 +335,36 @@
 		return -1;
 }
 
+/* Determine whether IPv6 connectivity is available. */
+static int
+_have_ipv6() {
+	/*
+	 * Connect a UDP socket to an global unicast IPv6 address. This will
+	 * cause no network traffic, but will fail fast if the system has no or
+	 * limited IPv6 connectivity (e.g., only a link-local address).
+	 */
+	static const struct sockaddr_in6 sin6_test = {
+		/* family, port, flow label */
+		AF_INET6, 0, 0,
+		/* 2000:: */
+		{{{ 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}},
+		/* scope ID */
+		0};
+	static const struct sockaddr *sa_test = (struct sockaddr *) &sin6_test;
+	int s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+	if (s < 0)
+		return 0;
+	int ret;
+	do {
+		ret = connect(s, sa_test, sizeof(sin6_test));
+	} while (ret < 0 && errno == EINTR);
+	int have_ipv6 = (ret == 0);
+	do {
+		ret = close(s);
+	} while (ret < 0 && errno == EINTR);
+	return have_ipv6;
+}
+
 int
 getaddrinfo(const char *hostname, const char *servname,
     const struct addrinfo *hints, struct addrinfo **res)
@@ -1274,7 +1304,6 @@
 
 	name = va_arg(ap, char *);
 	pai = va_arg(ap, const struct addrinfo *);
-
 	//fprintf(stderr, "_dns_getaddrinfo() name = '%s'\n", name);
 
 	memset(&q, 0, sizeof(q));
@@ -1299,15 +1328,20 @@
 		/* prefer IPv6 */
 		q.name = name;
 		q.qclass = C_IN;
-		q.qtype = T_AAAA;
 		q.answer = buf->buf;
 		q.anslen = sizeof(buf->buf);
-		q.next = &q2;
-		q2.name = name;
-		q2.qclass = C_IN;
-		q2.qtype = T_A;
-		q2.answer = buf2->buf;
-		q2.anslen = sizeof(buf2->buf);
+		/* If AI_ADDRCONFIG, lookup IPv6 only if we have connectivity */
+		if (!(pai->ai_flags & AI_ADDRCONFIG) || _have_ipv6()) {
+			q.qtype = T_AAAA;
+			q.next = &q2;
+			q2.name = name;
+			q2.qclass = C_IN;
+			q2.qtype = T_A;
+			q2.answer = buf2->buf;
+			q2.anslen = sizeof(buf2->buf);
+		} else {
+			q.qtype = T_A;
+		}
 		break;
 	case AF_INET:
 		q.name = name;
diff --git a/libc/netbsd/resolv/res_send.c b/libc/netbsd/resolv/res_send.c
index 3aca760..696f8cf 100644
--- a/libc/netbsd/resolv/res_send.c
+++ b/libc/netbsd/resolv/res_send.c
@@ -95,7 +95,6 @@
 #include <sys/uio.h>
 
 #include <netinet/in.h>
-#include <netinet/in6.h>
 #include "arpa_nameser.h"
 #include <arpa/inet.h>
 
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 82c8cd9..2e7a82b 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -88,7 +88,18 @@
 
 /* get the TLS */
 #ifdef __arm__
-#  define __get_tls() ( *((volatile void **) 0xffff0ff0) )
+/* For performance reasons, avoid calling the kernel helper
+ * Note that HAVE_ARM_TLS_REGISTER is build-specific
+ * (it must match your kernel configuration)
+ */
+#  ifdef HAVE_ARM_TLS_REGISTER
+#    define __get_tls() \
+    ({ register unsigned int __val asm("r0"); \
+       asm ("mrc p15, 0, r0, c13, c0, 3" : "=r"(__val) ); \
+       (volatile void*)__val; })
+#  else /* !HAVE_ARM_TLS_REGISTER */
+#    define __get_tls() ( *((volatile void **) 0xffff0ff0) )
+#  endif
 #else
 extern void*  __get_tls( void );
 #endif
diff --git a/libc/tzcode/asctime.c b/libc/tzcode/asctime.c
index e0804f1..22bba34 100644
--- a/libc/tzcode/asctime.c
+++ b/libc/tzcode/asctime.c
@@ -11,7 +11,7 @@
 
 #ifndef lint
 #ifndef NOID
-static char	elsieid[] = "@(#)asctime.c	8.2";
+static char elsieid[] = "@(#)asctime.c  8.2";
 #endif /* !defined NOID */
 #endif /* !defined lint */
 
@@ -39,9 +39,9 @@
 ** but many implementations pad anyway; most likely the standards are buggy.
 */
 #ifdef __GNUC__
-#define ASCTIME_FMT	"%.3s %.3s%3d %2.2d:%2.2d:%2.2d %-4s\n"
+#define ASCTIME_FMT "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %-4s\n"
 #else /* !defined __GNUC__ */
-#define ASCTIME_FMT	"%.3s %.3s%3d %02.2d:%02.2d:%02.2d %-4s\n"
+#define ASCTIME_FMT "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %-4s\n"
 #endif /* !defined __GNUC__ */
 /*
 ** For years that are more than four digits we put extra spaces before the year
@@ -50,12 +50,12 @@
 ** that no output is better than wrong output).
 */
 #ifdef __GNUC__
-#define ASCTIME_FMT_B	"%.3s %.3s%3d %2.2d:%2.2d:%2.2d     %s\n"
+#define ASCTIME_FMT_B   "%.3s %.3s%3d %2.2d:%2.2d:%2.2d     %s\n"
 #else /* !defined __GNUC__ */
-#define ASCTIME_FMT_B	"%.3s %.3s%3d %02.2d:%02.2d:%02.2d     %s\n"
+#define ASCTIME_FMT_B   "%.3s %.3s%3d %02.2d:%02.2d:%02.2d     %s\n"
 #endif /* !defined __GNUC__ */
 
-#define STD_ASCTIME_BUF_SIZE	26
+#define STD_ASCTIME_BUF_SIZE    26
 /*
 ** Big enough for something such as
 ** ??? ???-2147483648 -2147483648:-2147483648:-2147483648     -2147483648\n
@@ -66,9 +66,9 @@
 ** as an example; the define below calculates the maximum for the system at
 ** hand.
 */
-#define MAX_ASCTIME_BUF_SIZE	(2*3+5*INT_STRLEN_MAXIMUM(int)+7+2+1+1)
+#define MAX_ASCTIME_BUF_SIZE    (2*3+5*INT_STRLEN_MAXIMUM(int)+7+2+1+1)
 
-static char	buf_asctime[MAX_ASCTIME_BUF_SIZE];
+static char buf_asctime[MAX_ASCTIME_BUF_SIZE];
 
 /*
 ** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition.
@@ -76,54 +76,54 @@
 
 char *
 asctime_r(timeptr, buf)
-register const struct tm *	timeptr;
-char *				buf;
+register const struct tm *  timeptr;
+char *              buf;
 {
-	static const char	wday_name[][3] = {
-		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
-	};
-	static const char	mon_name[][3] = {
-		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
-		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-	};
-	register const char *	wn;
-	register const char *	mn;
-	char			year[INT_STRLEN_MAXIMUM(int) + 2];
-	char			result[MAX_ASCTIME_BUF_SIZE];
+    static const char   wday_name[][3] = {
+        "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+    };
+    static const char   mon_name[][3] = {
+        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+    };
+    register const char *   wn;
+    register const char *   mn;
+    char            year[INT_STRLEN_MAXIMUM(int) + 2];
+    char            result[MAX_ASCTIME_BUF_SIZE];
 
-	if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK)
-		wn = "???";
-	else	wn = wday_name[timeptr->tm_wday];
-	if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR)
-		mn = "???";
-	else	mn = mon_name[timeptr->tm_mon];
-	/*
-	** Use strftime's %Y to generate the year, to avoid overflow problems
-	** when computing timeptr->tm_year + TM_YEAR_BASE.
-	** Assume that strftime is unaffected by other out-of-range members
-	** (e.g., timeptr->tm_mday) when processing "%Y".
-	*/
-	(void) strftime(year, sizeof year, "%Y", timeptr);
-	/*
-	** We avoid using snprintf since it's not available on all systems.
-	*/
-	(void) sprintf(result,
-		((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B),
-		wn, mn,
-		timeptr->tm_mday, timeptr->tm_hour,
-		timeptr->tm_min, timeptr->tm_sec,
-		year);
-	if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime) {
-		(void) strcpy(buf, result);
-		return buf;
-	} else {
+    if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK)
+        wn = "???";
+    else    wn = wday_name[timeptr->tm_wday];
+    if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR)
+        mn = "???";
+    else    mn = mon_name[timeptr->tm_mon];
+    /*
+    ** Use strftime's %Y to generate the year, to avoid overflow problems
+    ** when computing timeptr->tm_year + TM_YEAR_BASE.
+    ** Assume that strftime is unaffected by other out-of-range members
+    ** (e.g., timeptr->tm_mday) when processing "%Y".
+    */
+    (void) strftime(year, sizeof year, "%Y", timeptr);
+    /*
+    ** We avoid using snprintf since it's not available on all systems.
+    */
+    (void) sprintf(result,
+        ((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B),
+        wn, mn,
+        timeptr->tm_mday, timeptr->tm_hour,
+        timeptr->tm_min, timeptr->tm_sec,
+        year);
+    if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime) {
+        (void) strcpy(buf, result);
+        return buf;
+    } else {
 #ifdef EOVERFLOW
-		errno = EOVERFLOW;
+        errno = EOVERFLOW;
 #else /* !defined EOVERFLOW */
-		errno = EINVAL;
+        errno = EINVAL;
 #endif /* !defined EOVERFLOW */
-		return NULL;
-	}
+        return NULL;
+    }
 }
 
 /*
@@ -132,7 +132,7 @@
 
 char *
 asctime(timeptr)
-register const struct tm *	timeptr;
+register const struct tm *  timeptr;
 {
-	return asctime_r(timeptr, buf_asctime);
+    return asctime_r(timeptr, buf_asctime);
 }
diff --git a/libc/tzcode/difftime.c b/libc/tzcode/difftime.c
index da77977..f7581a4 100644
--- a/libc/tzcode/difftime.c
+++ b/libc/tzcode/difftime.c
@@ -5,61 +5,61 @@
 
 #ifndef lint
 #ifndef NOID
-static char	elsieid[] = "@(#)difftime.c	8.1";
+static char elsieid[] = "@(#)difftime.c 8.1";
 #endif /* !defined NOID */
 #endif /* !defined lint */
 
 /*LINTLIBRARY*/
 
-#include "private.h"	/* for time_t, TYPE_INTEGRAL, and TYPE_SIGNED */
+#include "private.h"    /* for time_t, TYPE_INTEGRAL, and TYPE_SIGNED */
 
 double
 difftime(time1, time0)
-const time_t	time1;
-const time_t	time0;
+const time_t    time1;
+const time_t    time0;
 {
-	/*
-	** If (sizeof (double) > sizeof (time_t)) simply convert and subtract
-	** (assuming that the larger type has more precision).
-	** This is the common real-world case circa 2004.
-	*/
-	if (sizeof (double) > sizeof (time_t))
-		return (double) time1 - (double) time0;
-	if (!TYPE_INTEGRAL(time_t)) {
-		/*
-		** time_t is floating.
-		*/
-		return time1 - time0;
-	}
-	if (!TYPE_SIGNED(time_t)) {
-		/*
-		** time_t is integral and unsigned.
-		** The difference of two unsigned values can't overflow
-		** if the minuend is greater than or equal to the subtrahend.
-		*/
-		if (time1 >= time0)
-			return time1 - time0;
-		else	return -((double) (time0 - time1));
-	}
-	/*
-	** time_t is integral and signed.
-	** Handle cases where both time1 and time0 have the same sign
-	** (meaning that their difference cannot overflow).
-	*/
-	if ((time1 < 0) == (time0 < 0))
-		return time1 - time0;
-	/*
-	** time1 and time0 have opposite signs.
-	** Punt if unsigned long is too narrow.
-	*/
-	if (sizeof (unsigned long) < sizeof (time_t))
-		return (double) time1 - (double) time0;
-	/*
-	** Stay calm...decent optimizers will eliminate the complexity below.
-	*/
-	if (time1 >= 0 /* && time0 < 0 */)
-		return (unsigned long) time1 +
-			(unsigned long) (-(time0 + 1)) + 1;
-	return -(double) ((unsigned long) time0 +
-		(unsigned long) (-(time1 + 1)) + 1);
+    /*
+    ** If (sizeof (double) > sizeof (time_t)) simply convert and subtract
+    ** (assuming that the larger type has more precision).
+    ** This is the common real-world case circa 2004.
+    */
+    if (sizeof (double) > sizeof (time_t))
+        return (double) time1 - (double) time0;
+    if (!TYPE_INTEGRAL(time_t)) {
+        /*
+        ** time_t is floating.
+        */
+        return time1 - time0;
+    }
+    if (!TYPE_SIGNED(time_t)) {
+        /*
+        ** time_t is integral and unsigned.
+        ** The difference of two unsigned values can't overflow
+        ** if the minuend is greater than or equal to the subtrahend.
+        */
+        if (time1 >= time0)
+            return time1 - time0;
+        else    return -((double) (time0 - time1));
+    }
+    /*
+    ** time_t is integral and signed.
+    ** Handle cases where both time1 and time0 have the same sign
+    ** (meaning that their difference cannot overflow).
+    */
+    if ((time1 < 0) == (time0 < 0))
+        return time1 - time0;
+    /*
+    ** time1 and time0 have opposite signs.
+    ** Punt if unsigned long is too narrow.
+    */
+    if (sizeof (unsigned long) < sizeof (time_t))
+        return (double) time1 - (double) time0;
+    /*
+    ** Stay calm...decent optimizers will eliminate the complexity below.
+    */
+    if (time1 >= 0 /* && time0 < 0 */)
+        return (unsigned long) time1 +
+            (unsigned long) (-(time0 + 1)) + 1;
+    return -(double) ((unsigned long) time0 +
+        (unsigned long) (-(time1 + 1)) + 1);
 }
diff --git a/libc/tzcode/localtime.c b/libc/tzcode/localtime.c
index 19d0fbc..83c1011 100644
--- a/libc/tzcode/localtime.c
+++ b/libc/tzcode/localtime.c
@@ -5,7 +5,7 @@
 
 #ifndef lint
 #ifndef NOID
-static char	elsieid[] = "@(#)localtime.c	8.3";
+static char elsieid[] = "@(#)localtime.c    8.3";
 #endif /* !defined NOID */
 #endif /* !defined lint */
 
@@ -19,21 +19,22 @@
 #include "private.h"
 #include "tzfile.h"
 #include "fcntl.h"
-#include "float.h"	/* for FLT_MAX and DBL_MAX */
+#include "float.h"  /* for FLT_MAX and DBL_MAX */
 
+#include "thread_private.h"
 #include <sys/system_properties.h>
 
 #ifndef TZ_ABBR_MAX_LEN
-#define TZ_ABBR_MAX_LEN	16
+#define TZ_ABBR_MAX_LEN 16
 #endif /* !defined TZ_ABBR_MAX_LEN */
 
 #ifndef TZ_ABBR_CHAR_SET
 #define TZ_ABBR_CHAR_SET \
-	"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
+    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
 #endif /* !defined TZ_ABBR_CHAR_SET */
 
 #ifndef TZ_ABBR_ERR_CHAR
-#define TZ_ABBR_ERR_CHAR	'_'
+#define TZ_ABBR_ERR_CHAR    '_'
 #endif /* !defined TZ_ABBR_ERR_CHAR */
 
 #define INDEXFILE "/system/usr/share/zoneinfo/zoneinfo.idx"
@@ -47,10 +48,10 @@
 */
 
 #ifdef O_BINARY
-#define OPEN_MODE	(O_RDONLY | O_BINARY)
+#define OPEN_MODE   (O_RDONLY | O_BINARY)
 #endif /* defined O_BINARY */
 #ifndef O_BINARY
-#define OPEN_MODE	O_RDONLY
+#define OPEN_MODE   O_RDONLY
 #endif /* !defined O_BINARY */
 
 #if 0
@@ -59,19 +60,58 @@
 #  define  XLOG(x)   do{}while (0)
 #endif
 
+/* THREAD-SAFETY SUPPORT GOES HERE */
+static pthread_mutex_t  _tzMutex = PTHREAD_MUTEX_INITIALIZER;
+
+static __inline__ void _tzLock(void)
+{
+    if (__isthreaded)
+        pthread_mutex_lock(&_tzMutex);
+}
+
+static __inline__ void _tzUnlock(void)
+{
+    if (__isthreaded)
+        pthread_mutex_unlock(&_tzMutex);
+}
+
+/* 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.
+**  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
@@ -80,12 +120,12 @@
 ** manual page of what this "time zone abbreviation" means (doing this so
 ** that tzname[0] has the "normal" length of three characters).
 */
-#define WILDABBR	"   "
+#define WILDABBR    "   "
 #endif /* !defined WILDABBR */
 
-static char		wildabbr[] = WILDABBR;
+static char     wildabbr[] = WILDABBR;
 
-static const char	gmt[] = "GMT";
+static const char   gmt[] = "GMT";
 
 /*
 ** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
@@ -98,251 +138,257 @@
 #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 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 */
+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))
+#define BIGGEST(a, b)   (((a) > (b)) ? (a) : (b))
 
 #ifdef TZNAME_MAX
-#define MY_TZNAME_MAX	TZNAME_MAX
+#define MY_TZNAME_MAX   TZNAME_MAX
 #endif /* defined TZNAME_MAX */
 #ifndef TZNAME_MAX
-#define MY_TZNAME_MAX	255
+#define MY_TZNAME_MAX   255
 #endif /* !defined TZNAME_MAX */
 
+/* XXX: This code should really use time64_t instead of time_t
+ *      but we can't change it without re-generating the index
+ *      file first with the correct data.
+ */
 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];
+    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 */
+    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 */
+#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));
-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 *)),
-				long offset));
-static time_t		time2 P((struct tm *tmp,
-				struct tm * (*funcp) P((const time_t *,
-				long, struct tm*)),
-				long offset, int * okayp));
-static time_t		time2sub P((struct tm *tmp,
-				struct tm * (*funcp) P((const time_t *,
-				long, struct tm*)),
-				long offset, int * okayp, int do_norm_secs));
-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		tzparse P((const char * name, struct state * sp,
-				int lastditch));
+/* NOTE: all internal functions assume that _tzLock() was already called */
+
+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));
+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 *)),
+                long offset));
+static time_t       time2 P((struct tm *tmp,
+                struct tm * (*funcp) P((const time_t *,
+                long, struct tm*)),
+                long offset, int * okayp));
+static time_t       time2sub P((struct tm *tmp,
+                struct tm * (*funcp) P((const time_t *,
+                long, struct tm*)),
+                long offset, int * okayp, int do_norm_secs));
+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      tzparse P((const char * name, struct state * sp,
+                int lastditch));
 
 #ifdef ALL_STATE
-static struct state *	lclptr;
-static struct state *	gmtptr;
+static struct state *   lclptr;
+static struct state *   gmtptr;
 #endif /* defined ALL_STATE */
 
 #ifndef ALL_STATE
-static struct state	lclmem;
-static struct state	gmtmem;
-#define lclptr		(&lclmem)
-#define gmtptr		(&gmtmem)
+static struct state lclmem;
+static struct state gmtmem;
+#define lclptr      (&lclmem)
+#define gmtptr      (&gmtmem)
 #endif /* State Farm */
 
 #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;
+static char     lcl_TZname[TZ_STRLEN_MAX + 1];
+static int      lcl_is_set;
+static int      gmt_is_set;
 
-char *			tzname[2] = {
-	wildabbr,
-	wildabbr
+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.
+**  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;
+static struct tm    tmGlobal;
 
 #ifdef USG_COMPAT
-time_t			timezone = 0;
-int			daylight = 0;
+time_t          timezone = 0;
+int         daylight = 0;
 #endif /* defined USG_COMPAT */
 
 #ifdef ALTZONE
-time_t			altzone = 0;
+time_t          altzone = 0;
 #endif /* defined ALTZONE */
 
 static long
 detzcode(codep)
-const char * const	codep;
+const char * const  codep;
 {
-	register long	result;
-	register int	i;
+    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;
+    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;
+const char * const  codep;
 {
-	register time_t	result;
-	register int	i;
+    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;
+    result = (codep[0] & 0x80) ?  (~(int_fast64_t) 0) : 0;
+    for (i = 0; i < 8; ++i)
+        result = result * 256 + (codep[i] & 0xff);
+    return result;
 }
 
 static void
 settzname P((void))
 {
-	register struct state * const	sp = lclptr;
-	register int			i;
+    register struct state * const   sp = lclptr;
+    register int            i;
 
-	tzname[0] = wildabbr;
-	tzname[1] = wildabbr;
+    tzname[0] = wildabbr;
+    tzname[1] = wildabbr;
 #ifdef USG_COMPAT
-	daylight = 0;
-	timezone = 0;
+    daylight = 0;
+    timezone = 0;
 #endif /* defined USG_COMPAT */
 #ifdef ALTZONE
-	altzone = 0;
+    altzone = 0;
 #endif /* defined ALTZONE */
 #ifdef ALL_STATE
-	if (sp == NULL) {
-		tzname[0] = tzname[1] = gmt;
-		return;
-	}
+    if (sp == NULL) {
+        tzname[0] = tzname[1] = gmt;
+        return;
+    }
 #endif /* defined ALL_STATE */
-	for (i = 0; i < sp->typecnt; ++i) {
-		register const struct ttinfo * const	ttisp = &sp->ttis[i];
+    for (i = 0; i < sp->typecnt; ++i) {
+        register const struct ttinfo * const    ttisp = &sp->ttis[i];
 
-		tzname[ttisp->tt_isdst] =
-			&sp->chars[ttisp->tt_abbrind];
+        tzname[ttisp->tt_isdst] =
+            &sp->chars[ttisp->tt_abbrind];
 #ifdef USG_COMPAT
-		if (ttisp->tt_isdst)
-			daylight = 1;
-		if (i == 0 || !ttisp->tt_isdst)
-			timezone = -(ttisp->tt_gmtoff);
+        if (ttisp->tt_isdst)
+            daylight = 1;
+        if (i == 0 || !ttisp->tt_isdst)
+            timezone = -(ttisp->tt_gmtoff);
 #endif /* defined USG_COMPAT */
 #ifdef ALTZONE
-		if (i == 0 || ttisp->tt_isdst)
-			altzone = -(ttisp->tt_gmtoff);
+        if (i == 0 || ttisp->tt_isdst)
+            altzone = -(ttisp->tt_gmtoff);
 #endif /* defined ALTZONE */
-	}
-	/*
-	** And to get the latest zone names into tzname. . .
-	*/
-	for (i = 0; i < sp->timecnt; ++i) {
-		register const struct ttinfo * const	ttisp =
-							&sp->ttis[
-								sp->types[i]];
+    }
+    /*
+    ** And to get the latest zone names into tzname. . .
+    */
+    for (i = 0; i < sp->timecnt; ++i) {
+        register const struct ttinfo * const    ttisp =
+                            &sp->ttis[
+                                sp->types[i]];
 
-		tzname[ttisp->tt_isdst] =
-			&sp->chars[ttisp->tt_abbrind];
-	}
-	/*
-	** Finally, scrub the abbreviations.
-	** First, replace bogus characters.
-	*/
-	for (i = 0; i < sp->charcnt; ++i)
-		if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
-			sp->chars[i] = TZ_ABBR_ERR_CHAR;
-	/*
-	** Second, truncate long abbreviations.
-	*/
-	for (i = 0; i < sp->typecnt; ++i) {
-		register const struct ttinfo * const	ttisp = &sp->ttis[i];
-		register char *				cp = &sp->chars[ttisp->tt_abbrind];
+        tzname[ttisp->tt_isdst] =
+            &sp->chars[ttisp->tt_abbrind];
+    }
+    /*
+    ** Finally, scrub the abbreviations.
+    ** First, replace bogus characters.
+    */
+    for (i = 0; i < sp->charcnt; ++i)
+        if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
+            sp->chars[i] = TZ_ABBR_ERR_CHAR;
+    /*
+    ** Second, truncate long abbreviations.
+    */
+    for (i = 0; i < sp->typecnt; ++i) {
+        register const struct ttinfo * const    ttisp = &sp->ttis[i];
+        register char *             cp = &sp->chars[ttisp->tt_abbrind];
 
-		if (strlen(cp) > TZ_ABBR_MAX_LEN &&
-			strcmp(cp, GRANDPARENTED) != 0)
-				*(cp + TZ_ABBR_MAX_LEN) = '\0';
-	}
+        if (strlen(cp) > TZ_ABBR_MAX_LEN &&
+            strcmp(cp, GRANDPARENTED) != 0)
+                *(cp + TZ_ABBR_MAX_LEN) = '\0';
+    }
 }
 
 static int
 differ_by_repeat(t1, t0)
-const time_t	t1;
-const time_t	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;
+    if (TYPE_INTEGRAL(time_t) &&
+        TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
+            return 0;
         return (t1 - t0) == SECSPERREPEAT;
 }
 
@@ -352,66 +398,66 @@
 
 static int
 tzload(name, sp, doextend)
-register const char *		name;
-register struct state * const	sp;
-register const int		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;
+    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) {
                 XLOG(("tzload: null 'name' parameter\n" ));
                 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];
-                char        *origname = (char*) name;
+    {
+        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];
+        char        *origname = (char*) name;
 
-		if (name[0] == ':')
-			++name;
-		doaccess = name[0] == '/';
-		if (!doaccess) {
-                        if ((p = TZDIR) == NULL) {
-                                XLOG(("tzload: null TZDIR macro ?\n" ));
-				return -1;
-                        }
-                        if ((strlen(p) + strlen(name) + 1) >= sizeof fullname) {
-                                XLOG(( "tzload: path too long: %s/%s\n", p, name ));
-				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) {
-                        XLOG(( "tzload: could not find '%s'\n", name ));
-			return -1;
-                }
-		if ((fid = open(name, OPEN_MODE)) == -1) {
+        if (name[0] == ':')
+            ++name;
+        doaccess = name[0] == '/';
+        if (!doaccess) {
+            if ((p = TZDIR) == NULL) {
+                XLOG(("tzload: null TZDIR macro ?\n" ));
+                return -1;
+            }
+            if ((strlen(p) + strlen(name) + 1) >= sizeof fullname) {
+                XLOG(( "tzload: path too long: %s/%s\n", p, name ));
+                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) {
+            XLOG(( "tzload: could not find '%s'\n", name ));
+            return -1;
+        }
+        if ((fid = open(name, OPEN_MODE)) == -1) {
             char buf[READLEN];
             char name[NAMELEN + 1];
             int fidix = open(INDEXFILE, OPEN_MODE);
@@ -453,197 +499,197 @@
                 return -1;
             }
         }
-	}
-	nread = read(fid, u.buf, toread);
+    }
+    nread = read(fid, u.buf, toread);
         if (close(fid) < 0 || nread <= 0) {
-                XLOG(( "tzload: could not read content of '%s'\n", DATAFILE ));
-		return -1;
+            XLOG(( "tzload: could not read content of '%s'\n", DATAFILE ));
+            return -1;
         }
-	for (stored = 4; stored <= 8; stored *= 2) {
-		int		ttisstdcnt;
-		int		ttisgmtcnt;
+    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;
+        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;
+            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;
+            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 (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;
+            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;
+                    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]);
+            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]);
         XLOG(( "tzload: load ok !!\n" ));
-	return 0;
+    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    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
+static const int    year_lengths[2] = {
+    DAYSPERNYEAR, DAYSPERLYEAR
 };
 
 /*
@@ -654,14 +700,14 @@
 
 static const char *
 getzname(strp)
-register const char *	strp;
+register const char *   strp;
 {
-	register char	c;
+    register char   c;
 
-	while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
-		c != '+')
-			++strp;
-	return strp;
+    while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
+        c != '+')
+            ++strp;
+    return strp;
 }
 
 /*
@@ -676,11 +722,11 @@
 static const char *
 getqzname(register const char *strp, const int delim)
 {
-	register int	c;
+    register int    c;
 
-	while ((c = *strp) != '\0' && c != delim)
-		++strp;
-	return strp;
+    while ((c = *strp) != '\0' && c != delim)
+        ++strp;
+    return strp;
 }
 
 /*
@@ -692,27 +738,27 @@
 
 static const char *
 getnum(strp, nump, min, max)
-register const char *	strp;
-int * const		nump;
-const int		min;
-const int		max;
+register const char *   strp;
+int * const     nump;
+const int       min;
+const int       max;
 {
-	register char	c;
-	register int	num;
+    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;
+    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;
 }
 
 /*
@@ -725,37 +771,37 @@
 
 static const char *
 getsecs(strp, secsp)
-register const char *	strp;
-long * const		secsp;
+register const char *   strp;
+long * const        secsp;
 {
-	int	num;
+    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;
+    /*
+    ** `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;
 }
 
 /*
@@ -767,22 +813,22 @@
 
 static const char *
 getoffset(strp, offsetp)
-register const char *	strp;
-long * const		offsetp;
+register const char *   strp;
+long * const        offsetp;
 {
-	register int	neg = 0;
+    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;
+    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;
 }
 
 /*
@@ -794,50 +840,50 @@
 
 static const char *
 getrule(strp, rulep)
-const char *			strp;
-register struct rule * const	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;
+    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;
 }
 
 /*
@@ -848,92 +894,92 @@
 
 static time_t
 transtime(janfirst, year, rulep, offset)
-const time_t				janfirst;
-const int				year;
-register const struct rule * const	rulep;
-const long				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;
+    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) {
+    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 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 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;
+    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;
+        /*
+        ** 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;
-		}
+        /*
+        ** "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;
-	}
+        /*
+        ** "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;
+    /*
+    ** "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;
 }
 
 /*
@@ -943,322 +989,323 @@
 
 static int
 tzparse(name, sp, lastditch)
-const char *			name;
-register struct state * const	sp;
-const int			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;
+    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;
+    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;
+            ++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;
+                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;
+            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;
+struct state * const    sp;
 {
-	if (tzload(gmt, sp, TRUE) != 0)
-		(void) tzparse(gmt, sp, TRUE);
+    if (tzload(gmt, sp, TRUE) != 0)
+        (void) tzparse(gmt, sp, TRUE);
 }
 
-#ifndef STD_INSPIRED
-/*
-** A non-static declaration of tzsetwall in a system header file
-** may cause a warning about this upcoming static declaration...
-*/
-static
-#endif /* !defined STD_INSPIRED */
-void
+static void
 tzsetwall P((void))
 {
-	if (lcl_is_set < 0)
-		return;
-	lcl_is_set = -1;
+    if (lcl_is_set < 0)
+        return;
+    lcl_is_set = -1;
 
 #ifdef ALL_STATE
-	if (lclptr == NULL) {
-		lclptr = (struct state *) malloc(sizeof *lclptr);
-		if (lclptr == NULL) {
-			settzname();	/* all we can do */
-			return;
-		}
-	}
+    if (lclptr == NULL) {
+        lclptr = (struct state *) malloc(sizeof *lclptr);
+        if (lclptr == NULL) {
+            settzname();    /* all we can do */
+            return;
+        }
+    }
 #endif /* defined ALL_STATE */
-	if (tzload((char *) NULL, lclptr, TRUE) != 0)
-		gmtload(lclptr);
-	settzname();
+    if (tzload((char *) NULL, lclptr, TRUE) != 0)
+        gmtload(lclptr);
+    settzname();
+}
+
+static void
+tzset_locked P((void))
+{
+    register const char *   name = NULL;
+    static char buf[PROP_VALUE_MAX];
+
+    name = getenv("TZ");
+
+    // try the "persist.sys.timezone" system property first
+    if (name == NULL && __system_property_get("persist.sys.timezone", buf) > 0)
+        name = buf;
+
+    if (name == NULL) {
+        tzsetwall();
+        return;
+    }
+
+    if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0)
+        return;
+    lcl_is_set = strlen(name) < sizeof lcl_TZname;
+    if (lcl_is_set)
+        (void) strcpy(lcl_TZname, name);
+
+#ifdef ALL_STATE
+    if (lclptr == NULL) {
+        lclptr = (struct state *) malloc(sizeof *lclptr);
+        if (lclptr == NULL) {
+            settzname();    /* all we can do */
+            return;
+        }
+    }
+#endif /* defined ALL_STATE */
+    if (*name == '\0') {
+        /*
+        ** User wants it fast rather than right.
+        */
+        lclptr->leapcnt = 0;        /* so, we're off a little */
+        lclptr->timecnt = 0;
+        lclptr->typecnt = 0;
+        lclptr->ttis[0].tt_isdst = 0;
+        lclptr->ttis[0].tt_gmtoff = 0;
+        lclptr->ttis[0].tt_abbrind = 0;
+        (void) strcpy(lclptr->chars, gmt);
+    } else if (tzload(name, lclptr, TRUE) != 0)
+        if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
+            (void) gmtload(lclptr);
+    settzname();
 }
 
 void
 tzset P((void))
 {
-	register const char *	name = NULL;
-    static char buf[PROP_VALUE_MAX];
-
-	name = getenv("TZ");
-
-	// try the "persist.sys.timezone" system property first
-	if (name == NULL && __system_property_get("persist.sys.timezone", buf) > 0)
-	    name = buf;
-
-	if (name == NULL) {
-		tzsetwall();
-		return;
-	}
-
-	if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0)
-		return;
-	lcl_is_set = strlen(name) < sizeof lcl_TZname;
-	if (lcl_is_set)
-		(void) strcpy(lcl_TZname, name);
-
-#ifdef ALL_STATE
-	if (lclptr == NULL) {
-		lclptr = (struct state *) malloc(sizeof *lclptr);
-		if (lclptr == NULL) {
-			settzname();	/* all we can do */
-			return;
-		}
-	}
-#endif /* defined ALL_STATE */
-	if (*name == '\0') {
-		/*
-		** User wants it fast rather than right.
-		*/
-		lclptr->leapcnt = 0;		/* so, we're off a little */
-		lclptr->timecnt = 0;
-		lclptr->typecnt = 0;
-		lclptr->ttis[0].tt_isdst = 0;
-		lclptr->ttis[0].tt_gmtoff = 0;
-		lclptr->ttis[0].tt_abbrind = 0;
-		(void) strcpy(lclptr->chars, gmt);
-	} else if (tzload(name, lclptr, TRUE) != 0)
-		if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
-			(void) gmtload(lclptr);
-	settzname();
+    _tzLock();
+    tzset_locked();
+    _tzUnlock();
 }
 
 /*
@@ -1273,102 +1320,101 @@
 /*ARGSUSED*/
 static struct tm *
 localsub(timep, offset, tmp)
-const time_t * const	timep;
-const long		offset;
-struct tm * const	tmp;
+const time_t * const    timep;
+const long      offset;
+struct tm * const   tmp;
 {
-	register struct state *		sp;
-	register const struct ttinfo *	ttisp;
-	register int			i;
-	register struct tm *		result;
-	const time_t			t = *timep;
+    register struct state *     sp;
+    register const struct ttinfo *  ttisp;
+    register int            i;
+    register struct tm *        result;
+    const time_t            t = *timep;
 
-	sp = lclptr;
+    sp = lclptr;
 #ifdef ALL_STATE
-	if (sp == NULL)
-		return gmtsub(timep, offset, tmp);
+    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 ((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);
-			if (result == tmp) {
-				register time_t	newy;
+            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);
+            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;
+                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;
+        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;
-	tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
+            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;
+    tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
 #ifdef TM_ZONE
-	tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
+    tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
 #endif /* defined TM_ZONE */
-	return result;
+    return result;
 }
 
 struct tm *
 localtime(timep)
-const time_t * const	timep;
+const time_t * const    timep;
 {
-	tzset();
-	return localsub(timep, 0L, &tm);
+    return localtime_r(timep, &tmGlobal);
 }
 
 /*
@@ -1377,11 +1423,17 @@
 
 struct tm *
 localtime_r(timep, tmp)
-const time_t * const	timep;
-struct tm *		tmp;
+const time_t * const    timep;
+struct tm *     tmp;
 {
-        tzset();
-	return localsub(timep, 0L, tmp);
+    struct tm*  result;
+
+    _tzLock();
+    tzset_locked();
+    result = localsub(timep, 0L, tmp);
+    _tzUnlock();
+
+    return result;
 }
 
 /*
@@ -1390,48 +1442,48 @@
 
 static struct tm *
 gmtsub(timep, offset, tmp)
-const time_t * const	timep;
-const long		offset;
-struct tm * const	tmp;
+const time_t * const    timep;
+const long      offset;
+struct tm * const   tmp;
 {
-	register struct tm *	result;
+    register struct tm *    result;
 
-	if (!gmt_is_set) {
-		gmt_is_set = TRUE;
+    if (!gmt_is_set) {
+        gmt_is_set = TRUE;
 #ifdef ALL_STATE
-		gmtptr = (struct state *) malloc(sizeof *gmtptr);
-		if (gmtptr != NULL)
+        gmtptr = (struct state *) malloc(sizeof *gmtptr);
+        if (gmtptr != NULL)
 #endif /* defined ALL_STATE */
-			gmtload(gmtptr);
-	}
-	result = timesub(timep, offset, gmtptr, tmp);
+            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 {
+    /*
+    ** 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;
+        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;
+        tmp->TM_ZONE = gmtptr->chars;
 #endif /* State Farm */
-	}
+    }
 #endif /* defined TM_ZONE */
-	return result;
+    return result;
 }
 
 struct tm *
 gmtime(timep)
-const time_t * const	timep;
+const time_t * const    timep;
 {
-	return gmtsub(timep, 0L, &tm);
+    return gmtime_r(timep, &tmGlobal);
 }
 
 /*
@@ -1440,20 +1492,26 @@
 
 struct tm *
 gmtime_r(timep, tmp)
-const time_t * const	timep;
-struct tm *		tmp;
+const time_t * const    timep;
+struct tm *     tmp;
 {
-	return gmtsub(timep, 0L, tmp);
+    struct tm*  result;
+
+    _tzLock();
+    result = gmtsub(timep, 0L, tmp);
+    _tzUnlock();
+
+    return result;
 }
 
 #ifdef STD_INSPIRED
 
 struct tm *
 offtime(timep, offset)
-const time_t * const	timep;
-const long		offset;
+const time_t * const    timep;
+const long      offset;
 {
-	return gmtsub(timep, offset, &tm);
+    return gmtsub(timep, offset, &tmGlobal);
 }
 
 #endif /* defined STD_INSPIRED */
@@ -1465,180 +1523,180 @@
 
 static int
 leaps_thru_end_of(y)
-register const int	y;
+register const int  y;
 {
-	return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
-		-(leaps_thru_end_of(-(y + 1)) + 1);
+    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;
+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;
+    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;
+    corr = 0;
+    hit = 0;
 #ifdef ALL_STATE
-	i = (sp == NULL) ? 0 : sp->leapcnt;
+    i = (sp == NULL) ? 0 : sp->leapcnt;
 #endif /* defined ALL_STATE */
 #ifndef ALL_STATE
-	i = sp->leapcnt;
+    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;
+    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;
+        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;
+        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;
+    tmp->TM_GMTOFF = offset;
 #endif /* defined TM_GMTOFF */
-	return tmp;
+    return tmp;
 }
 
 char *
 ctime(timep)
-const time_t * const	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))
+**  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));
+    return asctime(localtime(timep));
 }
 
 char *
 ctime_r(timep, buf)
-const time_t * const	timep;
-char *			buf;
+const time_t * const    timep;
+char *          buf;
 {
-	struct tm	mytm;
+    struct tm   mytm;
 
-	return asctime_r(localtime_r(timep, &mytm), buf);
+    return asctime_r(localtime_r(timep, &mytm), buf);
 }
 
 /*
 ** 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).
+**  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)
+#define WRONG   (-1)
 #endif /* !defined WRONG */
 
 /*
@@ -1647,56 +1705,66 @@
 
 static int
 increment_overflow(number, delta)
-int *	number;
-int	delta;
+int *   number;
+int delta;
 {
-	int	number0;
+    unsigned  number0 = (unsigned)*number;
+    unsigned  number1 = (unsigned)(number0 + delta);
 
-	number0 = *number;
-	*number += delta;
-	return (*number < number0) != (delta < 0);
+    *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;
+long *  number;
+int delta;
 {
-	long	number0;
+    unsigned long  number0 = (unsigned long)*number;
+    unsigned long  number1 = (unsigned long)(number0 + delta);
 
-	number0 = *number;
-	*number += delta;
-	return (*number < number0) != (delta < 0);
+    *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;
+int * const tensptr;
+int * const unitsptr;
+const int   base;
 {
-	register int	tensdelta;
+    register int    tensdelta;
 
-	tensdelta = (*unitsptr >= 0) ?
-		(*unitsptr / base) :
-		(-1 - (-1 - *unitsptr) / base);
-	*unitsptr -= tensdelta * base;
-	return increment_overflow(tensptr, 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;
+long * const    tensptr;
+int * const unitsptr;
+const int   base;
 {
-	register int	tensdelta;
+    register int    tensdelta;
 
-	tensdelta = (*unitsptr >= 0) ?
-		(*unitsptr / base) :
-		(-1 - (-1 - *unitsptr) / base);
-	*unitsptr -= tensdelta * base;
-	return long_increment_overflow(tensptr, tensdelta);
+    tensdelta = (*unitsptr >= 0) ?
+        (*unitsptr / base) :
+        (-1 - (-1 - *unitsptr) / base);
+    *unitsptr -= tensdelta * base;
+    return long_increment_overflow(tensptr, tensdelta);
 }
 
 static int
@@ -1704,333 +1772,349 @@
 register const struct tm * const atmp;
 register const struct tm * const btmp;
 {
-	register int	result;
+    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;
+    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)
-struct tm * const	tmp;
-struct tm * (* const	funcp) P((const time_t*, long, struct tm*));
-const long		offset;
-int * const		okayp;
-const int		do_norm_secs;
+struct tm * const   tmp;
+struct tm * (* const    funcp) P((const time_t*, long, struct tm*));
+const long      offset;
+int * const     okayp;
+const int       do_norm_secs;
 {
-	register 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;
+    register 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) == 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) {
-				++t;
-				if (t <= lo)
-					return WRONG;
-				++lo;
-			} else if (t == hi) {
-				--t;
-				if (t >= hi)
-					return WRONG;
-				--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.
-		*/
-		sp = (const struct state *)
-			(((void *) funcp == (void *) localsub) ?
-			lclptr : gmtptr);
+    *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) == 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.
+        */
+        sp = (const struct state *)
+            (((void *) funcp == (void *) localsub) ?
+            lclptr : gmtptr);
 #ifdef ALL_STATE
-		if (sp == NULL)
-			return WRONG;
+        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) == 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;
-	}
+        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) == 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))
-		*okayp = TRUE;
-	return t;
+    newt = t + saved_seconds;
+    if ((newt < t) != (saved_seconds < 0))
+        return WRONG;
+    t = newt;
+    if ((*funcp)(&t, offset, tmp))
+        *okayp = TRUE;
+    return t;
 }
 
 static time_t
 time2(tmp, funcp, offset, okayp)
-struct tm * const	tmp;
-struct tm * (* const	funcp) P((const time_t*, long, struct tm*));
-const long		offset;
-int * const		okayp;
+struct tm * const   tmp;
+struct tm * (* const    funcp) P((const time_t*, long, struct tm*));
+const long      offset;
+int * const     okayp;
 {
-	time_t	t;
+    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);
-	return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);
+    /*
+    ** 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);
+    return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);
 }
 
 static time_t
 time1(tmp, funcp, offset)
-struct tm * const	tmp;
-struct tm * (* const	funcp) P((const time_t *, long, struct tm *));
-const long		offset;
+struct tm * const   tmp;
+struct tm * (* const    funcp) P((const time_t *, long, struct tm *));
+const long      offset;
 {
-	register time_t			t;
-	register const struct state *	sp;
-	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;
+    register time_t         t;
+    register const struct state *   sp;
+    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);
+    if (tmp->tm_isdst > 1)
+        tmp->tm_isdst = 1;
+    t = time2(tmp, funcp, offset, &okay);
 #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 */
+    /*
+    ** 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;
+    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.
-	*/
-	sp = (const struct state *) (((void *) funcp == (void *) localsub) ?
-		lclptr : gmtptr);
+    /*
+    ** 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.
+    */
+    sp = (const struct state *) (((void *) funcp == (void *) localsub) ?
+        lclptr : gmtptr);
 #ifdef ALL_STATE
-	if (sp == NULL)
-		return WRONG;
+    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);
-			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;
+    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);
+            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(tmp)
-struct tm * const	tmp;
+struct tm * const   tmp;
 {
-	tzset();
-	return time1(tmp, localsub, 0L);
+    time_t  result;
+    _tzLock();
+    tzset_locked();
+    result = time1(tmp, localsub, 0L);
+    _tzUnlock();
+    return result;
 }
 
 #ifdef STD_INSPIRED
 
 time_t
 timelocal(tmp)
-struct tm * const	tmp;
+struct tm * const   tmp;
 {
-	tmp->tm_isdst = -1;	/* in case it wasn't initialized */
-	return mktime(tmp);
+    tmp->tm_isdst = -1; /* in case it wasn't initialized */
+    return mktime(tmp);
 }
 
 time_t
 timegm(tmp)
-struct tm * const	tmp;
+struct tm * const   tmp;
 {
-	tmp->tm_isdst = 0;
-	return time1(tmp, gmtsub, 0L);
+    time_t  result;
+
+    tmp->tm_isdst = 0;
+    _tzLock();
+    result = time1(tmp, gmtsub, 0L);
+    _tzUnlock();
+
+    return result;
 }
 
 time_t
 timeoff(tmp, offset)
-struct tm * const	tmp;
-const long		offset;
+struct tm * const   tmp;
+const long      offset;
 {
-	tmp->tm_isdst = 0;
-	return time1(tmp, gmtsub, offset);
+    time_t  result;
+
+    tmp->tm_isdst = 0;
+    _tzLock();
+    result = time1(tmp, gmtsub, offset);
+    _tzUnlock();
+
+    return result;
 }
 
 #endif /* defined STD_INSPIRED */
@@ -2044,13 +2128,13 @@
 
 long
 gtime(tmp)
-struct tm * const	tmp;
+struct tm * const   tmp;
 {
-	const time_t	t = mktime(tmp);
+    const time_t    t = mktime(tmp);
 
-	if (t == WRONG)
-		return -1;
-	return t;
+    if (t == WRONG)
+        return -1;
+    return t;
 }
 
 #endif /* defined CMUCS */
@@ -2071,62 +2155,62 @@
 
 static long
 leapcorr(timep)
-time_t *	timep;
+time_t *    timep;
 {
-	register struct state *		sp;
-	register struct lsinfo *	lp;
-	register int			i;
+    register struct state *     sp;
+    register struct lsinfo *    lp;
+    register int            i;
 
-	sp = lclptr;
-	i = sp->leapcnt;
-	while (--i >= 0) {
-		lp = &sp->lsis[i];
-		if (*timep >= lp->ls_trans)
-			return lp->ls_corr;
-	}
-	return 0;
+    sp = lclptr;
+    i = sp->leapcnt;
+    while (--i >= 0) {
+        lp = &sp->lsis[i];
+        if (*timep >= lp->ls_trans)
+            return lp->ls_corr;
+    }
+    return 0;
 }
 
 time_t
 time2posix(t)
-time_t	t;
+time_t  t;
 {
-	tzset();
-	return t - leapcorr(&t);
+    tzset();
+    return t - leapcorr(&t);
 }
 
 time_t
 posix2time(t)
-time_t	t;
+time_t  t;
 {
-	time_t	x;
-	time_t	y;
+    time_t  x;
+    time_t  y;
 
-	tzset();
-	/*
-	** For a positive leap second hit, the result
-	** is not unique. For a negative leap second
-	** hit, the corresponding time doesn't exist,
-	** so we return an adjacent second.
-	*/
-	x = t + leapcorr(&t);
-	y = x - leapcorr(&x);
-	if (y < t) {
-		do {
-			x++;
-			y = x - leapcorr(&x);
-		} while (y < t);
-		if (t != y)
-			return x - 1;
-	} else if (y > t) {
-		do {
-			--x;
-			y = x - leapcorr(&x);
-		} while (y > t);
-		if (t != y)
-			return x + 1;
-	}
-	return x;
+    tzset();
+    /*
+    ** For a positive leap second hit, the result
+    ** is not unique. For a negative leap second
+    ** hit, the corresponding time doesn't exist,
+    ** so we return an adjacent second.
+    */
+    x = t + leapcorr(&t);
+    y = x - leapcorr(&x);
+    if (y < t) {
+        do {
+            x++;
+            y = x - leapcorr(&x);
+        } while (y < t);
+        if (t != y)
+            return x - 1;
+    } else if (y > t) {
+        do {
+            --x;
+            y = x - leapcorr(&x);
+        } while (y > t);
+        if (t != y)
+            return x + 1;
+    }
+    return x;
 }
 
 #endif /* defined STD_INSPIRED */
diff --git a/libc/tzcode/private.h b/libc/tzcode/private.h
index 2837b70..e82a655 100644
--- a/libc/tzcode/private.h
+++ b/libc/tzcode/private.h
@@ -21,11 +21,11 @@
 
 #ifndef lint
 #ifndef NOID
-static char	privatehid[] = "@(#)private.h	8.2";
+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"
+#define GRANDPARENTED   "Local time zone must be set--see zic manual page"
 
 /*
 ** Defaults for preprocessor symbols.
@@ -33,49 +33,45 @@
 */
 
 #ifndef HAVE_ADJTIME
-#define HAVE_ADJTIME		1
+#define HAVE_ADJTIME        1
 #endif /* !defined HAVE_ADJTIME */
 
 #ifndef HAVE_GETTEXT
-#define HAVE_GETTEXT		0
+#define HAVE_GETTEXT        0
 #endif /* !defined HAVE_GETTEXT */
 
 #ifndef HAVE_INCOMPATIBLE_CTIME_R
-#define HAVE_INCOMPATIBLE_CTIME_R	0
+#define HAVE_INCOMPATIBLE_CTIME_R   0
 #endif /* !defined INCOMPATIBLE_CTIME_R */
 
 #ifndef HAVE_SETTIMEOFDAY
-#define HAVE_SETTIMEOFDAY	3
+#define HAVE_SETTIMEOFDAY   3
 #endif /* !defined HAVE_SETTIMEOFDAY */
 
 #ifndef HAVE_STRERROR
-#define HAVE_STRERROR		1
+#define HAVE_STRERROR       1
 #endif /* !defined HAVE_STRERROR */
 
 #ifndef HAVE_SYMLINK
-#define HAVE_SYMLINK		1
+#define HAVE_SYMLINK        1
 #endif /* !defined HAVE_SYMLINK */
 
 #ifndef HAVE_SYS_STAT_H
-#define HAVE_SYS_STAT_H		1
+#define HAVE_SYS_STAT_H     1
 #endif /* !defined HAVE_SYS_STAT_H */
 
 #ifndef HAVE_SYS_WAIT_H
-#define HAVE_SYS_WAIT_H		1
+#define HAVE_SYS_WAIT_H     1
 #endif /* !defined HAVE_SYS_WAIT_H */
 
 #ifndef HAVE_UNISTD_H
-#define HAVE_UNISTD_H		1
+#define HAVE_UNISTD_H       1
 #endif /* !defined HAVE_UNISTD_H */
 
 #ifndef HAVE_UTMPX_H
-#define HAVE_UTMPX_H		0
+#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
@@ -85,11 +81,11 @@
 ** Nested includes
 */
 
-#include "sys/types.h"	/* for time_t */
+#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 "limits.h" /* for CHAR_BIT et al. */
 #include "time.h"
 #include "stdlib.h"
 
@@ -98,26 +94,26 @@
 #endif /* HAVE_GETTEXT */
 
 #if HAVE_SYS_WAIT_H
-#include <sys/wait.h>	/* for WIFEXITED and WEXITSTATUS */
+#include <sys/wait.h>   /* for WIFEXITED and WEXITSTATUS */
 #endif /* HAVE_SYS_WAIT_H */
 
 #ifndef WIFEXITED
-#define WIFEXITED(status)	(((status) & 0xff) == 0)
+#define WIFEXITED(status)   (((status) & 0xff) == 0)
 #endif /* !defined WIFEXITED */
 #ifndef WEXITSTATUS
-#define WEXITSTATUS(status)	(((status) >> 8) & 0xff)
+#define WEXITSTATUS(status) (((status) >> 8) & 0xff)
 #endif /* !defined WEXITSTATUS */
 
 #if HAVE_UNISTD_H
-#include "unistd.h"	/* for F_OK and R_OK */
+#include "unistd.h" /* for F_OK and R_OK */
 #endif /* HAVE_UNISTD_H */
 
 #if !HAVE_UNISTD_H
 #ifndef F_OK
-#define F_OK	0
+#define F_OK    0
 #endif /* !defined F_OK */
 #ifndef R_OK
-#define R_OK	4
+#define R_OK    4
 #endif /* !defined R_OK */
 #endif /* !HAVE_UNISTD_H */
 
@@ -132,8 +128,8 @@
 */
 #ifndef HAVE_STDINT_H
 #define HAVE_STDINT_H \
-	(199901 <= __STDC_VERSION__ || \
-	2 < (__GLIBC__ + (0 < __GLIBC_MINOR__)))
+    (199901 <= __STDC_VERSION__ || \
+    2 < (__GLIBC__ + (0 < __GLIBC_MINOR__)))
 #endif /* !defined HAVE_STDINT_H */
 
 #if HAVE_STDINT_H
@@ -143,13 +139,13 @@
 #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;
+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;
+typedef long        int_fast64_t;
 #endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
 #endif /* !defined INT_FAST64_MAX */
 
@@ -169,7 +165,7 @@
 */
 
 #ifndef P
-#define P(x)	x
+#define P(x)    x
 #endif /* !defined P */
 
 /*
@@ -177,7 +173,7 @@
 */
 
 #ifndef EXIT_SUCCESS
-#define EXIT_SUCCESS	0
+#define EXIT_SUCCESS    0
 #endif /* !defined EXIT_SUCCESS */
 
 /*
@@ -185,7 +181,7 @@
 */
 
 #ifndef EXIT_FAILURE
-#define EXIT_FAILURE	1
+#define EXIT_FAILURE    1
 #endif /* !defined EXIT_FAILURE */
 
 /*
@@ -201,10 +197,10 @@
 #endif /* !defined MAXPATHLEN */
 
 #ifdef MAXPATHLEN
-#define FILENAME_MAX	MAXPATHLEN
+#define FILENAME_MAX    MAXPATHLEN
 #endif /* defined MAXPATHLEN */
 #ifndef MAXPATHLEN
-#define FILENAME_MAX	1024		/* Pure guesswork */
+#define FILENAME_MAX    1024        /* Pure guesswork */
 #endif /* !defined MAXPATHLEN */
 
 #endif /* !defined FILENAME_MAX */
@@ -214,8 +210,8 @@
 */
 
 #ifndef remove
-extern int	unlink P((const char * filename));
-#define remove	unlink
+extern int  unlink P((const char * filename));
+#define remove  unlink
 #endif /* !defined remove */
 
 /*
@@ -235,36 +231,36 @@
 */
 
 #ifndef asctime_r
-extern char *	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));
+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
+#define TRUE    1
 #endif /* !defined TRUE */
 
 #ifndef FALSE
-#define FALSE	0
+#define FALSE   0
 #endif /* !defined FALSE */
 
 #ifndef TYPE_BIT
-#define TYPE_BIT(type)	(sizeof (type) * CHAR_BIT)
+#define TYPE_BIT(type)  (sizeof (type) * CHAR_BIT)
 #endif /* !defined TYPE_BIT */
 
 #ifndef TYPE_SIGNED
@@ -288,8 +284,8 @@
 ** 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))
+    ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
+    1 + TYPE_SIGNED(type))
 #endif /* !defined INT_STRLEN_MAXIMUM */
 
 /*
@@ -309,7 +305,7 @@
 
 #ifndef INITIALIZE
 #ifdef GNUC_or_lint
-#define INITIALIZE(x)	((x) = 0)
+#define INITIALIZE(x)   ((x) = 0)
 #endif /* defined GNUC_or_lint */
 #ifndef GNUC_or_lint
 #define INITIALIZE(x)
@@ -342,7 +338,7 @@
 #endif /* HAVE_INCOMPATIBLE_CTIME_R */
 
 #ifndef YEARSPERREPEAT
-#define YEARSPERREPEAT		400	/* years before a Gregorian repeat */
+#define YEARSPERREPEAT      400 /* years before a Gregorian repeat */
 #endif /* !defined YEARSPERREPEAT */
 
 /*
@@ -350,15 +346,15 @@
 */
 
 #ifndef AVGSECSPERYEAR
-#define AVGSECSPERYEAR		31556952L
+#define AVGSECSPERYEAR      31556952L
 #endif /* !defined AVGSECSPERYEAR */
 
 #ifndef SECSPERREPEAT
-#define SECSPERREPEAT		((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
+#define SECSPERREPEAT       ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
 #endif /* !defined SECSPERREPEAT */
  
 #ifndef SECSPERREPEAT_BITS
-#define SECSPERREPEAT_BITS	34	/* ceil(log2(SECSPERREPEAT)) */
+#define SECSPERREPEAT_BITS  34  /* ceil(log2(SECSPERREPEAT)) */
 #endif /* !defined SECSPERREPEAT_BITS */
 
 /*
diff --git a/libc/tzcode/strftime.c b/libc/tzcode/strftime.c
index 946c91c..ab713fb 100644
--- a/libc/tzcode/strftime.c
+++ b/libc/tzcode/strftime.c
@@ -1,6 +1,6 @@
 #ifndef lint
 #ifndef NOID
-static char	elsieid[] = "@(#)strftime.c	8.1";
+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".
@@ -29,7 +29,7 @@
 
 #ifndef LIBC_SCCS
 #ifndef lint
-static const char	sccsid[] = "@(#)strftime.c	5.4 (Berkeley) 3/14/89";
+static const char   sccsid[] = "@(#)strftime.c  5.4 (Berkeley) 3/14/89";
 #endif /* !defined lint */
 #endif /* !defined LIBC_SCCS */
 
@@ -37,132 +37,143 @@
 #include "fcntl.h"
 #include "locale.h"
 #include <ctype.h>
+#include <time64.h>
 
+/* struct lc_time_T is now defined as strftime_locale
+ * in <time.h>
+ */
+#if 1
+#define  lc_time_T    strftime_locale
+#else
 struct lc_time_T {
-	const char *	mon[MONSPERYEAR];
-	const char *	month[MONSPERYEAR];
-	const char *	wday[DAYSPERWEEK];
-	const char *	weekday[DAYSPERWEEK];
-	const char *	X_fmt;
-	const char *	x_fmt;
-	const char *	c_fmt;
-	const char *	am;
-	const char *	pm;
-	const char *	date_fmt;
+    const char *    mon[MONSPERYEAR];
+    const char *    month[MONSPERYEAR];
+    const char *    wday[DAYSPERWEEK];
+    const char *    weekday[DAYSPERWEEK];
+    const char *    X_fmt;
+    const char *    x_fmt;
+    const char *    c_fmt;
+    const char *    am;
+    const char *    pm;
+    const char *    date_fmt;
+};
+#endif
+
+#define Locale  (&C_time_locale)
+
+static const struct lc_time_T   C_time_locale = {
+    {
+        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+    }, {
+        "January", "February", "March", "April", "May", "June",
+        "July", "August", "September", "October", "November", "December"
+    }, {
+        "January", "February", "March", "April", "May", "June",
+        "July", "August", "September", "October", "November", "December"
+    }, {
+        "Sun", "Mon", "Tue", "Wed",
+        "Thu", "Fri", "Sat"
+    }, {
+        "Sunday", "Monday", "Tuesday", "Wednesday",
+        "Thursday", "Friday", "Saturday"
+    },
+
+    /* X_fmt */
+    "%H:%M:%S",
+
+    /*
+    ** x_fmt
+    ** C99 requires this format.
+    ** Using just numbers (as here) makes Quakers happier;
+    ** it's also compatible with SVR4.
+    */
+    "%m/%d/%y",
+
+    /*
+    ** c_fmt
+    ** C99 requires this format.
+    ** Previously this code used "%D %X", but we now conform to C99.
+    ** Note that
+    **  "%a %b %d %H:%M:%S %Y"
+    ** is used by Solaris 2.3.
+    */
+    "%a %b %e %T %Y",
+
+    /* am */
+    "AM",
+
+    /* pm */
+    "PM",
+
+    /* date_fmt */
+    "%a %b %e %H:%M:%S %Z %Y"
 };
 
-#ifdef LOCALE_HOME
-#include "sys/stat.h"
-static struct lc_time_T		localebuf;
-static struct lc_time_T *	_loc P((void));
-#define Locale	_loc()
-#endif /* defined LOCALE_HOME */
-#ifndef LOCALE_HOME
-#define Locale	(&C_time_locale)
-#endif /* !defined LOCALE_HOME */
+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*));
+static char *   _yconv P((int, int, int, int, char *, const char *, int));
+static char *   getformat P((int, char *, char *, char *, char *));
 
-static const struct lc_time_T	C_time_locale = {
-	{
-		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
-		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-	}, {
-		"January", "February", "March", "April", "May", "June",
-		"July", "August", "September", "October", "November", "December"
-	}, {
-		"Sun", "Mon", "Tue", "Wed",
-		"Thu", "Fri", "Sat"
-	}, {
-		"Sunday", "Monday", "Tuesday", "Wednesday",
-		"Thursday", "Friday", "Saturday"
-	},
-
-	/* X_fmt */
-	"%H:%M:%S",
-
-	/*
-	** x_fmt
-	** C99 requires this format.
-	** Using just numbers (as here) makes Quakers happier;
-	** it's also compatible with SVR4.
-	*/
-	"%m/%d/%y",
-
-	/*
-	** c_fmt
-	** C99 requires this format.
-	** Previously this code used "%D %X", but we now conform to C99.
-	** Note that
-	**	"%a %b %d %H:%M:%S %Y"
-	** is used by Solaris 2.3.
-	*/
-	"%a %b %e %T %Y",
-
-	/* am */
-	"AM",
-
-	/* pm */
-	"PM",
-
-	/* date_fmt */
-	"%a %b %e %H:%M:%S %Z %Y"
-};
-
-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 *));
-static char *	_yconv P((int, int, int, int, char *, const char *, int));
-static char *	getformat P((int, char *, char *, char *, char *));
-
-extern char *	tzname[];
+extern char *   tzname[];
 
 #ifndef YEAR_2000_NAME
-#define YEAR_2000_NAME	"CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
+#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 IN_NONE 0
+#define IN_SOME 1
+#define IN_THIS 2
+#define IN_ALL  3
 
 #define FORCE_LOWER_CASE 0x100
 
 size_t
 strftime(s, maxsize, format, t)
-char * const		s;
-const size_t		maxsize;
-const char * const	format;
-const struct tm * const	t;
+char * const        s;
+const size_t        maxsize;
+const char * const  format;
+const struct tm * const t;
 {
-	char *	p;
-	int	warn;
+    return strftime_tz(s, maxsize, format, t, Locale);
+}
 
-	tzset();
-#ifdef LOCALE_HOME
-	localebuf.mon[0] = 0;
-#endif /* defined LOCALE_HOME */
-	warn = IN_NONE;
-	p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn);
-#ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
-	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");
-	}
+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;
+
+    tzset();
+    warn = IN_NONE;
+    p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn, locale);
+#if 0  /* ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */
+    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;
+    if (p == s + maxsize)
+        return 0;
+    *p = '\0';
+    return p - s;
 }
 
 static char *getformat(int modifier, char *normal, char *underscore,
@@ -182,89 +193,97 @@
 }
 
 static char *
-_fmt(format, t, pt, ptlim, warnp)
-const char *		format;
-const struct tm * const	t;
-char *			pt;
-const char * const	ptlim;
-int *			warnp;
+_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 == '%') {
+    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':
-				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;
+            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);
-				if (warn2 == IN_ALL)
-					warn2 = IN_THIS;
-				if (warn2 > *warnp)
-					*warnp = warn2;
-				}
-				continue;
-			case 'D':
-                                pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp);
-				continue;
-			case 'd':
+                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;
+                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':
@@ -272,155 +291,155 @@
             case '#':
                 modifier = *format;
                 goto label;
-			case 'e':
-				pt = _conv(t->tm_mday,
+            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);
-				continue;
-			case 'H':
-				pt = _conv(t->tm_hour,
+                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",
+                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,
+                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,
+                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;
+                continue;
 #ifdef KITCHEN_SINK
-			case 'K':
-				/*
-				** After all this time, still unclaimed!
-				*/
-				pt = _add("kitchen sink", pt, ptlim, modifier);
-				continue;
+            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",
+            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,
+                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,
+                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);
-				continue;
-			case 'r':
-				pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp);
-				continue;
-			case 'S':
-				pt = _conv(t->tm_sec,
+                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;
+                continue;
+            case 's':
+                {
+                    struct tm   tm;
+                    char        buf[INT_STRLEN_MAXIMUM(
+                                time64_t) + 1];
+                    time64_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);
-				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",
+                    tm = *t;
+                    mkt = mktime64(&tm);
+                    if (TYPE_SIGNED(time64_t))
+                        (void) sprintf(buf, "%lld",
+                            (long long) mkt);
+                    else    (void) sprintf(buf, "%llu",
+                            (unsigned long 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) */
+                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
@@ -439,232 +458,232 @@
 ** 1997 lasts from 1996-12-30 to 1997-01-05..."
 ** (ado, 1996-01-02)
 */
-				{
-					int	year;
-					int	base;
-					int	yday;
-					int	wday;
-					int	w;
+                {
+                    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;
+                    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;
-					}
+                        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;
+                    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,
+                    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);
-				continue;
-			case 'W':
-				pt = _conv((t->tm_yday + DAYSPERWEEK -
-					(t->tm_wday ?
-					(t->tm_wday - 1) :
-					(DAYSPERWEEK - 1))) / DAYSPERWEEK,
-					getformat(modifier, "%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);
-				continue;
-			case 'x':
-				{
-				int	warn2 = IN_SOME;
+                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);
-				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':
+                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,
+                if (t->TM_ZONE != NULL)
+                    pt = _add(t->TM_ZONE, pt, ptlim,
                                                   modifier);
-				else
+                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)
+                    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;
+                if (t->tm_isdst < 0)
+                    continue;
 #ifdef TM_GMTOFF
-				diff = t->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)
+                /*
+                ** 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;
+                    diff = -timezone;
 #else /* !defined USG_COMPAT */
-					continue;
+                    continue;
 #endif /* !defined USG_COMPAT */
-				else
+                else
 #ifdef ALTZONE
-					diff = -altzone;
+                    diff = -altzone;
 #else /* !defined ALTZONE */
-					continue;
+                    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,
+                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);
-				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;
+                }
+                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;
+const int       n;
+const char * const  format;
+char * const        pt;
+const char * const  ptlim;
 {
-	char	buf[INT_STRLEN_MAXIMUM(int) + 1];
+    char    buf[INT_STRLEN_MAXIMUM(int) + 1];
 
-	(void) sprintf(buf, format, n);
-	return _add(buf, pt, ptlim, 0);
+    (void) snprintf(buf, sizeof(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;
+const char *        str;
+char *          pt;
+const char * const  ptlim;
 int                     modifier;
 {
         int c;
@@ -701,7 +720,7 @@
                 }
         }
 
-	return pt;
+    return pt;
 }
 
 /*
@@ -714,159 +733,38 @@
 
 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;
+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;
+    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",
+#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),
+    }
+    if (convert_yy)
+        pt = _conv(((trail < 0) ? -trail : trail),
                            getformat(modifier, "%02d", "%2d", "%d", "%02d"),
                            pt, ptlim);
-	return pt;
+    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/libc/tzcode/strptime.c b/libc/tzcode/strptime.c
index 982daf4..1f481c9 100644
--- a/libc/tzcode/strptime.c
+++ b/libc/tzcode/strptime.c
@@ -1,5 +1,5 @@
-/*	$OpenBSD: strptime.c,v 1.11 2005/08/08 08:05:38 espie Exp $ */
-/*	$NetBSD: strptime.c,v 1.12 1998/01/20 21:39:40 mycroft Exp $	*/
+/*  $OpenBSD: strptime.c,v 1.11 2005/08/08 08:05:38 espie Exp $ */
+/*  $NetBSD: strptime.c,v 1.12 1998/01/20 21:39:40 mycroft Exp $    */
 
 /*-
  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -44,387 +44,387 @@
 #include "tzfile.h"
 
 static const struct {
-	const char *abday[7];
-	const char *day[7];
-	const char *abmon[12];
-	const char *mon[12];
-	const char *am_pm[2];
-	const char *d_t_fmt;
-	const char *d_fmt;
-	const char *t_fmt;
-	const char *t_fmt_ampm;
+    const char *abday[7];
+    const char *day[7];
+    const char *abmon[12];
+    const char *mon[12];
+    const char *am_pm[2];
+    const char *d_t_fmt;
+    const char *d_fmt;
+    const char *t_fmt;
+    const char *t_fmt_ampm;
 } _DefaultTimeLocale = {
-	{
-		"Sun","Mon","Tue","Wed","Thu","Fri","Sat",
-	},
-	{
-		"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
-		"Friday", "Saturday"
-	},
-	{
-		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
-		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-	},
-	{
-		"January", "February", "March", "April", "May", "June", "July",
-		"August", "September", "October", "November", "December"
-	},
-	{
-		"AM", "PM"
-	},
-	"%a %b %d %H:%M:%S %Y",
-	"%m/%d/%y",
-	"%H:%M:%S",
-	"%I:%M:%S %p"
+    {
+        "Sun","Mon","Tue","Wed","Thu","Fri","Sat",
+    },
+    {
+        "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
+        "Friday", "Saturday"
+    },
+    {
+        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+    },
+    {
+        "January", "February", "March", "April", "May", "June", "July",
+        "August", "September", "October", "November", "December"
+    },
+    {
+        "AM", "PM"
+    },
+    "%a %b %d %H:%M:%S %Y",
+    "%m/%d/%y",
+    "%H:%M:%S",
+    "%I:%M:%S %p"
 };
 
-#define	_ctloc(x) (_DefaultTimeLocale.x)
+#define _ctloc(x) (_DefaultTimeLocale.x)
 
 /*
  * We do not implement alternate representations. However, we always
  * check whether a given modifier is allowed for a certain conversion.
  */
-#define _ALT_E			0x01
-#define _ALT_O			0x02
-#define	_LEGAL_ALT(x)		{ if (alt_format & ~(x)) return (0); }
+#define _ALT_E          0x01
+#define _ALT_O          0x02
+#define _LEGAL_ALT(x)       { if (alt_format & ~(x)) return (0); }
 
 
-static	int _conv_num(const unsigned char **, int *, int, int);
-static	char *_strptime(const char *, const char *, struct tm *, int);
+static  int _conv_num(const unsigned char **, int *, int, int);
+static  unsigned char *_strptime(const unsigned char *, const char *, struct tm *, int);
 
 
 char *
 strptime(const char *buf, const char *fmt, struct tm *tm)
 {
-	return(_strptime(buf, fmt, tm, 1));
+    return (char*)(_strptime((const unsigned char*)buf, fmt, tm, 1));
 }
 
-static char *
-_strptime(const char *buf, const char *fmt, struct tm *tm, int initialize)
+static unsigned char *
+_strptime(const unsigned char *buf, const char *fmt, struct tm *tm, int initialize)
 {
-	unsigned char c;
-	const unsigned char *bp;
-	size_t len;
-	int alt_format, i;
-	static int century, relyear;
+    unsigned char c;
+    const unsigned char *bp;
+    size_t len = 0;
+    int alt_format, i;
+    static int century, relyear;
 
-	if (initialize) {
-		century = TM_YEAR_BASE;
-		relyear = -1;
-	}
+    if (initialize) {
+        century = TM_YEAR_BASE;
+        relyear = -1;
+    }
 
-	bp = (unsigned char *)buf;
-	while ((c = *fmt) != '\0') {
-		/* Clear `alternate' modifier prior to new conversion. */
-		alt_format = 0;
+    bp = (unsigned char *)buf;
+    while ((c = *fmt) != '\0') {
+        /* Clear `alternate' modifier prior to new conversion. */
+        alt_format = 0;
 
-		/* Eat up white-space. */
-		if (isspace(c)) {
-			while (isspace(*bp))
-				bp++;
+        /* Eat up white-space. */
+        if (isspace(c)) {
+            while (isspace(*bp))
+                bp++;
 
-			fmt++;
-			continue;
-		}
-				
-		if ((c = *fmt++) != '%')
-			goto literal;
+            fmt++;
+            continue;
+        }
+                
+        if ((c = *fmt++) != '%')
+            goto literal;
 
 
-again:		switch (c = *fmt++) {
-		case '%':	/* "%%" is converted to "%". */
+again:      switch (c = *fmt++) {
+        case '%':   /* "%%" is converted to "%". */
 literal:
-		if (c != *bp++)
-			return (NULL);
+        if (c != *bp++)
+            return (NULL);
 
-		break;
+        break;
 
-		/*
-		 * "Alternative" modifiers. Just set the appropriate flag
-		 * and start over again.
-		 */
-		case 'E':	/* "%E?" alternative conversion modifier. */
-			_LEGAL_ALT(0);
-			alt_format |= _ALT_E;
-			goto again;
+        /*
+         * "Alternative" modifiers. Just set the appropriate flag
+         * and start over again.
+         */
+        case 'E':   /* "%E?" alternative conversion modifier. */
+            _LEGAL_ALT(0);
+            alt_format |= _ALT_E;
+            goto again;
 
-		case 'O':	/* "%O?" alternative conversion modifier. */
-			_LEGAL_ALT(0);
-			alt_format |= _ALT_O;
-			goto again;
-			
-		/*
-		 * "Complex" conversion rules, implemented through recursion.
-		 */
-		case 'c':	/* Date and time, using the locale's format. */
-			_LEGAL_ALT(_ALT_E);
-			if (!(bp = _strptime(bp, _ctloc(d_t_fmt), tm, 0)))
-				return (NULL);
-			break;
+        case 'O':   /* "%O?" alternative conversion modifier. */
+            _LEGAL_ALT(0);
+            alt_format |= _ALT_O;
+            goto again;
+            
+        /*
+         * "Complex" conversion rules, implemented through recursion.
+         */
+        case 'c':   /* Date and time, using the locale's format. */
+            _LEGAL_ALT(_ALT_E);
+            if (!(bp = _strptime(bp, _ctloc(d_t_fmt), tm, 0)))
+                return (NULL);
+            break;
 
-		case 'D':	/* The date as "%m/%d/%y". */
-			_LEGAL_ALT(0);
-			if (!(bp = _strptime(bp, "%m/%d/%y", tm, 0)))
-				return (NULL);
-			break;
-	
-		case 'R':	/* The time as "%H:%M". */
-			_LEGAL_ALT(0);
-			if (!(bp = _strptime(bp, "%H:%M", tm, 0)))
-				return (NULL);
-			break;
+        case 'D':   /* The date as "%m/%d/%y". */
+            _LEGAL_ALT(0);
+            if (!(bp = _strptime(bp, "%m/%d/%y", tm, 0)))
+                return (NULL);
+            break;
+    
+        case 'R':   /* The time as "%H:%M". */
+            _LEGAL_ALT(0);
+            if (!(bp = _strptime(bp, "%H:%M", tm, 0)))
+                return (NULL);
+            break;
 
-		case 'r':	/* The time as "%I:%M:%S %p". */
-			_LEGAL_ALT(0);
-			if (!(bp = _strptime(bp, "%I:%M:%S %p", tm, 0)))
-				return (NULL);
-			break;
+        case 'r':   /* The time as "%I:%M:%S %p". */
+            _LEGAL_ALT(0);
+            if (!(bp = _strptime(bp, "%I:%M:%S %p", tm, 0)))
+                return (NULL);
+            break;
 
-		case 'T':	/* The time as "%H:%M:%S". */
-			_LEGAL_ALT(0);
-			if (!(bp = _strptime(bp, "%H:%M:%S", tm, 0)))
-				return (NULL);
-			break;
+        case 'T':   /* The time as "%H:%M:%S". */
+            _LEGAL_ALT(0);
+            if (!(bp = _strptime(bp, "%H:%M:%S", tm, 0)))
+                return (NULL);
+            break;
 
-		case 'X':	/* The time, using the locale's format. */
-			_LEGAL_ALT(_ALT_E);
-			if (!(bp = _strptime(bp, _ctloc(t_fmt), tm, 0)))
-				return (NULL);
-			break;
+        case 'X':   /* The time, using the locale's format. */
+            _LEGAL_ALT(_ALT_E);
+            if (!(bp = _strptime(bp, _ctloc(t_fmt), tm, 0)))
+                return (NULL);
+            break;
 
-		case 'x':	/* The date, using the locale's format. */
-			_LEGAL_ALT(_ALT_E);
-			if (!(bp = _strptime(bp, _ctloc(d_fmt), tm, 0)))
-				return (NULL);
-			break;
+        case 'x':   /* The date, using the locale's format. */
+            _LEGAL_ALT(_ALT_E);
+            if (!(bp = _strptime(bp, _ctloc(d_fmt), tm, 0)))
+                return (NULL);
+            break;
 
-		/*
-		 * "Elementary" conversion rules.
-		 */
-		case 'A':	/* The day of week, using the locale's form. */
-		case 'a':
-			_LEGAL_ALT(0);
-			for (i = 0; i < 7; i++) {
-				/* Full name. */
-				len = strlen(_ctloc(day[i]));
-				if (strncasecmp(_ctloc(day[i]), bp, len) == 0)
-					break;
+        /*
+         * "Elementary" conversion rules.
+         */
+        case 'A':   /* The day of week, using the locale's form. */
+        case 'a':
+            _LEGAL_ALT(0);
+            for (i = 0; i < 7; i++) {
+                /* Full name. */
+                len = strlen(_ctloc(day[i]));
+                if (strncasecmp(_ctloc(day[i]), (const char*)bp, len) == 0)
+                    break;
 
-				/* Abbreviated name. */
-				len = strlen(_ctloc(abday[i]));
-				if (strncasecmp(_ctloc(abday[i]), bp, len) == 0)
-					break;
-			}
+                /* Abbreviated name. */
+                len = strlen(_ctloc(abday[i]));
+                if (strncasecmp(_ctloc(abday[i]), (const char*)bp, len) == 0)
+                    break;
+            }
 
-			/* Nothing matched. */
-			if (i == 7)
-				return (NULL);
+            /* Nothing matched. */
+            if (i == 7)
+                return (NULL);
 
-			tm->tm_wday = i;
-			bp += len;
-			break;
+            tm->tm_wday = i;
+            bp += len;
+            break;
 
-		case 'B':	/* The month, using the locale's form. */
-		case 'b':
-		case 'h':
-			_LEGAL_ALT(0);
-			for (i = 0; i < 12; i++) {
-				/* Full name. */
-				len = strlen(_ctloc(mon[i]));
-				if (strncasecmp(_ctloc(mon[i]), bp, len) == 0)
-					break;
+        case 'B':   /* The month, using the locale's form. */
+        case 'b':
+        case 'h':
+            _LEGAL_ALT(0);
+            for (i = 0; i < 12; i++) {
+                /* Full name. */
+                len = strlen(_ctloc(mon[i]));
+                if (strncasecmp(_ctloc(mon[i]), (const char*)bp, len) == 0)
+                    break;
 
-				/* Abbreviated name. */
-				len = strlen(_ctloc(abmon[i]));
-				if (strncasecmp(_ctloc(abmon[i]), bp, len) == 0)
-					break;
-			}
+                /* Abbreviated name. */
+                len = strlen(_ctloc(abmon[i]));
+                if (strncasecmp(_ctloc(abmon[i]), (const char*)bp, len) == 0)
+                    break;
+            }
 
-			/* Nothing matched. */
-			if (i == 12)
-				return (NULL);
+            /* Nothing matched. */
+            if (i == 12)
+                return (NULL);
 
-			tm->tm_mon = i;
-			bp += len;
-			break;
+            tm->tm_mon = i;
+            bp += len;
+            break;
 
-		case 'C':	/* The century number. */
-			_LEGAL_ALT(_ALT_E);
-			if (!(_conv_num(&bp, &i, 0, 99)))
-				return (NULL);
+        case 'C':   /* The century number. */
+            _LEGAL_ALT(_ALT_E);
+            if (!(_conv_num(&bp, &i, 0, 99)))
+                return (NULL);
 
-			century = i * 100;
-			break;
+            century = i * 100;
+            break;
 
-		case 'd':	/* The day of month. */
-		case 'e':
-			_LEGAL_ALT(_ALT_O);
-			if (!(_conv_num(&bp, &tm->tm_mday, 1, 31)))
-				return (NULL);
-			break;
+        case 'd':   /* The day of month. */
+        case 'e':
+            _LEGAL_ALT(_ALT_O);
+            if (!(_conv_num(&bp, &tm->tm_mday, 1, 31)))
+                return (NULL);
+            break;
 
-		case 'k':	/* The hour (24-hour clock representation). */
-			_LEGAL_ALT(0);
-			/* FALLTHROUGH */
-		case 'H':
-			_LEGAL_ALT(_ALT_O);
-			if (!(_conv_num(&bp, &tm->tm_hour, 0, 23)))
-				return (NULL);
-			break;
+        case 'k':   /* The hour (24-hour clock representation). */
+            _LEGAL_ALT(0);
+            /* FALLTHROUGH */
+        case 'H':
+            _LEGAL_ALT(_ALT_O);
+            if (!(_conv_num(&bp, &tm->tm_hour, 0, 23)))
+                return (NULL);
+            break;
 
-		case 'l':	/* The hour (12-hour clock representation). */
-			_LEGAL_ALT(0);
-			/* FALLTHROUGH */
-		case 'I':
-			_LEGAL_ALT(_ALT_O);
-			if (!(_conv_num(&bp, &tm->tm_hour, 1, 12)))
-				return (NULL);
-			break;
+        case 'l':   /* The hour (12-hour clock representation). */
+            _LEGAL_ALT(0);
+            /* FALLTHROUGH */
+        case 'I':
+            _LEGAL_ALT(_ALT_O);
+            if (!(_conv_num(&bp, &tm->tm_hour, 1, 12)))
+                return (NULL);
+            break;
 
-		case 'j':	/* The day of year. */
-			_LEGAL_ALT(0);
-			if (!(_conv_num(&bp, &tm->tm_yday, 1, 366)))
-				return (NULL);
-			tm->tm_yday--;
-			break;
+        case 'j':   /* The day of year. */
+            _LEGAL_ALT(0);
+            if (!(_conv_num(&bp, &tm->tm_yday, 1, 366)))
+                return (NULL);
+            tm->tm_yday--;
+            break;
 
-		case 'M':	/* The minute. */
-			_LEGAL_ALT(_ALT_O);
-			if (!(_conv_num(&bp, &tm->tm_min, 0, 59)))
-				return (NULL);
-			break;
+        case 'M':   /* The minute. */
+            _LEGAL_ALT(_ALT_O);
+            if (!(_conv_num(&bp, &tm->tm_min, 0, 59)))
+                return (NULL);
+            break;
 
-		case 'm':	/* The month. */
-			_LEGAL_ALT(_ALT_O);
-			if (!(_conv_num(&bp, &tm->tm_mon, 1, 12)))
-				return (NULL);
-			tm->tm_mon--;
-			break;
+        case 'm':   /* The month. */
+            _LEGAL_ALT(_ALT_O);
+            if (!(_conv_num(&bp, &tm->tm_mon, 1, 12)))
+                return (NULL);
+            tm->tm_mon--;
+            break;
 
-		case 'p':	/* The locale's equivalent of AM/PM. */
-			_LEGAL_ALT(0);
-			/* AM? */
-			len = strlen(_ctloc(am_pm[0]));
-			if (strncasecmp(_ctloc(am_pm[0]), bp, len) == 0) {
-				if (tm->tm_hour > 12)	/* i.e., 13:00 AM ?! */
-					return (NULL);
-				else if (tm->tm_hour == 12)
-					tm->tm_hour = 0;
+        case 'p':   /* The locale's equivalent of AM/PM. */
+            _LEGAL_ALT(0);
+            /* AM? */
+            len = strlen(_ctloc(am_pm[0]));
+            if (strncasecmp(_ctloc(am_pm[0]), (const char*)bp, len) == 0) {
+                if (tm->tm_hour > 12)   /* i.e., 13:00 AM ?! */
+                    return (NULL);
+                else if (tm->tm_hour == 12)
+                    tm->tm_hour = 0;
 
-				bp += len;
-				break;
-			}
-			/* PM? */
-			len = strlen(_ctloc(am_pm[1]));
-			if (strncasecmp(_ctloc(am_pm[1]), bp, len) == 0) {
-				if (tm->tm_hour > 12)	/* i.e., 13:00 PM ?! */
-					return (NULL);
-				else if (tm->tm_hour < 12)
-					tm->tm_hour += 12;
+                bp += len;
+                break;
+            }
+            /* PM? */
+            len = strlen(_ctloc(am_pm[1]));
+            if (strncasecmp(_ctloc(am_pm[1]), (const char*)bp, len) == 0) {
+                if (tm->tm_hour > 12)   /* i.e., 13:00 PM ?! */
+                    return (NULL);
+                else if (tm->tm_hour < 12)
+                    tm->tm_hour += 12;
 
-				bp += len;
-				break;
-			}
+                bp += len;
+                break;
+            }
 
-			/* Nothing matched. */
-			return (NULL);
+            /* Nothing matched. */
+            return (NULL);
 
-		case 'S':	/* The seconds. */
-			_LEGAL_ALT(_ALT_O);
-			if (!(_conv_num(&bp, &tm->tm_sec, 0, 61)))
-				return (NULL);
-			break;
+        case 'S':   /* The seconds. */
+            _LEGAL_ALT(_ALT_O);
+            if (!(_conv_num(&bp, &tm->tm_sec, 0, 61)))
+                return (NULL);
+            break;
 
-		case 'U':	/* The week of year, beginning on sunday. */
-		case 'W':	/* The week of year, beginning on monday. */
-			_LEGAL_ALT(_ALT_O);
-			/*
-			 * XXX This is bogus, as we can not assume any valid
-			 * information present in the tm structure at this
-			 * point to calculate a real value, so just check the
-			 * range for now.
-			 */
-			 if (!(_conv_num(&bp, &i, 0, 53)))
-				return (NULL);
-			 break;
+        case 'U':   /* The week of year, beginning on sunday. */
+        case 'W':   /* The week of year, beginning on monday. */
+            _LEGAL_ALT(_ALT_O);
+            /*
+             * XXX This is bogus, as we can not assume any valid
+             * information present in the tm structure at this
+             * point to calculate a real value, so just check the
+             * range for now.
+             */
+             if (!(_conv_num(&bp, &i, 0, 53)))
+                return (NULL);
+             break;
 
-		case 'w':	/* The day of week, beginning on sunday. */
-			_LEGAL_ALT(_ALT_O);
-			if (!(_conv_num(&bp, &tm->tm_wday, 0, 6)))
-				return (NULL);
-			break;
+        case 'w':   /* The day of week, beginning on sunday. */
+            _LEGAL_ALT(_ALT_O);
+            if (!(_conv_num(&bp, &tm->tm_wday, 0, 6)))
+                return (NULL);
+            break;
 
-		case 'Y':	/* The year. */
-			_LEGAL_ALT(_ALT_E);
-			if (!(_conv_num(&bp, &i, 0, 9999)))
-				return (NULL);
+        case 'Y':   /* The year. */
+            _LEGAL_ALT(_ALT_E);
+            if (!(_conv_num(&bp, &i, 0, 9999)))
+                return (NULL);
 
-			relyear = -1;
-			tm->tm_year = i - TM_YEAR_BASE;
-			break;
+            relyear = -1;
+            tm->tm_year = i - TM_YEAR_BASE;
+            break;
 
-		case 'y':	/* The year within the century (2 digits). */
-			_LEGAL_ALT(_ALT_E | _ALT_O);
-			if (!(_conv_num(&bp, &relyear, 0, 99)))
-				return (NULL);
-			break;
+        case 'y':   /* The year within the century (2 digits). */
+            _LEGAL_ALT(_ALT_E | _ALT_O);
+            if (!(_conv_num(&bp, &relyear, 0, 99)))
+                return (NULL);
+            break;
 
-		/*
-		 * Miscellaneous conversions.
-		 */
-		case 'n':	/* Any kind of white-space. */
-		case 't':
-			_LEGAL_ALT(0);
-			while (isspace(*bp))
-				bp++;
-			break;
+        /*
+         * Miscellaneous conversions.
+         */
+        case 'n':   /* Any kind of white-space. */
+        case 't':
+            _LEGAL_ALT(0);
+            while (isspace(*bp))
+                bp++;
+            break;
 
 
-		default:	/* Unknown/unsupported conversion. */
-			return (NULL);
-		}
+        default:    /* Unknown/unsupported conversion. */
+            return (NULL);
+        }
 
 
-	}
+    }
 
-	/*
-	 * We need to evaluate the two digit year spec (%y)
-	 * last as we can get a century spec (%C) at any time.
-	 */
-	if (relyear != -1) {
-		if (century == TM_YEAR_BASE) {
-			if (relyear <= 68)
-				tm->tm_year = relyear + 2000 - TM_YEAR_BASE;
-			else
-				tm->tm_year = relyear + 1900 - TM_YEAR_BASE;
-		} else {
-			tm->tm_year = relyear + century - TM_YEAR_BASE;
-		}
-	}
+    /*
+     * We need to evaluate the two digit year spec (%y)
+     * last as we can get a century spec (%C) at any time.
+     */
+    if (relyear != -1) {
+        if (century == TM_YEAR_BASE) {
+            if (relyear <= 68)
+                tm->tm_year = relyear + 2000 - TM_YEAR_BASE;
+            else
+                tm->tm_year = relyear + 1900 - TM_YEAR_BASE;
+        } else {
+            tm->tm_year = relyear + century - TM_YEAR_BASE;
+        }
+    }
 
-	return ((char *)bp);
+    return (unsigned char*)bp;
 }
 
 
 static int
 _conv_num(const unsigned char **buf, int *dest, int llim, int ulim)
 {
-	int result = 0;
-	int rulim = ulim;
+    int result = 0;
+    int rulim = ulim;
 
-	if (**buf < '0' || **buf > '9')
-		return (0);
+    if (**buf < '0' || **buf > '9')
+        return (0);
 
-	/* we use rulim to break out of the loop when we run out of digits */
-	do {
-		result *= 10;
-		result += *(*buf)++ - '0';
-		rulim /= 10;
-	} while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9');
+    /* we use rulim to break out of the loop when we run out of digits */
+    do {
+        result *= 10;
+        result += *(*buf)++ - '0';
+        rulim /= 10;
+    } while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9');
 
-	if (result < llim || result > ulim)
-		return (0);
+    if (result < llim || result > ulim)
+        return (0);
 
-	*dest = result;
-	return (1);
+    *dest = result;
+    return (1);
 }
diff --git a/libc/tzcode/tzfile.h b/libc/tzcode/tzfile.h
index 480682e..f6c9a05 100644
--- a/libc/tzcode/tzfile.h
+++ b/libc/tzcode/tzfile.h
@@ -21,7 +21,7 @@
 
 #ifndef lint
 #ifndef NOID
-static char	tzfilehid[] = "@(#)tzfile.h	8.1";
+static char tzfilehid[] = "@(#)tzfile.h 8.1";
 #endif /* !defined NOID */
 #endif /* !defined lint */
 
@@ -34,54 +34,54 @@
 #endif /* !defined TZDIR */
 
 #ifndef TZDEFAULT
-#define TZDEFAULT	"localtime"
+#define TZDEFAULT   "localtime"
 #endif /* !defined TZDEFAULT */
 
 #ifndef TZDEFRULES
-#define TZDEFRULES	"posixrules"
+#define TZDEFRULES  "posixrules"
 #endif /* !defined TZDEFRULES */
 
 /*
 ** Each file begins with. . .
 */
 
-#define	TZ_MAGIC	"TZif"
+#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 */
+    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
+**  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
 */
 
 /*
@@ -100,81 +100,81 @@
 */
 
 #ifndef TZ_MAX_TIMES
-#define TZ_MAX_TIMES	1200
+#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 */
+#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 */
+#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) */
+#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 */
+#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 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_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_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 TM_YEAR_BASE    1900
 
-#define EPOCH_YEAR	1970
-#define EPOCH_WDAY	TM_THURSDAY
+#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)
+**  isleap(y) == isleap(y % 400)
 ** and so
-**	isleap(a + b) == isleap((a + b) % 400)
+**  isleap(a + b) == isleap((a + b) % 400)
 ** or
-**	isleap(a + b) == isleap(a % 400 + b % 400)
+**  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)
+#define isleap_sum(a, b)    isleap((a) % 400 + (b) % 400)
 
 #endif /* !defined TZFILE_H */
diff --git a/libc/unistd/abort.c b/libc/unistd/abort.c
index d4e40e1..3e3aab0 100644
--- a/libc/unistd/abort.c
+++ b/libc/unistd/abort.c
@@ -39,8 +39,13 @@
 #define debug_log(format, ...)  \
     __libc_android_log_print(ANDROID_LOG_DEBUG, "libc-abort", (format), ##__VA_ARGS__ )
 
+#ifdef __arm__
+void
+__libc_android_abort(void)
+#else
 void
 abort(void)
+#endif
 {
 	struct atexit *p = __atexit;
 	static int cleanup_called = 0;
@@ -73,10 +78,8 @@
 	}
 
     /* temporary, for bug hunting */
-    debug_log("abort() called in pid %d\n", getpid());
     /* seg fault seems to produce better debuggerd results than SIGABRT */
     *((char*)0xdeadbaad) = 39;
-    debug_log("somehow we're not dead?\n");
     /* -- */
 
 	(void)kill(getpid(), SIGABRT);
@@ -99,3 +102,29 @@
 	(void)kill(getpid(), SIGABRT);
 	_exit(1);
 }
+
+#ifdef __arm__
+/*
+ * abort() does not return, which gcc interprets to mean that it doesn't
+ * need to preserve any of the callee-save registers.  Unfortunately this
+ * includes the link register, so if LR is used there is no way to determine
+ * which function called abort().
+ *
+ * We work around this by inserting a trivial stub that doesn't alter
+ * any of the "interesting" registers and thus doesn't need to save them.
+ * We can't just call __libc_android_abort from C because gcc uses "bl"
+ * without first saving LR, so we use an asm statement.  This also has
+ * the side-effect of replacing abort() with __libc_android_abort() in
+ * the stack trace.
+ *
+ * Ideally __libc_android_abort would be static, but I haven't figured out
+ * how to tell gcc to call a static function from an asm statement.
+ */
+void
+abort(void)
+{
+    asm ("b __libc_android_abort");
+    _exit(1);       /* suppress gcc noreturn warnings */
+}
+#endif
+