am 0c9dc552: am aecb7f84: Merge "Revert "Revert "sound trigger: several data structure updates"""

* commit '0c9dc552921bf50d62c8b81084a703ac07e48cd6':
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 0254bd2..e78fc88 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -53,3 +53,4 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/reboot)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/default.prop)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/default.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/lmkd_intermediates/import_includes)
diff --git a/adb/sockets.c b/adb/sockets.c
index de14a22..faa9564 100644
--- a/adb/sockets.c
+++ b/adb/sockets.c
@@ -23,6 +23,10 @@
 
 #include "sysdeps.h"
 
+#if !ADB_HOST
+#include <cutils/properties.h>
+#endif
+
 #define  TRACE_TAG  TRACE_SOCKETS
 #include "adb.h"
 
@@ -428,6 +432,9 @@
 {
     asocket *s;
     int fd;
+#if !ADB_HOST
+    char debug[PROPERTY_VALUE_MAX];
+#endif
 
 #if !ADB_HOST
     if (!strcmp(name,"jdwp")) {
@@ -444,7 +451,11 @@
     D("LS(%d): bound to '%s' via %d\n", s->id, name, fd);
 
 #if !ADB_HOST
-    if ((!strncmp(name, "root:", 5) && getuid() != 0)
+    if (!strncmp(name, "root:", 5))
+        property_get("ro.debuggable", debug, "");
+
+    if ((!strncmp(name, "root:", 5) && getuid() != 0
+        && strcmp(debug, "1") == 0)
         || !strncmp(name, "usb:", 4)
         || !strncmp(name, "tcpip:", 6)) {
         D("LS(%d): enabling exit_on_close\n", s->id);
diff --git a/debuggerd/Android.mk b/debuggerd/Android.mk
index e4d7ecc..c33b263 100644
--- a/debuggerd/Android.mk
+++ b/debuggerd/Android.mk
@@ -22,13 +22,6 @@
     -Wunused \
     -Werror \
 
-ifeq ($(ARCH_ARM_HAVE_VFP),true)
-LOCAL_CFLAGS_arm += -DWITH_VFP
-endif # ARCH_ARM_HAVE_VFP
-ifeq ($(ARCH_ARM_HAVE_VFP_D32),true)
-LOCAL_CFLAGS_arm += -DWITH_VFP_D32
-endif # ARCH_ARM_HAVE_VFP_D32
-
 LOCAL_SHARED_LIBRARIES := \
     libbacktrace \
     libcutils \
@@ -45,6 +38,8 @@
 
 include $(BUILD_EXECUTABLE)
 
+
+
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := crasher.c
 LOCAL_SRC_FILES_arm    := arm/crashglue.S
@@ -59,36 +54,14 @@
 #LOCAL_FORCE_STATIC_EXECUTABLE := true
 LOCAL_SHARED_LIBRARIES := libcutils liblog libc
 
+# The arm emulator has VFP but not VFPv3-D32.
+ifeq ($(ARCH_ARM_HAVE_VFP_D32),true)
+LOCAL_ASFLAGS_arm += -DHAS_VFP_D32
+endif
+
 LOCAL_MODULE := crasher
 LOCAL_MODULE_STEM_32 := crasher
 LOCAL_MODULE_STEM_64 := crasher64
 LOCAL_MULTILIB := both
 
 include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-ifeq ($(ARCH_ARM_HAVE_VFP),true)
-LOCAL_MODULE_TARGET_ARCH += arm
-LOCAL_SRC_FILES_arm := arm/vfp.S
-LOCAL_CFLAGS_arm += -DWITH_VFP
-ifeq ($(ARCH_ARM_HAVE_VFP_D32),true)
-LOCAL_CFLAGS_arm += -DWITH_VFP_D32
-endif # ARCH_ARM_HAVE_VFP_D32
-endif # ARCH_ARM_HAVE_VFP == true
-LOCAL_CFLAGS += -Werror
-
-LOCAL_SRC_FILES_arm64 := arm64/vfp.S
-LOCAL_MODULE_TARGET_ARCH += arm64
-
-LOCAL_SRC_FILES := vfp-crasher.c
-LOCAL_MODULE := vfp-crasher
-LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
-LOCAL_MODULE_TAGS := optional
-LOCAL_SHARED_LIBRARIES := libcutils liblog libc
-
-LOCAL_MODULE_STEM_32 := vfp-crasher
-LOCAL_MODULE_STEM_64 := vfp-crasher64
-LOCAL_MULTILIB := both
-
-include $(BUILD_EXECUTABLE)
diff --git a/debuggerd/arm/crashglue.S b/debuggerd/arm/crashglue.S
index eb9d0e3..4fbfd6e 100644
--- a/debuggerd/arm/crashglue.S
+++ b/debuggerd/arm/crashglue.S
@@ -1,8 +1,5 @@
 .globl crash1
 .type crash1, %function
-.globl crashnostack
-.type crashnostack, %function
-
 crash1:
 	ldr r0, =0xa5a50000
 	ldr r1, =0xa5a50001
@@ -18,11 +15,48 @@
 	ldr r11, =0xa5a50011
 	ldr r12, =0xa5a50012
 
+
+	fconstd   d0, #0
+	fconstd   d1, #1
+	fconstd   d2, #2
+	fconstd   d3, #3
+	fconstd   d4, #4
+	fconstd   d5, #5
+	fconstd   d6, #6
+	fconstd   d7, #7
+	fconstd   d8, #8
+	fconstd   d9, #9
+	fconstd   d10, #10
+	fconstd   d11, #11
+	fconstd   d12, #12
+	fconstd   d13, #13
+	fconstd   d14, #14
+	fconstd   d15, #15
+#if defined(HAS_VFP_D32)
+	fconstd   d16, #16
+	fconstd   d17, #17
+	fconstd   d18, #18
+	fconstd   d19, #19
+	fconstd   d20, #20
+	fconstd   d21, #21
+	fconstd   d22, #22
+	fconstd   d23, #23
+	fconstd   d24, #24
+	fconstd   d25, #25
+	fconstd   d26, #26
+	fconstd   d27, #27
+	fconstd   d28, #28
+	fconstd   d29, #29
+	fconstd   d30, #30
+	fconstd   d31, #31
+#endif
+
 	mov lr, #0
 	ldr lr, [lr]
 	b .
 
-
+.globl crashnostack
+.type crashnostack, %function
 crashnostack:
 	mov sp, #0
 	mov r0, #0
diff --git a/debuggerd/arm/machine.cpp b/debuggerd/arm/machine.cpp
index 839d47a..8270066 100644
--- a/debuggerd/arm/machine.cpp
+++ b/debuggerd/arm/machine.cpp
@@ -27,21 +27,8 @@
 #include "../utility.h"
 #include "../machine.h"
 
-// enable to dump memory pointed to by every register
-#define DUMP_MEMORY_FOR_ALL_REGISTERS 1
-
-#ifdef WITH_VFP
-#ifdef WITH_VFP_D32
-#define NUM_VFP_REGS 32
-#else
-#define NUM_VFP_REGS 16
-#endif
-#endif
-
-// If configured to do so, dump memory around *all* registers
-// for the crashing thread.
 void dump_memory_and_code(log_t* log, pid_t tid) {
-  struct pt_regs regs;
+  pt_regs regs;
   if (ptrace(PTRACE_GETREGS, tid, 0, &regs)) {
     return;
   }
@@ -73,7 +60,7 @@
 }
 
 void dump_registers(log_t* log, pid_t tid) {
-  struct pt_regs r;
+  pt_regs r;
   if (ptrace(PTRACE_GETREGS, tid, 0, &r)) {
     _LOG(log, logtype::REGISTERS, "cannot get registers: %s\n", strerror(errno));
     return;
@@ -93,19 +80,15 @@
        static_cast<uint32_t>(r.ARM_lr), static_cast<uint32_t>(r.ARM_pc),
        static_cast<uint32_t>(r.ARM_cpsr));
 
-#ifdef WITH_VFP
-  struct user_vfp vfp_regs;
-  int i;
-
+  user_vfp vfp_regs;
   if (ptrace(PTRACE_GETVFPREGS, tid, 0, &vfp_regs)) {
     _LOG(log, logtype::REGISTERS, "cannot get registers: %s\n", strerror(errno));
     return;
   }
 
-  for (i = 0; i < NUM_VFP_REGS; i += 2) {
+  for (size_t i = 0; i < 32; i += 2) {
     _LOG(log, logtype::REGISTERS, "    d%-2d %016llx  d%-2d %016llx\n",
          i, vfp_regs.fpregs[i], i+1, vfp_regs.fpregs[i+1]);
   }
   _LOG(log, logtype::REGISTERS, "    scr %08lx\n", vfp_regs.fpscr);
-#endif
 }
diff --git a/debuggerd/arm/vfp.S b/debuggerd/arm/vfp.S
deleted file mode 100644
index 9744f6f..0000000
--- a/debuggerd/arm/vfp.S
+++ /dev/null
@@ -1,43 +0,0 @@
-    .text
-    .align 2
-    .global crash
-    .type crash, %function
-crash:
-    fconstd   d0, #0
-    fconstd   d1, #1
-    fconstd   d2, #2
-    fconstd   d3, #3
-    fconstd   d4, #4
-    fconstd   d5, #5
-    fconstd   d6, #6
-    fconstd   d7, #7
-    fconstd   d8, #8
-    fconstd   d9, #9
-    fconstd   d10, #10
-    fconstd   d11, #11
-    fconstd   d12, #12
-    fconstd   d13, #13
-    fconstd   d14, #14
-    fconstd   d15, #15
-#ifdef WITH_VFP_D32
-    fconstd   d16, #16
-    fconstd   d17, #17
-    fconstd   d18, #18
-    fconstd   d19, #19
-    fconstd   d20, #20
-    fconstd   d21, #21
-    fconstd   d22, #22
-    fconstd   d23, #23
-    fconstd   d24, #24
-    fconstd   d25, #25
-    fconstd   d26, #26
-    fconstd   d27, #27
-    fconstd   d28, #28
-    fconstd   d29, #29
-    fconstd   d30, #30
-    fconstd   d31, #31
-#endif
-    mov       r0, #0
-    str       r0, [r0]
-    bx        lr
-
diff --git a/debuggerd/arm64/crashglue.S b/debuggerd/arm64/crashglue.S
index b06b67c..e58b542 100644
--- a/debuggerd/arm64/crashglue.S
+++ b/debuggerd/arm64/crashglue.S
@@ -1,8 +1,5 @@
 .globl crash1
 .type crash1, %function
-.globl crashnostack
-.type crashnostack, %function
-
 crash1:
 	ldr x0, =0xa5a50000
 	ldr x1, =0xa5a50001
@@ -35,11 +32,46 @@
 	ldr x28, =0xa5a50028
 	ldr x29, =0xa5a50029
 
+	fmov   d0, -1.0  // -1 is more convincing than 0.
+	fmov   d1, 1.0
+	fmov   d2, 2.0
+	fmov   d3, 3.0
+	fmov   d4, 4.0
+	fmov   d5, 5.0
+	fmov   d6, 6.0
+	fmov   d7, 7.0
+	fmov   d8, 8.0
+	fmov   d9, 9.0
+	fmov   d10, 10.0
+	fmov   d11, 11.0
+	fmov   d12, 12.0
+	fmov   d13, 13.0
+	fmov   d14, 14.0
+	fmov   d15, 15.0
+	fmov   d16, 16.0
+	fmov   d17, 17.0
+	fmov   d18, 18.0
+	fmov   d19, 19.0
+	fmov   d20, 20.0
+	fmov   d21, 21.0
+	fmov   d22, 22.0
+	fmov   d23, 23.0
+	fmov   d24, 24.0
+	fmov   d25, 25.0
+	fmov   d26, 26.0
+	fmov   d27, 27.0
+	fmov   d28, 28.0
+	fmov   d29, 29.0
+	fmov   d30, 30.0
+	fmov   d31, 31.0
+
 	mov x30, xzr
 	ldr x30, [x30]
 	b .
 
 
+.globl crashnostack
+.type crashnostack, %function
 crashnostack:
 	mov x0, xzr
 	add sp, x0, xzr
diff --git a/debuggerd/arm64/machine.cpp b/debuggerd/arm64/machine.cpp
index 48308c3..ec664bd 100644
--- a/debuggerd/arm64/machine.cpp
+++ b/debuggerd/arm64/machine.cpp
@@ -30,13 +30,6 @@
 #include "../utility.h"
 #include "../machine.h"
 
-/* enable to dump memory pointed to by every register */
-#define DUMP_MEMORY_FOR_ALL_REGISTERS 1
-
-/*
- * If configured to do so, dump memory around *all* registers
- * for the crashing thread.
- */
 void dump_memory_and_code(log_t* log, pid_t tid) {
     struct user_pt_regs regs;
     struct iovec io;
diff --git a/debuggerd/arm64/vfp.S b/debuggerd/arm64/vfp.S
deleted file mode 100644
index bf12c22..0000000
--- a/debuggerd/arm64/vfp.S
+++ /dev/null
@@ -1,42 +0,0 @@
-    .text
-    .align 2
-    .global crash
-    .type crash, %function
-crash:
-    fmov   d0, XZR
-    fmov   d1, 1.0
-    fmov   d2, 2.0
-    fmov   d3, 3.0
-    fmov   d4, 4.0
-    fmov   d5, 5.0
-    fmov   d6, 6.0
-    fmov   d7, 7.0
-    fmov   d8, 8.0
-    fmov   d9, 9.0
-    fmov   d10, 10.0
-    fmov   d11, 11.0
-    fmov   d12, 12.0
-    fmov   d13, 13.0
-    fmov   d14, 14.0
-    fmov   d15, 15.0
-    fmov   d16, 16.0
-    fmov   d17, 17.0
-    fmov   d18, 18.0
-    fmov   d19, 19.0
-    fmov   d20, 20.0
-    fmov   d21, 21.0
-    fmov   d22, 22.0
-    fmov   d23, 23.0
-    fmov   d24, 24.0
-    fmov   d25, 25.0
-    fmov   d26, 26.0
-    fmov   d27, 27.0
-    fmov   d28, 28.0
-    fmov   d29, 29.0
-    fmov   d30, 30.0
-    fmov   d31, 31.0
-
-    mov       x0, xzr
-    str       x0, [x0]
-    br        x30
-
diff --git a/debuggerd/vfp-crasher.c b/debuggerd/vfp-crasher.c
deleted file mode 100644
index 7a19cdd..0000000
--- a/debuggerd/vfp-crasher.c
+++ /dev/null
@@ -1,7 +0,0 @@
-int main()
-{
-  extern void crash(void);
-
-  crash();
-  return 0;
-}
diff --git a/fastboot/fs.h b/fastboot/fs.h
index 8388629..8444081 100644
--- a/fastboot/fs.h
+++ b/fastboot/fs.h
@@ -1,5 +1,5 @@
 #ifndef _FS_H_
-#define _FH_H_
+#define _FS_H_
 
 #include <stdint.h>
 
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index 1ee33a1..4a6b702 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -35,6 +35,8 @@
 
 #define POWER_SUPPLY_SUBSYSTEM "power_supply"
 #define POWER_SUPPLY_SYSFS_PATH "/sys/class/" POWER_SUPPLY_SUBSYSTEM
+#define FAKE_BATTERY_CAPACITY 42
+#define FAKE_BATTERY_TEMPERATURE 424
 
 namespace android {
 
@@ -530,11 +532,11 @@
             KLOG_WARNING(LOG_TAG, "BatteryTechnologyPath not found\n");
     }
 
-    if (property_get("persist.sys.battery.capacity", pval, NULL) > 0)
-        mBatteryFixedCapacity = (int) strtol(pval, NULL, 10);
-
-    if (property_get("persist.sys.battery.temperature", pval, NULL) > 0)
-        mBatteryFixedTemperature = (int) strtol(pval, NULL, 10);
+    if (property_get("ro.boot.fake_battery", pval, NULL) > 0
+                                               && strtol(pval, NULL, 10) != 0) {
+        mBatteryFixedCapacity = FAKE_BATTERY_CAPACITY;
+        mBatteryFixedTemperature = FAKE_BATTERY_TEMPERATURE;
+    }
 }
 
 }; // namespace android
diff --git a/include/system/audio.h b/include/system/audio.h
index c7cd109..f42c640 100644
--- a/include/system/audio.h
+++ b/include/system/audio.h
@@ -52,7 +52,9 @@
     AUDIO_STREAM_ALARM            = 4,
     AUDIO_STREAM_NOTIFICATION     = 5,
     AUDIO_STREAM_BLUETOOTH_SCO    = 6,
-    AUDIO_STREAM_ENFORCED_AUDIBLE = 7, /* Sounds that cannot be muted by user and must be routed to speaker */
+    AUDIO_STREAM_ENFORCED_AUDIBLE = 7, /* Sounds that cannot be muted by user
+                                        * and must be routed to speaker
+                                        */
     AUDIO_STREAM_DTMF             = 8,
     AUDIO_STREAM_TTS              = 9,
 
@@ -200,7 +202,16 @@
 
 /* AAC sub format field definition: specify profile or bitrate for recording... */
 typedef enum {
-    AUDIO_FORMAT_AAC_SUB_NONE            = 0x0,
+    AUDIO_FORMAT_AAC_SUB_MAIN            = 0x1,
+    AUDIO_FORMAT_AAC_SUB_LC              = 0x2,
+    AUDIO_FORMAT_AAC_SUB_SSR             = 0x4,
+    AUDIO_FORMAT_AAC_SUB_LTP             = 0x8,
+    AUDIO_FORMAT_AAC_SUB_HE_V1           = 0x10,
+    AUDIO_FORMAT_AAC_SUB_SCALABLE        = 0x20,
+    AUDIO_FORMAT_AAC_SUB_ERLC            = 0x40,
+    AUDIO_FORMAT_AAC_SUB_LD              = 0x80,
+    AUDIO_FORMAT_AAC_SUB_HE_V2           = 0x100,
+    AUDIO_FORMAT_AAC_SUB_ELD             = 0x200,
 } audio_format_aac_sub_fmt_t;
 
 /* VORBIS sub format field definition: specify quality for recording... */
@@ -225,8 +236,8 @@
     AUDIO_FORMAT_AMR_NB              = 0x02000000UL,
     AUDIO_FORMAT_AMR_WB              = 0x03000000UL,
     AUDIO_FORMAT_AAC                 = 0x04000000UL,
-    AUDIO_FORMAT_HE_AAC_V1           = 0x05000000UL,
-    AUDIO_FORMAT_HE_AAC_V2           = 0x06000000UL,
+    AUDIO_FORMAT_HE_AAC_V1           = 0x05000000UL, /* Deprecated, Use AUDIO_FORMAT_AAC_HE_V1*/
+    AUDIO_FORMAT_HE_AAC_V2           = 0x06000000UL, /* Deprecated, Use AUDIO_FORMAT_AAC_HE_V2*/
     AUDIO_FORMAT_VORBIS              = 0x07000000UL,
     AUDIO_FORMAT_OPUS                = 0x08000000UL,
     AUDIO_FORMAT_AC3                 = 0x09000000UL,
@@ -249,10 +260,41 @@
                                         AUDIO_FORMAT_PCM_SUB_FLOAT),
     AUDIO_FORMAT_PCM_24_BIT_PACKED   = (AUDIO_FORMAT_PCM |
                                         AUDIO_FORMAT_PCM_SUB_24_BIT_PACKED),
+    AUDIO_FORMAT_AAC_MAIN            = (AUDIO_FORMAT_AAC |
+                                        AUDIO_FORMAT_AAC_SUB_MAIN),
+    AUDIO_FORMAT_AAC_LC              = (AUDIO_FORMAT_AAC |
+                                        AUDIO_FORMAT_AAC_SUB_LC),
+    AUDIO_FORMAT_AAC_SSR             = (AUDIO_FORMAT_AAC |
+                                        AUDIO_FORMAT_AAC_SUB_SSR),
+    AUDIO_FORMAT_AAC_LTP             = (AUDIO_FORMAT_AAC |
+                                        AUDIO_FORMAT_AAC_SUB_LTP),
+    AUDIO_FORMAT_AAC_HE_V1           = (AUDIO_FORMAT_AAC |
+                                        AUDIO_FORMAT_AAC_SUB_HE_V1),
+    AUDIO_FORMAT_AAC_SCALABLE        = (AUDIO_FORMAT_AAC |
+                                        AUDIO_FORMAT_AAC_SUB_SCALABLE),
+    AUDIO_FORMAT_AAC_ERLC            = (AUDIO_FORMAT_AAC |
+                                        AUDIO_FORMAT_AAC_SUB_ERLC),
+    AUDIO_FORMAT_AAC_LD              = (AUDIO_FORMAT_AAC |
+                                        AUDIO_FORMAT_AAC_SUB_LD),
+    AUDIO_FORMAT_AAC_HE_V2           = (AUDIO_FORMAT_AAC |
+                                        AUDIO_FORMAT_AAC_SUB_HE_V2),
+    AUDIO_FORMAT_AAC_ELD             = (AUDIO_FORMAT_AAC |
+                                        AUDIO_FORMAT_AAC_SUB_ELD),
 } audio_format_t;
 
+/* For the channel mask for position assignment representation */
 enum {
+
+/* These can be a complete audio_channel_mask_t. */
+
     AUDIO_CHANNEL_NONE                      = 0x0,
+    AUDIO_CHANNEL_INVALID                   = 0xC0000000,
+
+/* These can be the bits portion of an audio_channel_mask_t
+ * with representation AUDIO_CHANNEL_REPRESENTATION_POSITION.
+ * Using these bits as a complete audio_channel_mask_t is deprecated.
+ */
+
     /* output channels */
     AUDIO_CHANNEL_OUT_FRONT_LEFT            = 0x1,
     AUDIO_CHANNEL_OUT_FRONT_RIGHT           = 0x2,
@@ -273,6 +315,8 @@
     AUDIO_CHANNEL_OUT_TOP_BACK_CENTER       = 0x10000,
     AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT        = 0x20000,
 
+/* TODO: should these be considered complete channel masks, or only bits? */
+
     AUDIO_CHANNEL_OUT_MONO     = AUDIO_CHANNEL_OUT_FRONT_LEFT,
     AUDIO_CHANNEL_OUT_STEREO   = (AUDIO_CHANNEL_OUT_FRONT_LEFT |
                                   AUDIO_CHANNEL_OUT_FRONT_RIGHT),
@@ -328,6 +372,8 @@
                                   AUDIO_CHANNEL_OUT_TOP_BACK_CENTER|
                                   AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT),
 
+/* These are bits only, not complete values */
+
     /* input channels */
     AUDIO_CHANNEL_IN_LEFT            = 0x4,
     AUDIO_CHANNEL_IN_RIGHT           = 0x8,
@@ -344,6 +390,8 @@
     AUDIO_CHANNEL_IN_VOICE_UPLINK    = 0x4000,
     AUDIO_CHANNEL_IN_VOICE_DNLINK    = 0x8000,
 
+/* TODO: should these be considered complete channel masks, or only bits, or deprecated? */
+
     AUDIO_CHANNEL_IN_MONO   = AUDIO_CHANNEL_IN_FRONT,
     AUDIO_CHANNEL_IN_STEREO = (AUDIO_CHANNEL_IN_LEFT | AUDIO_CHANNEL_IN_RIGHT),
     AUDIO_CHANNEL_IN_FRONT_BACK = (AUDIO_CHANNEL_IN_FRONT | AUDIO_CHANNEL_IN_BACK),
@@ -365,9 +413,95 @@
 
 /* A channel mask per se only defines the presence or absence of a channel, not the order.
  * But see AUDIO_INTERLEAVE_* below for the platform convention of order.
+ *
+ * audio_channel_mask_t is an opaque type and its internal layout should not
+ * be assumed as it may change in the future.
+ * Instead, always use the functions declared in this header to examine.
+ *
+ * These are the current representations:
+ *
+ *   AUDIO_CHANNEL_REPRESENTATION_POSITION
+ *     is a channel mask representation for position assignment.
+ *     Each low-order bit corresponds to the spatial position of a transducer (output),
+ *     or interpretation of channel (input).
+ *     The user of a channel mask needs to know the context of whether it is for output or input.
+ *     The constants AUDIO_CHANNEL_OUT_* or AUDIO_CHANNEL_IN_* apply to the bits portion.
+ *     It is not permitted for no bits to be set.
+ *
+ *   AUDIO_CHANNEL_REPRESENTATION_INDEX
+ *     is a channel mask representation for index assignment.
+ *     Each low-order bit corresponds to a selected channel.
+ *     There is no platform interpretation of the various bits.
+ *     There is no concept of output or input.
+ *     It is not permitted for no bits to be set.
+ *
+ * All other representations are reserved for future use.
+ *
+ * Warning: current representation distinguishes between input and output, but this will not the be
+ * case in future revisions of the platform. Wherever there is an ambiguity between input and output
+ * that is currently resolved by checking the channel mask, the implementer should look for ways to
+ * fix it with additional information outside of the mask.
  */
 typedef uint32_t audio_channel_mask_t;
 
+/* Maximum number of channels for all representations */
+#define AUDIO_CHANNEL_COUNT_MAX             30
+
+/* log(2) of maximum number of representations, not part of public API */
+#define AUDIO_CHANNEL_REPRESENTATION_LOG2   2
+
+/* Representations */
+typedef enum {
+    AUDIO_CHANNEL_REPRESENTATION_POSITION    = 0,    // must be zero for compatibility
+    // 1 is reserved for future use
+    AUDIO_CHANNEL_REPRESENTATION_INDEX       = 2,
+    // 3 is reserved for future use
+} audio_channel_representation_t;
+
+/* The return value is undefined if the channel mask is invalid. */
+static inline uint32_t audio_channel_mask_get_bits(audio_channel_mask_t channel)
+{
+    return channel & ((1 << AUDIO_CHANNEL_COUNT_MAX) - 1);
+}
+
+/* The return value is undefined if the channel mask is invalid. */
+static inline audio_channel_representation_t audio_channel_mask_get_representation(
+        audio_channel_mask_t channel)
+{
+    // The right shift should be sufficient, but also "and" for safety in case mask is not 32 bits
+    return (audio_channel_representation_t)
+            ((channel >> AUDIO_CHANNEL_COUNT_MAX) & ((1 << AUDIO_CHANNEL_REPRESENTATION_LOG2) - 1));
+}
+
+/* Returns true if the channel mask is valid,
+ * or returns false for AUDIO_CHANNEL_NONE, AUDIO_CHANNEL_INVALID, and other invalid values.
+ * This function is unable to determine whether a channel mask for position assignment
+ * is invalid because an output mask has an invalid output bit set,
+ * or because an input mask has an invalid input bit set.
+ * All other APIs that take a channel mask assume that it is valid.
+ */
+static inline bool audio_channel_mask_is_valid(audio_channel_mask_t channel)
+{
+    uint32_t bits = audio_channel_mask_get_bits(channel);
+    audio_channel_representation_t representation = audio_channel_mask_get_representation(channel);
+    switch (representation) {
+    case AUDIO_CHANNEL_REPRESENTATION_POSITION:
+    case AUDIO_CHANNEL_REPRESENTATION_INDEX:
+        break;
+    default:
+        bits = 0;
+        break;
+    }
+    return bits != 0;
+}
+
+/* Not part of public API */
+static inline audio_channel_mask_t audio_channel_mask_from_representation_and_bits(
+        audio_channel_representation_t representation, uint32_t bits)
+{
+    return (audio_channel_mask_t) ((representation << AUDIO_CHANNEL_COUNT_MAX) | bits);
+}
+
 /* Expresses the convention when stereo audio samples are stored interleaved
  * in an array.  This should improve readability by allowing code to use
  * symbolic indices instead of hard-coded [0] and [1].
@@ -499,6 +633,7 @@
     /* S/PDIF in */
     AUDIO_DEVICE_IN_SPDIF                 = AUDIO_DEVICE_BIT_IN | 0x10000,
     AUDIO_DEVICE_IN_BLUETOOTH_A2DP        = AUDIO_DEVICE_BIT_IN | 0x20000,
+    AUDIO_DEVICE_IN_LOOPBACK              = AUDIO_DEVICE_BIT_IN | 0x40000,
     AUDIO_DEVICE_IN_DEFAULT               = AUDIO_DEVICE_BIT_IN | AUDIO_DEVICE_BIT_DEFAULT,
 
     AUDIO_DEVICE_IN_ALL     = (AUDIO_DEVICE_IN_COMMUNICATION |
@@ -519,6 +654,7 @@
                                AUDIO_DEVICE_IN_LINE |
                                AUDIO_DEVICE_IN_SPDIF |
                                AUDIO_DEVICE_IN_BLUETOOTH_A2DP |
+                               AUDIO_DEVICE_IN_LOOPBACK |
                                AUDIO_DEVICE_IN_DEFAULT),
     AUDIO_DEVICE_IN_ALL_SCO = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
     AUDIO_DEVICE_IN_ALL_USB  = (AUDIO_DEVICE_IN_USB_ACCESSORY |
@@ -643,10 +779,10 @@
     audio_gain_mode_t    mode;              /* mode requested for this command */
     audio_channel_mask_t channel_mask;      /* channels which gain value follows.
                                                N/A in joint mode */
-    int                  values[sizeof(audio_channel_mask_t)]; /* gain values in millibels for each
-                                               channel ordered from LSb to MSb in channel mask.
-                                               The number of values is 1 in joint mode or
-                                               popcount(channel_mask) */
+    int                  values[sizeof(audio_channel_mask_t) * 8]; /* gain values in millibels
+                                               for each channel ordered from LSb to MSb in
+                                               channel mask. The number of values is 1 in joint
+                                               mode or popcount(channel_mask) */
     unsigned int         ramp_duration_ms; /* ramp duration in ms */
 };
 
@@ -911,81 +1047,182 @@
         return false;
 }
 
+/* Returns true if:
+ *  representation is valid, and
+ *  there is at least one channel bit set which _could_ correspond to an input channel, and
+ *  there are no channel bits set which could _not_ correspond to an input channel.
+ * Otherwise returns false.
+ */
 static inline bool audio_is_input_channel(audio_channel_mask_t channel)
 {
-    if ((channel & ~AUDIO_CHANNEL_IN_ALL) == 0)
-        return channel != 0;
-    else
+    uint32_t bits = audio_channel_mask_get_bits(channel);
+    switch (audio_channel_mask_get_representation(channel)) {
+    case AUDIO_CHANNEL_REPRESENTATION_POSITION:
+        if (bits & ~AUDIO_CHANNEL_IN_ALL) {
+            bits = 0;
+        }
+        // fall through
+    case AUDIO_CHANNEL_REPRESENTATION_INDEX:
+        return bits != 0;
+    default:
         return false;
+    }
 }
 
+/* Returns true if:
+ *  representation is valid, and
+ *  there is at least one channel bit set which _could_ correspond to an output channel, and
+ *  there are no channel bits set which could _not_ correspond to an output channel.
+ * Otherwise returns false.
+ */
 static inline bool audio_is_output_channel(audio_channel_mask_t channel)
 {
-    if ((channel & ~AUDIO_CHANNEL_OUT_ALL) == 0)
-        return channel != 0;
-    else
+    uint32_t bits = audio_channel_mask_get_bits(channel);
+    switch (audio_channel_mask_get_representation(channel)) {
+    case AUDIO_CHANNEL_REPRESENTATION_POSITION:
+        if (bits & ~AUDIO_CHANNEL_OUT_ALL) {
+            bits = 0;
+        }
+        // fall through
+    case AUDIO_CHANNEL_REPRESENTATION_INDEX:
+        return bits != 0;
+    default:
         return false;
+    }
 }
 
 /* Returns the number of channels from an input channel mask,
  * used in the context of audio input or recording.
+ * If a channel bit is set which could _not_ correspond to an input channel,
+ * it is excluded from the count.
+ * Returns zero if the representation is invalid.
  */
 static inline uint32_t audio_channel_count_from_in_mask(audio_channel_mask_t channel)
 {
-    return popcount(channel & AUDIO_CHANNEL_IN_ALL);
+    uint32_t bits = audio_channel_mask_get_bits(channel);
+    switch (audio_channel_mask_get_representation(channel)) {
+    case AUDIO_CHANNEL_REPRESENTATION_POSITION:
+        // TODO: We can now merge with from_out_mask and remove anding
+        bits &= AUDIO_CHANNEL_IN_ALL;
+        // fall through
+    case AUDIO_CHANNEL_REPRESENTATION_INDEX:
+        return popcount(bits);
+    default:
+        return 0;
+    }
 }
 
 /* Returns the number of channels from an output channel mask,
  * used in the context of audio output or playback.
+ * If a channel bit is set which could _not_ correspond to an output channel,
+ * it is excluded from the count.
+ * Returns zero if the representation is invalid.
  */
 static inline uint32_t audio_channel_count_from_out_mask(audio_channel_mask_t channel)
 {
-    return popcount(channel & AUDIO_CHANNEL_OUT_ALL);
+    uint32_t bits = audio_channel_mask_get_bits(channel);
+    switch (audio_channel_mask_get_representation(channel)) {
+    case AUDIO_CHANNEL_REPRESENTATION_POSITION:
+        // TODO: We can now merge with from_in_mask and remove anding
+        bits &= AUDIO_CHANNEL_OUT_ALL;
+        // fall through
+    case AUDIO_CHANNEL_REPRESENTATION_INDEX:
+        return popcount(bits);
+    default:
+        return 0;
+    }
 }
 
-/* Derive an output channel mask from a channel count.
+/* Derive an output channel mask for position assignment from a channel count.
  * This is to be used when the content channel mask is unknown. The 1, 2, 4, 5, 6, 7 and 8 channel
  * cases are mapped to the standard game/home-theater layouts, but note that 4 is mapped to quad,
  * and not stereo + FC + mono surround. A channel count of 3 is arbitrarily mapped to stereo + FC
  * for continuity with stereo.
- * Returns the matching channel mask, or 0 if the number of channels exceeds that of the
- * configurations for which a default channel mask is defined.
+ * Returns the matching channel mask,
+ * or AUDIO_CHANNEL_NONE if the channel count is zero,
+ * or AUDIO_CHANNEL_INVALID if the channel count exceeds that of the
+ * configurations for which a default output channel mask is defined.
  */
 static inline audio_channel_mask_t audio_channel_out_mask_from_count(uint32_t channel_count)
 {
+    uint32_t bits;
     switch (channel_count) {
+    case 0:
+        return AUDIO_CHANNEL_NONE;
     case 1:
-        return AUDIO_CHANNEL_OUT_MONO;
+        bits = AUDIO_CHANNEL_OUT_MONO;
+        break;
     case 2:
-        return AUDIO_CHANNEL_OUT_STEREO;
+        bits = AUDIO_CHANNEL_OUT_STEREO;
+        break;
     case 3:
-        return (AUDIO_CHANNEL_OUT_STEREO | AUDIO_CHANNEL_OUT_FRONT_CENTER);
+        bits = AUDIO_CHANNEL_OUT_STEREO | AUDIO_CHANNEL_OUT_FRONT_CENTER;
+        break;
     case 4: // 4.0
-        return AUDIO_CHANNEL_OUT_QUAD;
+        bits = AUDIO_CHANNEL_OUT_QUAD;
+        break;
     case 5: // 5.0
-        return (AUDIO_CHANNEL_OUT_QUAD | AUDIO_CHANNEL_OUT_FRONT_CENTER);
+        bits = AUDIO_CHANNEL_OUT_QUAD | AUDIO_CHANNEL_OUT_FRONT_CENTER;
+        break;
     case 6: // 5.1
-        return AUDIO_CHANNEL_OUT_5POINT1;
+        bits = AUDIO_CHANNEL_OUT_5POINT1;
+        break;
     case 7: // 6.1
-        return (AUDIO_CHANNEL_OUT_5POINT1 | AUDIO_CHANNEL_OUT_BACK_CENTER);
+        bits = AUDIO_CHANNEL_OUT_5POINT1 | AUDIO_CHANNEL_OUT_BACK_CENTER;
+        break;
     case 8:
-        return AUDIO_CHANNEL_OUT_7POINT1;
+        bits = AUDIO_CHANNEL_OUT_7POINT1;
+        break;
     default:
-        return 0;
+        return AUDIO_CHANNEL_INVALID;
     }
+    return audio_channel_mask_from_representation_and_bits(
+            AUDIO_CHANNEL_REPRESENTATION_POSITION, bits);
 }
 
-/* Similar to above, but for input.  Currently handles only mono and stereo. */
+/* Derive an input channel mask for position assignment from a channel count.
+ * Currently handles only mono and stereo.
+ * Returns the matching channel mask,
+ * or AUDIO_CHANNEL_NONE if the channel count is zero,
+ * or AUDIO_CHANNEL_INVALID if the channel count exceeds that of the
+ * configurations for which a default input channel mask is defined.
+ */
 static inline audio_channel_mask_t audio_channel_in_mask_from_count(uint32_t channel_count)
 {
+    uint32_t bits;
     switch (channel_count) {
+    case 0:
+        return AUDIO_CHANNEL_NONE;
     case 1:
-        return AUDIO_CHANNEL_IN_MONO;
+        bits = AUDIO_CHANNEL_IN_MONO;
+        break;
     case 2:
-        return AUDIO_CHANNEL_IN_STEREO;
+        bits = AUDIO_CHANNEL_IN_STEREO;
+        break;
     default:
-        return 0;
+        return AUDIO_CHANNEL_INVALID;
     }
+    return audio_channel_mask_from_representation_and_bits(
+            AUDIO_CHANNEL_REPRESENTATION_POSITION, bits);
+}
+
+/* Derive a channel mask for index assignment from a channel count.
+ * Returns the matching channel mask,
+ * or AUDIO_CHANNEL_NONE if the channel count is zero,
+ * or AUDIO_CHANNEL_INVALID if the channel count exceeds AUDIO_CHANNEL_COUNT_MAX.
+ */
+static inline audio_channel_mask_t audio_channel_mask_for_index_assignment_from_count(
+        uint32_t channel_count)
+{
+    if (channel_count == 0) {
+        return AUDIO_CHANNEL_NONE;
+    }
+    if (channel_count > AUDIO_CHANNEL_COUNT_MAX) {
+        return AUDIO_CHANNEL_INVALID;
+    }
+    uint32_t bits = (1 << channel_count) - 1;
+    return audio_channel_mask_from_representation_and_bits(
+            AUDIO_CHANNEL_REPRESENTATION_INDEX, bits);
 }
 
 static inline bool audio_is_valid_format(audio_format_t format)
diff --git a/include/system/audio_policy.h b/include/system/audio_policy.h
index 3085830..a6554de 100644
--- a/include/system/audio_policy.h
+++ b/include/system/audio_policy.h
@@ -44,9 +44,6 @@
     AUDIO_POLICY_FORCE_DIGITAL_DOCK,
     AUDIO_POLICY_FORCE_NO_BT_A2DP, /* A2DP sink is not preferred to speaker or wired HS */
     AUDIO_POLICY_FORCE_SYSTEM_ENFORCED,
-    AUDIO_POLICY_FORCE_SYSTEM_AUDIO_HDMI_ARC,
-    AUDIO_POLICY_FORCE_SYSTEM_AUDIO_SPDIF,
-    AUDIO_POLICY_FORCE_SYSTEM_AUDIO_LINE,
 
     AUDIO_POLICY_FORCE_CFG_CNT,
     AUDIO_POLICY_FORCE_CFG_MAX = AUDIO_POLICY_FORCE_CFG_CNT - 1,
diff --git a/init/builtins.c b/init/builtins.c
index f7bd8a9..6032184 100644
--- a/init/builtins.c
+++ b/init/builtins.c
@@ -48,7 +48,7 @@
 
 #include <private/android_filesystem_config.h>
 
-void add_environment(const char *name, const char *value);
+int add_environment(const char *name, const char *value);
 
 extern int init_module(void *, unsigned long, const char *);
 
@@ -261,8 +261,7 @@
 
 int do_export(int nargs, char **args)
 {
-    add_environment(args[1], args[2]);
-    return 0;
+    return add_environment(args[1], args[2]);
 }
 
 int do_hostname(int nargs, char **args)
diff --git a/init/init.c b/init/init.c
index e4ac1cf..74c0308 100644
--- a/init/init.c
+++ b/init/init.c
@@ -96,11 +96,24 @@
 /* add_environment - add "key=value" to the current environment */
 int add_environment(const char *key, const char *val)
 {
-    int n;
+    size_t n;
+    size_t key_len = strlen(key);
 
-    for (n = 0; n < 31; n++) {
-        if (!ENV[n]) {
-            size_t len = strlen(key) + strlen(val) + 2;
+    /* The last environment entry is reserved to terminate the list */
+    for (n = 0; n < (ARRAY_SIZE(ENV) - 1); n++) {
+
+        /* Delete any existing entry for this key */
+        if (ENV[n] != NULL) {
+            size_t entry_key_len = strcspn(ENV[n], "=");
+            if ((entry_key_len == key_len) && (strncmp(ENV[n], key, entry_key_len) == 0)) {
+                free((char*)ENV[n]);
+                ENV[n] = NULL;
+            }
+        }
+
+        /* Add entry if a free slot is available */
+        if (ENV[n] == NULL) {
+            size_t len = key_len + strlen(val) + 2;
             char *entry = malloc(len);
             snprintf(entry, len, "%s=%s", key, val);
             ENV[n] = entry;
@@ -108,7 +121,9 @@
         }
     }
 
-    return 1;
+    ERROR("No env. room to store: '%s':'%s'\n", key, val);
+
+    return -1;
 }
 
 static void zap_stdio(void)
diff --git a/libcutils/sched_policy.c b/libcutils/sched_policy.c
index fa0792f..f8ffb1d 100644
--- a/libcutils/sched_policy.c
+++ b/libcutils/sched_policy.c
@@ -39,17 +39,9 @@
 
 #if defined(HAVE_ANDROID_OS) && defined(HAVE_SCHED_H) && defined(HAVE_PTHREADS)
 
-#include <linux/prctl.h>
-#include <sched.h>
 #include <pthread.h>
-
-#ifndef SCHED_NORMAL
-  #define SCHED_NORMAL 0
-#endif
-
-#ifndef SCHED_BATCH
-  #define SCHED_BATCH 3
-#endif
+#include <sched.h>
+#include <sys/prctl.h>
 
 #define POLICY_DEBUG 0
 
diff --git a/libprocessgroup/Android.mk b/libprocessgroup/Android.mk
new file mode 100644
index 0000000..501321f
--- /dev/null
+++ b/libprocessgroup/Android.mk
@@ -0,0 +1,21 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := processgroup.cpp
+LOCAL_MODULE := libprocessgroup
+LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_CFLAGS := -Wall -Werror
+LOCAL_REQUIRED_MODULE := processgroup_cleanup
+include external/libcxx/libcxx.mk
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := cleanup.cpp
+LOCAL_MODULE := processgroup_cleanup
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_CFLAGS := -Wall -Werror
+LOCAL_FORCE_STATIC_EXECUTABLE := true
+LOCAL_STATIC_LIBRARIES := libc libcutils
+include $(BUILD_EXECUTABLE)
diff --git a/libprocessgroup/cleanup.cpp b/libprocessgroup/cleanup.cpp
new file mode 100644
index 0000000..cca8dc4
--- /dev/null
+++ b/libprocessgroup/cleanup.cpp
@@ -0,0 +1,31 @@
+/*
+ *  Copyright 2014 Google, Inc
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+#include <string.h>
+#include <unistd.h>
+#include <sys/syslimits.h>
+
+#include "processgroup_priv.h"
+
+int main(int argc, char **argv)
+{
+    char buf[PATH_MAX];
+    if (argc != 2)
+        return -1;
+
+    memcpy(buf, PROCESSGROUP_CGROUP_PATH, sizeof(PROCESSGROUP_CGROUP_PATH));
+    strlcat(buf, argv[1], sizeof(buf));
+    return rmdir(buf);
+}
diff --git a/libprocessgroup/include/processgroup/processgroup.h b/libprocessgroup/include/processgroup/processgroup.h
new file mode 100644
index 0000000..11bd8cc
--- /dev/null
+++ b/libprocessgroup/include/processgroup/processgroup.h
@@ -0,0 +1,33 @@
+/*
+ *  Copyright 2014 Google, Inc
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef _PROCESSGROUP_H_
+#define _PROCESSGROUP_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+int killProcessGroup(uid_t uid, int initialPid, int signal);
+
+int createProcessGroup(uid_t uid, int initialPid);
+
+void removeAllProcessGroups(void);
+
+__END_DECLS
+
+#endif
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
new file mode 100644
index 0000000..c32e741
--- /dev/null
+++ b/libprocessgroup/processgroup.cpp
@@ -0,0 +1,316 @@
+/*
+ *  Copyright 2014 Google, Inc
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "libprocessgroup"
+
+#include <assert.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <log/log.h>
+#include <private/android_filesystem_config.h>
+
+#include <processgroup/processgroup.h>
+#include "processgroup_priv.h"
+
+struct ctx {
+    bool initialized;
+    int fd;
+    char buf[128];
+    char *buf_ptr;
+    size_t buf_len;
+};
+
+static int convertUidToPath(char *path, size_t size, uid_t uid)
+{
+    return snprintf(path, size, "%s/%s%d",
+            PROCESSGROUP_CGROUP_PATH,
+            PROCESSGROUP_UID_PREFIX,
+            uid);
+}
+
+static int convertUidPidToPath(char *path, size_t size, uid_t uid, int pid)
+{
+    return snprintf(path, size, "%s/%s%d/%s%d",
+            PROCESSGROUP_CGROUP_PATH,
+            PROCESSGROUP_UID_PREFIX,
+            uid,
+            PROCESSGROUP_PID_PREFIX,
+            pid);
+}
+
+static int initCtx(uid_t uid, int pid, struct ctx *ctx)
+{
+    int ret;
+    char path[PROCESSGROUP_MAX_PATH_LEN] = {0};
+    convertUidPidToPath(path, sizeof(path), uid, pid);
+    strlcat(path, PROCESSGROUP_CGROUP_PROCS_FILE, sizeof(path));
+
+    int fd = open(path, O_RDONLY);
+    if (fd < 0) {
+        ret = -errno;
+        SLOGV("failed to open %s: %s", path, strerror(errno));
+        return ret;
+    }
+
+    ctx->fd = fd;
+    ctx->buf_ptr = ctx->buf;
+    ctx->buf_len = 0;
+    ctx->initialized = true;
+
+    return 0;
+}
+
+static int refillBuffer(struct ctx *ctx)
+{
+    memmove(ctx->buf, ctx->buf_ptr, ctx->buf_len);
+    ctx->buf_ptr = ctx->buf;
+
+    ssize_t ret = read(ctx->fd, ctx->buf_ptr + ctx->buf_len,
+                sizeof(ctx->buf) - ctx->buf_len);
+    if (ret < 0) {
+        return -errno;
+    } else if (ret == 0) {
+        return 0;
+    }
+
+    ctx->buf_len += ret;
+    assert(ctx->buf_len <= sizeof(ctx->buf));
+
+    return ret;
+}
+
+static pid_t getOneAppProcess(uid_t uid, int appProcessPid, struct ctx *ctx)
+{
+    if (!ctx->initialized) {
+        int ret = initCtx(uid, appProcessPid, ctx);
+        if (ret < 0) {
+            return ret;
+        }
+    }
+
+    char *eptr;
+    while ((eptr = (char *)memchr(ctx->buf_ptr, '\n', ctx->buf_len)) == NULL) {
+        int ret = refillBuffer(ctx);
+        if (ret == 0) {
+            return -ERANGE;
+        }
+        if (ret < 0) {
+            return ret;
+        }
+    }
+
+    *eptr = '\0';
+    char *pid_eptr = NULL;
+    errno = 0;
+    long pid = strtol(ctx->buf_ptr, &pid_eptr, 10);
+    if (errno != 0) {
+        return -errno;
+    }
+    if (pid_eptr != eptr) {
+        return -EINVAL;
+    }
+
+    ctx->buf_ptr = eptr + 1;
+
+    return (pid_t)pid;
+}
+
+static int removeProcessGroup(uid_t uid, int pid)
+{
+    int ret;
+    char path[PROCESSGROUP_MAX_PATH_LEN] = {0};
+
+    convertUidPidToPath(path, sizeof(path), uid, pid);
+    ret = rmdir(path);
+
+    convertUidToPath(path, sizeof(path), uid);
+    rmdir(path);
+
+    return ret;
+}
+
+static void removeUidProcessGroups(const char *uid_path)
+{
+    DIR *uid = opendir(uid_path);
+    if (uid != NULL) {
+        struct dirent cur;
+        struct dirent *dir;
+        while ((readdir_r(uid, &cur, &dir) == 0) && dir) {
+            char path[PROCESSGROUP_MAX_PATH_LEN];
+
+            if (dir->d_type != DT_DIR) {
+                continue;
+            }
+
+            if (strncmp(dir->d_name, PROCESSGROUP_PID_PREFIX, strlen(PROCESSGROUP_PID_PREFIX))) {
+                continue;
+            }
+
+            snprintf(path, sizeof(path), "%s/%s", uid_path, dir->d_name);
+            SLOGV("removing %s\n", path);
+            rmdir(path);
+        }
+    }
+}
+
+void removeAllProcessGroups()
+{
+    SLOGV("removeAllProcessGroups()");
+    DIR *root = opendir(PROCESSGROUP_CGROUP_PATH);
+    if (root == NULL) {
+        SLOGE("failed to open %s: %s", PROCESSGROUP_CGROUP_PATH, strerror(errno));
+    }
+    if (root != NULL) {
+        struct dirent cur;
+        struct dirent *dir;
+        while ((readdir_r(root, &cur, &dir) == 0) && dir) {
+            char path[PROCESSGROUP_MAX_PATH_LEN];
+
+            if (dir->d_type != DT_DIR) {
+                continue;
+            }
+            if (strncmp(dir->d_name, PROCESSGROUP_UID_PREFIX, strlen(PROCESSGROUP_UID_PREFIX))) {
+                continue;
+            }
+
+            snprintf(path, sizeof(path), "%s/%s", PROCESSGROUP_CGROUP_PATH, dir->d_name);
+            removeUidProcessGroups(path);
+            SLOGV("removing %s\n", path);
+            rmdir(path);
+        }
+    }
+}
+
+static int killProcessGroupOnce(uid_t uid, int initialPid, int signal)
+{
+    int processes = 0;
+    struct ctx ctx;
+    pid_t pid;
+
+    ctx.initialized = false;
+
+    while ((pid = getOneAppProcess(uid, initialPid, &ctx)) >= 0) {
+        processes++;
+        SLOGV("sending processgroup kill to pid %d\n", pid);
+        int ret = kill(pid, signal);
+        if (ret == -1) {
+            SLOGV("failed to kill pid %d: %s", pid, strerror(errno));
+        }
+    }
+
+    if (ctx.initialized) {
+        close(ctx.fd);
+    }
+
+    return processes;
+}
+
+int killProcessGroup(uid_t uid, int initialPid, int signal)
+{
+    int processes;
+    int sleep_us = 100;
+
+    while ((processes = killProcessGroupOnce(uid, initialPid, signal)) > 0) {
+        SLOGV("killed %d processes for processgroup %d\n", processes, initialPid);
+        if (sleep_us < 128000) {
+            usleep(sleep_us);
+            sleep_us *= 2;
+        } else {
+            SLOGE("failed to kill %d processes for processgroup %d\n",
+                    processes, initialPid);
+            break;
+        }
+    }
+
+    if (processes == 0) {
+        return removeProcessGroup(uid, initialPid);
+    } else {
+        return -1;
+    }
+}
+
+static int mkdirAndChown(const char *path, mode_t mode, uid_t uid, gid_t gid)
+{
+    int ret;
+
+    ret = mkdir(path, 0750);
+    if (ret < 0 && errno != EEXIST) {
+        return -errno;
+    }
+
+    ret = chown(path, AID_SYSTEM, AID_SYSTEM);
+    if (ret < 0) {
+        ret = -errno;
+        rmdir(path);
+        return ret;
+    }
+
+    return 0;
+}
+
+int createProcessGroup(uid_t uid, int initialPid)
+{
+    char path[PROCESSGROUP_MAX_PATH_LEN] = {0};
+    int ret;
+
+    convertUidToPath(path, sizeof(path), uid);
+
+    ret = mkdirAndChown(path, 0750, AID_SYSTEM, AID_SYSTEM);
+    if (ret < 0) {
+        SLOGE("failed to make and chown %s: %s", path, strerror(-ret));
+        return ret;
+    }
+
+    convertUidPidToPath(path, sizeof(path), uid, initialPid);
+
+    ret = mkdirAndChown(path, 0750, AID_SYSTEM, AID_SYSTEM);
+    if (ret < 0) {
+        SLOGE("failed to make and chown %s: %s", path, strerror(-ret));
+        return ret;
+    }
+
+    strlcat(path, PROCESSGROUP_CGROUP_PROCS_FILE, sizeof(path));
+
+    int fd = open(path, O_WRONLY);
+    if (fd < 0) {
+        ret = -errno;
+        SLOGE("failed to open %s: %s", path, strerror(errno));
+        return ret;
+    }
+
+    char pid[PROCESSGROUP_MAX_PID_LEN + 1] = {0};
+    int len = snprintf(pid, sizeof(pid), "%d", initialPid);
+
+    ret = write(fd, pid, len);
+    if (ret < 0) {
+        ret = -errno;
+        SLOGE("failed to write '%s' to %s: %s", pid, path, strerror(errno));
+    } else {
+        ret = 0;
+    }
+
+    close(fd);
+    return ret;
+}
+
diff --git a/libprocessgroup/processgroup_priv.h b/libprocessgroup/processgroup_priv.h
new file mode 100644
index 0000000..1895bf9
--- /dev/null
+++ b/libprocessgroup/processgroup_priv.h
@@ -0,0 +1,35 @@
+/*
+ *  Copyright 2014 Google, Inc
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef _PROCESSGROUP_PRIV_H_
+#define _PROCESSGROUP_PRIV_H_
+
+#define PROCESSGROUP_CGROUP_PATH "/acct"
+#define PROCESSGROUP_UID_PREFIX "uid_"
+#define PROCESSGROUP_PID_PREFIX "pid_"
+#define PROCESSGROUP_CGROUP_PROCS_FILE "/cgroup.procs"
+#define PROCESSGROUP_MAX_UID_LEN 11
+#define PROCESSGROUP_MAX_PID_LEN 11
+#define PROCESSGROUP_MAX_PATH_LEN \
+        (sizeof(PROCESSGROUP_CGROUP_PATH) + \
+         sizeof(PROCESSGROUP_UID_PREFIX) + 1 + \
+         PROCESSGROUP_MAX_UID_LEN + \
+         sizeof(PROCESSGROUP_PID_PREFIX) + 1 + \
+         PROCESSGROUP_MAX_PID_LEN + \
+         sizeof(PROCESSGROUP_CGROUP_PROCS_FILE) + \
+         1)
+
+#endif
diff --git a/lmkd/Android.mk b/lmkd/Android.mk
index 2dd8af2..043a085 100644
--- a/lmkd/Android.mk
+++ b/lmkd/Android.mk
@@ -2,7 +2,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := lmkd.c
-LOCAL_SHARED_LIBRARIES := libcutils liblog libm libc
+LOCAL_SHARED_LIBRARIES := libcutils liblog libm libc libprocessgroup
 LOCAL_CFLAGS := -Werror
 
 LOCAL_MODULE := lmkd
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 5caf77d..1aeb182 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -32,6 +32,7 @@
 
 #include <cutils/sockets.h>
 #include <log/log.h>
+#include <processgroup/processgroup.h>
 
 #ifndef __unused
 #define __unused __attribute__((__unused__))
@@ -104,6 +105,7 @@
 struct proc {
     struct adjslot_list asl;
     int pid;
+    uid_t uid;
     int oomadj;
     struct proc *pidhash_next;
 };
@@ -227,7 +229,7 @@
     close(fd);
 }
 
-static void cmd_procprio(int pid, int oomadj) {
+static void cmd_procprio(int pid, int uid, int oomadj) {
     struct proc *procp;
     char path[80];
     char val[20];
@@ -253,6 +255,7 @@
             }
 
             procp->pid = pid;
+            procp->uid = uid;
             procp->oomadj = oomadj;
             proc_insert(procp);
     } else {
@@ -356,9 +359,9 @@
         cmd_target(targets, &ibuf[1]);
         break;
     case LMK_PROCPRIO:
-        if (nargs != 2)
+        if (nargs != 3)
             goto wronglen;
-        cmd_procprio(ntohl(ibuf[1]), ntohl(ibuf[2]));
+        cmd_procprio(ntohl(ibuf[1]), ntohl(ibuf[2]), ntohl(ibuf[3]));
         break;
     case LMK_PROCREMOVE:
         if (nargs != 1)
@@ -565,6 +568,7 @@
 
         if (procp) {
             int pid = procp->pid;
+            uid_t uid = procp->uid;
             char *taskname;
             int tasksize;
             int r;
@@ -581,13 +585,14 @@
                 goto retry;
             }
 
-            ALOGI("Killing '%s' (%d), adj %d\n"
+            ALOGI("Killing '%s' (%d), uid %d, adj %d\n"
                   "   to free %ldkB because cache %ldkB is below limit %ldkB for oom_adj %d\n"
                   "   Free memory is %ldkB %s reserved",
-                  taskname, pid, procp->oomadj, tasksize * page_k,
+                  taskname, pid, uid, procp->oomadj, tasksize * page_k,
                   other_file * page_k, minfree * page_k, min_score_adj,
                   other_free * page_k, other_free >= 0 ? "above" : "below");
             r = kill(pid, SIGKILL);
+            killProcessGroup(uid, pid, SIGKILL);
             pid_remove(pid);
 
             if (r) {
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index 957fdb5..4bea4be 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -503,13 +503,11 @@
             (user_logger_content)     ? yes : no,
             (kernel_logger_available) ? yes : no,
             (kernel_logger_content)   ? yes : no,
-            (user_logger_available && kernel_logger_available) ? "WARNING" : "ok",
+            (user_logger_available && kernel_logger_available) ? "ERROR" : "ok",
             (user_logger_content && kernel_logger_content) ? "ERROR" : "ok");
 
-    if (user_logger_available && kernel_logger_available) {
-        printf("WARNING: kernel & user logger; both consuming resources!!!\n");
-    }
-
+    EXPECT_EQ(0, user_logger_available && kernel_logger_available);
+    EXPECT_EQ(0, !user_logger_available && !kernel_logger_available);
     EXPECT_EQ(0, user_logger_content && kernel_logger_content);
     EXPECT_EQ(0, !user_logger_content && !kernel_logger_content);
 }
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 1bbc7ab..68eae67 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -193,13 +193,11 @@
     chown system cache /cache
     chmod 0770 /cache
     # We restorecon /cache in case the cache partition has been reset.
-    restorecon /cache
+    restorecon_recursive /cache
 
     # This may have been created by the recovery system with odd permissions
     chown system cache /cache/recovery
     chmod 0770 /cache/recovery
-    # This may have been created by the recovery system with the wrong context.
-    restorecon /cache/recovery
 
     #change permissions on vmallocinfo so we can grab it from bugreports
     chown root log /proc/vmallocinfo
@@ -613,6 +611,7 @@
 
 service flash_recovery /system/bin/install-recovery.sh
     class main
+    seclabel u:r:install_recovery:s0
     oneshot
 
 service racoon /system/bin/racoon
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c
index 3a164ed..d3afcb1 100644
--- a/sdcard/sdcard.c
+++ b/sdcard/sdcard.c
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "sdcard"
+
 #include <ctype.h>
 #include <dirent.h>
 #include <errno.h>
@@ -35,6 +37,7 @@
 
 #include <cutils/fs.h>
 #include <cutils/hashmap.h>
+#include <cutils/log.h>
 #include <cutils/multiuser.h>
 
 #include <private/android_filesystem_config.h>
@@ -90,12 +93,12 @@
 #define FUSE_TRACE 0
 
 #if FUSE_TRACE
-#define TRACE(x...) fprintf(stderr,x)
+#define TRACE(x...) ALOGD(x)
 #else
 #define TRACE(x...) do {} while (0)
 #endif
 
-#define ERROR(x...) fprintf(stderr,x)
+#define ERROR(x...) ALOGE(x)
 
 #define FUSE_UNKNOWN_INO 0xffffffff
 
@@ -1313,14 +1316,23 @@
 static int handle_fsync(struct fuse* fuse, struct fuse_handler* handler,
         const struct fuse_in_header* hdr, const struct fuse_fsync_in* req)
 {
-    int is_data_sync = req->fsync_flags & 1;
-    struct handle *h = id_to_ptr(req->fh);
-    int res;
+    bool is_dir = (hdr->opcode == FUSE_FSYNCDIR);
+    bool is_data_sync = req->fsync_flags & 1;
 
-    TRACE("[%d] FSYNC %p(%d) is_data_sync=%d\n", handler->token,
-            h, h->fd, is_data_sync);
-    res = is_data_sync ? fdatasync(h->fd) : fsync(h->fd);
-    if (res < 0) {
+    int fd = -1;
+    if (is_dir) {
+      struct dirhandle *dh = id_to_ptr(req->fh);
+      fd = dirfd(dh->d);
+    } else {
+      struct handle *h = id_to_ptr(req->fh);
+      fd = h->fd;
+    }
+
+    TRACE("[%d] %s %p(%d) is_data_sync=%d\n", handler->token,
+            is_dir ? "FSYNCDIR" : "FSYNC",
+            id_to_ptr(req->fh), fd, is_data_sync);
+    int res = is_data_sync ? fdatasync(fd) : fsync(fd);
+    if (res == -1) {
         return -errno;
     }
     return 0;
diff --git a/toolbox/bsd-compatibility.h b/toolbox/bsd-compatibility.h
index a304631..abc3064 100644
--- a/toolbox/bsd-compatibility.h
+++ b/toolbox/bsd-compatibility.h
@@ -31,6 +31,9 @@
 /* We want chown to support user.group as well as user:group. */
 #define SUPPORT_DOT
 
+/* We don't localize /system/bin! */
+#define WITHOUT_NLS
+
 __BEGIN_DECLS
 
 extern int uid_from_user(const char* name, uid_t* uid);
diff --git a/toolbox/grep/grep.c b/toolbox/grep/grep.c
index 7b2c487..7314e13 100644
--- a/toolbox/grep/grep.c
+++ b/toolbox/grep/grep.c
@@ -159,7 +159,6 @@
 {
 	fprintf(stderr, getstr(4), __progname);
 	fprintf(stderr, "%s", getstr(5));
-	fprintf(stderr, "%s", getstr(5));
 	fprintf(stderr, "%s", getstr(6));
 	fprintf(stderr, "%s", getstr(7));
 	exit(2);
@@ -403,7 +402,7 @@
 				Aflag = 0;
 			else if (Aflag > LLONG_MAX / 10) {
 				errno = ERANGE;
-				err(2, "%llu", Aflag);
+				err(2, NULL);
 			}
 			Aflag = Bflag = (Aflag * 10) + (c - '0');
 			break;
@@ -420,10 +419,10 @@
 			l = strtoull(optarg, &ep, 10);
 			if (((errno == ERANGE) && (l == ULLONG_MAX)) ||
 			    ((errno == EINVAL) && (l == 0)))
-				err(2, "strtoull");
+				err(2, NULL);
 			else if (ep[0] != '\0') {
 				errno = EINVAL;
-				err(2, "empty");
+				err(2, NULL);
 			}
 			if (c == 'A')
 				Aflag = l;
@@ -509,10 +508,10 @@
 			mcount = strtoull(optarg, &ep, 10);
 			if (((errno == ERANGE) && (mcount == ULLONG_MAX)) ||
 			    ((errno == EINVAL) && (mcount == 0)))
-				err(2, "strtoull");
+				err(2, NULL);
 			else if (ep[0] != '\0') {
 				errno = EINVAL;
-				err(2, "empty");
+				err(2, NULL);
 			}
 			break;
 		case 'n':
diff --git a/toolbox/grep/grep.h b/toolbox/grep/grep.h
index 6454f93..eafb00e 100644
--- a/toolbox/grep/grep.h
+++ b/toolbox/grep/grep.h
@@ -29,10 +29,6 @@
  * SUCH DAMAGE.
  */
 
-#ifdef ANDROID
-#define WITHOUT_NLS
-#endif
-
 #ifndef ANDROID
 #include <bzlib.h>
 #endif
diff --git a/toolbox/grep/util.c b/toolbox/grep/util.c
index 5712fee..ecd948d 100644
--- a/toolbox/grep/util.c
+++ b/toolbox/grep/util.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: util.c,v 1.16 2012/05/06 22:32:05 joerg Exp $	*/
+/*	$NetBSD: util.c,v 1.17 2013/01/21 03:24:43 msaitoh Exp $	*/
 /*	$FreeBSD: head/usr.bin/grep/util.c 211496 2010-08-19 09:28:59Z des $	*/
 /*	$OpenBSD: util.c,v 1.39 2010/07/02 22:18:03 tedu Exp $	*/
 
@@ -34,7 +34,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: util.c,v 1.16 2012/05/06 22:32:05 joerg Exp $");
+__RCSID("$NetBSD: util.c,v 1.17 2013/01/21 03:24:43 msaitoh Exp $");
 
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -74,9 +74,10 @@
 	for (i = 0; i < fpatterns; ++i) {
 		if (fnmatch(fpattern[i].pat, fname, 0) == 0 ||
 		    fnmatch(fpattern[i].pat, fname_base, 0) == 0) {
-			if (fpattern[i].mode == EXCL_PAT)
+			if (fpattern[i].mode == EXCL_PAT) {
+				free(fname_copy);
 				return (false);
-			else
+			} else
 				ret = true;
 		}
 	}
@@ -128,7 +129,7 @@
 		break;
 	default:
 		fts_flags = FTS_LOGICAL;
-
+			
 	}
 
 	fts_flags |= FTS_NOSTAT | FTS_NOCHDIR;
@@ -273,7 +274,7 @@
 	return (c);
 }
 
-#define iswword(x)	(iswalnum((wint_t)(x)) || (x) == L'_')
+#define iswword(x)	(iswalnum((x)) || (x) == L'_')
 
 /*
  * Processes a line comparing it with the specified patterns.  Each pattern
@@ -474,13 +475,13 @@
 			if (!oflag)
 				fwrite(line->dat + a, matches[i].rm_so - a, 1,
 				    stdout);
-			if (color)
+			if (color) 
 				fprintf(stdout, "\33[%sm\33[K", color);
 
-				fwrite(line->dat + matches[i].rm_so,
+				fwrite(line->dat + matches[i].rm_so, 
 				    matches[i].rm_eo - matches[i].rm_so, 1,
 				    stdout);
-			if (color)
+			if (color) 
 				fprintf(stdout, "\33[m\33[K");
 			a = matches[i].rm_eo;
 			if (oflag)
diff --git a/toolbox/newfs_msdos.c b/toolbox/newfs_msdos.c
index 30b9f77..5fbca8d 100644
--- a/toolbox/newfs_msdos.c
+++ b/toolbox/newfs_msdos.c
@@ -27,20 +27,20 @@
 
 #ifndef lint
 static const char rcsid[] =
-  "$FreeBSD: src/sbin/newfs_msdos/newfs_msdos.c,v 1.33 2009/04/11 14:56:29 ed Exp $";
+        "$FreeBSD: src/sbin/newfs_msdos/newfs_msdos.c,v 1.33 2009/04/11 14:56:29 ed Exp $";
 #endif /* not lint */
 
 #include <sys/param.h>
 
 #ifndef ANDROID
-  #include <sys/fdcio.h>
-  #include <sys/disk.h>
-  #include <sys/disklabel.h>
-  #include <sys/mount.h>
+#include <sys/fdcio.h>
+#include <sys/disk.h>
+#include <sys/disklabel.h>
+#include <sys/mount.h>
 #else
-  #include <stdarg.h>
-  #include <linux/fs.h>
-  #include <linux/hdreg.h>
+#include <stdarg.h>
+#include <linux/fs.h>
+#include <linux/hdreg.h>
 #endif
 
 #include <sys/stat.h>
@@ -58,44 +58,44 @@
 #include <time.h>
 #include <unistd.h>
 
-#define MAXU16	  0xffff	/* maximum unsigned 16-bit quantity */
-#define BPN	  4		/* bits per nibble */
-#define NPB	  2		/* nibbles per byte */
+#define MAXU16   0xffff     /* maximum unsigned 16-bit quantity */
+#define BPN      4          /* bits per nibble */
+#define NPB      2          /* nibbles per byte */
 
-#define DOSMAGIC  0xaa55	/* DOS magic number */
-#define MINBPS	  512		/* minimum bytes per sector */
-#define MAXSPC	  128		/* maximum sectors per cluster */
-#define MAXNFT	  16		/* maximum number of FATs */
-#define DEFBLK	  4096		/* default block size */
-#define DEFBLK16  2048		/* default block size FAT16 */
-#define DEFRDE	  512		/* default root directory entries */
-#define RESFTE	  2		/* reserved FAT entries */
-#define MINCLS12  1		/* minimum FAT12 clusters */
-#define MINCLS16  0x1000	/* minimum FAT16 clusters */
-#define MINCLS32  2		/* minimum FAT32 clusters */
-#define MAXCLS12  0xfed 	/* maximum FAT12 clusters */
-#define MAXCLS16  0xfff5	/* maximum FAT16 clusters */
-#define MAXCLS32  0xffffff5	/* maximum FAT32 clusters */
+#define DOSMAGIC  0xaa55    /* DOS magic number */
+#define MINBPS    512       /* minimum bytes per sector */
+#define MAXSPC    128       /* maximum sectors per cluster */
+#define MAXNFT    16        /* maximum number of FATs */
+#define DEFBLK    4096      /* default block size */
+#define DEFBLK16  2048      /* default block size FAT16 */
+#define DEFRDE    512       /* default root directory entries */
+#define RESFTE    2         /* reserved FAT entries */
+#define MINCLS12  1         /* minimum FAT12 clusters */
+#define MINCLS16  0x1000    /* minimum FAT16 clusters */
+#define MINCLS32  2         /* minimum FAT32 clusters */
+#define MAXCLS12  0xfed     /* maximum FAT12 clusters */
+#define MAXCLS16  0xfff5    /* maximum FAT16 clusters */
+#define MAXCLS32  0xffffff5 /* maximum FAT32 clusters */
 
-#define mincls(fat)  ((fat) == 12 ? MINCLS12 :	\
-		      (fat) == 16 ? MINCLS16 :	\
-				    MINCLS32)
+#define mincls(fat)  ((fat) == 12 ? MINCLS12 :    \
+                      (fat) == 16 ? MINCLS16 :    \
+                                        MINCLS32)
 
-#define maxcls(fat)  ((fat) == 12 ? MAXCLS12 :	\
-		      (fat) == 16 ? MAXCLS16 :	\
-				    MAXCLS32)
+#define maxcls(fat)  ((fat) == 12 ? MAXCLS12 :    \
+                      (fat) == 16 ? MAXCLS16 :    \
+                                        MAXCLS32)
 
-#define mk1(p, x)				\
+#define mk1(p, x)                           \
     (p) = (u_int8_t)(x)
 
-#define mk2(p, x)				\
-    (p)[0] = (u_int8_t)(x),			\
+#define mk2(p, x)                           \
+    (p)[0] = (u_int8_t)(x),                 \
     (p)[1] = (u_int8_t)((x) >> 010)
 
-#define mk4(p, x)				\
-    (p)[0] = (u_int8_t)(x),			\
-    (p)[1] = (u_int8_t)((x) >> 010),		\
-    (p)[2] = (u_int8_t)((x) >> 020),		\
+#define mk4(p, x)                           \
+    (p)[0] = (u_int8_t)(x),                 \
+    (p)[1] = (u_int8_t)((x) >> 010),        \
+    (p)[2] = (u_int8_t)((x) >> 020),        \
     (p)[3] = (u_int8_t)((x) >> 030)
 
 #define argto1(arg, lo, msg)  argtou(arg, lo, 0xff, msg)
@@ -104,71 +104,71 @@
 #define argtox(arg, lo, msg)  argtou(arg, lo, UINT_MAX, msg)
 
 struct bs {
-    u_int8_t jmp[3];		/* bootstrap entry point */
-    u_int8_t oem[8];		/* OEM name and version */
+    u_int8_t jmp[3];        /* bootstrap entry point */
+    u_int8_t oem[8];        /* OEM name and version */
 };
 
 struct bsbpb {
-    u_int8_t bps[2];		/* bytes per sector */
-    u_int8_t spc;		/* sectors per cluster */
-    u_int8_t res[2];		/* reserved sectors */
-    u_int8_t nft;		/* number of FATs */
-    u_int8_t rde[2];		/* root directory entries */
-    u_int8_t sec[2];		/* total sectors */
-    u_int8_t mid;		/* media descriptor */
-    u_int8_t spf[2];		/* sectors per FAT */
-    u_int8_t spt[2];		/* sectors per track */
-    u_int8_t hds[2];		/* drive heads */
-    u_int8_t hid[4];		/* hidden sectors */
-    u_int8_t bsec[4];		/* big total sectors */
+    u_int8_t bps[2];    /* bytes per sector */
+    u_int8_t spc;       /* sectors per cluster */
+    u_int8_t res[2];    /* reserved sectors */
+    u_int8_t nft;       /* number of FATs */
+    u_int8_t rde[2];    /* root directory entries */
+    u_int8_t sec[2];    /* total sectors */
+    u_int8_t mid;       /* media descriptor */
+    u_int8_t spf[2];    /* sectors per FAT */
+    u_int8_t spt[2];    /* sectors per track */
+    u_int8_t hds[2];    /* drive heads */
+    u_int8_t hid[4];    /* hidden sectors */
+    u_int8_t bsec[4];   /* big total sectors */
 };
 
 struct bsxbpb {
-    u_int8_t bspf[4];		/* big sectors per FAT */
-    u_int8_t xflg[2];		/* FAT control flags */
-    u_int8_t vers[2];		/* file system version */
-    u_int8_t rdcl[4];		/* root directory start cluster */
-    u_int8_t infs[2];		/* file system info sector */
-    u_int8_t bkbs[2];		/* backup boot sector */
-    u_int8_t rsvd[12];		/* reserved */
+    u_int8_t bspf[4];       /* big sectors per FAT */
+    u_int8_t xflg[2];       /* FAT control flags */
+    u_int8_t vers[2];       /* file system version */
+    u_int8_t rdcl[4];       /* root directory start cluster */
+    u_int8_t infs[2];       /* file system info sector */
+    u_int8_t bkbs[2];       /* backup boot sector */
+    u_int8_t rsvd[12];      /* reserved */
 };
 
 struct bsx {
-    u_int8_t drv;		/* drive number */
-    u_int8_t rsvd;		/* reserved */
-    u_int8_t sig;		/* extended boot signature */
-    u_int8_t volid[4];		/* volume ID number */
-    u_int8_t label[11]; 	/* volume label */
-    u_int8_t type[8];		/* file system type */
+    u_int8_t drv;           /* drive number */
+    u_int8_t rsvd;          /* reserved */
+    u_int8_t sig;           /* extended boot signature */
+    u_int8_t volid[4];      /* volume ID number */
+    u_int8_t label[11];     /* volume label */
+    u_int8_t type[8];       /* file system type */
 };
 
 struct de {
-    u_int8_t namext[11];	/* name and extension */
-    u_int8_t attr;		/* attributes */
-    u_int8_t rsvd[10];		/* reserved */
-    u_int8_t time[2];		/* creation time */
-    u_int8_t date[2];		/* creation date */
-    u_int8_t clus[2];		/* starting cluster */
-    u_int8_t size[4];		/* size */
+    u_int8_t namext[11];    /* name and extension */
+    u_int8_t attr;          /* attributes */
+    u_int8_t rsvd[10];      /* reserved */
+    u_int8_t time[2];       /* creation time */
+    u_int8_t date[2];       /* creation date */
+    u_int8_t clus[2];       /* starting cluster */
+    u_int8_t size[4];       /* size */
 };
 
 struct bpb {
-    u_int bps;			/* bytes per sector */
-    u_int spc;			/* sectors per cluster */
-    u_int res;			/* reserved sectors */
-    u_int nft;			/* number of FATs */
-    u_int rde;			/* root directory entries */
-    u_int sec;			/* total sectors */
-    u_int mid;			/* media descriptor */
-    u_int spf;			/* sectors per FAT */
-    u_int spt;			/* sectors per track */
-    u_int hds;			/* drive heads */
-    u_int hid;			/* hidden sectors */
-    u_int bsec; 		/* big total sectors */
-    u_int bspf; 		/* big sectors per FAT */
-    u_int rdcl; 		/* root directory start cluster */
-    u_int infs; 		/* file system info sector */
-    u_int bkbs; 		/* backup boot sector */
+    u_int bps;          /* bytes per sector */
+    u_int spc;          /* sectors per cluster */
+    u_int res;          /* reserved sectors */
+    u_int nft;          /* number of FATs */
+    u_int rde;          /* root directory entries */
+    u_int sec;          /* total sectors */
+    u_int mid;          /* media descriptor */
+    u_int spf;          /* sectors per FAT */
+    u_int spt;          /* sectors per track */
+    u_int hds;          /* drive heads */
+    u_int hid;          /* hidden sectors */
+    u_int bsec;         /* big total sectors */
+    u_int bspf;         /* big sectors per FAT */
+    u_int rdcl;         /* root directory start cluster */
+    u_int infs;         /* file system info sector */
+    u_int bkbs;         /* backup boot sector */
 };
 
 #define BPBGAP 0, 0, 0, 0, 0, 0
@@ -181,35 +181,35 @@
     {"180",  {512, 1, 1, 2,  64,  360, 0xfc, 2,  9, 1, BPBGAP}},
     {"320",  {512, 2, 1, 2, 112,  640, 0xff, 1,  8, 2, BPBGAP}},
     {"360",  {512, 2, 1, 2, 112,  720, 0xfd, 2,  9, 2, BPBGAP}},
-    {"640",  {512, 2, 1, 2, 112, 1280, 0xfb, 2,  8, 2, BPBGAP}},    
+    {"640",  {512, 2, 1, 2, 112, 1280, 0xfb, 2,  8, 2, BPBGAP}},
     {"720",  {512, 2, 1, 2, 112, 1440, 0xf9, 3,  9, 2, BPBGAP}},
     {"1200", {512, 1, 1, 2, 224, 2400, 0xf9, 7, 15, 2, BPBGAP}},
-    {"1232", {1024,1, 1, 2, 192, 1232, 0xfe, 2,  8, 2, BPBGAP}},    
+    {"1232", {1024,1, 1, 2, 192, 1232, 0xfe, 2,  8, 2, BPBGAP}},
     {"1440", {512, 1, 1, 2, 224, 2880, 0xf0, 9, 18, 2, BPBGAP}},
     {"2880", {512, 2, 1, 2, 240, 5760, 0xf0, 9, 36, 2, BPBGAP}}
 };
 
 static const u_int8_t bootcode[] = {
-    0xfa,			/* cli		    */
-    0x31, 0xc0, 		/* xor	   ax,ax    */
-    0x8e, 0xd0, 		/* mov	   ss,ax    */
-    0xbc, 0x00, 0x7c,		/* mov	   sp,7c00h */
-    0xfb,			/* sti		    */
-    0x8e, 0xd8, 		/* mov	   ds,ax    */
-    0xe8, 0x00, 0x00,		/* call    $ + 3    */
-    0x5e,			/* pop	   si	    */
-    0x83, 0xc6, 0x19,		/* add	   si,+19h  */
-    0xbb, 0x07, 0x00,		/* mov	   bx,0007h */
-    0xfc,			/* cld		    */
-    0xac,			/* lodsb	    */
-    0x84, 0xc0, 		/* test    al,al    */
-    0x74, 0x06, 		/* jz	   $ + 8    */
-    0xb4, 0x0e, 		/* mov	   ah,0eh   */
-    0xcd, 0x10, 		/* int	   10h	    */
-    0xeb, 0xf5, 		/* jmp	   $ - 9    */
-    0x30, 0xe4, 		/* xor	   ah,ah    */
-    0xcd, 0x16, 		/* int	   16h	    */
-    0xcd, 0x19, 		/* int	   19h	    */
+    0xfa,               /* cli             */
+    0x31, 0xc0,         /* xor    ax,ax    */
+    0x8e, 0xd0,         /* mov    ss,ax    */
+    0xbc, 0x00, 0x7c,   /* mov    sp,7c00h */
+    0xfb,               /* sti             */
+    0x8e, 0xd8,         /* mov    ds,ax    */
+    0xe8, 0x00, 0x00,   /* call   $ + 3    */
+    0x5e,               /* pop    si       */
+    0x83, 0xc6, 0x19,   /* add    si,+19h  */
+    0xbb, 0x07, 0x00,   /* mov    bx,0007h */
+    0xfc,               /* cld             */
+    0xac,               /* lodsb           */
+    0x84, 0xc0,         /* test   al,al    */
+    0x74, 0x06,         /* jz     $ + 8    */
+    0xb4, 0x0e,         /* mov    ah,0eh   */
+    0xcd, 0x10,         /* int    10h      */
+    0xeb, 0xf5,         /* jmp    $ - 9    */
+    0x30, 0xe4,         /* xor    ah,ah    */
+    0xcd, 0x16,         /* int    16h      */
+    0xcd, 0x19,         /* int    19h      */
     0x0d, 0x0a,
     'N', 'o', 'n', '-', 's', 'y', 's', 't',
     'e', 'm', ' ', 'd', 'i', 's', 'k',
@@ -223,8 +223,7 @@
 
 static void check_mounted(const char *, mode_t);
 static void getstdfmt(const char *, struct bpb *);
-static void getdiskinfo(int, const char *, const char *, int,
-			struct bpb *);
+static void getdiskinfo(int, const char *, const char *, int, struct bpb *);
 static void print_bpb(struct bpb *);
 static u_int ckgeom(const char *, u_int, const char *);
 static u_int argtou(const char *, u_int, u_int, const char *);
@@ -237,8 +236,7 @@
 /*
  * Construct a FAT12, FAT16, or FAT32 file system.
  */
-int
-newfs_msdos_main(int argc, char *argv[])
+int newfs_msdos_main(int argc, char *argv[])
 {
     static const char opts[] = "@:NB:C:F:I:L:O:S:a:b:c:e:f:h:i:k:m:n:o:r:s:u:";
     const char *opt_B = NULL, *opt_L = NULL, *opt_O = NULL, *opt_f = NULL;
@@ -266,458 +264,444 @@
     off_t opt_create = 0, opt_ofs = 0;
 
     while ((ch = getopt(argc, argv, opts)) != -1)
-	switch (ch) {
-	case '@':
-	    opt_ofs = argtooff(optarg, "offset");
-	    break;
-	case 'N':
-	    opt_N = 1;
-	    break;
-	case 'B':
-	    opt_B = optarg;
-	    break;
-	case 'C':
-	    opt_create = argtooff(optarg, "create size");
-	    break;
-	case 'F':
-	    if (strcmp(optarg, "12") &&
-		strcmp(optarg, "16") &&
-		strcmp(optarg, "32"))
-		errx(1, "%s: bad FAT type", optarg);
-	    opt_F = atoi(optarg);
-	    break;
-	case 'I':
-	    opt_I = argto4(optarg, 0, "volume ID");
-	    Iflag = 1;
-	    break;
-	case 'L':
-	    if (!oklabel(optarg))
-		errx(1, "%s: bad volume label", optarg);
-	    opt_L = optarg;
-	    break;
-	case 'O':
-	    if (strlen(optarg) > 8)
-		errx(1, "%s: bad OEM string", optarg);
-	    opt_O = optarg;
-	    break;
-	case 'S':
-	    opt_S = argto2(optarg, 1, "bytes/sector");
-	    break;
-	case 'a':
-	    opt_a = argto4(optarg, 1, "sectors/FAT");
-	    break;
-	case 'b':
-	    opt_b = argtox(optarg, 1, "block size");
-	    opt_c = 0;
-	    break;
-	case 'c':
-	    opt_c = argto1(optarg, 1, "sectors/cluster");
-	    opt_b = 0;
-	    break;
-	case 'e':
-	    opt_e = argto2(optarg, 1, "directory entries");
-	    break;
-	case 'f':
-	    opt_f = optarg;
-	    break;
-	case 'h':
-	    opt_h = argto2(optarg, 1, "drive heads");
-	    break;
-	case 'i':
-	    opt_i = argto2(optarg, 1, "info sector");
-	    break;
-	case 'k':
-	    opt_k = argto2(optarg, 1, "backup sector");
-	    break;
-	case 'm':
-	    opt_m = argto1(optarg, 0, "media descriptor");
-	    mflag = 1;
-	    break;
-	case 'n':
-	    opt_n = argto1(optarg, 1, "number of FATs");
-	    break;
-	case 'o':
-	    opt_o = argto4(optarg, 0, "hidden sectors");
-	    oflag = 1;
-	    break;
-	case 'r':
-	    opt_r = argto2(optarg, 1, "reserved sectors");
-	    break;
-	case 's':
-	    opt_s = argto4(optarg, 1, "file system size");
-	    break;
-	case 'u':
-	    opt_u = argto2(optarg, 1, "sectors/track");
-	    break;
-	default:
-	    usage();
-	}
+        switch (ch) {
+        case '@':
+            opt_ofs = argtooff(optarg, "offset");
+            break;
+        case 'N':
+            opt_N = 1;
+            break;
+        case 'B':
+            opt_B = optarg;
+            break;
+        case 'C':
+            opt_create = argtooff(optarg, "create size");
+            break;
+        case 'F':
+            if (strcmp(optarg, "12") &&  strcmp(optarg, "16") && strcmp(optarg, "32"))
+                errx(1, "%s: bad FAT type", optarg);
+            opt_F = atoi(optarg);
+            break;
+        case 'I':
+            opt_I = argto4(optarg, 0, "volume ID");
+            Iflag = 1;
+            break;
+        case 'L':
+            if (!oklabel(optarg))
+                errx(1, "%s: bad volume label", optarg);
+            opt_L = optarg;
+            break;
+        case 'O':
+            if (strlen(optarg) > 8)
+                errx(1, "%s: bad OEM string", optarg);
+            opt_O = optarg;
+            break;
+        case 'S':
+            opt_S = argto2(optarg, 1, "bytes/sector");
+            break;
+        case 'a':
+            opt_a = argto4(optarg, 1, "sectors/FAT");
+            break;
+        case 'b':
+            opt_b = argtox(optarg, 1, "block size");
+            opt_c = 0;
+            break;
+        case 'c':
+            opt_c = argto1(optarg, 1, "sectors/cluster");
+            opt_b = 0;
+            break;
+        case 'e':
+            opt_e = argto2(optarg, 1, "directory entries");
+            break;
+        case 'f':
+            opt_f = optarg;
+            break;
+        case 'h':
+            opt_h = argto2(optarg, 1, "drive heads");
+            break;
+        case 'i':
+            opt_i = argto2(optarg, 1, "info sector");
+            break;
+        case 'k':
+            opt_k = argto2(optarg, 1, "backup sector");
+            break;
+        case 'm':
+            opt_m = argto1(optarg, 0, "media descriptor");
+            mflag = 1;
+            break;
+        case 'n':
+            opt_n = argto1(optarg, 1, "number of FATs");
+            break;
+        case 'o':
+            opt_o = argto4(optarg, 0, "hidden sectors");
+            oflag = 1;
+            break;
+        case 'r':
+            opt_r = argto2(optarg, 1, "reserved sectors");
+            break;
+        case 's':
+            opt_s = argto4(optarg, 1, "file system size");
+            break;
+        case 'u':
+            opt_u = argto2(optarg, 1, "sectors/track");
+            break;
+        default:
+            usage();
+        }
     argc -= optind;
     argv += optind;
     if (argc < 1 || argc > 2)
-	usage();
+        usage();
     fname = *argv++;
     if (!opt_create && !strchr(fname, '/')) {
-	snprintf(buf, sizeof(buf), "%s%s", _PATH_DEV, fname);
-	if (!(fname = strdup(buf)))
-	    err(1, "%s", buf);
+        snprintf(buf, sizeof(buf), "%s%s", _PATH_DEV, fname);
+        if (!(fname = strdup(buf)))
+            err(1, "%s", buf);
     }
     dtype = *argv;
     if (opt_create) {
-	if (opt_N)
-	    errx(1, "create (-C) is incompatible with -N");
-	fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0644);
-	if (fd == -1)
-	    errx(1, "failed to create %s", fname);
-	if (ftruncate(fd, opt_create))
-	    errx(1, "failed to initialize %jd bytes", (intmax_t)opt_create);
+        if (opt_N)
+            errx(1, "create (-C) is incompatible with -N");
+        fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0644);
+        if (fd == -1)
+            errx(1, "failed to create %s", fname);
+        if (ftruncate(fd, opt_create))
+            errx(1, "failed to initialize %jd bytes", (intmax_t)opt_create);
     } else if ((fd = open(fname, opt_N ? O_RDONLY : O_RDWR)) == -1)
-	err(1, "%s", fname);
+        err(1, "%s", fname);
     if (fstat(fd, &sb))
-	err(1, "%s", fname);
+        err(1, "%s", fname);
     if (opt_create) {
-	if (!S_ISREG(sb.st_mode))
-	    warnx("warning, %s is not a regular file", fname);
+        if (!S_ISREG(sb.st_mode))
+            warnx("warning, %s is not a regular file", fname);
     } else {
-	if (!S_ISCHR(sb.st_mode))
-	    warnx("warning, %s is not a character device", fname);
+        if (!S_ISCHR(sb.st_mode))
+            warnx("warning, %s is not a character device", fname);
     }
     if (!opt_N)
-	check_mounted(fname, sb.st_mode);
+        check_mounted(fname, sb.st_mode);
     if (opt_ofs && opt_ofs != lseek(fd, opt_ofs, SEEK_SET))
-	errx(1, "cannot seek to %jd", (intmax_t)opt_ofs);
+        errx(1, "cannot seek to %jd", (intmax_t)opt_ofs);
     memset(&bpb, 0, sizeof(bpb));
     if (opt_f) {
-	getstdfmt(opt_f, &bpb);
-	bpb.bsec = bpb.sec;
-	bpb.sec = 0;
-	bpb.bspf = bpb.spf;
-	bpb.spf = 0;
+        getstdfmt(opt_f, &bpb);
+        bpb.bsec = bpb.sec;
+        bpb.sec = 0;
+        bpb.bspf = bpb.spf;
+        bpb.spf = 0;
     }
     if (opt_h)
-	bpb.hds = opt_h;
+        bpb.hds = opt_h;
     if (opt_u)
-	bpb.spt = opt_u;
+        bpb.spt = opt_u;
     if (opt_S)
-	bpb.bps = opt_S;
+        bpb.bps = opt_S;
     if (opt_s)
-	bpb.bsec = opt_s;
+        bpb.bsec = opt_s;
     if (oflag)
-	bpb.hid = opt_o;
+        bpb.hid = opt_o;
     if (!(opt_f || (opt_h && opt_u && opt_S && opt_s && oflag))) {
-	off_t delta;
-	getdiskinfo(fd, fname, dtype, oflag, &bpb);
+        off_t delta;
+        getdiskinfo(fd, fname, dtype, oflag, &bpb);
         if (opt_s) {
             bpb.bsec = opt_s;
         }
-	bpb.bsec -= (opt_ofs / bpb.bps);
-	delta = bpb.bsec % bpb.spt;
-	if (delta != 0) {
-	    warnx("trim %d sectors from %d to adjust to a multiple of %d",
-		(int)delta, bpb.bsec, bpb.spt);
-	    bpb.bsec -= delta;
-	}
-	if (bpb.spc == 0) {	/* set defaults */
-	    if (bpb.bsec <= 6000)	/* about 3MB -> 512 bytes */
-		bpb.spc = 1;
-	    else if (bpb.bsec <= (1<<17)) /* 64M -> 4k */
-		bpb.spc = 8;
-	    else if (bpb.bsec <= (1<<19)) /* 256M -> 8k */
-		bpb.spc = 16;
-	    else if (bpb.bsec <= (1<<22)) /* 2G -> 16k, some versions of windows
-					     require a minimum of 65527 clusters */
-		bpb.spc = 32;
-	    else
-		bpb.spc = 64;		/* otherwise 32k */
-	}
+        bpb.bsec -= (opt_ofs / bpb.bps);
+        delta = bpb.bsec % bpb.spt;
+        if (delta != 0) {
+            warnx("trim %d sectors from %d to adjust to a multiple of %d",
+                  (int)delta, bpb.bsec, bpb.spt);
+            bpb.bsec -= delta;
+        }
+        if (bpb.spc == 0) {    /* set defaults */
+            if (bpb.bsec <= 6000)    /* about 3MB -> 512 bytes */
+                bpb.spc = 1;
+            else if (bpb.bsec <= (1<<17)) /* 64M -> 4k */
+                bpb.spc = 8;
+            else if (bpb.bsec <= (1<<19)) /* 256M -> 8k */
+                bpb.spc = 16;
+            else if (bpb.bsec <= (1<<22)) /* 2G -> 16k, some versions of windows
+                                         require a minimum of 65527 clusters */
+                bpb.spc = 32;
+            else
+                bpb.spc = 64;        /* otherwise 32k */
+        }
     }
     if (!powerof2(bpb.bps))
-	errx(1, "bytes/sector (%u) is not a power of 2", bpb.bps);
+        errx(1, "bytes/sector (%u) is not a power of 2", bpb.bps);
     if (bpb.bps < MINBPS)
-	errx(1, "bytes/sector (%u) is too small; minimum is %u",
-	     bpb.bps, MINBPS);
+        errx(1, "bytes/sector (%u) is too small; minimum is %u",
+             bpb.bps, MINBPS);
     if (!(fat = opt_F)) {
-	if (opt_f)
-	    fat = 12;
-	else if (!opt_e && (opt_i || opt_k))
-	    fat = 32;
+        if (opt_f)
+            fat = 12;
+        else if (!opt_e && (opt_i || opt_k))
+            fat = 32;
     }
     if ((fat == 32 && opt_e) || (fat != 32 && (opt_i || opt_k)))
-	errx(1, "-%c is not a legal FAT%s option",
-	     fat == 32 ? 'e' : opt_i ? 'i' : 'k',
-	     fat == 32 ? "32" : "12/16");
+        errx(1, "-%c is not a legal FAT%s option",
+             fat == 32 ? 'e' : opt_i ? 'i' : 'k',
+                     fat == 32 ? "32" : "12/16");
     if (opt_f && fat == 32)
-	bpb.rde = 0;
+        bpb.rde = 0;
     if (opt_b) {
-	if (!powerof2(opt_b))
-	    errx(1, "block size (%u) is not a power of 2", opt_b);
-	if (opt_b < bpb.bps)
-	    errx(1, "block size (%u) is too small; minimum is %u",
-		 opt_b, bpb.bps);
-	if (opt_b > bpb.bps * MAXSPC)
-	    errx(1, "block size (%u) is too large; maximum is %u",
-		 opt_b, bpb.bps * MAXSPC);
-	bpb.spc = opt_b / bpb.bps;
+        if (!powerof2(opt_b))
+            errx(1, "block size (%u) is not a power of 2", opt_b);
+        if (opt_b < bpb.bps)
+            errx(1, "block size (%u) is too small; minimum is %u",
+                 opt_b, bpb.bps);
+        if (opt_b > bpb.bps * MAXSPC)
+            errx(1, "block size (%u) is too large; maximum is %u", opt_b, bpb.bps * MAXSPC);
+        bpb.spc = opt_b / bpb.bps;
     }
     if (opt_c) {
-	if (!powerof2(opt_c))
-	    errx(1, "sectors/cluster (%u) is not a power of 2", opt_c);
-	bpb.spc = opt_c;
+        if (!powerof2(opt_c))
+            errx(1, "sectors/cluster (%u) is not a power of 2", opt_c);
+        bpb.spc = opt_c;
     }
     if (opt_r)
-	bpb.res = opt_r;
+        bpb.res = opt_r;
     if (opt_n) {
-	if (opt_n > MAXNFT)
-	    errx(1, "number of FATs (%u) is too large; maximum is %u",
-		 opt_n, MAXNFT);
-	bpb.nft = opt_n;
+        if (opt_n > MAXNFT)
+            errx(1, "number of FATs (%u) is too large; maximum is %u", opt_n, MAXNFT);
+        bpb.nft = opt_n;
     }
     if (opt_e)
-	bpb.rde = opt_e;
+        bpb.rde = opt_e;
     if (mflag) {
-	if (opt_m < 0xf0)
-	    errx(1, "illegal media descriptor (%#x)", opt_m);
-	bpb.mid = opt_m;
+        if (opt_m < 0xf0)
+            errx(1, "illegal media descriptor (%#x)", opt_m);
+        bpb.mid = opt_m;
     }
     if (opt_a)
-	bpb.bspf = opt_a;
+        bpb.bspf = opt_a;
     if (opt_i)
-	bpb.infs = opt_i;
+        bpb.infs = opt_i;
     if (opt_k)
-	bpb.bkbs = opt_k;
+        bpb.bkbs = opt_k;
     bss = 1;
     bname = NULL;
     fd1 = -1;
     if (opt_B) {
-	bname = opt_B;
-	if (!strchr(bname, '/')) {
-	    snprintf(buf, sizeof(buf), "/boot/%s", bname);
-	    if (!(bname = strdup(buf)))
-		err(1, "%s", buf);
-	}
-	if ((fd1 = open(bname, O_RDONLY)) == -1 || fstat(fd1, &sb))
-	    err(1, "%s", bname);
-	if (!S_ISREG(sb.st_mode) || sb.st_size % bpb.bps ||
-	    sb.st_size < bpb.bps || sb.st_size > bpb.bps * MAXU16)
-	    errx(1, "%s: inappropriate file type or format", bname);
-	bss = sb.st_size / bpb.bps;
+        bname = opt_B;
+        if (!strchr(bname, '/')) {
+            snprintf(buf, sizeof(buf), "/boot/%s", bname);
+            if (!(bname = strdup(buf)))
+                err(1, "%s", buf);
+        }
+        if ((fd1 = open(bname, O_RDONLY)) == -1 || fstat(fd1, &sb))
+            err(1, "%s", bname);
+        if (!S_ISREG(sb.st_mode) || sb.st_size % bpb.bps ||
+                sb.st_size < bpb.bps || sb.st_size > bpb.bps * MAXU16)
+            errx(1, "%s: inappropriate file type or format", bname);
+        bss = sb.st_size / bpb.bps;
     }
     if (!bpb.nft)
-	bpb.nft = 2;
+        bpb.nft = 2;
     if (!fat) {
-	if (bpb.bsec < (bpb.res ? bpb.res : bss) +
-	    howmany((RESFTE + (bpb.spc ? MINCLS16 : MAXCLS12 + 1)) *
-		    ((bpb.spc ? 16 : 12) / BPN), bpb.bps * NPB) *
-	    bpb.nft +
-	    howmany(bpb.rde ? bpb.rde : DEFRDE,
-		    bpb.bps / sizeof(struct de)) +
-	    (bpb.spc ? MINCLS16 : MAXCLS12 + 1) *
-	    (bpb.spc ? bpb.spc : howmany(DEFBLK, bpb.bps)))
-	    fat = 12;
-	else if (bpb.rde || bpb.bsec <
-		 (bpb.res ? bpb.res : bss) +
-		 howmany((RESFTE + MAXCLS16) * 2, bpb.bps) * bpb.nft +
-		 howmany(DEFRDE, bpb.bps / sizeof(struct de)) +
-		 (MAXCLS16 + 1) *
-		 (bpb.spc ? bpb.spc : howmany(8192, bpb.bps)))
-	    fat = 16;
-	else
-	    fat = 32;
+        if (bpb.bsec < (bpb.res ? bpb.res : bss) +
+                howmany((RESFTE + (bpb.spc ? MINCLS16 : MAXCLS12 + 1)) *
+                        ((bpb.spc ? 16 : 12) / BPN), bpb.bps * NPB) *
+                        bpb.nft +
+                        howmany(bpb.rde ? bpb.rde : DEFRDE,
+                                bpb.bps / sizeof(struct de)) +
+                                (bpb.spc ? MINCLS16 : MAXCLS12 + 1) *
+                                (bpb.spc ? bpb.spc : howmany(DEFBLK, bpb.bps)))
+            fat = 12;
+        else if (bpb.rde || bpb.bsec <
+                (bpb.res ? bpb.res : bss) +
+                howmany((RESFTE + MAXCLS16) * 2, bpb.bps) * bpb.nft +
+                howmany(DEFRDE, bpb.bps / sizeof(struct de)) +
+                (MAXCLS16 + 1) *
+                (bpb.spc ? bpb.spc : howmany(8192, bpb.bps)))
+            fat = 16;
+        else
+            fat = 32;
     }
     x = bss;
     if (fat == 32) {
-	if (!bpb.infs) {
-	    if (x == MAXU16 || x == bpb.bkbs)
-		errx(1, "no room for info sector");
-	    bpb.infs = x;
-	}
-	if (bpb.infs != MAXU16 && x <= bpb.infs)
-	    x = bpb.infs + 1;
-	if (!bpb.bkbs) {
-	    if (x == MAXU16)
-		errx(1, "no room for backup sector");
-	    bpb.bkbs = x;
-	} else if (bpb.bkbs != MAXU16 && bpb.bkbs == bpb.infs)
-	    errx(1, "backup sector would overwrite info sector");
-	if (bpb.bkbs != MAXU16 && x <= bpb.bkbs)
-	    x = bpb.bkbs + 1;
+        if (!bpb.infs) {
+            if (x == MAXU16 || x == bpb.bkbs)
+                errx(1, "no room for info sector");
+            bpb.infs = x;
+        }
+        if (bpb.infs != MAXU16 && x <= bpb.infs)
+            x = bpb.infs + 1;
+        if (!bpb.bkbs) {
+            if (x == MAXU16)
+                errx(1, "no room for backup sector");
+            bpb.bkbs = x;
+        } else if (bpb.bkbs != MAXU16 && bpb.bkbs == bpb.infs)
+            errx(1, "backup sector would overwrite info sector");
+        if (bpb.bkbs != MAXU16 && x <= bpb.bkbs)
+            x = bpb.bkbs + 1;
     }
     if (!bpb.res)
-	bpb.res = fat == 32 ? MAX(x, MAX(16384 / bpb.bps, 4)) : x;
+        bpb.res = fat == 32 ? MAX(x, MAX(16384 / bpb.bps, 4)) : x;
     else if (bpb.res < x)
-	errx(1, "too few reserved sectors");
+        errx(1, "too few reserved sectors");
     if (fat != 32 && !bpb.rde)
-	bpb.rde = DEFRDE;
+        bpb.rde = DEFRDE;
     rds = howmany(bpb.rde, bpb.bps / sizeof(struct de));
     if (!bpb.spc)
-	for (bpb.spc = howmany(fat == 16 ? DEFBLK16 : DEFBLK, bpb.bps);
-	     bpb.spc < MAXSPC &&
-	     bpb.res +
-	     howmany((RESFTE + maxcls(fat)) * (fat / BPN),
-		     bpb.bps * NPB) * bpb.nft +
-	     rds +
-	     (u_int64_t)(maxcls(fat) + 1) * bpb.spc <= bpb.bsec;
-	     bpb.spc <<= 1);
+        for (bpb.spc = howmany(fat == 16 ? DEFBLK16 : DEFBLK, bpb.bps);
+                bpb.spc < MAXSPC &&
+                bpb.res +
+                howmany((RESFTE + maxcls(fat)) * (fat / BPN),
+                        bpb.bps * NPB) * bpb.nft +
+                        rds +
+                        (u_int64_t)(maxcls(fat) + 1) * bpb.spc <= bpb.bsec;
+                bpb.spc <<= 1);
     if (fat != 32 && bpb.bspf > MAXU16)
-	errx(1, "too many sectors/FAT for FAT12/16");
+        errx(1, "too many sectors/FAT for FAT12/16");
     x1 = bpb.res + rds;
     x = bpb.bspf ? bpb.bspf : 1;
     if (x1 + (u_int64_t)x * bpb.nft > bpb.bsec)
-	errx(1, "meta data exceeds file system size");
+        errx(1, "meta data exceeds file system size");
     x1 += x * bpb.nft;
     x = (u_int64_t)(bpb.bsec - x1) * bpb.bps * NPB /
-	(bpb.spc * bpb.bps * NPB + fat / BPN * bpb.nft);
-    x2 = howmany((RESFTE + MIN(x, maxcls(fat))) * (fat / BPN),
-		 bpb.bps * NPB);
+            (bpb.spc * bpb.bps * NPB + fat / BPN * bpb.nft);
+    x2 = howmany((RESFTE + MIN(x, maxcls(fat))) * (fat / BPN), bpb.bps * NPB);
     if (!bpb.bspf) {
-	bpb.bspf = x2;
-	x1 += (bpb.bspf - 1) * bpb.nft;
+        bpb.bspf = x2;
+        x1 += (bpb.bspf - 1) * bpb.nft;
     }
     cls = (bpb.bsec - x1) / bpb.spc;
     x = (u_int64_t)bpb.bspf * bpb.bps * NPB / (fat / BPN) - RESFTE;
     if (cls > x)
-	cls = x;
+        cls = x;
     if (bpb.bspf < x2)
-	warnx("warning: sectors/FAT limits file system to %u clusters",
-	      cls);
+        warnx("warning: sectors/FAT limits file system to %u clusters", cls);
     if (cls < mincls(fat))
-	errx(1, "%u clusters too few clusters for FAT%u, need %u", cls, fat,
-	    mincls(fat));
+        errx(1, "%u clusters too few clusters for FAT%u, need %u", cls, fat, mincls(fat));
     if (cls > maxcls(fat)) {
-	cls = maxcls(fat);
-	bpb.bsec = x1 + (cls + 1) * bpb.spc - 1;
-	warnx("warning: FAT type limits file system to %u sectors",
-	      bpb.bsec);
+        cls = maxcls(fat);
+        bpb.bsec = x1 + (cls + 1) * bpb.spc - 1;
+        warnx("warning: FAT type limits file system to %u sectors", bpb.bsec);
     }
-    printf("%s: %u sector%s in %u FAT%u cluster%s "
-	   "(%u bytes/cluster)\n", fname, cls * bpb.spc,
-	   cls * bpb.spc == 1 ? "" : "s", cls, fat,
-	   cls == 1 ? "" : "s", bpb.bps * bpb.spc);
+    printf("%s: %u sector%s in %u FAT%u cluster%s (%u bytes/cluster)\n",
+           fname, cls * bpb.spc, cls * bpb.spc == 1 ? "" : "s", cls, fat,
+           cls == 1 ? "" : "s", bpb.bps * bpb.spc);
     if (!bpb.mid)
-	bpb.mid = !bpb.hid ? 0xf0 : 0xf8;
+        bpb.mid = !bpb.hid ? 0xf0 : 0xf8;
     if (fat == 32)
-	bpb.rdcl = RESFTE;
+        bpb.rdcl = RESFTE;
     if (bpb.hid + bpb.bsec <= MAXU16) {
-	bpb.sec = bpb.bsec;
-	bpb.bsec = 0;
+        bpb.sec = bpb.bsec;
+        bpb.bsec = 0;
     }
     if (fat != 32) {
-	bpb.spf = bpb.bspf;
-	bpb.bspf = 0;
+        bpb.spf = bpb.bspf;
+        bpb.bspf = 0;
     }
     print_bpb(&bpb);
     if (!opt_N) {
-	gettimeofday(&tv, NULL);
-	now = tv.tv_sec;
-	tm = localtime(&now);
-	if (!(img = malloc(bpb.bps)))
-	    err(1, "%u", bpb.bps);
-	dir = bpb.res + (bpb.spf ? bpb.spf : bpb.bspf) * bpb.nft;
-	for (lsn = 0; lsn < dir + (fat == 32 ? bpb.spc : rds); lsn++) {
-	    x = lsn;
-	    if (opt_B &&
-		fat == 32 && bpb.bkbs != MAXU16 &&
-		bss <= bpb.bkbs && x >= bpb.bkbs) {
-		x -= bpb.bkbs;
-		if (!x && lseek(fd1, opt_ofs, SEEK_SET))
-		    err(1, "%s", bname);
-	    }
-	    if (opt_B && x < bss) {
-		if ((n = read(fd1, img, bpb.bps)) == -1)
-		    err(1, "%s", bname);
-		if ((unsigned)n != bpb.bps)
-		    errx(1, "%s: can't read sector %u", bname, x);
-	    } else
-		memset(img, 0, bpb.bps);
-	    if (!lsn ||
-	      (fat == 32 && bpb.bkbs != MAXU16 && lsn == bpb.bkbs)) {
-		x1 = sizeof(struct bs);
-		bsbpb = (struct bsbpb *)(img + x1);
-		mk2(bsbpb->bps, bpb.bps);
-		mk1(bsbpb->spc, bpb.spc);
-		mk2(bsbpb->res, bpb.res);
-		mk1(bsbpb->nft, bpb.nft);
-		mk2(bsbpb->rde, bpb.rde);
-		mk2(bsbpb->sec, bpb.sec);
-		mk1(bsbpb->mid, bpb.mid);
-		mk2(bsbpb->spf, bpb.spf);
-		mk2(bsbpb->spt, bpb.spt);
-		mk2(bsbpb->hds, bpb.hds);
-		mk4(bsbpb->hid, bpb.hid);
-		mk4(bsbpb->bsec, bpb.bsec);
-		x1 += sizeof(struct bsbpb);
-		if (fat == 32) {
-		    bsxbpb = (struct bsxbpb *)(img + x1);
-		    mk4(bsxbpb->bspf, bpb.bspf);
-		    mk2(bsxbpb->xflg, 0);
-		    mk2(bsxbpb->vers, 0);
-		    mk4(bsxbpb->rdcl, bpb.rdcl);
-		    mk2(bsxbpb->infs, bpb.infs);
-		    mk2(bsxbpb->bkbs, bpb.bkbs);
-		    x1 += sizeof(struct bsxbpb);
-		}
-		bsx = (struct bsx *)(img + x1);
-		mk1(bsx->sig, 0x29);
-		if (Iflag)
-		    x = opt_I;
-		else
-		    x = (((u_int)(1 + tm->tm_mon) << 8 |
-			  (u_int)tm->tm_mday) +
-			 ((u_int)tm->tm_sec << 8 |
-			  (u_int)(tv.tv_usec / 10))) << 16 |
-			((u_int)(1900 + tm->tm_year) +
-			 ((u_int)tm->tm_hour << 8 |
-			  (u_int)tm->tm_min));
-		mk4(bsx->volid, x);
-		mklabel(bsx->label, opt_L ? opt_L : "NO NAME");
-		sprintf(buf, "FAT%u", fat);
-		setstr(bsx->type, buf, sizeof(bsx->type));
-		if (!opt_B) {
-		    x1 += sizeof(struct bsx);
-		    bs = (struct bs *)img;
-		    mk1(bs->jmp[0], 0xeb);
-		    mk1(bs->jmp[1], x1 - 2);
-		    mk1(bs->jmp[2], 0x90);
-		    setstr(bs->oem, opt_O ? opt_O : "BSD  4.4",
-			   sizeof(bs->oem));
-		    memcpy(img + x1, bootcode, sizeof(bootcode));
-		    mk2(img + MINBPS - 2, DOSMAGIC);
-		}
-	    } else if (fat == 32 && bpb.infs != MAXU16 &&
-		       (lsn == bpb.infs ||
-			(bpb.bkbs != MAXU16 &&
-			 lsn == bpb.bkbs + bpb.infs))) {
-		mk4(img, 0x41615252);
-		mk4(img + MINBPS - 28, 0x61417272);
-		mk4(img + MINBPS - 24, 0xffffffff);
-		mk4(img + MINBPS - 20, bpb.rdcl);
-		mk2(img + MINBPS - 2, DOSMAGIC);
-	    } else if (lsn >= bpb.res && lsn < dir &&
-		       !((lsn - bpb.res) %
-			 (bpb.spf ? bpb.spf : bpb.bspf))) {
-		mk1(img[0], bpb.mid);
-		for (x = 1; x < fat * (fat == 32 ? 3 : 2) / 8; x++)
-		    mk1(img[x], fat == 32 && x % 4 == 3 ? 0x0f : 0xff);
-	    } else if (lsn == dir && opt_L) {
-		de = (struct de *)img;
-		mklabel(de->namext, opt_L);
-		mk1(de->attr, 050);
-		x = (u_int)tm->tm_hour << 11 |
-		    (u_int)tm->tm_min << 5 |
-		    (u_int)tm->tm_sec >> 1;
-		mk2(de->time, x);
-		x = (u_int)(tm->tm_year - 80) << 9 |
-		    (u_int)(tm->tm_mon + 1) << 5 |
-		    (u_int)tm->tm_mday;
-		mk2(de->date, x);
-	    }
-	    if ((n = write(fd, img, bpb.bps)) == -1)
-		err(1, "%s", fname);
-	    if ((unsigned)n != bpb.bps) {
-		errx(1, "%s: can't write sector %u", fname, lsn);
+        gettimeofday(&tv, NULL);
+        now = tv.tv_sec;
+        tm = localtime(&now);
+        if (!(img = malloc(bpb.bps)))
+            err(1, "%u", bpb.bps);
+        dir = bpb.res + (bpb.spf ? bpb.spf : bpb.bspf) * bpb.nft;
+        for (lsn = 0; lsn < dir + (fat == 32 ? bpb.spc : rds); lsn++) {
+            x = lsn;
+            if (opt_B && fat == 32 && bpb.bkbs != MAXU16 && bss <= bpb.bkbs && x >= bpb.bkbs) {
+                x -= bpb.bkbs;
+                if (!x && lseek(fd1, opt_ofs, SEEK_SET))
+                    err(1, "%s", bname);
+            }
+            if (opt_B && x < bss) {
+                if ((n = read(fd1, img, bpb.bps)) == -1)
+                    err(1, "%s", bname);
+                if ((unsigned)n != bpb.bps)
+                    errx(1, "%s: can't read sector %u", bname, x);
+            } else
+                memset(img, 0, bpb.bps);
+            if (!lsn || (fat == 32 && bpb.bkbs != MAXU16 && lsn == bpb.bkbs)) {
+                x1 = sizeof(struct bs);
+                bsbpb = (struct bsbpb *)(img + x1);
+                mk2(bsbpb->bps, bpb.bps);
+                mk1(bsbpb->spc, bpb.spc);
+                mk2(bsbpb->res, bpb.res);
+                mk1(bsbpb->nft, bpb.nft);
+                mk2(bsbpb->rde, bpb.rde);
+                mk2(bsbpb->sec, bpb.sec);
+                mk1(bsbpb->mid, bpb.mid);
+                mk2(bsbpb->spf, bpb.spf);
+                mk2(bsbpb->spt, bpb.spt);
+                mk2(bsbpb->hds, bpb.hds);
+                mk4(bsbpb->hid, bpb.hid);
+                mk4(bsbpb->bsec, bpb.bsec);
+                x1 += sizeof(struct bsbpb);
+                if (fat == 32) {
+                    bsxbpb = (struct bsxbpb *)(img + x1);
+                    mk4(bsxbpb->bspf, bpb.bspf);
+                    mk2(bsxbpb->xflg, 0);
+                    mk2(bsxbpb->vers, 0);
+                    mk4(bsxbpb->rdcl, bpb.rdcl);
+                    mk2(bsxbpb->infs, bpb.infs);
+                    mk2(bsxbpb->bkbs, bpb.bkbs);
+                    x1 += sizeof(struct bsxbpb);
+                }
+                bsx = (struct bsx *)(img + x1);
+                mk1(bsx->sig, 0x29);
+                if (Iflag)
+                    x = opt_I;
+                else
+                    x = (((u_int)(1 + tm->tm_mon) << 8 |
+                            (u_int)tm->tm_mday) +
+                            ((u_int)tm->tm_sec << 8 |
+                                    (u_int)(tv.tv_usec / 10))) << 16 |
+                                    ((u_int)(1900 + tm->tm_year) +
+                                            ((u_int)tm->tm_hour << 8 |
+                                                    (u_int)tm->tm_min));
+                mk4(bsx->volid, x);
+                mklabel(bsx->label, opt_L ? opt_L : "NO NAME");
+                sprintf(buf, "FAT%u", fat);
+                setstr(bsx->type, buf, sizeof(bsx->type));
+                if (!opt_B) {
+                    x1 += sizeof(struct bsx);
+                    bs = (struct bs *)img;
+                    mk1(bs->jmp[0], 0xeb);
+                    mk1(bs->jmp[1], x1 - 2);
+                    mk1(bs->jmp[2], 0x90);
+                    setstr(bs->oem, opt_O ? opt_O : "BSD  4.4",
+                            sizeof(bs->oem));
+                    memcpy(img + x1, bootcode, sizeof(bootcode));
+                    mk2(img + MINBPS - 2, DOSMAGIC);
+                }
+            } else if (fat == 32 && bpb.infs != MAXU16 &&
+                    (lsn == bpb.infs || (bpb.bkbs != MAXU16 &&
+                                    lsn == bpb.bkbs + bpb.infs))) {
+                mk4(img, 0x41615252);
+                mk4(img + MINBPS - 28, 0x61417272);
+                mk4(img + MINBPS - 24, 0xffffffff);
+                mk4(img + MINBPS - 20, bpb.rdcl);
+                mk2(img + MINBPS - 2, DOSMAGIC);
+            } else if (lsn >= bpb.res && lsn < dir &&
+                    !((lsn - bpb.res) % (bpb.spf ? bpb.spf : bpb.bspf))) {
+                mk1(img[0], bpb.mid);
+                for (x = 1; x < fat * (fat == 32 ? 3 : 2) / 8; x++)
+                    mk1(img[x], fat == 32 && x % 4 == 3 ? 0x0f : 0xff);
+            } else if (lsn == dir && opt_L) {
+                de = (struct de *)img;
+                mklabel(de->namext, opt_L);
+                mk1(de->attr, 050);
+                x = (u_int)tm->tm_hour << 11 |
+                        (u_int)tm->tm_min << 5 |
+                        (u_int)tm->tm_sec >> 1;
+                mk2(de->time, x);
+                x = (u_int)(tm->tm_year - 80) << 9 |
+                        (u_int)(tm->tm_mon + 1) << 5 |
+                        (u_int)tm->tm_mday;
+                mk2(de->date, x);
+            }
+            if ((n = write(fd, img, bpb.bps)) == -1)
+                err(1, "%s", fname);
+            if ((unsigned)n != bpb.bps) {
+                errx(1, "%s: can't write sector %u", fname, lsn);
                 exit(1);
             }
-	}
+        }
     }
     return 0;
 }
@@ -725,8 +709,7 @@
 /*
  * Exit with error if file system is mounted.
  */
-static void
-check_mounted(const char *fname, mode_t mode)
+static void check_mounted(const char *fname, mode_t mode)
 {
 #ifdef ANDROID
     warnx("Skipping mount checks");
@@ -737,19 +720,18 @@
     int n, r;
 
     if (!(n = getmntinfo(&mp, MNT_NOWAIT)))
-	err(1, "getmntinfo");
+        err(1, "getmntinfo");
     len = strlen(_PATH_DEV);
     s1 = fname;
     if (!strncmp(s1, _PATH_DEV, len))
-	s1 += len;
+        s1 += len;
     r = S_ISCHR(mode) && s1 != fname && *s1 == 'r';
     for (; n--; mp++) {
-	s2 = mp->f_mntfromname;
-	if (!strncmp(s2, _PATH_DEV, len))
-	    s2 += len;
-	if ((r && s2 != mp->f_mntfromname && !strcmp(s1 + 1, s2)) ||
-	    !strcmp(s1, s2))
-	    errx(1, "%s is mounted on %s", fname, mp->f_mntonname);
+        s2 = mp->f_mntfromname;
+        if (!strncmp(s2, _PATH_DEV, len))
+            s2 += len;
+        if ((r && s2 != mp->f_mntfromname && !strcmp(s1 + 1, s2)) || !strcmp(s1, s2))
+            errx(1, "%s is mounted on %s", fname, mp->f_mntonname);
     }
 #endif
 }
@@ -757,15 +739,14 @@
 /*
  * Get a standard format.
  */
-static void
-getstdfmt(const char *fmt, struct bpb *bpb)
+static void getstdfmt(const char *fmt, struct bpb *bpb)
 {
     u_int x, i;
 
     x = sizeof(stdfmt) / sizeof(stdfmt[0]);
     for (i = 0; i < x && strcmp(fmt, stdfmt[i].name); i++);
     if (i == x)
-	errx(1, "%s: unknown standard format", fmt);
+        errx(1, "%s: unknown standard format", fmt);
     *bpb = stdfmt[i].bpb;
 }
 
@@ -774,9 +755,8 @@
  */
 
 #ifdef ANDROID
-static void
-getdiskinfo(int fd, const char *fname, const char *dtype, __unused int oflag,
-	    struct bpb *bpb)
+static void getdiskinfo(int fd, const char *fname, const char *dtype,
+                        __unused int oflag,struct bpb *bpb)
 {
     struct hd_geometry geom;
 
@@ -817,9 +797,8 @@
 
 #else
 
-static void
-getdiskinfo(int fd, const char *fname, const char *dtype, __unused int oflag,
-	    struct bpb *bpb)
+static void getdiskinfo(int fd, const char *fname, const char *dtype,
+                        __unused int oflag, struct bpb *bpb)
 {
     struct disklabel *lp, dlp;
     struct fd_type type;
@@ -829,97 +808,96 @@
 
     /* If the user specified a disk type, try to use that */
     if (dtype != NULL) {
-	lp = getdiskbyname(dtype);
+        lp = getdiskbyname(dtype);
     }
 
     /* Maybe it's a floppy drive */
     if (lp == NULL) {
-	if (ioctl(fd, DIOCGMEDIASIZE, &ms) == -1) {
-	    struct stat st;
+        if (ioctl(fd, DIOCGMEDIASIZE, &ms) == -1) {
+            struct stat st;
 
-	    if (fstat(fd, &st))
-		err(1, "Cannot get disk size");
-	    /* create a fake geometry for a file image */
-	    ms = st.st_size;
-	    dlp.d_secsize = 512;
-	    dlp.d_nsectors = 63;
-	    dlp.d_ntracks = 255;
-	    dlp.d_secperunit = ms / dlp.d_secsize;
-	    lp = &dlp;
-	} else if (ioctl(fd, FD_GTYPE, &type) != -1) {
-	    dlp.d_secsize = 128 << type.secsize;
-	    dlp.d_nsectors = type.sectrac;
-	    dlp.d_ntracks = type.heads;
-	    dlp.d_secperunit = ms / dlp.d_secsize;
-	    lp = &dlp;
-	}
+            if (fstat(fd, &st))
+                err(1, "Cannot get disk size");
+            /* create a fake geometry for a file image */
+            ms = st.st_size;
+            dlp.d_secsize = 512;
+            dlp.d_nsectors = 63;
+            dlp.d_ntracks = 255;
+            dlp.d_secperunit = ms / dlp.d_secsize;
+            lp = &dlp;
+        } else if (ioctl(fd, FD_GTYPE, &type) != -1) {
+            dlp.d_secsize = 128 << type.secsize;
+            dlp.d_nsectors = type.sectrac;
+            dlp.d_ntracks = type.heads;
+            dlp.d_secperunit = ms / dlp.d_secsize;
+            lp = &dlp;
+        }
     }
 
     /* Maybe it's a fixed drive */
     if (lp == NULL) {
-	if (ioctl(fd, DIOCGDINFO, &dlp) == -1) {
-	    if (bpb->bps == 0 && ioctl(fd, DIOCGSECTORSIZE, &dlp.d_secsize) == -1)
-		errx(1, "Cannot get sector size, %s", strerror(errno));
+        if (ioctl(fd, DIOCGDINFO, &dlp) == -1) {
+            if (bpb->bps == 0 && ioctl(fd, DIOCGSECTORSIZE, &dlp.d_secsize) == -1)
+                errx(1, "Cannot get sector size, %s", strerror(errno));
 
-	    /* XXX Should we use bpb->bps if it's set? */
-	    dlp.d_secperunit = ms / dlp.d_secsize;
+            /* XXX Should we use bpb->bps if it's set? */
+            dlp.d_secperunit = ms / dlp.d_secsize;
 
-	    if (bpb->spt == 0 && ioctl(fd, DIOCGFWSECTORS, &dlp.d_nsectors) == -1) {
-		warnx("Cannot get number of sectors per track, %s", strerror(errno));
-		dlp.d_nsectors = 63;
-	    }
-	    if (bpb->hds == 0 && ioctl(fd, DIOCGFWHEADS, &dlp.d_ntracks) == -1) {
-		warnx("Cannot get number of heads, %s", strerror(errno));
-		if (dlp.d_secperunit <= 63*1*1024)
-		    dlp.d_ntracks = 1;
-		else if (dlp.d_secperunit <= 63*16*1024)
-		    dlp.d_ntracks = 16;
-		else
-		    dlp.d_ntracks = 255;
-	    }
-	}
+            if (bpb->spt == 0 && ioctl(fd, DIOCGFWSECTORS, &dlp.d_nsectors) == -1) {
+                warnx("Cannot get number of sectors per track, %s", strerror(errno));
+                dlp.d_nsectors = 63;
+            }
+            if (bpb->hds == 0 && ioctl(fd, DIOCGFWHEADS, &dlp.d_ntracks) == -1) {
+                warnx("Cannot get number of heads, %s", strerror(errno));
+                if (dlp.d_secperunit <= 63*1*1024)
+                    dlp.d_ntracks = 1;
+                else if (dlp.d_secperunit <= 63*16*1024)
+                    dlp.d_ntracks = 16;
+                else
+                    dlp.d_ntracks = 255;
+            }
+        }
 
-	hs = (ms / dlp.d_secsize) - dlp.d_secperunit;
-	lp = &dlp;
+        hs = (ms / dlp.d_secsize) - dlp.d_secperunit;
+        lp = &dlp;
     }
 
     if (bpb->bps == 0)
-	bpb->bps = ckgeom(fname, lp->d_secsize, "bytes/sector");
+        bpb->bps = ckgeom(fname, lp->d_secsize, "bytes/sector");
     if (bpb->spt == 0)
-	bpb->spt = ckgeom(fname, lp->d_nsectors, "sectors/track");
+        bpb->spt = ckgeom(fname, lp->d_nsectors, "sectors/track");
     if (bpb->hds == 0)
-	bpb->hds = ckgeom(fname, lp->d_ntracks, "drive heads");
+        bpb->hds = ckgeom(fname, lp->d_ntracks, "drive heads");
     if (bpb->bsec == 0)
-	bpb->bsec = lp->d_secperunit;
+        bpb->bsec = lp->d_secperunit;
     if (bpb->hid == 0)
-	bpb->hid = hs;
+        bpb->hid = hs;
 }
 #endif
 
 /*
  * Print out BPB values.
  */
-static void
-print_bpb(struct bpb *bpb)
+static void print_bpb(struct bpb *bpb)
 {
     printf("bps=%u spc=%u res=%u nft=%u", bpb->bps, bpb->spc, bpb->res,
-	   bpb->nft);
+           bpb->nft);
     if (bpb->rde)
-	printf(" rde=%u", bpb->rde);
+        printf(" rde=%u", bpb->rde);
     if (bpb->sec)
-	printf(" sec=%u", bpb->sec);
+        printf(" sec=%u", bpb->sec);
     printf(" mid=%#x", bpb->mid);
     if (bpb->spf)
-	printf(" spf=%u", bpb->spf);
+        printf(" spf=%u", bpb->spf);
     printf(" spt=%u hds=%u hid=%u", bpb->spt, bpb->hds, bpb->hid);
     if (bpb->bsec)
-	printf(" bsec=%u", bpb->bsec);
+        printf(" bsec=%u", bpb->bsec);
     if (!bpb->spf) {
-	printf(" bspf=%u rdcl=%u", bpb->bspf, bpb->rdcl);
-	printf(" infs=");
-	printf(bpb->infs == MAXU16 ? "%#x" : "%u", bpb->infs);
-	printf(" bkbs=");
-	printf(bpb->bkbs == MAXU16 ? "%#x" : "%u", bpb->bkbs);
+        printf(" bspf=%u rdcl=%u", bpb->bspf, bpb->rdcl);
+        printf(" infs=");
+        printf(bpb->infs == MAXU16 ? "%#x" : "%u", bpb->infs);
+        printf(" bkbs=");
+        printf(bpb->bkbs == MAXU16 ? "%#x" : "%u", bpb->bkbs);
     }
     printf("\n");
 }
@@ -927,21 +905,19 @@
 /*
  * Check a disk geometry value.
  */
-static u_int
-ckgeom(const char *fname, u_int val, const char *msg)
+static u_int ckgeom(const char *fname, u_int val, const char *msg)
 {
     if (!val)
-	errx(1, "%s: no default %s", fname, msg);
+        errx(1, "%s: no default %s", fname, msg);
     if (val > MAXU16)
-	errx(1, "%s: illegal %s %d", fname, msg, val);
+        errx(1, "%s: illegal %s %d", fname, msg, val);
     return val;
 }
 
 /*
  * Convert and check a numeric option argument.
  */
-static u_int
-argtou(const char *arg, u_int lo, u_int hi, const char *msg)
+static u_int argtou(const char *arg, u_int lo, u_int hi, const char *msg)
 {
     char *s;
     u_long x;
@@ -949,15 +925,14 @@
     errno = 0;
     x = strtoul(arg, &s, 0);
     if (errno || !*arg || *s || x < lo || x > hi)
-	errx(1, "%s: bad %s", arg, msg);
+        errx(1, "%s: bad %s", arg, msg);
     return x;
 }
 
 /*
  * Same for off_t, with optional skmgpP suffix
  */
-static off_t
-argtooff(const char *arg, const char *msg)
+static off_t argtooff(const char *arg, const char *msg)
 {
     char *s;
     off_t x;
@@ -965,40 +940,40 @@
     x = strtoll(arg, &s, 0);
     /* allow at most one extra char */
     if (errno || x < 0 || (s[0] && s[1]) )
-	errx(1, "%s: bad %s", arg, msg);
-    if (*s) {	/* the extra char is the multiplier */
-	switch (*s) {
-	default:
-	    errx(1, "%s: bad %s", arg, msg);
-	    /* notreached */
-	
-	case 's':	/* sector */
-	case 'S':
-	    x <<= 9;	/* times 512 */
-	    break;
+        errx(1, "%s: bad %s", arg, msg);
+    if (*s) {    /* the extra char is the multiplier */
+        switch (*s) {
+            default:
+                errx(1, "%s: bad %s", arg, msg);
+                /* notreached */
 
-	case 'k':	/* kilobyte */
-	case 'K':
-	    x <<= 10;	/* times 1024 */
-	    break;
+            case 's':       /* sector */
+            case 'S':
+                x <<= 9;    /* times 512 */
+                break;
 
-	case 'm':	/* megabyte */
-	case 'M':
-	    x <<= 20;	/* times 1024*1024 */
-	    break;
+            case 'k':       /* kilobyte */
+            case 'K':
+                x <<= 10;   /* times 1024 */
+                break;
 
-	case 'g':	/* gigabyte */
-	case 'G':
-	    x <<= 30;	/* times 1024*1024*1024 */
-	    break;
+            case 'm':       /* megabyte */
+            case 'M':
+                x <<= 20;   /* times 1024*1024 */
+                break;
 
-	case 'p':	/* partition start */
-	case 'P':	/* partition start */
-	case 'l':	/* partition length */
-	case 'L':	/* partition length */
-	    errx(1, "%s: not supported yet %s", arg, msg);
-	    /* notreached */
-	}
+            case 'g':       /* gigabyte */
+            case 'G':
+                x <<= 30;   /* times 1024*1024*1024 */
+                break;
+
+            case 'p':       /* partition start */
+            case 'P':       /* partition start */
+            case 'l':       /* partition length */
+            case 'L':       /* partition length */
+                errx(1, "%s: not supported yet %s", arg, msg);
+                /* notreached */
+        }
     }
     return x;
 }
@@ -1006,15 +981,14 @@
 /*
  * Check a volume label.
  */
-static int
-oklabel(const char *src)
+static int oklabel(const char *src)
 {
     int c, i;
 
     for (i = 0; i <= 11; i++) {
-	c = (u_char)*src++;
-	if (c < ' ' + !i || strchr("\"*+,./:;<=>?[\\]|", c))
-	    break;
+        c = (u_char)*src++;
+        if (c < ' ' + !i || strchr("\"*+,./:;<=>?[\\]|", c))
+            break;
     }
     return i && !c;
 }
@@ -1022,58 +996,55 @@
 /*
  * Make a volume label.
  */
-static void
-mklabel(u_int8_t *dest, const char *src)
+static void mklabel(u_int8_t *dest, const char *src)
 {
     int c, i;
 
     for (i = 0; i < 11; i++) {
-	c = *src ? toupper(*src++) : ' ';
-	*dest++ = !i && c == '\xe5' ? 5 : c;
+        c = *src ? toupper(*src++) : ' ';
+        *dest++ = !i && c == '\xe5' ? 5 : c;
     }
 }
 
 /*
  * Copy string, padding with spaces.
  */
-static void
-setstr(u_int8_t *dest, const char *src, size_t len)
+static void setstr(u_int8_t *dest, const char *src, size_t len)
 {
     while (len--)
-	*dest++ = *src ? *src++ : ' ';
+        *dest++ = *src ? *src++ : ' ';
 }
 
 /*
  * Print usage message.
  */
-static void
-usage(void)
+static void usage(void)
 {
-	fprintf(stderr,
-	    "usage: newfs_msdos [ -options ] special [disktype]\n"
-	    "where the options are:\n"
-	    "\t-@ create file system at specified offset\n"                         
-	    "\t-B get bootstrap from file\n"
-	    "\t-C create image file with specified size\n"
-	    "\t-F FAT type (12, 16, or 32)\n"
-	    "\t-I volume ID\n"
-	    "\t-L volume label\n"
-	    "\t-N don't create file system: just print out parameters\n"
-	    "\t-O OEM string\n"
-	    "\t-S bytes/sector\n"
-	    "\t-a sectors/FAT\n"
-	    "\t-b block size\n"
-	    "\t-c sectors/cluster\n"
-	    "\t-e root directory entries\n"
-	    "\t-f standard format\n"
-	    "\t-h drive heads\n"
-	    "\t-i file system info sector\n"
-	    "\t-k backup boot sector\n"
-	    "\t-m media descriptor\n"
-	    "\t-n number of FATs\n"
-	    "\t-o hidden sectors\n"
-	    "\t-r reserved sectors\n"
-	    "\t-s file system size (sectors)\n"
-	    "\t-u sectors/track\n");
-	exit(1);
+    fprintf(stderr,
+            "usage: newfs_msdos [ -options ] special [disktype]\n"
+            "where the options are:\n"
+            "\t-@ create file system at specified offset\n"
+            "\t-B get bootstrap from file\n"
+            "\t-C create image file with specified size\n"
+            "\t-F FAT type (12, 16, or 32)\n"
+            "\t-I volume ID\n"
+            "\t-L volume label\n"
+            "\t-N don't create file system: just print out parameters\n"
+            "\t-O OEM string\n"
+            "\t-S bytes/sector\n"
+            "\t-a sectors/FAT\n"
+            "\t-b block size\n"
+            "\t-c sectors/cluster\n"
+            "\t-e root directory entries\n"
+            "\t-f standard format\n"
+            "\t-h drive heads\n"
+            "\t-i file system info sector\n"
+            "\t-k backup boot sector\n"
+            "\t-m media descriptor\n"
+            "\t-n number of FATs\n"
+            "\t-o hidden sectors\n"
+            "\t-r reserved sectors\n"
+            "\t-s file system size (sectors)\n"
+            "\t-u sectors/track\n");
+    exit(1);
 }